diff options
author | Gerald Schaefer <gerald.schaefer@de.ibm.com> | 2009-10-06 04:34:14 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2009-10-06 04:35:10 -0400 |
commit | af9d2ff9afaae8040dbf09238b2579f92c93579e (patch) | |
tree | 61ceddb80062cae529b9c5a34cdf7a07566f1a30 /arch/s390/lib/uaccess_std.c | |
parent | ea2a4d3a3a929ef494952bba57a0ef1a8a877881 (diff) |
[S390] Add EX_TABLE for addressing exception in usercopy functions.
This patch adds an EX_TABLE entry to mvc{p|s|os} usercopy functions that
may be called with KERNEL_DS. In combination with collaborative memory
management, kernel pages marked as unused may trigger an adressing exception
in the usercopy functions. This fixes an unhandled addressing exception bug
where strncpy_from_user() is used with len > strnlen and KERNEL_DS, crossing
a page boundary to an unused page.
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/lib/uaccess_std.c')
-rw-r--r-- | arch/s390/lib/uaccess_std.c | 14 |
1 files changed, 8 insertions, 6 deletions
diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c index d2ffbadb51a7..07deaeee14c8 100644 --- a/arch/s390/lib/uaccess_std.c +++ b/arch/s390/lib/uaccess_std.c | |||
@@ -36,12 +36,12 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) | |||
36 | tmp1 = -256UL; | 36 | tmp1 = -256UL; |
37 | asm volatile( | 37 | asm volatile( |
38 | "0: mvcp 0(%0,%2),0(%1),%3\n" | 38 | "0: mvcp 0(%0,%2),0(%1),%3\n" |
39 | " jz 8f\n" | 39 | "10:jz 8f\n" |
40 | "1:"ALR" %0,%3\n" | 40 | "1:"ALR" %0,%3\n" |
41 | " la %1,256(%1)\n" | 41 | " la %1,256(%1)\n" |
42 | " la %2,256(%2)\n" | 42 | " la %2,256(%2)\n" |
43 | "2: mvcp 0(%0,%2),0(%1),%3\n" | 43 | "2: mvcp 0(%0,%2),0(%1),%3\n" |
44 | " jnz 1b\n" | 44 | "11:jnz 1b\n" |
45 | " j 8f\n" | 45 | " j 8f\n" |
46 | "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ | 46 | "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ |
47 | " "LHI" %3,-4096\n" | 47 | " "LHI" %3,-4096\n" |
@@ -50,7 +50,7 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) | |||
50 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ | 50 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
51 | " jnh 5f\n" | 51 | " jnh 5f\n" |
52 | "4: mvcp 0(%4,%2),0(%1),%3\n" | 52 | "4: mvcp 0(%4,%2),0(%1),%3\n" |
53 | " "SLR" %0,%4\n" | 53 | "12:"SLR" %0,%4\n" |
54 | " "ALR" %2,%4\n" | 54 | " "ALR" %2,%4\n" |
55 | "5:"LHI" %4,-1\n" | 55 | "5:"LHI" %4,-1\n" |
56 | " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ | 56 | " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ |
@@ -65,6 +65,7 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) | |||
65 | "8:"SLR" %0,%0\n" | 65 | "8:"SLR" %0,%0\n" |
66 | "9: \n" | 66 | "9: \n" |
67 | EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,5b) | 67 | EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,5b) |
68 | EX_TABLE(10b,3b) EX_TABLE(11b,3b) EX_TABLE(12b,5b) | ||
68 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) | 69 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
69 | : : "cc", "memory"); | 70 | : : "cc", "memory"); |
70 | return size; | 71 | return size; |
@@ -85,12 +86,12 @@ size_t copy_to_user_std(size_t size, void __user *ptr, const void *x) | |||
85 | tmp1 = -256UL; | 86 | tmp1 = -256UL; |
86 | asm volatile( | 87 | asm volatile( |
87 | "0: mvcs 0(%0,%1),0(%2),%3\n" | 88 | "0: mvcs 0(%0,%1),0(%2),%3\n" |
88 | " jz 5f\n" | 89 | "7: jz 5f\n" |
89 | "1:"ALR" %0,%3\n" | 90 | "1:"ALR" %0,%3\n" |
90 | " la %1,256(%1)\n" | 91 | " la %1,256(%1)\n" |
91 | " la %2,256(%2)\n" | 92 | " la %2,256(%2)\n" |
92 | "2: mvcs 0(%0,%1),0(%2),%3\n" | 93 | "2: mvcs 0(%0,%1),0(%2),%3\n" |
93 | " jnz 1b\n" | 94 | "8: jnz 1b\n" |
94 | " j 5f\n" | 95 | " j 5f\n" |
95 | "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ | 96 | "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ |
96 | " "LHI" %3,-4096\n" | 97 | " "LHI" %3,-4096\n" |
@@ -99,11 +100,12 @@ size_t copy_to_user_std(size_t size, void __user *ptr, const void *x) | |||
99 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ | 100 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
100 | " jnh 6f\n" | 101 | " jnh 6f\n" |
101 | "4: mvcs 0(%4,%1),0(%2),%3\n" | 102 | "4: mvcs 0(%4,%1),0(%2),%3\n" |
102 | " "SLR" %0,%4\n" | 103 | "9:"SLR" %0,%4\n" |
103 | " j 6f\n" | 104 | " j 6f\n" |
104 | "5:"SLR" %0,%0\n" | 105 | "5:"SLR" %0,%0\n" |
105 | "6: \n" | 106 | "6: \n" |
106 | EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b) | 107 | EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b) |
108 | EX_TABLE(7b,3b) EX_TABLE(8b,3b) EX_TABLE(9b,6b) | ||
107 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) | 109 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
108 | : : "cc", "memory"); | 110 | : : "cc", "memory"); |
109 | return size; | 111 | return size; |