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 | |
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')
-rw-r--r-- | arch/s390/lib/uaccess_mvcos.c | 22 | ||||
-rw-r--r-- | arch/s390/lib/uaccess_std.c | 36 |
2 files changed, 42 insertions, 16 deletions
diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c index 86c96d6c191a..121b2935a422 100644 --- a/arch/s390/lib/uaccess_mvcos.c +++ b/arch/s390/lib/uaccess_mvcos.c | |||
@@ -35,7 +35,7 @@ size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) | |||
35 | tmp1 = -4096UL; | 35 | tmp1 = -4096UL; |
36 | asm volatile( | 36 | asm volatile( |
37 | "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n" | 37 | "0: .insn ss,0xc80000000000,0(%0,%2),0(%1),0\n" |
38 | " jz 4f\n" | 38 | " jz 7f\n" |
39 | "1:"ALR" %0,%3\n" | 39 | "1:"ALR" %0,%3\n" |
40 | " "SLR" %1,%3\n" | 40 | " "SLR" %1,%3\n" |
41 | " "SLR" %2,%3\n" | 41 | " "SLR" %2,%3\n" |
@@ -44,13 +44,23 @@ size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) | |||
44 | " nr %4,%3\n" /* %4 = (ptr + 4095) & -4096 */ | 44 | " nr %4,%3\n" /* %4 = (ptr + 4095) & -4096 */ |
45 | " "SLR" %4,%1\n" | 45 | " "SLR" %4,%1\n" |
46 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ | 46 | " "CLR" %0,%4\n" /* copy crosses next page boundary? */ |
47 | " jnh 5f\n" | 47 | " jnh 4f\n" |
48 | "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n" | 48 | "3: .insn ss,0xc80000000000,0(%4,%2),0(%1),0\n" |
49 | " "SLR" %0,%4\n" | 49 | " "SLR" %0,%4\n" |
50 | " j 5f\n" | 50 | " "ALR" %2,%4\n" |
51 | "4:"SLR" %0,%0\n" | 51 | "4:"LHI" %4,-1\n" |
52 | "5: \n" | 52 | " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */ |
53 | EX_TABLE(0b,2b) EX_TABLE(3b,5b) | 53 | " bras %3,6f\n" /* memset loop */ |
54 | " xc 0(1,%2),0(%2)\n" | ||
55 | "5: xc 0(256,%2),0(%2)\n" | ||
56 | " la %2,256(%2)\n" | ||
57 | "6:"AHI" %4,-256\n" | ||
58 | " jnm 5b\n" | ||
59 | " ex %4,0(%3)\n" | ||
60 | " j 8f\n" | ||
61 | "7:"SLR" %0,%0\n" | ||
62 | "8: \n" | ||
63 | EX_TABLE(0b,2b) EX_TABLE(3b,4b) | ||
54 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) | 64 | : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2) |
55 | : "d" (reg0) : "cc", "memory"); | 65 | : "d" (reg0) : "cc", "memory"); |
56 | return size; | 66 | return size; |
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"); |