Message ID | 1497018633-88501-2-git-send-email-brad.figg@canonical.com |
---|---|
State | New |
Headers | show |
On 09.06.2017 16:30, Brad Figg wrote: > From: Al Viro <viro@zeniv.linux.org.uk> > > CVE-2015-8966 > > Cc: stable@vger.kernel.org # 3.15+ > Reviewed-by: Jeff Layton <jeff.layton@primarydata.com> > Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> > (backported from commit 76cc404bfdc0d419c720de4daaf2584542734f42 upstream) > Signed-off-by: Brad Figg <brad.figg@canonical.com> Though a bit weird that the stable tag said 3.15+ (Trusty is 3.13). Still it appears applicable. Acked-by: Stefan Bader <stefan.bader@canonical.com> > --- > arch/arm/kernel/sys_oabi-compat.c | 71 ++++++++++++++++++++------------------- > 1 file changed, 36 insertions(+), 35 deletions(-) > > diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c > index 3e94811..20a6f3a 100644 > --- a/arch/arm/kernel/sys_oabi-compat.c > +++ b/arch/arm/kernel/sys_oabi-compat.c > @@ -193,52 +193,53 @@ struct oabi_flock64 { > pid_t l_pid; > } __attribute__ ((packed,aligned(4))); > > -asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd, > +static long do_locks(unsigned int fd, unsigned int cmd, > unsigned long arg) > { > - struct oabi_flock64 user; > struct flock64 kernel; > - mm_segment_t fs = USER_DS; /* initialized to kill a warning */ > - unsigned long local_arg = arg; > - int ret; > + struct oabi_flock64 user; > + mm_segment_t fs; > + long ret; > > - switch (cmd) { > - case F_GETLK64: > - case F_SETLK64: > - case F_SETLKW64: > - if (copy_from_user(&user, (struct oabi_flock64 __user *)arg, > - sizeof(user))) > - return -EFAULT; > - kernel.l_type = user.l_type; > - kernel.l_whence = user.l_whence; > - kernel.l_start = user.l_start; > - kernel.l_len = user.l_len; > - kernel.l_pid = user.l_pid; > - local_arg = (unsigned long)&kernel; > - fs = get_fs(); > - set_fs(KERNEL_DS); > - } > + if (copy_from_user(&user, (struct oabi_flock64 __user *)arg, > + sizeof(user))) > + return -EFAULT; > + kernel.l_type = user.l_type; > + kernel.l_whence = user.l_whence; > + kernel.l_start = user.l_start; > + kernel.l_len = user.l_len; > + kernel.l_pid = user.l_pid; > > - ret = sys_fcntl64(fd, cmd, local_arg); > + fs = get_fs(); > + set_fs(KERNEL_DS); > + ret = sys_fcntl64(fd, cmd, (unsigned long)&kernel); > + set_fs(fs); > > + if (!ret && (cmd == F_GETLK64 || cmd == F_OFD_GETLK)) { > + user.l_type = kernel.l_type; > + user.l_whence = kernel.l_whence; > + user.l_start = kernel.l_start; > + user.l_len = kernel.l_len; > + user.l_pid = kernel.l_pid; > + if (copy_to_user((struct oabi_flock64 __user *)arg, > + &user, sizeof(user))) > + ret = -EFAULT; > + } > + return ret; > +} > + > +asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd, > + unsigned long arg) > +{ > switch (cmd) { > case F_GETLK64: > - if (!ret) { > - user.l_type = kernel.l_type; > - user.l_whence = kernel.l_whence; > - user.l_start = kernel.l_start; > - user.l_len = kernel.l_len; > - user.l_pid = kernel.l_pid; > - if (copy_to_user((struct oabi_flock64 __user *)arg, > - &user, sizeof(user))) > - ret = -EFAULT; > - } > case F_SETLK64: > case F_SETLKW64: > - set_fs(fs); > - } > + return do_locks(fd, cmd, arg); > > - return ret; > + default: > + return sys_fcntl64(fd, cmd, arg); > + } > } > > struct oabi_epoll_event { >
On Fri, Jun 09, 2017 at 07:30:33AM -0700, Brad Figg wrote: > From: Al Viro <viro@zeniv.linux.org.uk> > > CVE-2015-8966 > > Cc: stable@vger.kernel.org # 3.15+ > Reviewed-by: Jeff Layton <jeff.layton@primarydata.com> > Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> > (backported from commit 76cc404bfdc0d419c720de4daaf2584542734f42 upstream) > Signed-off-by: Brad Figg <brad.figg@canonical.com> Acked-by: Seth Forshee <seth.forshee@canonical.com>
Applied to Trusty master-next. Thanks, -Stefan
diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c index 3e94811..20a6f3a 100644 --- a/arch/arm/kernel/sys_oabi-compat.c +++ b/arch/arm/kernel/sys_oabi-compat.c @@ -193,52 +193,53 @@ struct oabi_flock64 { pid_t l_pid; } __attribute__ ((packed,aligned(4))); -asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd, +static long do_locks(unsigned int fd, unsigned int cmd, unsigned long arg) { - struct oabi_flock64 user; struct flock64 kernel; - mm_segment_t fs = USER_DS; /* initialized to kill a warning */ - unsigned long local_arg = arg; - int ret; + struct oabi_flock64 user; + mm_segment_t fs; + long ret; - switch (cmd) { - case F_GETLK64: - case F_SETLK64: - case F_SETLKW64: - if (copy_from_user(&user, (struct oabi_flock64 __user *)arg, - sizeof(user))) - return -EFAULT; - kernel.l_type = user.l_type; - kernel.l_whence = user.l_whence; - kernel.l_start = user.l_start; - kernel.l_len = user.l_len; - kernel.l_pid = user.l_pid; - local_arg = (unsigned long)&kernel; - fs = get_fs(); - set_fs(KERNEL_DS); - } + if (copy_from_user(&user, (struct oabi_flock64 __user *)arg, + sizeof(user))) + return -EFAULT; + kernel.l_type = user.l_type; + kernel.l_whence = user.l_whence; + kernel.l_start = user.l_start; + kernel.l_len = user.l_len; + kernel.l_pid = user.l_pid; - ret = sys_fcntl64(fd, cmd, local_arg); + fs = get_fs(); + set_fs(KERNEL_DS); + ret = sys_fcntl64(fd, cmd, (unsigned long)&kernel); + set_fs(fs); + if (!ret && (cmd == F_GETLK64 || cmd == F_OFD_GETLK)) { + user.l_type = kernel.l_type; + user.l_whence = kernel.l_whence; + user.l_start = kernel.l_start; + user.l_len = kernel.l_len; + user.l_pid = kernel.l_pid; + if (copy_to_user((struct oabi_flock64 __user *)arg, + &user, sizeof(user))) + ret = -EFAULT; + } + return ret; +} + +asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd, + unsigned long arg) +{ switch (cmd) { case F_GETLK64: - if (!ret) { - user.l_type = kernel.l_type; - user.l_whence = kernel.l_whence; - user.l_start = kernel.l_start; - user.l_len = kernel.l_len; - user.l_pid = kernel.l_pid; - if (copy_to_user((struct oabi_flock64 __user *)arg, - &user, sizeof(user))) - ret = -EFAULT; - } case F_SETLK64: case F_SETLKW64: - set_fs(fs); - } + return do_locks(fd, cmd, arg); - return ret; + default: + return sys_fcntl64(fd, cmd, arg); + } } struct oabi_epoll_event {