diff options
author | Vasiliy Kulikov <segooon@gmail.com> | 2013-05-22 08:59:11 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2013-06-19 17:29:20 -0400 |
commit | ecde3003e5205a283b46b931c729a2aecab64ba1 (patch) | |
tree | e76f86792706f5b3be85e7ac73fdb9b96cd532c5 /drivers/acpi/ec_sys.c | |
parent | 7d132055814ef17a6c7b69f342244c410a5e000f (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.c | 18 |
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 | ||
17 | MODULE_AUTHOR("Thomas Renninger <trenn@suse.de>"); | 18 | MODULE_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; |