sh: Force __access_ok() to obey address space limit.

When the thread_info->addr_limit changes were introduced, __access_ok()
was missed in the conversion, allowing user processes to perform P1/P2
accesses under certain conditions.

This has already been corrected with the nommu refactoring in later
kernels.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>

+14 -26
+14 -26
include/asm-sh/uaccess.h
··· 73 73 /* 74 74 * __access_ok: Check if address with size is OK or not. 75 75 * 76 - * We do three checks: 77 - * (1) is it user space? 78 - * (2) addr + size --> carry? 79 - * (3) addr + size >= 0x80000000 (PAGE_OFFSET) 76 + * Uhhuh, this needs 33-bit arithmetic. We have a carry.. 80 77 * 81 - * (1) (2) (3) | RESULT 82 - * 0 0 0 | ok 83 - * 0 0 1 | ok 84 - * 0 1 0 | bad 85 - * 0 1 1 | bad 86 - * 1 0 0 | ok 87 - * 1 0 1 | bad 88 - * 1 1 0 | bad 89 - * 1 1 1 | bad 78 + * sum := addr + size; carry? --> flag = true; 79 + * if (sum >= addr_limit) flag = true; 90 80 */ 91 81 static inline int __access_ok(unsigned long addr, unsigned long size) 92 82 { 93 - unsigned long flag, tmp; 83 + unsigned long flag, sum; 94 84 95 - __asm__("stc r7_bank, %0\n\t" 96 - "mov.l @(8,%0), %0\n\t" 97 - "clrt\n\t" 98 - "addc %2, %1\n\t" 99 - "and %1, %0\n\t" 100 - "rotcl %0\n\t" 101 - "rotcl %0\n\t" 102 - "and #3, %0" 103 - : "=&z" (flag), "=r" (tmp) 104 - : "r" (addr), "1" (size) 105 - : "t"); 106 - 85 + __asm__("clrt\n\t" 86 + "addc %3, %1\n\t" 87 + "movt %0\n\t" 88 + "cmp/hi %4, %1\n\t" 89 + "rotcl %0" 90 + :"=&r" (flag), "=r" (sum) 91 + :"1" (addr), "r" (size), 92 + "r" (current_thread_info()->addr_limit.seg) 93 + :"t"); 107 94 return flag == 0; 95 + 108 96 } 109 97 #endif /* CONFIG_MMU */ 110 98