]> err.no Git - linux-2.6/commitdiff
firewire: prevent userspace from accessing shut down devices
authorJay Fenlason <fenlason@redhat.com>
Fri, 16 May 2008 15:15:23 +0000 (11:15 -0400)
committerStefan Richter <stefanr@s5r6.in-berlin.de>
Tue, 20 May 2008 16:24:17 +0000 (18:24 +0200)
If userspace ignores the POLLERR bit from poll(), and only attempts to
read() the device when POLLIN is set, it can still make ioctl() calls on
a device that has been removed from the system.  The node_id and
generation returned by GET_INFO will be outdated, but INITIATE_BUS_RESET
would still cause a bus reset, and GET_CYCLE_TIMER will return data.
And if you guess the correct generation to use, you can send requests to
a different device on the bus, and get responses back.

This patch prevents open, ioctl, compat_ioctl, and mmap against shutdown
devices.

Signed-off-by: Jay Fenlason <fenlason@redhat.com>
Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
drivers/firewire/fw-cdev.c

index 4a541921a14a26e2a24c8c814b92f17035098de3..dda14015e873dce10c4bfbd796b03952d079b9b3 100644 (file)
@@ -113,6 +113,11 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
        if (device == NULL)
                return -ENODEV;
 
+       if (fw_device_is_shutdown(device)) {
+               fw_device_put(device);
+               return -ENODEV;
+       }
+
        client = kzalloc(sizeof(*client), GFP_KERNEL);
        if (client == NULL) {
                fw_device_put(device);
@@ -901,6 +906,9 @@ fw_device_op_ioctl(struct file *file,
 {
        struct client *client = file->private_data;
 
+       if (fw_device_is_shutdown(client->device))
+               return -ENODEV;
+
        return dispatch_ioctl(client, cmd, (void __user *) arg);
 }
 
@@ -911,6 +919,9 @@ fw_device_op_compat_ioctl(struct file *file,
 {
        struct client *client = file->private_data;
 
+       if (fw_device_is_shutdown(client->device))
+               return -ENODEV;
+
        return dispatch_ioctl(client, cmd, compat_ptr(arg));
 }
 #endif
@@ -922,6 +933,9 @@ static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma)
        unsigned long size;
        int page_count, retval;
 
+       if (fw_device_is_shutdown(client->device))
+               return -ENODEV;
+
        /* FIXME: We could support multiple buffers, but we don't. */
        if (client->buffer.pages != NULL)
                return -EBUSY;