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 e39d487bf7243850164cd22171837c9f9340cf3e..a3c7f271ad4c79dc982597b4ff99edcf01400abd 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 8e2b5b55648868199deed2f8e9aae5bafdf60d98..49691331ada4c1b8d8632fc8293a246e657cdb63 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 07f48827afdae8500fc7bc54294a5befee9b7e86..acf8aa07cbe099e35972e7d381d743da37bb2a5e 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 a035b1e5dfa7c6b5ae8ba10a1e1ad58d962c4a4b..8a2aecfe9b0246cbbea75a66aaa3020322fc87c5 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 1b60eb3676d55640c515633e799bbb7fde610b7d..5e6a63641a5f1916da30507eb744534a2da95486 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 977c3f280ba1900bf6d1a21990a0b17decc9821e..fa38c78de0f001f15c63d65632a78f3ce37c3def 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 c14e36f008c8f3a047fa4a9a583735a01264bcb3..62a7b83025dd24ab264d2d2901931b35c5ae9c2d 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 9eef9cc64c6846d11dc5febae97109f2addc3648..70bc1df580b2da3c9ee2f948686402534c385077 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 6fd311367efc8e0d89556f0c5cceb9a3f31317e1..0345a46b885654268d8ee37a659e100ebe6fdcf7 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: