Skip to content

Commit 979c407

Browse files
Alan-CoxJiri Kosina
authored andcommitted
HID: Push down BKL into ioctl handler in hidraw
In this case I simply wrapped it as code review suggests the locking already terminally broken and I didn't want to make it first. See added comment Signed-off-by: Alan Cox <[email protected]> Signed-off-by: Jiri Kosina <[email protected]>
1 parent 7961df1 commit 979c407

File tree

1 file changed

+24
-22
lines changed

1 file changed

+24
-22
lines changed

drivers/hid/hidraw.c

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count,
105105
static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
106106
{
107107
unsigned int minor = iminor(file->f_path.dentry->d_inode);
108+
/* FIXME: What stops hidraw_table going NULL */
108109
struct hid_device *dev = hidraw_table[minor]->hid;
109110
__u8 *buf;
110111
int ret = 0;
@@ -214,35 +215,38 @@ static int hidraw_release(struct inode * inode, struct file * file)
214215
return 0;
215216
}
216217

217-
static int hidraw_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
218+
static long hidraw_ioctl(struct file *file, unsigned int cmd,
219+
unsigned long arg)
218220
{
221+
struct inode *inode = file->f_path.dentry->d_inode;
219222
unsigned int minor = iminor(inode);
223+
long ret = 0;
224+
/* FIXME: What stops hidraw_table going NULL */
220225
struct hidraw *dev = hidraw_table[minor];
221226
void __user *user_arg = (void __user*) arg;
222227

228+
lock_kernel();
223229
switch (cmd) {
224230
case HIDIOCGRDESCSIZE:
225231
if (put_user(dev->hid->rsize, (int __user *)arg))
226-
return -EFAULT;
227-
return 0;
232+
ret = -EFAULT;
233+
break;
228234

229235
case HIDIOCGRDESC:
230236
{
231237
__u32 len;
232238

233239
if (get_user(len, (int __user *)arg))
234-
return -EFAULT;
235-
236-
if (len > HID_MAX_DESCRIPTOR_SIZE - 1)
237-
return -EINVAL;
238-
239-
if (copy_to_user(user_arg + offsetof(
240-
struct hidraw_report_descriptor,
241-
value[0]),
242-
dev->hid->rdesc,
243-
min(dev->hid->rsize, len)))
244-
return -EFAULT;
245-
return 0;
240+
ret = -EFAULT;
241+
else if (len > HID_MAX_DESCRIPTOR_SIZE - 1)
242+
ret = -EINVAL;
243+
else if (copy_to_user(user_arg + offsetof(
244+
struct hidraw_report_descriptor,
245+
value[0]),
246+
dev->hid->rdesc,
247+
min(dev->hid->rsize, len)))
248+
ret = -EFAULT;
249+
break;
246250
}
247251
case HIDIOCGRAWINFO:
248252
{
@@ -252,15 +256,13 @@ static int hidraw_ioctl(struct inode *inode, struct file *file, unsigned int cmd
252256
dinfo.vendor = dev->hid->vendor;
253257
dinfo.product = dev->hid->product;
254258
if (copy_to_user(user_arg, &dinfo, sizeof(dinfo)))
255-
return -EFAULT;
256-
257-
return 0;
259+
ret = -EFAULT;
260+
break;
258261
}
259262
default:
260-
printk(KERN_EMERG "hidraw: unsupported ioctl() %x\n",
261-
cmd);
263+
ret = -ENOTTY;
262264
}
263-
return -EINVAL;
265+
return ret;
264266
}
265267

266268
static const struct file_operations hidraw_ops = {
@@ -270,7 +272,7 @@ static const struct file_operations hidraw_ops = {
270272
.poll = hidraw_poll,
271273
.open = hidraw_open,
272274
.release = hidraw_release,
273-
.ioctl = hidraw_ioctl,
275+
.unlocked_ioctl = hidraw_ioctl,
274276
};
275277

276278
void hidraw_report_event(struct hid_device *hid, u8 *data, int len)

0 commit comments

Comments
 (0)