aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/mem.c
diff options
context:
space:
mode:
authorPetr Tesarik <ptesarik@suse.cz>2014-01-30 03:48:02 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-02-15 14:51:02 -0500
commit08d2d00b291ed4eb91530050274e67a761c1901d (patch)
tree89099e1078b50ff770f06a86106edc72dc52563f /drivers/char/mem.c
parent1bc9fac3da9aa7569e70e9fda605281ef7e42b9f (diff)
/dev/mem: handle out-of-bounds read/write
The loff_t type may be wider than phys_addr_t (e.g. on 32-bit systems). Consequently, the file offset may be truncated in the assignment. Currently, /dev/mem wraps around, which may cause applications to read or write incorrect regions of memory by accident. Let's follow POSIX file semantics here and return 0 when reading from and -EFBIG when writing to an offset that cannot be represented by a phys_addr_t. Note that the conditional is optimized out by the compiler if loff_t has the same size as phys_addr_t. Signed-off-by: Petr Tesarik <ptesarik@suse.cz> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/char/mem.c')
-rw-r--r--drivers/char/mem.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 92c5937f80c3..917403fe10da 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -99,6 +99,9 @@ static ssize_t read_mem(struct file *file, char __user *buf,
99 ssize_t read, sz; 99 ssize_t read, sz;
100 char *ptr; 100 char *ptr;
101 101
102 if (p != *ppos)
103 return 0;
104
102 if (!valid_phys_addr_range(p, count)) 105 if (!valid_phys_addr_range(p, count))
103 return -EFAULT; 106 return -EFAULT;
104 read = 0; 107 read = 0;
@@ -157,6 +160,9 @@ static ssize_t write_mem(struct file *file, const char __user *buf,
157 unsigned long copied; 160 unsigned long copied;
158 void *ptr; 161 void *ptr;
159 162
163 if (p != *ppos)
164 return -EFBIG;
165
160 if (!valid_phys_addr_range(p, count)) 166 if (!valid_phys_addr_range(p, count))
161 return -EFAULT; 167 return -EFAULT;
162 168