Skip to content

Commit b13c190

Browse files
hcahcaAlexander Gordeev
authored andcommitted
s390/uaccess: Initialize code pages executed with non-default access key
cmpxchg_user_key() may be executed with a non-zero key; if then the storage key of the page which belongs to the cmpxchg_user_key() code contains a key with fetch-protection enabled the result is a protection exception: Unable to handle kernel pointer dereference in virtual kernel address space Failing address: 0000000000000000 TEID: 000000000000080b Fault in home space mode while using kernel ASCE. AS:0000000002528007 R3:00000001ffffc007 S:00000001ffffb801 P:000000000000013d Oops: 0004 ilc:1 [#1]SMP Modules linked in: CPU: 3 UID: 0 PID: 791 Comm: memop Not tainted 6.16.0-rc1-00006-g3b568201d0a6-dirty #11 NONE Hardware name: IBM 3931 A01 704 (z/VM 7.4.0) Krnl PSW : 0794f00180000000 000003ffe0f4d91e (__cmpxchg_user_key1+0xbe/0x190) R:0 T:1 IO:1 EX:1 Key:9 M:1 W:0 P:0 AS:3 CC:3 PM:0 RI:0 EA:3 Krnl GPRS: 070003ffdfbf6af0 0000000000070000 0000000095b5a300 0000000000000000 00000000f1000000 0000000000000000 0000000000000090 0000000000000000 0000000000000040 0000000000000018 000003ff9b23d000 0000037fe0ef7bd8 000003ffdfbf7500 00000000962e4000 0000037f00ffffff 0000037fe0ef7aa0 Krnl Code: 000003ffe0f4d912: ad03f0a0 stosm 160(%r15),3 000003ffe0f4d916: a7780000 lhi %r7,0 #000003ffe0f4d91a: b20a6000 spka 0(%r6) >000003ffe0f4d91e: b2790100 sacf 256 000003ffe0f4d922: a56f0080 llill %r6,128 000003ffe0f4d926: 5810a000 l %r1,0(%r10) 000003ffe0f4d92a: 141e nr %r1,%r14 000003ffe0f4d92c: c0e7ffffffff xilf %r14,4294967295 Call Trace: [<000003ffe0f4d91e>] __cmpxchg_user_key1+0xbe/0x190 [<000003ffe0189c6e>] cmpxchg_guest_abs_with_key+0x2fe/0x370 [<000003ffe016d28e>] kvm_s390_vm_mem_op_cmpxchg+0x17e/0x350 [<000003ffe0173284>] kvm_arch_vm_ioctl+0x354/0x6f0 [<000003ffe015fedc>] kvm_vm_ioctl+0x2cc/0x6e0 [<000003ffe05348ae>] vfs_ioctl+0x2e/0x70 [<000003ffe0535e70>] __s390x_sys_ioctl+0xe0/0x100 [<000003ffe0f40f06>] __do_syscall+0x136/0x340 [<000003ffe0f4cb2e>] system_call+0x6e/0x90 Last Breaking-Event-Address: [<000003ffe0f4d896>] __cmpxchg_user_key1+0x36/0x190 Fix this by defining all code ranges within cmpxchg_user_key() functions which may be executed with a non-default key and explicitly initialize storage keys by calling skey_regions_initialize(). Reviewed-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
1 parent ee417a8 commit b13c190

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

arch/s390/lib/uaccess.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <linux/mm.h>
1414
#include <asm/asm-extable.h>
1515
#include <asm/ctlreg.h>
16+
#include <asm/skey.h>
1617

1718
#ifdef CONFIG_DEBUG_ENTRY
1819
void debug_user_asce(int exit)
@@ -156,14 +157,15 @@ int __cmpxchg_user_key1(unsigned long address, unsigned char *uval,
156157
bool sacf_flag;
157158
int rc = 0;
158159

160+
skey_regions_initialize();
159161
shift = (3 ^ (address & 3)) << 3;
160162
address ^= address & 3;
161163
_old = (unsigned int)old << shift;
162164
_new = (unsigned int)new << shift;
163165
mask = ~(0xff << shift);
164166
sacf_flag = enable_sacf_uaccess();
165167
asm_inline volatile(
166-
" spka 0(%[key])\n"
168+
"20: spka 0(%[key])\n"
167169
" sacf 256\n"
168170
" llill %[count],%[max_loops]\n"
169171
"0: l %[prev],%[address]\n"
@@ -181,10 +183,12 @@ int __cmpxchg_user_key1(unsigned long address, unsigned char *uval,
181183
" brct %[count],2b\n"
182184
"5: sacf 768\n"
183185
" spka %[default_key]\n"
186+
"21:\n"
184187
EX_TABLE_UA_LOAD_REG(0b, 5b, %[rc], %[prev])
185188
EX_TABLE_UA_LOAD_REG(1b, 5b, %[rc], %[prev])
186189
EX_TABLE_UA_LOAD_REG(3b, 5b, %[rc], %[prev])
187190
EX_TABLE_UA_LOAD_REG(4b, 5b, %[rc], %[prev])
191+
SKEY_REGION(20b, 21b)
188192
: [rc] "+&d" (rc),
189193
[prev] "=&d" (prev),
190194
[address] "+Q" (*(int *)address),
@@ -212,14 +216,15 @@ int __cmpxchg_user_key2(unsigned long address, unsigned short *uval,
212216
bool sacf_flag;
213217
int rc = 0;
214218

219+
skey_regions_initialize();
215220
shift = (2 ^ (address & 2)) << 3;
216221
address ^= address & 2;
217222
_old = (unsigned int)old << shift;
218223
_new = (unsigned int)new << shift;
219224
mask = ~(0xffff << shift);
220225
sacf_flag = enable_sacf_uaccess();
221226
asm_inline volatile(
222-
" spka 0(%[key])\n"
227+
"20: spka 0(%[key])\n"
223228
" sacf 256\n"
224229
" llill %[count],%[max_loops]\n"
225230
"0: l %[prev],%[address]\n"
@@ -237,10 +242,12 @@ int __cmpxchg_user_key2(unsigned long address, unsigned short *uval,
237242
" brct %[count],2b\n"
238243
"5: sacf 768\n"
239244
" spka %[default_key]\n"
245+
"21:\n"
240246
EX_TABLE_UA_LOAD_REG(0b, 5b, %[rc], %[prev])
241247
EX_TABLE_UA_LOAD_REG(1b, 5b, %[rc], %[prev])
242248
EX_TABLE_UA_LOAD_REG(3b, 5b, %[rc], %[prev])
243249
EX_TABLE_UA_LOAD_REG(4b, 5b, %[rc], %[prev])
250+
SKEY_REGION(20b, 21b)
244251
: [rc] "+&d" (rc),
245252
[prev] "=&d" (prev),
246253
[address] "+Q" (*(int *)address),
@@ -267,15 +274,18 @@ int __cmpxchg_user_key4(unsigned long address, unsigned int *uval,
267274
bool sacf_flag;
268275
int rc = 0;
269276

277+
skey_regions_initialize();
270278
sacf_flag = enable_sacf_uaccess();
271279
asm_inline volatile(
272-
" spka 0(%[key])\n"
280+
"20: spka 0(%[key])\n"
273281
" sacf 256\n"
274282
"0: cs %[prev],%[new],%[address]\n"
275283
"1: sacf 768\n"
276284
" spka %[default_key]\n"
285+
"21:\n"
277286
EX_TABLE_UA_LOAD_REG(0b, 1b, %[rc], %[prev])
278287
EX_TABLE_UA_LOAD_REG(1b, 1b, %[rc], %[prev])
288+
SKEY_REGION(20b, 21b)
279289
: [rc] "+&d" (rc),
280290
[prev] "+&d" (prev),
281291
[address] "+Q" (*(int *)address)
@@ -296,15 +306,18 @@ int __cmpxchg_user_key8(unsigned long address, unsigned long *uval,
296306
bool sacf_flag;
297307
int rc = 0;
298308

309+
skey_regions_initialize();
299310
sacf_flag = enable_sacf_uaccess();
300311
asm_inline volatile(
301-
" spka 0(%[key])\n"
312+
"20: spka 0(%[key])\n"
302313
" sacf 256\n"
303314
"0: csg %[prev],%[new],%[address]\n"
304315
"1: sacf 768\n"
305316
" spka %[default_key]\n"
317+
"21:\n"
306318
EX_TABLE_UA_LOAD_REG(0b, 1b, %[rc], %[prev])
307319
EX_TABLE_UA_LOAD_REG(1b, 1b, %[rc], %[prev])
320+
SKEY_REGION(20b, 21b)
308321
: [rc] "+&d" (rc),
309322
[prev] "+&d" (prev),
310323
[address] "+QS" (*(long *)address)
@@ -325,15 +338,18 @@ int __cmpxchg_user_key16(unsigned long address, __uint128_t *uval,
325338
bool sacf_flag;
326339
int rc = 0;
327340

341+
skey_regions_initialize();
328342
sacf_flag = enable_sacf_uaccess();
329343
asm_inline volatile(
330-
" spka 0(%[key])\n"
344+
"20: spka 0(%[key])\n"
331345
" sacf 256\n"
332346
"0: cdsg %[prev],%[new],%[address]\n"
333347
"1: sacf 768\n"
334348
" spka %[default_key]\n"
349+
"21:\n"
335350
EX_TABLE_UA_LOAD_REGPAIR(0b, 1b, %[rc], %[prev])
336351
EX_TABLE_UA_LOAD_REGPAIR(1b, 1b, %[rc], %[prev])
352+
SKEY_REGION(20b, 21b)
337353
: [rc] "+&d" (rc),
338354
[prev] "+&d" (prev),
339355
[address] "+QS" (*(__int128_t *)address)

0 commit comments

Comments
 (0)