aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hid/uhid.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
index 3c5507313606..051639c09f72 100644
--- a/drivers/hid/uhid.c
+++ b/drivers/hid/uhid.c
@@ -12,6 +12,7 @@
12 12
13#include <linux/atomic.h> 13#include <linux/atomic.h>
14#include <linux/compat.h> 14#include <linux/compat.h>
15#include <linux/cred.h>
15#include <linux/device.h> 16#include <linux/device.h>
16#include <linux/fs.h> 17#include <linux/fs.h>
17#include <linux/hid.h> 18#include <linux/hid.h>
@@ -722,6 +723,17 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer,
722 723
723 switch (uhid->input_buf.type) { 724 switch (uhid->input_buf.type) {
724 case UHID_CREATE: 725 case UHID_CREATE:
726 /*
727 * 'struct uhid_create_req' contains a __user pointer which is
728 * copied from, so it's unsafe to allow this with elevated
729 * privileges (e.g. from a setuid binary) or via kernel_write().
730 */
731 if (file->f_cred != current_cred() || uaccess_kernel()) {
732 pr_err_once("UHID_CREATE from different security context by process %d (%s), this is not allowed.\n",
733 task_tgid_vnr(current), current->comm);
734 ret = -EACCES;
735 goto unlock;
736 }
725 ret = uhid_dev_create(uhid, &uhid->input_buf); 737 ret = uhid_dev_create(uhid, &uhid->input_buf);
726 break; 738 break;
727 case UHID_CREATE2: 739 case UHID_CREATE2: