mips: sanitize __access_ok()
authorAl Viro <viro@zeniv.linux.org.uk>
Tue, 27 Dec 2016 15:10:53 +0000 (10:10 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 6 Apr 2017 06:08:06 +0000 (02:08 -0400)
for one thing, the last argument is always __access_mask and had been such
since 2.4.0-test3pre8; for another, it can bloody well be a static inline -
-O2 or -Os, __builtin_constant_p() propagates through static inline calls.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/mips/include/asm/uaccess.h
arch/mips/kernel/mips-r2-to-r6-emul.c
arch/mips/kernel/syscall.c
arch/mips/oprofile/backtrace.c

index 70ca8eee166a8e7a1a8a6535483e415659dd565e..0c59911349cef926990694d5605625d00940ed82 100644 (file)
@@ -128,23 +128,14 @@ static inline bool eva_kernel_access(void)
  * this function, memory access functions may still return -EFAULT.
  */
 
-#define __access_mask get_fs().seg
-
-#define __access_ok(addr, size, mask)                                  \
-({                                                                     \
-       unsigned long __addr = (unsigned long) (addr);                  \
-       unsigned long __size = size;                                    \
-       unsigned long __mask = mask;                                    \
-       unsigned long __ok;                                             \
-                                                                       \
-       __chk_user_ptr(addr);                                           \
-       __ok = (signed long)(__mask & (__addr | (__addr + __size) |     \
-               __ua_size(__size)));                                    \
-       __ok == 0;                                                      \
-})
+static inline int __access_ok(const void __user *p, unsigned long size)
+{
+       unsigned long addr = (unsigned long)p;
+       return (get_fs().seg & (addr | (addr + size) | __ua_size(size))) == 0;
+}
 
 #define access_ok(type, addr, size)                                    \
-       likely(__access_ok((addr), (size), __access_mask))
+       likely(__access_ok((addr), (size)))
 
 /*
  * put_user: - Write a simple value into user space.
index d8f1cf1ec3703ad56fcea2ac96a0c5c487ccdd67..550e7d03090a18fc9cafd8d2ed77ffd89d927a3d 100644 (file)
@@ -1200,7 +1200,7 @@ fpu_emul:
        case lwl_op:
                rt = regs->regs[MIPSInst_RT(inst)];
                vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst);
-               if (!access_ok(VERIFY_READ, vaddr, 4)) {
+               if (!access_ok(VERIFY_READ, (void __user *)vaddr, 4)) {
                        current->thread.cp0_baduaddr = vaddr;
                        err = SIGSEGV;
                        break;
@@ -1273,7 +1273,7 @@ fpu_emul:
        case lwr_op:
                rt = regs->regs[MIPSInst_RT(inst)];
                vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst);
-               if (!access_ok(VERIFY_READ, vaddr, 4)) {
+               if (!access_ok(VERIFY_READ, (void __user *)vaddr, 4)) {
                        current->thread.cp0_baduaddr = vaddr;
                        err = SIGSEGV;
                        break;
@@ -1347,7 +1347,7 @@ fpu_emul:
        case swl_op:
                rt = regs->regs[MIPSInst_RT(inst)];
                vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst);
-               if (!access_ok(VERIFY_WRITE, vaddr, 4)) {
+               if (!access_ok(VERIFY_WRITE, (void __user *)vaddr, 4)) {
                        current->thread.cp0_baduaddr = vaddr;
                        err = SIGSEGV;
                        break;
@@ -1417,7 +1417,7 @@ fpu_emul:
        case swr_op:
                rt = regs->regs[MIPSInst_RT(inst)];
                vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst);
-               if (!access_ok(VERIFY_WRITE, vaddr, 4)) {
+               if (!access_ok(VERIFY_WRITE, (void __user *)vaddr, 4)) {
                        current->thread.cp0_baduaddr = vaddr;
                        err = SIGSEGV;
                        break;
@@ -1492,7 +1492,7 @@ fpu_emul:
 
                rt = regs->regs[MIPSInst_RT(inst)];
                vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst);
-               if (!access_ok(VERIFY_READ, vaddr, 8)) {
+               if (!access_ok(VERIFY_READ, (void __user *)vaddr, 8)) {
                        current->thread.cp0_baduaddr = vaddr;
                        err = SIGSEGV;
                        break;
@@ -1611,7 +1611,7 @@ fpu_emul:
 
                rt = regs->regs[MIPSInst_RT(inst)];
                vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst);
-               if (!access_ok(VERIFY_READ, vaddr, 8)) {
+               if (!access_ok(VERIFY_READ, (void __user *)vaddr, 8)) {
                        current->thread.cp0_baduaddr = vaddr;
                        err = SIGSEGV;
                        break;
@@ -1730,7 +1730,7 @@ fpu_emul:
 
                rt = regs->regs[MIPSInst_RT(inst)];
                vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst);
-               if (!access_ok(VERIFY_WRITE, vaddr, 8)) {
+               if (!access_ok(VERIFY_WRITE, (void __user *)vaddr, 8)) {
                        current->thread.cp0_baduaddr = vaddr;
                        err = SIGSEGV;
                        break;
@@ -1848,7 +1848,7 @@ fpu_emul:
 
                rt = regs->regs[MIPSInst_RT(inst)];
                vaddr = regs->regs[MIPSInst_RS(inst)] + MIPSInst_SIMM(inst);
-               if (!access_ok(VERIFY_WRITE, vaddr, 8)) {
+               if (!access_ok(VERIFY_WRITE, (void __user *)vaddr, 8)) {
                        current->thread.cp0_baduaddr = vaddr;
                        err = SIGSEGV;
                        break;
@@ -1965,7 +1965,7 @@ fpu_emul:
                        err = SIGBUS;
                        break;
                }
-               if (!access_ok(VERIFY_READ, vaddr, 4)) {
+               if (!access_ok(VERIFY_READ, (void __user *)vaddr, 4)) {
                        current->thread.cp0_baduaddr = vaddr;
                        err = SIGBUS;
                        break;
@@ -2021,7 +2021,7 @@ fpu_emul:
                        err = SIGBUS;
                        break;
                }
-               if (!access_ok(VERIFY_WRITE, vaddr, 4)) {
+               if (!access_ok(VERIFY_WRITE, (void __user *)vaddr, 4)) {
                        current->thread.cp0_baduaddr = vaddr;
                        err = SIGBUS;
                        break;
@@ -2084,7 +2084,7 @@ fpu_emul:
                        err = SIGBUS;
                        break;
                }
-               if (!access_ok(VERIFY_READ, vaddr, 8)) {
+               if (!access_ok(VERIFY_READ, (void __user *)vaddr, 8)) {
                        current->thread.cp0_baduaddr = vaddr;
                        err = SIGBUS;
                        break;
@@ -2145,7 +2145,7 @@ fpu_emul:
                        err = SIGBUS;
                        break;
                }
-               if (!access_ok(VERIFY_WRITE, vaddr, 8)) {
+               if (!access_ok(VERIFY_WRITE, (void __user *)vaddr, 8)) {
                        current->thread.cp0_baduaddr = vaddr;
                        err = SIGBUS;
                        break;
index f1d17ece41819e39f9ce1fbcc396475a556fde49..1dfa7f5796c7c69dea60b531be757419d6780760 100644 (file)
@@ -98,7 +98,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new)
        if (unlikely(addr & 3))
                return -EINVAL;
 
-       if (unlikely(!access_ok(VERIFY_WRITE, addr, 4)))
+       if (unlikely(!access_ok(VERIFY_WRITE, (const void __user *)addr, 4)))
                return -EINVAL;
 
        if (cpu_has_llsc && R10000_LLSC_WAR) {
index 5e645c9a31627430191762cc1bc3d423b3802c92..16ace558cd9d4f2af65a2b946143b893e3bb9bc1 100644 (file)
@@ -18,7 +18,7 @@ struct stackframe {
 static inline int get_mem(unsigned long addr, unsigned long *result)
 {
        unsigned long *address = (unsigned long *) addr;
-       if (!access_ok(VERIFY_READ, addr, sizeof(unsigned long)))
+       if (!access_ok(VERIFY_READ, address, sizeof(unsigned long)))
                return -1;
        if (__copy_from_user_inatomic(result, address, sizeof(unsigned long)))
                return -3;