fcntl: don't cap l_start and l_end values for F_GETLK64 in compat syscall
authorJeff Layton <jlayton@redhat.com>
Tue, 14 Nov 2017 19:42:57 +0000 (14:42 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 17 Dec 2017 14:07:59 +0000 (15:07 +0100)
commit 4d2dc2cc766c3b51929658cacbc6e34fc8e242fb upstream.

Currently, we're capping the values too low in the F_GETLK64 case. The
fields in that structure are 64-bit values, so we shouldn't need to do
any sort of fixup there.

Make sure we check that assumption at build time in the future however
by ensuring that the sizes we're copying will fit.

With this, we no longer need COMPAT_LOFF_T_MAX either, so remove it.

Fixes: 94073ad77fff2 (fs/locks: don't mess with the address limit in compat_fcntl64)
Reported-by: Vitaly Lipatov <lav@etersoft.ru>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/arm64/include/asm/compat.h
arch/mips/include/asm/compat.h
arch/parisc/include/asm/compat.h
arch/powerpc/include/asm/compat.h
arch/s390/include/asm/compat.h
arch/sparc/include/asm/compat.h
arch/tile/include/asm/compat.h
arch/x86/include/asm/compat.h
fs/fcntl.c

index e39d487..a3c7f27 100644 (file)
@@ -215,7 +215,6 @@ typedef struct compat_siginfo {
 } compat_siginfo_t;
 
 #define COMPAT_OFF_T_MAX       0x7fffffff
-#define COMPAT_LOFF_T_MAX      0x7fffffffffffffffL
 
 /*
  * A pointer passed in from user mode. This should not
index 8e2b5b5..4969133 100644 (file)
@@ -200,7 +200,6 @@ typedef struct compat_siginfo {
 } compat_siginfo_t;
 
 #define COMPAT_OFF_T_MAX       0x7fffffff
-#define COMPAT_LOFF_T_MAX      0x7fffffffffffffffL
 
 /*
  * A pointer passed in from user mode. This should not
index 07f4882..acf8aa0 100644 (file)
@@ -195,7 +195,6 @@ typedef struct compat_siginfo {
 } compat_siginfo_t;
 
 #define COMPAT_OFF_T_MAX       0x7fffffff
-#define COMPAT_LOFF_T_MAX      0x7fffffffffffffffL
 
 struct compat_ipc64_perm {
        compat_key_t key;
index a035b1e..8a2aecf 100644 (file)
@@ -185,7 +185,6 @@ typedef struct compat_siginfo {
 } compat_siginfo_t;
 
 #define COMPAT_OFF_T_MAX       0x7fffffff
-#define COMPAT_LOFF_T_MAX      0x7fffffffffffffffL
 
 /*
  * A pointer passed in from user mode. This should not
index 1b60eb3..5e6a636 100644 (file)
@@ -263,7 +263,6 @@ typedef struct compat_siginfo {
 #define si_overrun     _sifields._timer._overrun
 
 #define COMPAT_OFF_T_MAX       0x7fffffff
-#define COMPAT_LOFF_T_MAX      0x7fffffffffffffffL
 
 /*
  * A pointer passed in from user mode. This should not
index 977c3f2..fa38c78 100644 (file)
@@ -209,7 +209,6 @@ typedef struct compat_siginfo {
 } compat_siginfo_t;
 
 #define COMPAT_OFF_T_MAX       0x7fffffff
-#define COMPAT_LOFF_T_MAX      0x7fffffffffffffffL
 
 /*
  * A pointer passed in from user mode. This should not
index c14e36f..62a7b83 100644 (file)
@@ -173,7 +173,6 @@ typedef struct compat_siginfo {
 } compat_siginfo_t;
 
 #define COMPAT_OFF_T_MAX       0x7fffffff
-#define COMPAT_LOFF_T_MAX      0x7fffffffffffffffL
 
 struct compat_ipc64_perm {
        compat_key_t key;
index 9eef9cc..70bc1df 100644 (file)
@@ -209,7 +209,6 @@ typedef struct compat_siginfo {
 } compat_siginfo_t;
 
 #define COMPAT_OFF_T_MAX       0x7fffffff
-#define COMPAT_LOFF_T_MAX      0x7fffffffffffffffL
 
 struct compat_ipc64_perm {
        compat_key_t key;
index 6fd3113..0345a46 100644 (file)
@@ -563,6 +563,9 @@ static int put_compat_flock64(const struct flock *kfl, struct compat_flock64 __u
 {
        struct compat_flock64 fl;
 
+       BUILD_BUG_ON(sizeof(kfl->l_start) > sizeof(ufl->l_start));
+       BUILD_BUG_ON(sizeof(kfl->l_len) > sizeof(ufl->l_len));
+
        memset(&fl, 0, sizeof(struct compat_flock64));
        copy_flock_fields(&fl, kfl);
        if (copy_to_user(ufl, &fl, sizeof(struct compat_flock64)))
@@ -641,12 +644,8 @@ COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
                if (err)
                        break;
                err = fcntl_getlk(f.file, convert_fcntl_cmd(cmd), &flock);
-               if (err)
-                       break;
-               err = fixup_compat_flock(&flock);
-               if (err)
-                       return err;
-               err = put_compat_flock64(&flock, compat_ptr(arg));
+               if (!err)
+                       err = put_compat_flock64(&flock, compat_ptr(arg));
                break;
        case F_SETLK:
        case F_SETLKW: