diff mbox

[1/1] arm: fix handling of F_OFD_... in oabi_fcntl64()

Message ID 1497018633-88501-2-git-send-email-brad.figg@canonical.com
State New
Headers show

Commit Message

Brad Figg June 9, 2017, 2:30 p.m. UTC
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>
---
 arch/arm/kernel/sys_oabi-compat.c | 71 ++++++++++++++++++++-------------------
 1 file changed, 36 insertions(+), 35 deletions(-)

Comments

Stefan Bader June 9, 2017, 3:15 p.m. UTC | #1
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 {
>
Seth Forshee June 14, 2017, 3:44 p.m. UTC | #2
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>
Stefan Bader June 21, 2017, 10:36 a.m. UTC | #3
Applied to Trusty master-next.

Thanks,
-Stefan
diff mbox

Patch

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 {