From ad606c95cd0cf19e28277030e2033e9b1d3d68fd Mon Sep 17 00:00:00 2001 From: Liangliang Lu Date: Fri, 17 Feb 2017 20:02:47 +0800 Subject: [PATCH] usb: dwc3: Replace sscanf with kstrtou8_from_user Variable "ubuf " and "buf" may point to kernel address, a malicious user could use code logic to get kernel information. Use kstrtou8_from_user() which take care of copying buffer, and finding u8 value here. Change-Id: Ibb4373bdef7e921b81255d29b8650dd31b46f3c9 Signed-off-by: Liangliang Lu --- drivers/usb/dwc3/debugfs.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/drivers/usb/dwc3/debugfs.c b/drivers/usb/dwc3/debugfs.c index 068b03a35bd5..20ac60d6b6a8 100644 --- a/drivers/usb/dwc3/debugfs.c +++ b/drivers/usb/dwc3/debugfs.c @@ -978,22 +978,30 @@ void dbg_print_reg(const char *name, int reg) static ssize_t dwc3_store_events(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - unsigned tty; + int ret; + u8 tty; if (buf == NULL) { pr_err("[%s] EINVAL\n", __func__); - goto done; + ret = -EINVAL; + return ret; } - if (sscanf(buf, "%u", &tty) != 1 || tty > 1) { + ret = kstrtou8_from_user(buf, count, 0, &tty); + if (ret < 0) { + pr_err("can't get enter value.\n"); + return ret; + } + + if (tty > 1) { pr_err("<1|0>: enable|disable console log\n"); - goto done; + ret = -EINVAL; + return ret; } dbg_dwc3_data.tty = tty; pr_info("tty = %u", dbg_dwc3_data.tty); - done: return count; } @@ -1034,21 +1042,30 @@ const struct file_operations dwc3_gadget_dbg_data_fops = { static ssize_t dwc3_store_int_events(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { - int clear_stats, i; + int i, ret; unsigned long flags; struct seq_file *s = file->private_data; struct dwc3 *dwc = s->private; struct dwc3_ep *dep; struct timespec ts; + u8 clear_stats; if (ubuf == NULL) { pr_err("[%s] EINVAL\n", __func__); - goto done; + ret = -EINVAL; + return ret; } - if (sscanf(ubuf, "%u", &clear_stats) != 1 || clear_stats != 0) { + ret = kstrtou8_from_user(ubuf, count, 0, &clear_stats); + if (ret < 0) { + pr_err("can't get enter value.\n"); + return ret; + } + + if (clear_stats != 0) { pr_err("Wrong value. To clear stats, enter value as 0.\n"); - goto done; + ret = -EINVAL; + return ret; } spin_lock_irqsave(&dwc->lock, flags); @@ -1065,7 +1082,6 @@ static ssize_t dwc3_store_int_events(struct file *file, spin_unlock_irqrestore(&dwc->lock, flags); -done: return count; }