Commit 551f4cb9 authored by Jay Fenlason's avatar Jay Fenlason Committed by Stefan Richter

firewire: prevent userspace from accessing shut down devices

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: default avatarJay Fenlason <fenlason@redhat.com>
Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
parent 93c596f7
...@@ -113,6 +113,11 @@ static int fw_device_op_open(struct inode *inode, struct file *file) ...@@ -113,6 +113,11 @@ static int fw_device_op_open(struct inode *inode, struct file *file)
if (device == NULL) if (device == NULL)
return -ENODEV; return -ENODEV;
if (fw_device_is_shutdown(device)) {
fw_device_put(device);
return -ENODEV;
}
client = kzalloc(sizeof(*client), GFP_KERNEL); client = kzalloc(sizeof(*client), GFP_KERNEL);
if (client == NULL) { if (client == NULL) {
fw_device_put(device); fw_device_put(device);
...@@ -901,6 +906,9 @@ fw_device_op_ioctl(struct file *file, ...@@ -901,6 +906,9 @@ fw_device_op_ioctl(struct file *file,
{ {
struct client *client = file->private_data; struct client *client = file->private_data;
if (fw_device_is_shutdown(client->device))
return -ENODEV;
return dispatch_ioctl(client, cmd, (void __user *) arg); return dispatch_ioctl(client, cmd, (void __user *) arg);
} }
...@@ -911,6 +919,9 @@ fw_device_op_compat_ioctl(struct file *file, ...@@ -911,6 +919,9 @@ fw_device_op_compat_ioctl(struct file *file,
{ {
struct client *client = file->private_data; struct client *client = file->private_data;
if (fw_device_is_shutdown(client->device))
return -ENODEV;
return dispatch_ioctl(client, cmd, compat_ptr(arg)); return dispatch_ioctl(client, cmd, compat_ptr(arg));
} }
#endif #endif
...@@ -922,6 +933,9 @@ static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -922,6 +933,9 @@ static int fw_device_op_mmap(struct file *file, struct vm_area_struct *vma)
unsigned long size; unsigned long size;
int page_count, retval; int page_count, retval;
if (fw_device_is_shutdown(client->device))
return -ENODEV;
/* FIXME: We could support multiple buffers, but we don't. */ /* FIXME: We could support multiple buffers, but we don't. */
if (client->buffer.pages != NULL) if (client->buffer.pages != NULL)
return -EBUSY; return -EBUSY;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment