| From cf01fb9985e8deb25ccf0ea54d916b8871ae0e62 Mon Sep 17 00:00:00 2001 |
| From: Chris Salls <salls@cs.ucsb.edu> |
| Date: Fri, 7 Apr 2017 23:48:11 -0700 |
| Subject: mm/mempolicy.c: fix error handling in set_mempolicy and mbind. |
| |
| From: Chris Salls <salls@cs.ucsb.edu> |
| |
| commit cf01fb9985e8deb25ccf0ea54d916b8871ae0e62 upstream. |
| |
| In the case that compat_get_bitmap fails we do not want to copy the |
| bitmap to the user as it will contain uninitialized stack data and leak |
| sensitive data. |
| |
| Signed-off-by: Chris Salls <salls@cs.ucsb.edu> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| mm/mempolicy.c | 20 ++++++++------------ |
| 1 file changed, 8 insertions(+), 12 deletions(-) |
| |
| --- a/mm/mempolicy.c |
| +++ b/mm/mempolicy.c |
| @@ -1492,7 +1492,6 @@ COMPAT_SYSCALL_DEFINE5(get_mempolicy, in |
| COMPAT_SYSCALL_DEFINE3(set_mempolicy, int, mode, compat_ulong_t __user *, nmask, |
| compat_ulong_t, maxnode) |
| { |
| - long err = 0; |
| unsigned long __user *nm = NULL; |
| unsigned long nr_bits, alloc_size; |
| DECLARE_BITMAP(bm, MAX_NUMNODES); |
| @@ -1501,14 +1500,13 @@ COMPAT_SYSCALL_DEFINE3(set_mempolicy, in |
| alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; |
| |
| if (nmask) { |
| - err = compat_get_bitmap(bm, nmask, nr_bits); |
| + if (compat_get_bitmap(bm, nmask, nr_bits)) |
| + return -EFAULT; |
| nm = compat_alloc_user_space(alloc_size); |
| - err |= copy_to_user(nm, bm, alloc_size); |
| + if (copy_to_user(nm, bm, alloc_size)) |
| + return -EFAULT; |
| } |
| |
| - if (err) |
| - return -EFAULT; |
| - |
| return sys_set_mempolicy(mode, nm, nr_bits+1); |
| } |
| |
| @@ -1516,7 +1514,6 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulo |
| compat_ulong_t, mode, compat_ulong_t __user *, nmask, |
| compat_ulong_t, maxnode, compat_ulong_t, flags) |
| { |
| - long err = 0; |
| unsigned long __user *nm = NULL; |
| unsigned long nr_bits, alloc_size; |
| nodemask_t bm; |
| @@ -1525,14 +1522,13 @@ COMPAT_SYSCALL_DEFINE6(mbind, compat_ulo |
| alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8; |
| |
| if (nmask) { |
| - err = compat_get_bitmap(nodes_addr(bm), nmask, nr_bits); |
| + if (compat_get_bitmap(nodes_addr(bm), nmask, nr_bits)) |
| + return -EFAULT; |
| nm = compat_alloc_user_space(alloc_size); |
| - err |= copy_to_user(nm, nodes_addr(bm), alloc_size); |
| + if (copy_to_user(nm, nodes_addr(bm), alloc_size)) |
| + return -EFAULT; |
| } |
| |
| - if (err) |
| - return -EFAULT; |
| - |
| return sys_mbind(start, len, mode, nm, nr_bits+1, flags); |
| } |
| |