1// SPDX-License-Identifier: GPL-2.0-only
2/*
3 * HID raw devices, giving access to raw HID events.
4 *
5 * In comparison to hiddev, this device does not process the
6 * hid events at all (no parsing, no lookups). This lets applications
7 * to work on raw hid events as they want to, and avoids a need to
8 * use a transport-specific userspace libhid/libusb libraries.
9 *
10 * Copyright (c) 2007-2014 Jiri Kosina
11 */
12
13
14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
16#include <linux/fs.h>
17#include <linux/module.h>
18#include <linux/errno.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/cdev.h>
22#include <linux/poll.h>
23#include <linux/device.h>
24#include <linux/major.h>
25#include <linux/slab.h>
26#include <linux/hid.h>
27#include <linux/mutex.h>
28#include <linux/sched/signal.h>
29#include <linux/string.h>
30
31#include <linux/hidraw.h>
32
33static int hidraw_major;
34static struct cdev hidraw_cdev;
35static const struct class hidraw_class = {
36 .name = "hidraw",
37};
38static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES];
39static DECLARE_RWSEM(minors_rwsem);
40
41static inline bool hidraw_is_revoked(struct hidraw_list *list)
42{
43 return list->revoked;
44}
45
46static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
47{
48 struct hidraw_list *list = file->private_data;
49 int ret = 0, len;
50 DECLARE_WAITQUEUE(wait, current);
51
52 if (hidraw_is_revoked(list))
53 return -ENODEV;
54
55 mutex_lock(lock: &list->read_mutex);
56
57 while (ret == 0) {
58 if (list->head == list->tail) {
59 add_wait_queue(wq_head: &list->hidraw->wait, wq_entry: &wait);
60 set_current_state(TASK_INTERRUPTIBLE);
61
62 while (list->head == list->tail) {
63 if (signal_pending(current)) {
64 ret = -ERESTARTSYS;
65 break;
66 }
67 if (!list->hidraw->exist) {
68 ret = -EIO;
69 break;
70 }
71 if (file->f_flags & O_NONBLOCK) {
72 ret = -EAGAIN;
73 break;
74 }
75
76 /* allow O_NONBLOCK to work well from other threads */
77 mutex_unlock(lock: &list->read_mutex);
78 schedule();
79 mutex_lock(lock: &list->read_mutex);
80 set_current_state(TASK_INTERRUPTIBLE);
81 }
82
83 set_current_state(TASK_RUNNING);
84 remove_wait_queue(wq_head: &list->hidraw->wait, wq_entry: &wait);
85 }
86
87 if (ret)
88 goto out;
89
90 len = list->buffer[list->tail].len > count ?
91 count : list->buffer[list->tail].len;
92
93 if (list->buffer[list->tail].value) {
94 if (copy_to_user(to: buffer, from: list->buffer[list->tail].value, n: len)) {
95 ret = -EFAULT;
96 goto out;
97 }
98 ret = len;
99 }
100
101 kfree(objp: list->buffer[list->tail].value);
102 list->buffer[list->tail].value = NULL;
103 list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1);
104 }
105out:
106 mutex_unlock(lock: &list->read_mutex);
107 return ret;
108}
109
110/*
111 * The first byte of the report buffer is expected to be a report number.
112 */
113static ssize_t hidraw_send_report(struct file *file, const char __user *buffer, size_t count, unsigned char report_type)
114{
115 unsigned int minor = iminor(inode: file_inode(f: file));
116 struct hid_device *dev;
117 __u8 *buf;
118 int ret = 0;
119
120 lockdep_assert_held(&minors_rwsem);
121
122 if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
123 ret = -ENODEV;
124 goto out;
125 }
126
127 dev = hidraw_table[minor]->hid;
128
129 if (count > HID_MAX_BUFFER_SIZE) {
130 hid_warn(dev, "pid %d passed too large report\n",
131 task_pid_nr(current));
132 ret = -EINVAL;
133 goto out;
134 }
135
136 if (count < 2) {
137 hid_warn(dev, "pid %d passed too short report\n",
138 task_pid_nr(current));
139 ret = -EINVAL;
140 goto out;
141 }
142
143 buf = memdup_user(buffer, count);
144 if (IS_ERR(ptr: buf)) {
145 ret = PTR_ERR(ptr: buf);
146 goto out;
147 }
148
149 if ((report_type == HID_OUTPUT_REPORT) &&
150 !(dev->quirks & HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP)) {
151 ret = __hid_hw_output_report(hdev: dev, buf, len: count, source: (u64)(long)file, from_bpf: false);
152 /*
153 * compatibility with old implementation of USB-HID and I2C-HID:
154 * if the device does not support receiving output reports,
155 * on an interrupt endpoint, fallback to SET_REPORT HID command.
156 */
157 if (ret != -ENOSYS)
158 goto out_free;
159 }
160
161 ret = __hid_hw_raw_request(hdev: dev, reportnum: buf[0], buf, len: count, rtype: report_type,
162 reqtype: HID_REQ_SET_REPORT, source: (u64)(long)file, from_bpf: false);
163
164out_free:
165 kfree(objp: buf);
166out:
167 return ret;
168}
169
170static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
171{
172 struct hidraw_list *list = file->private_data;
173 ssize_t ret;
174 down_read(sem: &minors_rwsem);
175 if (hidraw_is_revoked(list))
176 ret = -ENODEV;
177 else
178 ret = hidraw_send_report(file, buffer, count, report_type: HID_OUTPUT_REPORT);
179 up_read(sem: &minors_rwsem);
180 return ret;
181}
182
183
184/*
185 * This function performs a Get_Report transfer over the control endpoint
186 * per section 7.2.1 of the HID specification, version 1.1. The first byte
187 * of buffer is the report number to request, or 0x0 if the device does not
188 * use numbered reports. The report_type parameter can be HID_FEATURE_REPORT
189 * or HID_INPUT_REPORT.
190 */
191static ssize_t hidraw_get_report(struct file *file, char __user *buffer, size_t count, unsigned char report_type)
192{
193 unsigned int minor = iminor(inode: file_inode(f: file));
194 struct hid_device *dev;
195 __u8 *buf;
196 int ret = 0, len;
197 unsigned char report_number;
198
199 lockdep_assert_held(&minors_rwsem);
200
201 if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
202 ret = -ENODEV;
203 goto out;
204 }
205
206 dev = hidraw_table[minor]->hid;
207
208 if (!dev->ll_driver->raw_request) {
209 ret = -ENODEV;
210 goto out;
211 }
212
213 if (count > HID_MAX_BUFFER_SIZE) {
214 hid_warn(dev, "pid %d passed too large report\n",
215 task_pid_nr(current));
216 ret = -EINVAL;
217 goto out;
218 }
219
220 if (count < 2) {
221 hid_warn(dev, "pid %d passed too short report\n",
222 task_pid_nr(current));
223 ret = -EINVAL;
224 goto out;
225 }
226
227 buf = kmalloc(count, GFP_KERNEL);
228 if (!buf) {
229 ret = -ENOMEM;
230 goto out;
231 }
232
233 /*
234 * Read the first byte from the user. This is the report number,
235 * which is passed to hid_hw_raw_request().
236 */
237 if (copy_from_user(to: &report_number, from: buffer, n: 1)) {
238 ret = -EFAULT;
239 goto out_free;
240 }
241
242 ret = __hid_hw_raw_request(hdev: dev, reportnum: report_number, buf, len: count, rtype: report_type,
243 reqtype: HID_REQ_GET_REPORT, source: (u64)(long)file, from_bpf: false);
244
245 if (ret < 0)
246 goto out_free;
247
248 len = (ret < count) ? ret : count;
249
250 if (copy_to_user(to: buffer, from: buf, n: len)) {
251 ret = -EFAULT;
252 goto out_free;
253 }
254
255 ret = len;
256
257out_free:
258 kfree(objp: buf);
259out:
260 return ret;
261}
262
263static __poll_t hidraw_poll(struct file *file, poll_table *wait)
264{
265 struct hidraw_list *list = file->private_data;
266 __poll_t mask = EPOLLOUT | EPOLLWRNORM; /* hidraw is always writable */
267
268 poll_wait(filp: file, wait_address: &list->hidraw->wait, p: wait);
269 if (list->head != list->tail)
270 mask |= EPOLLIN | EPOLLRDNORM;
271 if (!list->hidraw->exist || hidraw_is_revoked(list))
272 mask |= EPOLLERR | EPOLLHUP;
273 return mask;
274}
275
276static int hidraw_open(struct inode *inode, struct file *file)
277{
278 unsigned int minor = iminor(inode);
279 struct hidraw *dev;
280 struct hidraw_list *list;
281 unsigned long flags;
282 int err = 0;
283
284 if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) {
285 err = -ENOMEM;
286 goto out;
287 }
288
289 /*
290 * Technically not writing to the hidraw_table but a write lock is
291 * required to protect the device refcount. This is symmetrical to
292 * hidraw_release().
293 */
294 down_write(sem: &minors_rwsem);
295 if (!hidraw_table[minor] || !hidraw_table[minor]->exist) {
296 err = -ENODEV;
297 goto out_unlock;
298 }
299
300 dev = hidraw_table[minor];
301 if (!dev->open++) {
302 err = hid_hw_power(hdev: dev->hid, PM_HINT_FULLON);
303 if (err < 0) {
304 dev->open--;
305 goto out_unlock;
306 }
307
308 err = hid_hw_open(hdev: dev->hid);
309 if (err < 0) {
310 hid_hw_power(hdev: dev->hid, PM_HINT_NORMAL);
311 dev->open--;
312 goto out_unlock;
313 }
314 }
315
316 list->hidraw = hidraw_table[minor];
317 mutex_init(&list->read_mutex);
318 spin_lock_irqsave(&hidraw_table[minor]->list_lock, flags);
319 list_add_tail(new: &list->node, head: &hidraw_table[minor]->list);
320 spin_unlock_irqrestore(lock: &hidraw_table[minor]->list_lock, flags);
321 file->private_data = list;
322out_unlock:
323 up_write(sem: &minors_rwsem);
324out:
325 if (err < 0)
326 kfree(objp: list);
327 return err;
328
329}
330
331static int hidraw_fasync(int fd, struct file *file, int on)
332{
333 struct hidraw_list *list = file->private_data;
334
335 if (hidraw_is_revoked(list))
336 return -ENODEV;
337
338 return fasync_helper(fd, file, on, &list->fasync);
339}
340
341static void drop_ref(struct hidraw *hidraw, int exists_bit)
342{
343 if (exists_bit) {
344 hidraw->exist = 0;
345 if (hidraw->open) {
346 hid_hw_close(hdev: hidraw->hid);
347 wake_up_interruptible(&hidraw->wait);
348 }
349 device_destroy(cls: &hidraw_class,
350 MKDEV(hidraw_major, hidraw->minor));
351 } else {
352 --hidraw->open;
353 }
354 if (!hidraw->open) {
355 if (!hidraw->exist) {
356 hidraw_table[hidraw->minor] = NULL;
357 kfree(objp: hidraw);
358 } else {
359 /* close device for last reader */
360 hid_hw_close(hdev: hidraw->hid);
361 hid_hw_power(hdev: hidraw->hid, PM_HINT_NORMAL);
362 }
363 }
364}
365
366static int hidraw_release(struct inode * inode, struct file * file)
367{
368 unsigned int minor = iminor(inode);
369 struct hidraw_list *list = file->private_data;
370 unsigned long flags;
371
372 down_write(sem: &minors_rwsem);
373
374 spin_lock_irqsave(&hidraw_table[minor]->list_lock, flags);
375 while (list->tail != list->head) {
376 kfree(objp: list->buffer[list->tail].value);
377 list->buffer[list->tail].value = NULL;
378 list->tail = (list->tail + 1) & (HIDRAW_BUFFER_SIZE - 1);
379 }
380 list_del(entry: &list->node);
381 spin_unlock_irqrestore(lock: &hidraw_table[minor]->list_lock, flags);
382 kfree(objp: list);
383
384 drop_ref(hidraw: hidraw_table[minor], exists_bit: 0);
385
386 up_write(sem: &minors_rwsem);
387 return 0;
388}
389
390static int hidraw_revoke(struct hidraw_list *list)
391{
392 list->revoked = true;
393
394 return 0;
395}
396
397static long hidraw_fixed_size_ioctl(struct file *file, struct hidraw *dev, unsigned int cmd,
398 void __user *arg)
399{
400 struct hid_device *hid = dev->hid;
401
402 switch (cmd) {
403 case HIDIOCGRDESCSIZE:
404 if (put_user(hid->rsize, (int __user *)arg))
405 return -EFAULT;
406 break;
407
408 case HIDIOCGRDESC:
409 {
410 __u32 len;
411
412 if (get_user(len, (int __user *)arg))
413 return -EFAULT;
414
415 if (len > HID_MAX_DESCRIPTOR_SIZE - 1)
416 return -EINVAL;
417
418 if (copy_to_user(to: arg + offsetof(
419 struct hidraw_report_descriptor,
420 value[0]),
421 from: hid->rdesc,
422 min(hid->rsize, len)))
423 return -EFAULT;
424
425 break;
426 }
427 case HIDIOCGRAWINFO:
428 {
429 struct hidraw_devinfo dinfo;
430
431 dinfo.bustype = hid->bus;
432 dinfo.vendor = hid->vendor;
433 dinfo.product = hid->product;
434 if (copy_to_user(to: arg, from: &dinfo, n: sizeof(dinfo)))
435 return -EFAULT;
436 break;
437 }
438 case HIDIOCREVOKE:
439 {
440 struct hidraw_list *list = file->private_data;
441
442 if (arg)
443 return -EINVAL;
444
445 return hidraw_revoke(list);
446 }
447 default:
448 /*
449 * None of the above ioctls can return -EAGAIN, so
450 * use it as a marker that we need to check variable
451 * length ioctls.
452 */
453 return -EAGAIN;
454 }
455
456 return 0;
457}
458
459static long hidraw_rw_variable_size_ioctl(struct file *file, struct hidraw *dev, unsigned int cmd,
460 void __user *user_arg)
461{
462 int len = _IOC_SIZE(cmd);
463
464 switch (cmd & ~IOCSIZE_MASK) {
465 case HIDIOCSFEATURE(0):
466 return hidraw_send_report(file, buffer: user_arg, count: len, report_type: HID_FEATURE_REPORT);
467 case HIDIOCGFEATURE(0):
468 return hidraw_get_report(file, buffer: user_arg, count: len, report_type: HID_FEATURE_REPORT);
469 case HIDIOCSINPUT(0):
470 return hidraw_send_report(file, buffer: user_arg, count: len, report_type: HID_INPUT_REPORT);
471 case HIDIOCGINPUT(0):
472 return hidraw_get_report(file, buffer: user_arg, count: len, report_type: HID_INPUT_REPORT);
473 case HIDIOCSOUTPUT(0):
474 return hidraw_send_report(file, buffer: user_arg, count: len, report_type: HID_OUTPUT_REPORT);
475 case HIDIOCGOUTPUT(0):
476 return hidraw_get_report(file, buffer: user_arg, count: len, report_type: HID_OUTPUT_REPORT);
477 }
478
479 return -EINVAL;
480}
481
482static long hidraw_ro_variable_size_ioctl(struct file *file, struct hidraw *dev, unsigned int cmd,
483 void __user *user_arg)
484{
485 struct hid_device *hid = dev->hid;
486 int len = _IOC_SIZE(cmd);
487 int field_len;
488
489 switch (cmd & ~IOCSIZE_MASK) {
490 case HIDIOCGRAWNAME(0):
491 field_len = strlen(hid->name) + 1;
492 if (len > field_len)
493 len = field_len;
494 return copy_to_user(to: user_arg, from: hid->name, n: len) ? -EFAULT : len;
495 case HIDIOCGRAWPHYS(0):
496 field_len = strlen(hid->phys) + 1;
497 if (len > field_len)
498 len = field_len;
499 return copy_to_user(to: user_arg, from: hid->phys, n: len) ? -EFAULT : len;
500 case HIDIOCGRAWUNIQ(0):
501 field_len = strlen(hid->uniq) + 1;
502 if (len > field_len)
503 len = field_len;
504 return copy_to_user(to: user_arg, from: hid->uniq, n: len) ? -EFAULT : len;
505 }
506
507 return -EINVAL;
508}
509
510static long hidraw_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
511{
512 struct inode *inode = file_inode(f: file);
513 unsigned int minor = iminor(inode);
514 struct hidraw *dev;
515 struct hidraw_list *list = file->private_data;
516 void __user *user_arg = (void __user *)arg;
517 int ret;
518
519 down_read(sem: &minors_rwsem);
520 dev = hidraw_table[minor];
521 if (!dev || !dev->exist || hidraw_is_revoked(list)) {
522 ret = -ENODEV;
523 goto out;
524 }
525
526 if (_IOC_TYPE(cmd) != 'H') {
527 ret = -EINVAL;
528 goto out;
529 }
530
531 if (_IOC_NR(cmd) > HIDIOCTL_LAST || _IOC_NR(cmd) == 0) {
532 ret = -ENOTTY;
533 goto out;
534 }
535
536 ret = hidraw_fixed_size_ioctl(file, dev, cmd, arg: user_arg);
537 if (ret != -EAGAIN)
538 goto out;
539
540 switch (_IOC_DIR(cmd)) {
541 case (_IOC_READ | _IOC_WRITE):
542 ret = hidraw_rw_variable_size_ioctl(file, dev, cmd, user_arg);
543 break;
544 case _IOC_READ:
545 ret = hidraw_ro_variable_size_ioctl(file, dev, cmd, user_arg);
546 break;
547 default:
548 /* Any other IOC_DIR is wrong */
549 ret = -EINVAL;
550 }
551
552out:
553 up_read(sem: &minors_rwsem);
554 return ret;
555}
556
557static const struct file_operations hidraw_ops = {
558 .owner = THIS_MODULE,
559 .read = hidraw_read,
560 .write = hidraw_write,
561 .poll = hidraw_poll,
562 .open = hidraw_open,
563 .release = hidraw_release,
564 .unlocked_ioctl = hidraw_ioctl,
565 .fasync = hidraw_fasync,
566 .compat_ioctl = compat_ptr_ioctl,
567 .llseek = noop_llseek,
568};
569
570int hidraw_report_event(struct hid_device *hid, u8 *data, int len)
571{
572 struct hidraw *dev = hid->hidraw;
573 struct hidraw_list *list;
574 int ret = 0;
575 unsigned long flags;
576
577 spin_lock_irqsave(&dev->list_lock, flags);
578 list_for_each_entry(list, &dev->list, node) {
579 int new_head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1);
580
581 if (hidraw_is_revoked(list) || new_head == list->tail)
582 continue;
583
584 if (!(list->buffer[list->head].value = kmemdup(data, len, GFP_ATOMIC))) {
585 ret = -ENOMEM;
586 break;
587 }
588 list->buffer[list->head].len = len;
589 list->head = new_head;
590 kill_fasync(&list->fasync, SIGIO, POLL_IN);
591 }
592 spin_unlock_irqrestore(lock: &dev->list_lock, flags);
593
594 wake_up_interruptible(&dev->wait);
595 return ret;
596}
597EXPORT_SYMBOL_GPL(hidraw_report_event);
598
599int hidraw_connect(struct hid_device *hid)
600{
601 int minor, result;
602 struct hidraw *dev;
603
604 /* we accept any HID device, all applications */
605
606 dev = kzalloc(sizeof(struct hidraw), GFP_KERNEL);
607 if (!dev)
608 return -ENOMEM;
609
610 result = -EINVAL;
611
612 down_write(sem: &minors_rwsem);
613
614 for (minor = 0; minor < HIDRAW_MAX_DEVICES; minor++) {
615 if (hidraw_table[minor])
616 continue;
617 hidraw_table[minor] = dev;
618 result = 0;
619 break;
620 }
621
622 if (result) {
623 up_write(sem: &minors_rwsem);
624 kfree(objp: dev);
625 goto out;
626 }
627
628 dev->dev = device_create(cls: &hidraw_class, parent: &hid->dev, MKDEV(hidraw_major, minor),
629 NULL, fmt: "%s%d", "hidraw", minor);
630
631 if (IS_ERR(ptr: dev->dev)) {
632 hidraw_table[minor] = NULL;
633 up_write(sem: &minors_rwsem);
634 result = PTR_ERR(ptr: dev->dev);
635 kfree(objp: dev);
636 goto out;
637 }
638
639 init_waitqueue_head(&dev->wait);
640 spin_lock_init(&dev->list_lock);
641 INIT_LIST_HEAD(list: &dev->list);
642
643 dev->hid = hid;
644 dev->minor = minor;
645
646 dev->exist = 1;
647 hid->hidraw = dev;
648
649 up_write(sem: &minors_rwsem);
650out:
651 return result;
652
653}
654EXPORT_SYMBOL_GPL(hidraw_connect);
655
656void hidraw_disconnect(struct hid_device *hid)
657{
658 struct hidraw *hidraw = hid->hidraw;
659
660 down_write(sem: &minors_rwsem);
661
662 drop_ref(hidraw, exists_bit: 1);
663
664 up_write(sem: &minors_rwsem);
665}
666EXPORT_SYMBOL_GPL(hidraw_disconnect);
667
668int __init hidraw_init(void)
669{
670 int result;
671 dev_t dev_id;
672
673 result = alloc_chrdev_region(&dev_id, HIDRAW_FIRST_MINOR,
674 HIDRAW_MAX_DEVICES, "hidraw");
675 if (result < 0) {
676 pr_warn("can't get major number\n");
677 goto out;
678 }
679
680 hidraw_major = MAJOR(dev_id);
681
682 result = class_register(class: &hidraw_class);
683 if (result)
684 goto error_cdev;
685
686 cdev_init(&hidraw_cdev, &hidraw_ops);
687 result = cdev_add(&hidraw_cdev, dev_id, HIDRAW_MAX_DEVICES);
688 if (result < 0)
689 goto error_class;
690
691 pr_info("raw HID events driver (C) Jiri Kosina\n");
692out:
693 return result;
694
695error_class:
696 class_unregister(class: &hidraw_class);
697error_cdev:
698 unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES);
699 goto out;
700}
701
702void hidraw_exit(void)
703{
704 dev_t dev_id = MKDEV(hidraw_major, 0);
705
706 cdev_del(&hidraw_cdev);
707 class_unregister(class: &hidraw_class);
708 unregister_chrdev_region(dev_id, HIDRAW_MAX_DEVICES);
709
710}
711