Message ID | 20170725114238.1268-2-po-hsu.lin@canonical.com |
---|---|
State | New |
Headers | show |
On 25.07.2017 13:42, Po-Hsu Lin wrote: > From: Chris Salls <salls@cs.ucsb.edu> > > CVE-2017-7616 > > 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> > (cherry picked from commit cf01fb9985e8deb25ccf0ea54d916b8871ae0e62) > Signed-off-by: Po-Hsu Lin <po-hsu.lin@canonical.com> Acked-by: Stefan Bader <stefan.bader@canonical.com> > --- > mm/mempolicy.c | 20 ++++++++------------ > 1 file changed, 8 insertions(+), 12 deletions(-) > > diff --git a/mm/mempolicy.c b/mm/mempolicy.c > index 5990620..c5802e4 100644 > --- a/mm/mempolicy.c > +++ b/mm/mempolicy.c > @@ -1590,7 +1590,6 @@ asmlinkage long compat_sys_get_mempolicy(int __user *policy, > asmlinkage long compat_sys_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); > @@ -1599,14 +1598,13 @@ asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask, > 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); > } > > @@ -1614,7 +1612,6 @@ asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len, > 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; > @@ -1623,14 +1620,13 @@ asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len, > 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); > } > >
Applied on trusty master-next branch. Thank you, Kleber
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 5990620..c5802e4 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c @@ -1590,7 +1590,6 @@ asmlinkage long compat_sys_get_mempolicy(int __user *policy, asmlinkage long compat_sys_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); @@ -1599,14 +1598,13 @@ asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask, 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); } @@ -1614,7 +1612,6 @@ asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len, 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; @@ -1623,14 +1620,13 @@ asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len, 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); }