• Stefan Richter's avatar
    firewire: cdev: prevent race between first get_info ioctl and bus reset event queuing · 93b37905
    Stefan Richter authored
    Between open(2) of a /dev/fw* and the first FW_CDEV_IOC_GET_INFO
    ioctl(2) on it, the kernel already queues FW_CDEV_EVENT_BUS_RESET events
    to be read(2) by the client.  The get_info ioctl is practically always
    issued right away after open, hence this condition only occurs if the
    client opens during a bus reset, especially during a rapid series of bus
    resets.
    
    The problem with this condition is twofold:
    
      - These bus reset events carry the (as yet undocumented) @closure
        value of 0.  But it is not the kernel's place to choose closures;
        they are privat to the client.  E.g., this 0 value forced from the
        kernel makes it unsafe for clients to dereference it as a pointer to
        a closure object without NULL pointer check.
    
      - It is impossible for clients to determine the relative order of bus
        reset events from get_info ioctl(2) versus those from read(2),
        except in one way:  By comparison of closure values.  Again, such a
        procedure imposes complexity on clients and reduces freedom in use
        of the bus reset closure.
    
    So, change the ABI to suppress queuing of bus reset events before the
    first FW_CDEV_IOC_GET_INFO ioctl was issued by the client.
    
    Note, this ABI change cannot be version-controlled.  The kernel cannot
    distinguish old from new clients before the first FW_CDEV_IOC_GET_INFO
    ioctl.
    
    We will try to back-merge this change into currently maintained stable/
    longterm series, and we only document the new behaviour.  The old
    behavior is now considered a kernel bug, which it basically is.
    Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
    Cc: <stable@kernel.org>
    93b37905
core-cdev.c 45.1 KB