diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-09-28 10:56:03 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2006-09-28 10:56:03 -0400 |
commit | 52149ba6b0ddf3e9d965257cc0513193650b3ea8 (patch) | |
tree | af8097516b3cd9d9f2397080e4cf81414fd4172a /arch/s390/lib/uaccess_std.c | |
parent | 51dced544e3964b684afc99282ceceaa384b16a8 (diff) |
[S390] user readable uninitialised kernel memory.
A user space program can read uninitialised kernel memory
by appending to a file from a bad address and then reading
the result back. The cause is the copy_from_user function
that does not clear the remaining bytes of the kernel
buffer after it got a fault on the user space address.
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 | 36 |
1 files changed, 26 insertions, 10 deletions
diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c index 9a4d4a29ea79..f44f0078b354 100644 --- a/arch/s390/lib/uaccess_std.c +++ b/arch/s390/lib/uaccess_std.c | |||
@@ -35,25 +35,35 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) | |||
35 | tmp1 = -256UL; | 35 | tmp1 = -256UL; |
36 | asm volatile( | 36 | asm volatile( |
37 | "0: mvcp 0(%0,%2),0(%1),%3\n" | 37 | "0: mvcp 0(%0,%2),0(%1),%3\n" |
38 | " jz 5f\n" | 38 | " jz 8f\n" |
39 | "1:"ALR" %0,%3\n" | 39 | "1:"ALR" %0,%3\n" |
40 | " la %1,256(%1)\n" | 40 | " la %1,256(%1)\n" |
41 | " la %2,256(%2)\n" | 41 | " la %2,256(%2)\n" |
42 | "2: mvcp 0(%0,%2),0(%1),%3\n" | 42 | "2: mvcp 0(%0,%2),0(%1),%3\n" |
43 | " jnz 1b\n" | 43 | " jnz 1b\n" |
44 | " j 5f\n" | 44 | " j 8f\n" |
45 | "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ | 45 | "3: la %4,255(%1)\n" /* %4 = ptr + 255 */ |
46 | " "LHI" %3,-4096\n" | 46 | " "LHI" %3,-4096\n" |
47 | " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */ | 47 | " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */ |
48 | " "SLR" %4,%1\n" | 48 | " "SLR" %4,%1\n" |
49 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ | 49 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
50 | " jnh 6f\n" | 50 | " jnh 5f\n" |
51 | "4: mvcp 0(%4,%2),0(%1),%3\n" | 51 | "4: mvcp 0(%4,%2),0(%1),%3\n" |
52 | " "SLR" %0,%4\n" | 52 | " "SLR" %0,%4\n" |
53 | " j 6f\n" | 53 | " "ALR" %2,%4\n" |
54 | "5:"SLR" %0,%0\n" | 54 | "5:"LHI" %4,-1\n" |
55 | "6: \n" | 55 | " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ |
56 | EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,6b) | 56 | " bras %3,7f\n" /* memset loop */ |
57 | " xc 0(1,%2),0(%2)\n" | ||
58 | "6: xc 0(256,%2),0(%2)\n" | ||
59 | " la %2,256(%2)\n" | ||
60 | "7:"AHI" %4,-256\n" | ||
61 | " jnm 6b\n" | ||
62 | " ex %4,0(%3)\n" | ||
63 | " j 9f\n" | ||
64 | "8:"SLR" %0,%0\n" | ||
65 | "9: \n" | ||
66 | EX_TABLE(0b,3b) EX_TABLE(2b,3b) EX_TABLE(4b,5b) | ||
57 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) | 67 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
58 | : : "cc", "memory"); | 68 | : : "cc", "memory"); |
59 | return size; | 69 | return size; |
@@ -67,16 +77,22 @@ size_t copy_from_user_std_small(size_t size, const void __user *ptr, void *x) | |||
67 | asm volatile( | 77 | asm volatile( |
68 | "0: mvcp 0(%0,%2),0(%1),%3\n" | 78 | "0: mvcp 0(%0,%2),0(%1),%3\n" |
69 | " "SLR" %0,%0\n" | 79 | " "SLR" %0,%0\n" |
70 | " j 3f\n" | 80 | " j 5f\n" |
71 | "1: la %4,255(%1)\n" /* %4 = ptr + 255 */ | 81 | "1: la %4,255(%1)\n" /* %4 = ptr + 255 */ |
72 | " "LHI" %3,-4096\n" | 82 | " "LHI" %3,-4096\n" |
73 | " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */ | 83 | " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */ |
74 | " "SLR" %4,%1\n" | 84 | " "SLR" %4,%1\n" |
75 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ | 85 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
76 | " jnh 3f\n" | 86 | " jnh 5f\n" |
77 | "2: mvcp 0(%4,%2),0(%1),%3\n" | 87 | "2: mvcp 0(%4,%2),0(%1),%3\n" |
78 | " "SLR" %0,%4\n" | 88 | " "SLR" %0,%4\n" |
79 | "3:\n" | 89 | " "ALR" %2,%4\n" |
90 | "3:"LHI" %4,-1\n" | ||
91 | " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ | ||
92 | " bras %3,4f\n" | ||
93 | " xc 0(1,%2),0(%2)\n" | ||
94 | "4: ex %4,0(%3)\n" | ||
95 | "5:\n" | ||
80 | EX_TABLE(0b,1b) EX_TABLE(2b,3b) | 96 | EX_TABLE(0b,1b) EX_TABLE(2b,3b) |
81 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) | 97 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
82 | : : "cc", "memory"); | 98 | : : "cc", "memory"); |