Skip to contentSkip to conversation

hiddev: Switch to unlocked_ioctl

PATCH In review Alan Cox 3 participants 3 messages May 22, 2008 – May 26, 2008

Subsystems (2)
lore
Share & tools
lore

Alan Cox

author
#0 lore raw

PATCH 1/1 hiddev: Switch to unlocked_ioctl

Push down the BKL. In some cases compat_ioctl already doesn't take the BKL so we don't either. Some of the locking here seems already dubious and object lifetimes want documenting

drivers/hid/usbhid/hiddev.c +9 -2
index 95cc192..fe4f364 100644
@@ -406,6 +406,7 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
 	uref_multi = kmalloc(sizeof(struct hiddev_usage_ref_multi), GFP_KERNEL);
 	if (!uref_multi)
 		return -ENOMEM;
+	lock_kernel();
 	uref = &uref_multi->uref;
 	if (cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) {
 		if (copy_from_user(uref_multi, user_arg,
@@ -501,12 +502,15 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
 		}
 
 goodreturn:
+		unlock_kernel();
 		kfree(uref_multi);
 		return 0;
 fault:
+		unlock_kernel();
 		kfree(uref_multi);
 		return -EFAULT;
 inval:
+		unlock_kernel();
 		kfree(uref_multi);
 		return -EINVAL;
 	}
@@ -540,7 +544,7 @@ static noinline int hiddev_ioctl_string(struct hiddev *hiddev, unsigned int cmd,
 	return len;
 }
 
-static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct hiddev_list *list = file->private_data;
 	struct hiddev *hiddev = list->hiddev;
@@ -555,7 +559,10 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 	struct usbhid_device *usbhid = hid->driver_data;
 	void __user *user_arg = (void __user *)arg;
 	int i;
+	
+	/* Called without BKL by compat methods so no BKL taken */
 
+	/* FIXME: Who or what stop this racing with a disconnect ?? */
 	if (!hiddev->exist)
 		return -EIO;
 
@@ -768,7 +775,7 @@ static const struct file_operations hiddev_fops = {
 	.poll =		hiddev_poll,
 	.open =		hiddev_open,
 	.release =	hiddev_release,
-	.ioctl =	hiddev_ioctl,
+	.unlocked_ioctl =	hiddev_ioctl,
 	.fasync =	hiddev_fasync,
 #ifdef CONFIG_COMPAT
 	.compat_ioctl	= hiddev_compat_ioctl,
#1 lore raw
Quoted 2 lines · Alan Cox

Push down the BKL. In some cases compat_ioctl already doesn't take the BKL so we don't either.

Thanks.

drivers/hid/usbhid/hiddev.c static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd · line 567

Quoted 10 lines
drivers/hid/usbhid/hiddev.c +3 -0
@@ -555,7 +559,10 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
 	struct usbhid_device *usbhid = hid->driver_data;
 	void __user *user_arg = (void __user *)arg;
 	int i;
+	
+	/* Called without BKL by compat methods so no BKL taken */
 
+	/* FIXME: Who or what stop this racing with a disconnect ?? */
 	if (!hiddev->exist)
 		return -EIO;

Oliver (added to CC) -- I vaguely remember you already fixing this race, but I don't seem to be able to find the patch anywhere. Do I just remember incorrectly?

Thanks,

Signature · 1 line
Jiri Kosina
#2 lore raw

Am Montag 26 Mai 2008 10:55:09 schrieb Jiri Kosina:

Quoted 7 lines · Alan Cox
Quoted 3 lines

Push down the BKL. In some cases compat_ioctl already doesn't take the BKL so we don't either.

Thanks.

Quoted 14 lines
Quoted 10 lines
drivers/hid/usbhid/hiddev.c +2 -0
@@ -555,7 +559,10 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd
       struct usbhid_device *usbhid = hid->driver_data;
       void __user *user_arg = (void __user *)arg;
       int i;
+     
+     /* Called without BKL by compat methods so no BKL taken */


+     /* FIXME: Who or what stop this racing with a disconnect ?? */ if (!hiddev->exist)
              return -EIO;

Oliver (added to CC) -- I vaguely remember you already fixing this race, but I don't seem to be able to find the patch anywhere. Do I just remember incorrectly?

I fixed a race between disconnect and open. Ioctl was not involved.

Regards
Oliver