Commit 6937a82d authored by Benjamin Tissoires's avatar Benjamin Tissoires
Browse files

Merge branch 'for-6.12/hidraw' into for-linus

- introduction of HIDIOCREVOKE ioctl to revoke a hidraw fd opened by a
  regular (non-root) application (Peter Hutterer)
parents 054e0bd3 321f7798
Loading
Loading
Loading
Loading
+35 −4
Original line number Diff line number Diff line
@@ -38,12 +38,20 @@ static const struct class hidraw_class = {
static struct hidraw *hidraw_table[HIDRAW_MAX_DEVICES];
static DECLARE_RWSEM(minors_rwsem);

static inline bool hidraw_is_revoked(struct hidraw_list *list)
{
	return list->revoked;
}

static ssize_t hidraw_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
{
	struct hidraw_list *list = file->private_data;
	int ret = 0, len;
	DECLARE_WAITQUEUE(wait, current);

	if (hidraw_is_revoked(list))
		return -ENODEV;

	mutex_lock(&list->read_mutex);

	while (ret == 0) {
@@ -161,8 +169,12 @@ static ssize_t hidraw_send_report(struct file *file, const char __user *buffer,

static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
{
	struct hidraw_list *list = file->private_data;
	ssize_t ret;
	down_read(&minors_rwsem);
	if (hidraw_is_revoked(list))
		ret = -ENODEV;
	else
		ret = hidraw_send_report(file, buffer, count, HID_OUTPUT_REPORT);
	up_read(&minors_rwsem);
	return ret;
@@ -256,7 +268,7 @@ static __poll_t hidraw_poll(struct file *file, poll_table *wait)
	poll_wait(file, &list->hidraw->wait, wait);
	if (list->head != list->tail)
		mask |= EPOLLIN | EPOLLRDNORM;
	if (!list->hidraw->exist)
	if (!list->hidraw->exist || hidraw_is_revoked(list))
		mask |= EPOLLERR | EPOLLHUP;
	return mask;
}
@@ -320,6 +332,9 @@ static int hidraw_fasync(int fd, struct file *file, int on)
{
	struct hidraw_list *list = file->private_data;

	if (hidraw_is_revoked(list))
		return -ENODEV;

	return fasync_helper(fd, file, on, &list->fasync);
}

@@ -372,6 +387,13 @@ static int hidraw_release(struct inode * inode, struct file * file)
	return 0;
}

static int hidraw_revoke(struct hidraw_list *list)
{
	list->revoked = true;

	return 0;
}

static long hidraw_ioctl(struct file *file, unsigned int cmd,
							unsigned long arg)
{
@@ -379,11 +401,12 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
	unsigned int minor = iminor(inode);
	long ret = 0;
	struct hidraw *dev;
	struct hidraw_list *list = file->private_data;
	void __user *user_arg = (void __user*) arg;

	down_read(&minors_rwsem);
	dev = hidraw_table[minor];
	if (!dev || !dev->exist) {
	if (!dev || !dev->exist || hidraw_is_revoked(list)) {
		ret = -ENODEV;
		goto out;
	}
@@ -421,6 +444,14 @@ static long hidraw_ioctl(struct file *file, unsigned int cmd,
					ret = -EFAULT;
				break;
			}
		case HIDIOCREVOKE:
			{
				if (user_arg)
					ret = -EINVAL;
				else
					ret = hidraw_revoke(list);
				break;
			}
		default:
			{
				struct hid_device *hid = dev->hid;
@@ -527,7 +558,7 @@ int hidraw_report_event(struct hid_device *hid, u8 *data, int len)
	list_for_each_entry(list, &dev->list, node) {
		int new_head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1);

		if (new_head == list->tail)
		if (hidraw_is_revoked(list) || new_head == list->tail)
			continue;

		if (!(list->buffer[list->head].value = kmemdup(data, len, GFP_ATOMIC))) {
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ struct hidraw_list {
	struct hidraw *hidraw;
	struct list_head node;
	struct mutex read_mutex;
	bool revoked;
};

#ifdef CONFIG_HIDRAW
+1 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ struct hidraw_devinfo {
/* The first byte of SOUTPUT and GOUTPUT is the report number */
#define HIDIOCSOUTPUT(len)    _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x0B, len)
#define HIDIOCGOUTPUT(len)    _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x0C, len)
#define HIDIOCREVOKE	      _IOW('H', 0x0D, int) /* Revoke device access */

#define HIDRAW_FIRST_MINOR 0
#define HIDRAW_MAX_DEVICES 64
+1 −0
Original line number Diff line number Diff line
@@ -2,4 +2,5 @@ bpftool
*.skel.h
/tools
hid_bpf
hidraw
results
+1 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ CFLAGS += -Wno-unused-command-line-argument
endif

# Order correspond to 'make run_tests' order
TEST_GEN_PROGS = hid_bpf
TEST_GEN_PROGS = hid_bpf hidraw

# Emit succinct information message describing current building step
# $1 - generic step name (e.g., CC, LINK, etc);
Loading