aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/ec_sys.c
diff options
context:
space:
mode:
authorVasiliy Kulikov <segooon@gmail.com>2013-05-22 08:59:11 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-06-19 17:29:20 -0400
commitecde3003e5205a283b46b931c729a2aecab64ba1 (patch)
treee76f86792706f5b3be85e7ac73fdb9b96cd532c5 /drivers/acpi/ec_sys.c
parent7d132055814ef17a6c7b69f342244c410a5e000f (diff)
ACPI / EC: access user space with get_user()/put_user()
User space pointer may not be dereferenced. Use get_user()/put_user() instead and check their return codes. Signed-off-by: Vasiliy Kulikov <segooon@gmail.com> Signed-off-by: Thomas Renninger <trenn@suse.de> Signed-off-by: Jiri Slaby <jslaby@suse.cz> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/acpi/ec_sys.c')
-rw-r--r--drivers/acpi/ec_sys.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/acpi/ec_sys.c b/drivers/acpi/ec_sys.c
index 7586544fddb4..4e7b798900f2 100644
--- a/drivers/acpi/ec_sys.c
+++ b/drivers/acpi/ec_sys.c
@@ -12,6 +12,7 @@
12#include <linux/acpi.h> 12#include <linux/acpi.h>
13#include <linux/debugfs.h> 13#include <linux/debugfs.h>
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/uaccess.h>
15#include "internal.h" 16#include "internal.h"
16 17
17MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>"); 18MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>");
@@ -34,7 +35,6 @@ static ssize_t acpi_ec_read_io(struct file *f, char __user *buf,
34 * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private; 35 * struct acpi_ec *ec = ((struct seq_file *)f->private_data)->private;
35 */ 36 */
36 unsigned int size = EC_SPACE_SIZE; 37 unsigned int size = EC_SPACE_SIZE;
37 u8 *data = (u8 *) buf;
38 loff_t init_off = *off; 38 loff_t init_off = *off;
39 int err = 0; 39 int err = 0;
40 40
@@ -47,9 +47,15 @@ static ssize_t acpi_ec_read_io(struct file *f, char __user *buf,
47 size = count; 47 size = count;
48 48
49 while (size) { 49 while (size) {
50 err = ec_read(*off, &data[*off - init_off]); 50 u8 byte_read;
51 err = ec_read(*off, &byte_read);
51 if (err) 52 if (err)
52 return err; 53 return err;
54 if (put_user(byte_read, buf + *off - init_off)) {
55 if (*off - init_off)
56 return *off - init_off; /* partial read */
57 return -EFAULT;
58 }
53 *off += 1; 59 *off += 1;
54 size--; 60 size--;
55 } 61 }
@@ -65,7 +71,6 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
65 71
66 unsigned int size = count; 72 unsigned int size = count;
67 loff_t init_off = *off; 73 loff_t init_off = *off;
68 u8 *data = (u8 *) buf;
69 int err = 0; 74 int err = 0;
70 75
71 if (*off >= EC_SPACE_SIZE) 76 if (*off >= EC_SPACE_SIZE)
@@ -76,7 +81,12 @@ static ssize_t acpi_ec_write_io(struct file *f, const char __user *buf,
76 } 81 }
77 82
78 while (size) { 83 while (size) {
79 u8 byte_write = data[*off - init_off]; 84 u8 byte_write;
85 if (get_user(byte_write, buf + *off - init_off)) {
86 if (*off - init_off)
87 return *off - init_off; /* partial write */
88 return -EFAULT;
89 }
80 err = ec_write(*off, byte_write); 90 err = ec_write(*off, byte_write);
81 if (err) 91 if (err)
82 return err; 92 return err;