xref: /linux/tools/testing/selftests/mm/protection_keys.c (revision ed3b875bea55a3ec4837113356df2ead11115af9)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Tests Memory Protection Keys (see Documentation/core-api/protection-keys.rst)
4  *
5  * There are examples in here of:
6  *  * how to set protection keys on memory
7  *  * how to set/clear bits in pkey registers (the rights register)
8  *  * how to handle SEGV_PKUERR signals and extract pkey-relevant
9  *    information from the siginfo
10  *
11  * Things to add:
12  *	make sure KSM and KSM COW breaking works
13  *	prefault pages in at malloc, or not
14  *	protect MPX bounds tables with protection keys?
15  *	make sure VMA splitting/merging is working correctly
16  *	OOMs can destroy mm->mmap (see exit_mmap()), so make sure it is immune to pkeys
17  *	look for pkey "leaks" where it is still set on a VMA but "freed" back to the kernel
18  *	do a plain mprotect() to a mprotect_pkey() area and make sure the pkey sticks
19  *
20  * Compile like this:
21  *	gcc -mxsave      -o protection_keys    -O2 -g -std=gnu99 -pthread -Wall protection_keys.c -lrt -ldl -lm
22  *	gcc -mxsave -m32 -o protection_keys_32 -O2 -g -std=gnu99 -pthread -Wall protection_keys.c -lrt -ldl -lm
23  */
24 #define _GNU_SOURCE
25 #define __SANE_USERSPACE_TYPES__
26 #include <errno.h>
27 #include <linux/elf.h>
28 #include <linux/futex.h>
29 #include <time.h>
30 #include <sys/time.h>
31 #include <sys/syscall.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <stdint.h>
35 #include <stdbool.h>
36 #include <signal.h>
37 #include <assert.h>
38 #include <stdlib.h>
39 #include <ucontext.h>
40 #include <sys/mman.h>
41 #include <sys/types.h>
42 #include <sys/wait.h>
43 #include <sys/stat.h>
44 #include <fcntl.h>
45 #include <unistd.h>
46 #include <sys/ptrace.h>
47 #include <setjmp.h>
48 
49 #include "hugepage_settings.h"
50 #include "pkey-helpers.h"
51 
52 u64 shadow_pkey_reg;
53 
54 noinline int read_ptr(int *ptr)
55 {
56 	/* Keep GCC from optimizing this away somehow */
57 	barrier();
58 	return *ptr;
59 }
60 
61 /*
62  * This attempts to have roughly a page of instructions followed by a few
63  * instructions that do a write, and another page of instructions.  That
64  * way, we are pretty sure that the write is in the second page of
65  * instructions and has at least a page of padding behind it.
66  *
67  * *That* lets us be sure to madvise() away the write instruction, which
68  * will then fault, which makes sure that the fault code handles
69  * execute-only memory properly.
70  */
71 #if defined(__powerpc64__) || defined(__aarch64__)
72 /* This way, both 4K and 64K alignment are maintained */
73 __attribute__((__aligned__(65536)))
74 #else
75 __attribute__((__aligned__(PAGE_SIZE)))
76 #endif
77 static void lots_o_noops_around_write(int *write_to_me)
78 {
79 	dprintf3("running %s()\n", __func__);
80 	__page_o_noops();
81 	/* Assume this happens in the second page of instructions: */
82 	*write_to_me = __LINE__;
83 	/* pad out by another page: */
84 	__page_o_noops();
85 	dprintf3("%s() done\n", __func__);
86 }
87 
88 static void dump_mem(void *dumpme, int len_bytes)
89 {
90 	char *c = (void *)dumpme;
91 	int i;
92 
93 	for (i = 0; i < len_bytes; i += sizeof(u64)) {
94 		u64 *ptr = (u64 *)(c + i);
95 		dprintf1("dump[%03d][@%p]: %016llx\n", i, ptr, *ptr);
96 	}
97 }
98 
99 static u32 hw_pkey_get(int pkey, unsigned long flags)
100 {
101 	u64 pkey_reg = __read_pkey_reg();
102 
103 	dprintf1("%s(pkey=%d, flags=%lx) = %x / %d\n",
104 			__func__, pkey, flags, 0, 0);
105 	dprintf2("%s() raw pkey_reg: %016llx\n", __func__, pkey_reg);
106 
107 	return (u32) get_pkey_bits(pkey_reg, pkey);
108 }
109 
110 static int hw_pkey_set(int pkey, unsigned long rights, unsigned long flags)
111 {
112 	u32 mask = (PKEY_DISABLE_ACCESS|PKEY_DISABLE_WRITE);
113 	u64 old_pkey_reg = __read_pkey_reg();
114 	u64 new_pkey_reg;
115 
116 	/* make sure that 'rights' only contains the bits we expect: */
117 	assert(!(rights & ~mask));
118 
119 	/* modify bits accordingly in old pkey_reg and assign it */
120 	new_pkey_reg = set_pkey_bits(old_pkey_reg, pkey, rights);
121 
122 	__write_pkey_reg(new_pkey_reg);
123 
124 	dprintf3("%s(pkey=%d, rights=%lx, flags=%lx) = %x"
125 		" pkey_reg now: %016llx old_pkey_reg: %016llx\n",
126 		__func__, pkey, rights, flags, 0, __read_pkey_reg(),
127 		old_pkey_reg);
128 	return 0;
129 }
130 
131 static void pkey_disable_set(int pkey, int flags)
132 {
133 	unsigned long syscall_flags = 0;
134 	int ret;
135 	int pkey_rights;
136 
137 	dprintf1("START->%s(%d, 0x%x)\n", __func__,
138 		pkey, flags);
139 	pkey_assert(flags & (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE));
140 
141 	pkey_rights = hw_pkey_get(pkey, syscall_flags);
142 
143 	dprintf1("%s(%d) hw_pkey_get(%d): %x\n", __func__,
144 			pkey, pkey, pkey_rights);
145 
146 	pkey_assert(pkey_rights >= 0);
147 
148 	pkey_rights |= flags;
149 
150 	ret = hw_pkey_set(pkey, pkey_rights, syscall_flags);
151 	assert(!ret);
152 	/* pkey_reg and flags have the same format */
153 	shadow_pkey_reg = set_pkey_bits(shadow_pkey_reg, pkey, pkey_rights);
154 	dprintf1("%s(%d) shadow: 0x%016llx\n",
155 		__func__, pkey, shadow_pkey_reg);
156 
157 	pkey_assert(ret >= 0);
158 
159 	pkey_rights = hw_pkey_get(pkey, syscall_flags);
160 	dprintf1("%s(%d) hw_pkey_get(%d): %x\n", __func__,
161 			pkey, pkey, pkey_rights);
162 
163 	dprintf1("%s(%d) pkey_reg: 0x%016llx\n",
164 		__func__, pkey, read_pkey_reg());
165 	dprintf1("END<---%s(%d, 0x%x)\n", __func__,
166 		pkey, flags);
167 }
168 
169 static void pkey_disable_clear(int pkey, int flags)
170 {
171 	unsigned long syscall_flags = 0;
172 	int ret;
173 	int pkey_rights = hw_pkey_get(pkey, syscall_flags);
174 
175 	pkey_assert(flags & (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE));
176 
177 	dprintf1("%s(%d) hw_pkey_get(%d): %x\n", __func__,
178 			pkey, pkey, pkey_rights);
179 	pkey_assert(pkey_rights >= 0);
180 
181 	pkey_rights &= ~flags;
182 
183 	ret = hw_pkey_set(pkey, pkey_rights, 0);
184 	shadow_pkey_reg = set_pkey_bits(shadow_pkey_reg, pkey, pkey_rights);
185 	pkey_assert(ret >= 0);
186 
187 	pkey_rights = hw_pkey_get(pkey, syscall_flags);
188 	dprintf1("%s(%d) hw_pkey_get(%d): %x\n", __func__,
189 			pkey, pkey, pkey_rights);
190 
191 	dprintf1("%s(%d) pkey_reg: 0x%016llx\n", __func__,
192 			pkey, read_pkey_reg());
193 }
194 
195 __maybe_unused static void pkey_write_allow(int pkey)
196 {
197 	pkey_disable_clear(pkey, PKEY_DISABLE_WRITE);
198 }
199 __maybe_unused static void pkey_write_deny(int pkey)
200 {
201 	pkey_disable_set(pkey, PKEY_DISABLE_WRITE);
202 }
203 __maybe_unused static void pkey_access_allow(int pkey)
204 {
205 	pkey_disable_clear(pkey, PKEY_DISABLE_ACCESS);
206 }
207 __maybe_unused static void pkey_access_deny(int pkey)
208 {
209 	pkey_disable_set(pkey, PKEY_DISABLE_ACCESS);
210 }
211 
212 static char *si_code_str(int si_code)
213 {
214 	if (si_code == SEGV_MAPERR)
215 		return "SEGV_MAPERR";
216 	if (si_code == SEGV_ACCERR)
217 		return "SEGV_ACCERR";
218 	if (si_code == SEGV_BNDERR)
219 		return "SEGV_BNDERR";
220 	if (si_code == SEGV_PKUERR)
221 		return "SEGV_PKUERR";
222 	return "UNKNOWN";
223 }
224 
225 static int pkey_faults;
226 static int last_si_pkey = -1;
227 static void signal_handler(int signum, siginfo_t *si, void *vucontext)
228 {
229 	ucontext_t *uctxt = vucontext;
230 	int trapno;
231 	unsigned long ip;
232 #ifdef MCONTEXT_FPREGS
233 	char *fpregs;
234 #endif
235 #if defined(__i386__) || defined(__x86_64__) /* arch */
236 	u32 *pkey_reg_ptr;
237 	int pkey_reg_offset;
238 #endif /* arch */
239 	u64 siginfo_pkey;
240 	u32 *si_pkey_ptr;
241 
242 	dprint_in_signal = 1;
243 	dprintf1(">>>>===============SIGSEGV============================\n");
244 	dprintf1("%s()::%d, pkey_reg: 0x%016llx shadow: %016llx\n",
245 			__func__, __LINE__,
246 			__read_pkey_reg(), shadow_pkey_reg);
247 
248 	trapno = MCONTEXT_TRAPNO(uctxt->uc_mcontext);
249 	ip = MCONTEXT_IP(uctxt->uc_mcontext);
250 #ifdef MCONTEXT_FPREGS
251 	fpregs = (char *) uctxt->uc_mcontext.fpregs;
252 #endif
253 
254 	dprintf2("%s() trapno: %d ip: 0x%016lx info->si_code: %s/%d\n",
255 			__func__, trapno, ip, si_code_str(si->si_code),
256 			si->si_code);
257 
258 #if defined(__i386__) || defined(__x86_64__) /* arch */
259 #ifdef __i386__
260 	/*
261 	 * 32-bit has some extra padding so that userspace can tell whether
262 	 * the XSTATE header is present in addition to the "legacy" FPU
263 	 * state.  We just assume that it is here.
264 	 */
265 	fpregs += 0x70;
266 #endif /* i386 */
267 	pkey_reg_offset = pkey_reg_xstate_offset();
268 	pkey_reg_ptr = (void *)(&fpregs[pkey_reg_offset]);
269 
270 	/*
271 	 * If we got a PKEY fault, we *HAVE* to have at least one bit set in
272 	 * here.
273 	 */
274 	dprintf1("pkey_reg_xstate_offset: %d\n", pkey_reg_xstate_offset());
275 	if (DEBUG_LEVEL > 4)
276 		dump_mem(pkey_reg_ptr - 128, 256);
277 	pkey_assert(*pkey_reg_ptr);
278 #endif /* arch */
279 
280 	dprintf1("siginfo: %p\n", si);
281 #ifdef MCONTEXT_FPREGS
282 	dprintf1(" fpregs: %p\n", fpregs);
283 #endif
284 
285 	if ((si->si_code == SEGV_MAPERR) ||
286 	    (si->si_code == SEGV_ACCERR) ||
287 	    (si->si_code == SEGV_BNDERR)) {
288 		dprintf0("# non-PK si_code: %d, exiting...\n", si->si_code);
289 		exit(1);
290 	}
291 
292 	si_pkey_ptr = siginfo_get_pkey_ptr(si);
293 	dprintf1("si_pkey_ptr: %p\n", si_pkey_ptr);
294 	dump_mem((u8 *)si_pkey_ptr - 8, 24);
295 	siginfo_pkey = *si_pkey_ptr;
296 	pkey_assert(siginfo_pkey < NR_PKEYS);
297 	last_si_pkey = siginfo_pkey;
298 
299 	/*
300 	 * need __read_pkey_reg() version so we do not do shadow_pkey_reg
301 	 * checking
302 	 */
303 	dprintf1("signal pkey_reg from  pkey_reg: %016llx\n",
304 			__read_pkey_reg());
305 	dprintf1("pkey from siginfo: %016llx\n", siginfo_pkey);
306 #if defined(__i386__) || defined(__x86_64__) /* arch */
307 	dprintf1("signal pkey_reg from xsave: %08x\n", *pkey_reg_ptr);
308 	*(u64 *)pkey_reg_ptr = 0x00000000;
309 	dprintf1("WARNING: set PKEY_REG=0 to allow faulting instruction to continue\n");
310 #elif defined(__powerpc64__) /* arch */
311 	/* restore access and let the faulting instruction continue */
312 	pkey_access_allow(siginfo_pkey);
313 #elif defined(__aarch64__)
314 	aarch64_write_signal_pkey(uctxt, PKEY_REG_ALLOW_ALL);
315 #endif /* arch */
316 	pkey_faults++;
317 	dprintf1("<<<<==================================================\n");
318 	dprint_in_signal = 0;
319 }
320 
321 static void sig_chld(int x)
322 {
323 	dprint_in_signal = 1;
324 	dprintf2("[%d] SIGCHLD: %d\n", getpid(), x);
325 	dprint_in_signal = 0;
326 }
327 
328 static void setup_sigsegv_handler(void)
329 {
330 	int r, rs;
331 	struct sigaction newact;
332 	struct sigaction oldact;
333 
334 	/* #PF is mapped to sigsegv */
335 	int signum  = SIGSEGV;
336 
337 	newact.sa_handler = 0;
338 	newact.sa_sigaction = signal_handler;
339 
340 	/*sigset_t - signals to block while in the handler */
341 	/* get the old signal mask. */
342 	rs = sigprocmask(SIG_SETMASK, 0, &newact.sa_mask);
343 	pkey_assert(rs == 0);
344 
345 	/* call sa_sigaction, not sa_handler*/
346 	newact.sa_flags = SA_SIGINFO;
347 
348 	newact.sa_restorer = 0;  /* void(*)(), obsolete */
349 	r = sigaction(signum, &newact, &oldact);
350 	r = sigaction(SIGALRM, &newact, &oldact);
351 	pkey_assert(r == 0);
352 }
353 
354 static void setup_handlers(void)
355 {
356 	signal(SIGCHLD, &sig_chld);
357 	setup_sigsegv_handler();
358 }
359 
360 static pid_t fork_lazy_child(void)
361 {
362 	pid_t forkret;
363 
364 	forkret = fork();
365 	pkey_assert(forkret >= 0);
366 	dprintf3("[%d] fork() ret: %d\n", getpid(), forkret);
367 
368 	if (!forkret) {
369 		/* in the child */
370 		while (1) {
371 			dprintf1("child sleeping...\n");
372 			sleep(30);
373 		}
374 	}
375 	return forkret;
376 }
377 
378 static int alloc_pkey(void)
379 {
380 	int ret;
381 	unsigned long init_val = PKEY_UNRESTRICTED;
382 
383 	dprintf1("%s()::%d, pkey_reg: 0x%016llx shadow: %016llx\n",
384 			__func__, __LINE__, __read_pkey_reg(), shadow_pkey_reg);
385 	ret = sys_pkey_alloc(0, init_val);
386 	/*
387 	 * pkey_alloc() sets PKEY register, so we need to reflect it in
388 	 * shadow_pkey_reg:
389 	 */
390 	dprintf4("%s()::%d, ret: %d pkey_reg: 0x%016llx"
391 			" shadow: 0x%016llx\n",
392 			__func__, __LINE__, ret, __read_pkey_reg(),
393 			shadow_pkey_reg);
394 	if (ret > 0) {
395 		/* clear both the bits: */
396 		shadow_pkey_reg = set_pkey_bits(shadow_pkey_reg, ret,
397 						~PKEY_MASK);
398 		dprintf4("%s()::%d, ret: %d pkey_reg: 0x%016llx"
399 				" shadow: 0x%016llx\n",
400 				__func__,
401 				__LINE__, ret, __read_pkey_reg(),
402 				shadow_pkey_reg);
403 		/*
404 		 * move the new state in from init_val
405 		 * (remember, we cheated and init_val == pkey_reg format)
406 		 */
407 		shadow_pkey_reg = set_pkey_bits(shadow_pkey_reg, ret,
408 						init_val);
409 	}
410 	dprintf4("%s()::%d, ret: %d pkey_reg: 0x%016llx"
411 			" shadow: 0x%016llx\n",
412 			__func__, __LINE__, ret, __read_pkey_reg(),
413 			shadow_pkey_reg);
414 	dprintf1("%s()::%d errno: %d\n", __func__, __LINE__, errno);
415 	/* for shadow checking: */
416 	read_pkey_reg();
417 	dprintf4("%s()::%d, ret: %d pkey_reg: 0x%016llx"
418 		 " shadow: 0x%016llx\n",
419 		__func__, __LINE__, ret, __read_pkey_reg(),
420 		shadow_pkey_reg);
421 	return ret;
422 }
423 
424 /*
425  * I had a bug where pkey bits could be set by mprotect() but
426  * not cleared.  This ensures we get lots of random bit sets
427  * and clears on the vma and pte pkey bits.
428  */
429 static int alloc_random_pkey(void)
430 {
431 	int max_nr_pkey_allocs;
432 	int ret;
433 	int i;
434 	int alloced_pkeys[NR_PKEYS];
435 	int nr_alloced = 0;
436 	int random_index;
437 	memset(alloced_pkeys, 0, sizeof(alloced_pkeys));
438 
439 	/* allocate every possible key and make a note of which ones we got */
440 	max_nr_pkey_allocs = NR_PKEYS;
441 	for (i = 0; i < max_nr_pkey_allocs; i++) {
442 		int new_pkey = alloc_pkey();
443 		if (new_pkey < 0)
444 			break;
445 		alloced_pkeys[nr_alloced++] = new_pkey;
446 	}
447 
448 	pkey_assert(nr_alloced > 0);
449 	/* select a random one out of the allocated ones */
450 	random_index = rand() % nr_alloced;
451 	ret = alloced_pkeys[random_index];
452 	/* now zero it out so we don't free it next */
453 	alloced_pkeys[random_index] = 0;
454 
455 	/* go through the allocated ones that we did not want and free them */
456 	for (i = 0; i < nr_alloced; i++) {
457 		int free_ret;
458 		if (!alloced_pkeys[i])
459 			continue;
460 		free_ret = sys_pkey_free(alloced_pkeys[i]);
461 		pkey_assert(!free_ret);
462 	}
463 	dprintf1("%s()::%d, ret: %d pkey_reg: 0x%016llx"
464 			 " shadow: 0x%016llx\n", __func__,
465 			__LINE__, ret, __read_pkey_reg(), shadow_pkey_reg);
466 	return ret;
467 }
468 
469 int mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot,
470 		unsigned long pkey)
471 {
472 	int nr_iterations = random() % 100;
473 	int ret;
474 
475 	while (nr_iterations-- >= 0) {
476 		int rpkey = alloc_random_pkey();
477 		ret = sys_mprotect_pkey(ptr, size, orig_prot, pkey);
478 		dprintf1("sys_mprotect_pkey(%p, %zx, prot=0x%lx, pkey=%ld) ret: %d\n",
479 				ptr, size, orig_prot, pkey, ret);
480 
481 		dprintf1("%s()::%d, ret: %d pkey_reg: 0x%016llx"
482 			" shadow: 0x%016llx\n",
483 			__func__, __LINE__, ret, __read_pkey_reg(),
484 			shadow_pkey_reg);
485 		sys_pkey_free(rpkey);
486 		dprintf1("%s()::%d, ret: %d pkey_reg: 0x%016llx"
487 			" shadow: 0x%016llx\n",
488 			__func__, __LINE__, ret, __read_pkey_reg(),
489 			shadow_pkey_reg);
490 	}
491 	pkey_assert(pkey < NR_PKEYS);
492 
493 	ret = sys_mprotect_pkey(ptr, size, orig_prot, pkey);
494 	dprintf1("mprotect_pkey(%p, %zx, prot=0x%lx, pkey=%ld) ret: %d\n",
495 			ptr, size, orig_prot, pkey, ret);
496 	pkey_assert(!ret);
497 	dprintf1("%s()::%d, ret: %d pkey_reg: 0x%016llx"
498 			" shadow: 0x%016llx\n", __func__,
499 			__LINE__, ret, __read_pkey_reg(), shadow_pkey_reg);
500 	return ret;
501 }
502 
503 struct pkey_malloc_record {
504 	void *ptr;
505 	long size;
506 	int prot;
507 };
508 struct pkey_malloc_record *pkey_malloc_records;
509 struct pkey_malloc_record *pkey_last_malloc_record;
510 static long nr_pkey_malloc_records;
511 void record_pkey_malloc(void *ptr, long size, int prot)
512 {
513 	long i;
514 	struct pkey_malloc_record *rec = NULL;
515 
516 	for (i = 0; i < nr_pkey_malloc_records; i++) {
517 		rec = &pkey_malloc_records[i];
518 		/* find a free record */
519 		if (rec)
520 			break;
521 	}
522 	if (!rec) {
523 		/* every record is full */
524 		size_t old_nr_records = nr_pkey_malloc_records;
525 		size_t new_nr_records = (nr_pkey_malloc_records * 2 + 1);
526 		size_t new_size = new_nr_records * sizeof(struct pkey_malloc_record);
527 		dprintf2("new_nr_records: %zd\n", new_nr_records);
528 		dprintf2("new_size: %zd\n", new_size);
529 		pkey_malloc_records = realloc(pkey_malloc_records, new_size);
530 		pkey_assert(pkey_malloc_records != NULL);
531 		rec = &pkey_malloc_records[nr_pkey_malloc_records];
532 		/*
533 		 * realloc() does not initialize memory, so zero it from
534 		 * the first new record all the way to the end.
535 		 */
536 		for (i = 0; i < new_nr_records - old_nr_records; i++)
537 			memset(rec + i, 0, sizeof(*rec));
538 	}
539 	dprintf3("filling malloc record[%d/%p]: {%p, %ld}\n",
540 		(int)(rec - pkey_malloc_records), rec, ptr, size);
541 	rec->ptr = ptr;
542 	rec->size = size;
543 	rec->prot = prot;
544 	pkey_last_malloc_record = rec;
545 	nr_pkey_malloc_records++;
546 }
547 
548 static void free_pkey_malloc(void *ptr)
549 {
550 	long i;
551 	int ret;
552 	dprintf3("%s(%p)\n", __func__, ptr);
553 	for (i = 0; i < nr_pkey_malloc_records; i++) {
554 		struct pkey_malloc_record *rec = &pkey_malloc_records[i];
555 		dprintf4("looking for ptr %p at record[%ld/%p]: {%p, %ld}\n",
556 				ptr, i, rec, rec->ptr, rec->size);
557 		if ((ptr <  rec->ptr) ||
558 		    (ptr >= rec->ptr + rec->size))
559 			continue;
560 
561 		dprintf3("found ptr %p at record[%ld/%p]: {%p, %ld}\n",
562 				ptr, i, rec, rec->ptr, rec->size);
563 		nr_pkey_malloc_records--;
564 		ret = munmap(rec->ptr, rec->size);
565 		dprintf3("munmap ret: %d\n", ret);
566 		pkey_assert(!ret);
567 		dprintf3("clearing rec->ptr, rec: %p\n", rec);
568 		rec->ptr = NULL;
569 		dprintf3("done clearing rec->ptr, rec: %p\n", rec);
570 		return;
571 	}
572 	pkey_assert(false);
573 }
574 
575 static void *malloc_pkey_with_mprotect(long size, int prot, u16 pkey)
576 {
577 	void *ptr;
578 	int ret;
579 
580 	read_pkey_reg();
581 	dprintf1("doing %s(size=%ld, prot=0x%x, pkey=%d)\n", __func__,
582 			size, prot, pkey);
583 	pkey_assert(pkey < NR_PKEYS);
584 	ptr = mmap(NULL, size, prot, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
585 	pkey_assert(ptr != MAP_FAILED);
586 	ret = mprotect_pkey((void *)ptr, PAGE_SIZE, prot, pkey);
587 	pkey_assert(!ret);
588 	record_pkey_malloc(ptr, size, prot);
589 	read_pkey_reg();
590 
591 	dprintf1("%s() for pkey %d @ %p\n", __func__, pkey, ptr);
592 	return ptr;
593 }
594 
595 static void *malloc_pkey_anon_huge(long size, int prot, u16 pkey)
596 {
597 	int ret;
598 	void *ptr;
599 
600 	dprintf1("doing %s(size=%ld, prot=0x%x, pkey=%d)\n", __func__,
601 			size, prot, pkey);
602 	/*
603 	 * Guarantee we can fit at least one huge page in the resulting
604 	 * allocation by allocating space for 2:
605 	 */
606 	size = ALIGN_UP(size, HPAGE_SIZE * 2);
607 	ptr = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
608 	pkey_assert(ptr != MAP_FAILED);
609 	record_pkey_malloc(ptr, size, prot);
610 	mprotect_pkey(ptr, size, prot, pkey);
611 
612 	dprintf1("unaligned ptr: %p\n", ptr);
613 	ptr = ALIGN_PTR_UP(ptr, HPAGE_SIZE);
614 	dprintf1("  aligned ptr: %p\n", ptr);
615 	ret = madvise(ptr, HPAGE_SIZE, MADV_HUGEPAGE);
616 	dprintf1("MADV_HUGEPAGE ret: %d\n", ret);
617 	ret = madvise(ptr, HPAGE_SIZE, MADV_WILLNEED);
618 	dprintf1("MADV_WILLNEED ret: %d\n", ret);
619 	memset(ptr, 0, HPAGE_SIZE);
620 
621 	dprintf1("mmap()'d thp for pkey %d @ %p\n", pkey, ptr);
622 	return ptr;
623 }
624 
625 static int hugetlb_setup_ok;
626 #define GET_NR_HUGE_PAGES 10
627 static void setup_hugetlbfs(void)
628 {
629 	long hpagesz_mb = HPAGE_SIZE / 1024 / 1024;
630 	unsigned long free_pages;
631 
632 	if (geteuid() != 0) {
633 		ksft_print_msg("WARNING: not run as root, can not do hugetlb test\n");
634 		return;
635 	}
636 
637 	/*
638 	 * Make sure that we got the pages and that they
639 	 * are PMD-level pages. Someone might have made PUD-level
640 	 * pages the default.
641 	 */
642 	hugetlb_save_settings();
643 	hugetlb_set_nr_pages(HPAGE_SIZE, GET_NR_HUGE_PAGES);
644 	free_pages = hugetlb_free_pages(HPAGE_SIZE);
645 	if (free_pages < GET_NR_HUGE_PAGES) {
646 		ksft_print_msg("could not confirm %ldM pages, got: '%lu' expected %d\n",
647 			       hpagesz_mb, free_pages, GET_NR_HUGE_PAGES);
648 		return;
649 	}
650 
651 	hugetlb_setup_ok = 1;
652 }
653 
654 static void *malloc_pkey_hugetlb(long size, int prot, u16 pkey)
655 {
656 	void *ptr;
657 	int flags = MAP_ANONYMOUS|MAP_PRIVATE|MAP_HUGETLB;
658 
659 	if (!hugetlb_setup_ok)
660 		return PTR_ERR_ENOTSUP;
661 
662 	dprintf1("doing %s(%ld, %x, %x)\n", __func__, size, prot, pkey);
663 	size = ALIGN_UP(size, HPAGE_SIZE * 2);
664 	pkey_assert(pkey < NR_PKEYS);
665 	ptr = mmap(NULL, size, PROT_NONE, flags, -1, 0);
666 	pkey_assert(ptr != MAP_FAILED);
667 	mprotect_pkey(ptr, size, prot, pkey);
668 
669 	record_pkey_malloc(ptr, size, prot);
670 
671 	dprintf1("mmap()'d hugetlbfs for pkey %d @ %p\n", pkey, ptr);
672 	return ptr;
673 }
674 
675 static void *(*pkey_malloc[])(long size, int prot, u16 pkey) = {
676 
677 	malloc_pkey_with_mprotect,
678 	malloc_pkey_with_mprotect_subpage,
679 	malloc_pkey_anon_huge,
680 	malloc_pkey_hugetlb
681 };
682 
683 static void *malloc_pkey(long size, int prot, u16 pkey)
684 {
685 	void *ret;
686 	static int malloc_type;
687 	int nr_malloc_types = ARRAY_SIZE(pkey_malloc);
688 
689 	pkey_assert(pkey < NR_PKEYS);
690 
691 	while (1) {
692 		pkey_assert(malloc_type < nr_malloc_types);
693 
694 		ret = pkey_malloc[malloc_type](size, prot, pkey);
695 		pkey_assert(ret != MAP_FAILED);
696 
697 		malloc_type++;
698 		if (malloc_type >= nr_malloc_types)
699 			malloc_type = (random()%nr_malloc_types);
700 
701 		/* try again if the malloc_type we tried is unsupported */
702 		if (ret == PTR_ERR_ENOTSUP)
703 			continue;
704 
705 		break;
706 	}
707 
708 	dprintf3("%s(%ld, prot=%x, pkey=%x) returning: %p\n", __func__,
709 			size, prot, pkey, ret);
710 	return ret;
711 }
712 
713 static int last_pkey_faults;
714 #define UNKNOWN_PKEY -2
715 void expected_pkey_fault(int pkey)
716 {
717 	dprintf2("%s(): last_pkey_faults: %d pkey_faults: %d\n",
718 			__func__, last_pkey_faults, pkey_faults);
719 	dprintf2("%s(%d): last_si_pkey: %d\n", __func__, pkey, last_si_pkey);
720 	pkey_assert(last_pkey_faults + 1 == pkey_faults);
721 
722        /*
723 	* For exec-only memory, we do not know the pkey in
724 	* advance, so skip this check.
725 	*/
726 	if (pkey != UNKNOWN_PKEY)
727 		pkey_assert(last_si_pkey == pkey);
728 
729 #if defined(__i386__) || defined(__x86_64__) /* arch */
730 	/*
731 	 * The signal handler shold have cleared out PKEY register to let the
732 	 * test program continue.  We now have to restore it.
733 	 */
734 	if (__read_pkey_reg() != 0)
735 #elif defined(__aarch64__)
736 	if (__read_pkey_reg() != PKEY_REG_ALLOW_ALL)
737 #else
738 	if (__read_pkey_reg() != shadow_pkey_reg)
739 #endif /* arch */
740 		pkey_assert(0);
741 
742 	__write_pkey_reg(shadow_pkey_reg);
743 	dprintf1("%s() set pkey_reg=%016llx to restore state after signal "
744 		       "nuked it\n", __func__, shadow_pkey_reg);
745 	last_pkey_faults = pkey_faults;
746 	last_si_pkey = -1;
747 }
748 
749 #define do_not_expect_pkey_fault(msg)	do {			\
750 	if (last_pkey_faults != pkey_faults)			\
751 		dprintf0("# unexpected PKey fault: %s\n", msg);	\
752 	pkey_assert(last_pkey_faults == pkey_faults);		\
753 } while (0)
754 
755 static int test_fds[10] = { -1 };
756 static int nr_test_fds;
757 static void __save_test_fd(int fd)
758 {
759 	pkey_assert(fd >= 0);
760 	pkey_assert(nr_test_fds < ARRAY_SIZE(test_fds));
761 	test_fds[nr_test_fds] = fd;
762 	nr_test_fds++;
763 }
764 
765 static int get_test_read_fd(void)
766 {
767 	int test_fd = open("/etc/passwd", O_RDONLY);
768 	__save_test_fd(test_fd);
769 	return test_fd;
770 }
771 
772 static void close_test_fds(void)
773 {
774 	int i;
775 
776 	for (i = 0; i < nr_test_fds; i++) {
777 		if (test_fds[i] < 0)
778 			continue;
779 		close(test_fds[i]);
780 		test_fds[i] = -1;
781 	}
782 	nr_test_fds = 0;
783 }
784 
785 static void test_pkey_alloc_free_attach_pkey0(int *ptr, u16 pkey)
786 {
787 	int i, err;
788 	int max_nr_pkey_allocs;
789 	int alloced_pkeys[NR_PKEYS];
790 	int nr_alloced = 0;
791 	long size;
792 
793 	pkey_assert(pkey_last_malloc_record);
794 	size = pkey_last_malloc_record->size;
795 	/*
796 	 * This is a bit of a hack.  But mprotect() requires
797 	 * huge-page-aligned sizes when operating on hugetlbfs.
798 	 * So, make sure that we use something that's a multiple
799 	 * of a huge page when we can.
800 	 */
801 	if (size >= HPAGE_SIZE)
802 		size = HPAGE_SIZE;
803 
804 	/* allocate every possible key and make sure key-0 never got allocated */
805 	max_nr_pkey_allocs = NR_PKEYS;
806 	for (i = 0; i < max_nr_pkey_allocs; i++) {
807 		int new_pkey = alloc_pkey();
808 		pkey_assert(new_pkey != 0);
809 
810 		if (new_pkey < 0)
811 			break;
812 		alloced_pkeys[nr_alloced++] = new_pkey;
813 	}
814 	/* free all the allocated keys */
815 	for (i = 0; i < nr_alloced; i++) {
816 		int free_ret;
817 
818 		if (!alloced_pkeys[i])
819 			continue;
820 		free_ret = sys_pkey_free(alloced_pkeys[i]);
821 		pkey_assert(!free_ret);
822 	}
823 
824 	/* attach key-0 in various modes */
825 	err = sys_mprotect_pkey(ptr, size, PROT_READ, 0);
826 	pkey_assert(!err);
827 	err = sys_mprotect_pkey(ptr, size, PROT_WRITE, 0);
828 	pkey_assert(!err);
829 	err = sys_mprotect_pkey(ptr, size, PROT_EXEC, 0);
830 	pkey_assert(!err);
831 	err = sys_mprotect_pkey(ptr, size, PROT_READ|PROT_WRITE, 0);
832 	pkey_assert(!err);
833 	err = sys_mprotect_pkey(ptr, size, PROT_READ|PROT_WRITE|PROT_EXEC, 0);
834 	pkey_assert(!err);
835 }
836 
837 static void test_read_of_write_disabled_region(int *ptr, u16 pkey)
838 {
839 	int ptr_contents;
840 
841 	dprintf1("disabling write access to PKEY[1], doing read\n");
842 	pkey_write_deny(pkey);
843 	ptr_contents = read_ptr(ptr);
844 	dprintf1("*ptr: %d\n", ptr_contents);
845 	dprintf1("\n");
846 }
847 static void test_read_of_access_disabled_region(int *ptr, u16 pkey)
848 {
849 	int ptr_contents;
850 
851 	dprintf1("disabling access to PKEY[%02d], doing read @ %p\n", pkey, ptr);
852 	read_pkey_reg();
853 	pkey_access_deny(pkey);
854 	ptr_contents = read_ptr(ptr);
855 	dprintf1("*ptr: %d\n", ptr_contents);
856 	expected_pkey_fault(pkey);
857 }
858 
859 static void test_read_of_access_disabled_region_with_page_already_mapped(int *ptr,
860 		u16 pkey)
861 {
862 	int ptr_contents;
863 
864 	dprintf1("disabling access to PKEY[%02d], doing read @ %p\n",
865 				pkey, ptr);
866 	ptr_contents = read_ptr(ptr);
867 	dprintf1("reading ptr before disabling the read : %d\n",
868 			ptr_contents);
869 	read_pkey_reg();
870 	pkey_access_deny(pkey);
871 	ptr_contents = read_ptr(ptr);
872 	dprintf1("*ptr: %d\n", ptr_contents);
873 	expected_pkey_fault(pkey);
874 }
875 
876 static void test_write_of_write_disabled_region_with_page_already_mapped(int *ptr,
877 		u16 pkey)
878 {
879 	*ptr = __LINE__;
880 	dprintf1("disabling write access; after accessing the page, "
881 		"to PKEY[%02d], doing write\n", pkey);
882 	pkey_write_deny(pkey);
883 	*ptr = __LINE__;
884 	expected_pkey_fault(pkey);
885 }
886 
887 static void test_write_of_write_disabled_region(int *ptr, u16 pkey)
888 {
889 	dprintf1("disabling write access to PKEY[%02d], doing write\n", pkey);
890 	pkey_write_deny(pkey);
891 	*ptr = __LINE__;
892 	expected_pkey_fault(pkey);
893 }
894 static void test_write_of_access_disabled_region(int *ptr, u16 pkey)
895 {
896 	dprintf1("disabling access to PKEY[%02d], doing write\n", pkey);
897 	pkey_access_deny(pkey);
898 	*ptr = __LINE__;
899 	expected_pkey_fault(pkey);
900 }
901 
902 static void test_write_of_access_disabled_region_with_page_already_mapped(int *ptr,
903 			u16 pkey)
904 {
905 	*ptr = __LINE__;
906 	dprintf1("disabling access; after accessing the page, "
907 		" to PKEY[%02d], doing write\n", pkey);
908 	pkey_access_deny(pkey);
909 	*ptr = __LINE__;
910 	expected_pkey_fault(pkey);
911 }
912 
913 static void test_kernel_write_of_access_disabled_region(int *ptr, u16 pkey)
914 {
915 	int ret;
916 	int test_fd = get_test_read_fd();
917 
918 	dprintf1("disabling access to PKEY[%02d], "
919 		 "having kernel read() to buffer\n", pkey);
920 	pkey_access_deny(pkey);
921 	ret = read(test_fd, ptr, 1);
922 	dprintf1("read ret: %d\n", ret);
923 	pkey_assert(ret);
924 }
925 
926 static void test_kernel_write_of_write_disabled_region(int *ptr, u16 pkey)
927 {
928 	int ret;
929 	int test_fd = get_test_read_fd();
930 
931 	pkey_write_deny(pkey);
932 	ret = read(test_fd, ptr, 100);
933 	dprintf1("read ret: %d\n", ret);
934 	if (ret < 0 && (DEBUG_LEVEL > 0))
935 		perror("verbose read result (OK for this to be bad)");
936 	pkey_assert(ret);
937 }
938 
939 static void test_kernel_gup_of_access_disabled_region(int *ptr, u16 pkey)
940 {
941 	int pipe_ret, vmsplice_ret;
942 	struct iovec iov;
943 	int pipe_fds[2];
944 
945 	pipe_ret = pipe(pipe_fds);
946 
947 	pkey_assert(pipe_ret == 0);
948 	dprintf1("disabling access to PKEY[%02d], "
949 		 "having kernel vmsplice from buffer\n", pkey);
950 	pkey_access_deny(pkey);
951 	iov.iov_base = ptr;
952 	iov.iov_len = PAGE_SIZE;
953 	vmsplice_ret = vmsplice(pipe_fds[1], &iov, 1, SPLICE_F_GIFT);
954 	dprintf1("vmsplice() ret: %d\n", vmsplice_ret);
955 	pkey_assert(vmsplice_ret == -1);
956 
957 	close(pipe_fds[0]);
958 	close(pipe_fds[1]);
959 }
960 
961 static void test_kernel_gup_write_to_write_disabled_region(int *ptr, u16 pkey)
962 {
963 	int ignored = 0xdada;
964 	int futex_ret;
965 	int some_int = __LINE__;
966 
967 	dprintf1("disabling write to PKEY[%02d], "
968 		 "doing futex gunk in buffer\n", pkey);
969 	*ptr = some_int;
970 	pkey_write_deny(pkey);
971 	futex_ret = syscall(SYS_futex, ptr, FUTEX_WAIT, some_int-1, NULL,
972 			&ignored, ignored);
973 	if (DEBUG_LEVEL > 0)
974 		perror("futex");
975 	dprintf1("futex() ret: %d\n", futex_ret);
976 }
977 
978 /* Assumes that all pkeys other than 'pkey' are unallocated */
979 static void test_pkey_syscalls_on_non_allocated_pkey(int *ptr, u16 pkey)
980 {
981 	int err;
982 	int i;
983 
984 	/* Note: 0 is the default pkey, so don't mess with it */
985 	for (i = 1; i < NR_PKEYS; i++) {
986 		if (pkey == i)
987 			continue;
988 
989 		dprintf1("trying get/set/free to non-allocated pkey: %2d\n", i);
990 		err = sys_pkey_free(i);
991 		pkey_assert(err);
992 
993 		err = sys_pkey_free(i);
994 		pkey_assert(err);
995 
996 		err = sys_mprotect_pkey(ptr, PAGE_SIZE, PROT_READ, i);
997 		pkey_assert(err);
998 	}
999 }
1000 
1001 /* Assumes that all pkeys other than 'pkey' are unallocated */
1002 static void test_pkey_syscalls_bad_args(int *ptr, u16 pkey)
1003 {
1004 	int err;
1005 	int bad_pkey = NR_PKEYS+99;
1006 
1007 	/* pass a known-invalid pkey in: */
1008 	err = sys_mprotect_pkey(ptr, PAGE_SIZE, PROT_READ, bad_pkey);
1009 	pkey_assert(err);
1010 }
1011 
1012 static void become_child(void)
1013 {
1014 	pid_t forkret;
1015 
1016 	forkret = fork();
1017 	pkey_assert(forkret >= 0);
1018 	dprintf3("[%d] fork() ret: %d\n", getpid(), forkret);
1019 
1020 	if (!forkret) {
1021 		/* in the child */
1022 		return;
1023 	}
1024 	_exit(0);
1025 }
1026 
1027 /* Assumes that all pkeys other than 'pkey' are unallocated */
1028 static void test_pkey_alloc_exhaust(int *ptr, u16 pkey)
1029 {
1030 	int err;
1031 	int allocated_pkeys[NR_PKEYS] = {0};
1032 	int nr_allocated_pkeys = 0;
1033 	int i;
1034 
1035 	for (i = 0; i < NR_PKEYS*3; i++) {
1036 		int new_pkey;
1037 		dprintf1("%s() alloc loop: %d\n", __func__, i);
1038 		new_pkey = alloc_pkey();
1039 		dprintf4("%s()::%d, err: %d pkey_reg: 0x%016llx"
1040 				" shadow: 0x%016llx\n",
1041 				__func__, __LINE__, err, __read_pkey_reg(),
1042 				shadow_pkey_reg);
1043 		read_pkey_reg(); /* for shadow checking */
1044 		dprintf2("%s() errno: %d ENOSPC: %d\n", __func__, errno, ENOSPC);
1045 		if ((new_pkey == -1) && (errno == ENOSPC)) {
1046 			dprintf2("%s() failed to allocate pkey after %d tries\n",
1047 				__func__, nr_allocated_pkeys);
1048 		} else {
1049 			/*
1050 			 * Ensure the number of successes never
1051 			 * exceeds the number of keys supported
1052 			 * in the hardware.
1053 			 */
1054 			pkey_assert(nr_allocated_pkeys < NR_PKEYS);
1055 			allocated_pkeys[nr_allocated_pkeys++] = new_pkey;
1056 		}
1057 
1058 		/*
1059 		 * Make sure that allocation state is properly
1060 		 * preserved across fork().
1061 		 */
1062 		if (i == NR_PKEYS*2)
1063 			become_child();
1064 	}
1065 
1066 	dprintf3("%s()::%d\n", __func__, __LINE__);
1067 
1068 	/*
1069 	 * On x86:
1070 	 * There are 16 pkeys supported in hardware.  Three are
1071 	 * allocated by the time we get here:
1072 	 *   1. The default key (0)
1073 	 *   2. One possibly consumed by an execute-only mapping.
1074 	 *   3. One allocated by the test code and passed in via
1075 	 *      'pkey' to this function.
1076 	 * Ensure that we can allocate at least another 13 (16-3).
1077 	 *
1078 	 * On powerpc:
1079 	 * There are either 5, 28, 29 or 32 pkeys supported in
1080 	 * hardware depending on the page size (4K or 64K) and
1081 	 * platform (powernv or powervm). Four are allocated by
1082 	 * the time we get here. These include pkey-0, pkey-1,
1083 	 * exec-only pkey and the one allocated by the test code.
1084 	 * Ensure that we can allocate the remaining.
1085 	 */
1086 	pkey_assert(i >= (NR_PKEYS - get_arch_reserved_keys() - 1));
1087 
1088 	for (i = 0; i < nr_allocated_pkeys; i++) {
1089 		err = sys_pkey_free(allocated_pkeys[i]);
1090 		pkey_assert(!err);
1091 		read_pkey_reg(); /* for shadow checking */
1092 	}
1093 }
1094 
1095 static void arch_force_pkey_reg_init(void)
1096 {
1097 #if defined(__i386__) || defined(__x86_64__) /* arch */
1098 	u64 *buf;
1099 
1100 	/*
1101 	 * All keys should be allocated and set to allow reads and
1102 	 * writes, so the register should be all 0.  If not, just
1103 	 * skip the test.
1104 	 */
1105 	if (read_pkey_reg())
1106 		return;
1107 
1108 	/*
1109 	 * Just allocate an absurd about of memory rather than
1110 	 * doing the XSAVE size enumeration dance.
1111 	 */
1112 	buf = mmap(NULL, 1*MB, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
1113 	pkey_assert(buf != MAP_FAILED);
1114 
1115 	/* These __builtins require compiling with -mxsave */
1116 
1117 	/* XSAVE to build a valid buffer: */
1118 	__builtin_ia32_xsave(buf, XSTATE_PKEY);
1119 	/* Clear XSTATE_BV[PKRU]: */
1120 	buf[XSTATE_BV_OFFSET/sizeof(u64)] &= ~XSTATE_PKEY;
1121 	/* XRSTOR will likely get PKRU back to the init state: */
1122 	__builtin_ia32_xrstor(buf, XSTATE_PKEY);
1123 
1124 	munmap(buf, 1*MB);
1125 #endif
1126 }
1127 
1128 
1129 /*
1130  * This is mostly useless on ppc for now.  But it will not
1131  * hurt anything and should give some better coverage as
1132  * a long-running test that continually checks the pkey
1133  * register.
1134  */
1135 static void test_pkey_init_state(int *ptr, u16 pkey)
1136 {
1137 	int err;
1138 	int allocated_pkeys[NR_PKEYS] = {0};
1139 	int nr_allocated_pkeys = 0;
1140 	int i;
1141 
1142 	for (i = 0; i < NR_PKEYS; i++) {
1143 		int new_pkey = alloc_pkey();
1144 
1145 		if (new_pkey < 0)
1146 			continue;
1147 		allocated_pkeys[nr_allocated_pkeys++] = new_pkey;
1148 	}
1149 
1150 	dprintf3("%s()::%d\n", __func__, __LINE__);
1151 
1152 	arch_force_pkey_reg_init();
1153 
1154 	/*
1155 	 * Loop for a bit, hoping to get exercise the kernel
1156 	 * context switch code.
1157 	 */
1158 	for (i = 0; i < 1000000; i++)
1159 		read_pkey_reg();
1160 
1161 	for (i = 0; i < nr_allocated_pkeys; i++) {
1162 		err = sys_pkey_free(allocated_pkeys[i]);
1163 		pkey_assert(!err);
1164 		read_pkey_reg(); /* for shadow checking */
1165 	}
1166 }
1167 
1168 /*
1169  * pkey 0 is special.  It is allocated by default, so you do not
1170  * have to call pkey_alloc() to use it first.  Make sure that it
1171  * is usable.
1172  */
1173 static void test_mprotect_with_pkey_0(int *ptr, u16 pkey)
1174 {
1175 	long size;
1176 	int prot;
1177 
1178 	assert(pkey_last_malloc_record);
1179 	size = pkey_last_malloc_record->size;
1180 	/*
1181 	 * This is a bit of a hack.  But mprotect() requires
1182 	 * huge-page-aligned sizes when operating on hugetlbfs.
1183 	 * So, make sure that we use something that's a multiple
1184 	 * of a huge page when we can.
1185 	 */
1186 	if (size >= HPAGE_SIZE)
1187 		size = HPAGE_SIZE;
1188 	prot = pkey_last_malloc_record->prot;
1189 
1190 	/* Use pkey 0 */
1191 	mprotect_pkey(ptr, size, prot, 0);
1192 
1193 	/* Make sure that we can set it back to the original pkey. */
1194 	mprotect_pkey(ptr, size, prot, pkey);
1195 }
1196 
1197 static void test_ptrace_of_child(int *ptr, u16 pkey)
1198 {
1199 	__always_unused int peek_result;
1200 	pid_t child_pid;
1201 	void *ignored = 0;
1202 	long ret;
1203 	int status;
1204 	/*
1205 	 * This is the "control" for our little expermient.  Make sure
1206 	 * we can always access it when ptracing.
1207 	 */
1208 	int *plain_ptr_unaligned = malloc(HPAGE_SIZE);
1209 	int *plain_ptr = ALIGN_PTR_UP(plain_ptr_unaligned, PAGE_SIZE);
1210 
1211 	/*
1212 	 * Fork a child which is an exact copy of this process, of course.
1213 	 * That means we can do all of our tests via ptrace() and then plain
1214 	 * memory access and ensure they work differently.
1215 	 */
1216 	child_pid = fork_lazy_child();
1217 	dprintf1("[%d] child pid: %d\n", getpid(), child_pid);
1218 
1219 	ret = ptrace(PTRACE_ATTACH, child_pid, ignored, ignored);
1220 	if (ret)
1221 		perror("attach");
1222 	dprintf1("[%d] attach ret: %ld %d\n", getpid(), ret, __LINE__);
1223 	pkey_assert(ret != -1);
1224 	ret = waitpid(child_pid, &status, WUNTRACED);
1225 	if ((ret != child_pid) || !(WIFSTOPPED(status))) {
1226 		fprintf(stderr, "weird waitpid result %ld stat %x\n",
1227 				ret, status);
1228 		pkey_assert(0);
1229 	}
1230 	dprintf2("waitpid ret: %ld\n", ret);
1231 	dprintf2("waitpid status: %d\n", status);
1232 
1233 	pkey_access_deny(pkey);
1234 	pkey_write_deny(pkey);
1235 
1236 	/* Write access, untested for now:
1237 	ret = ptrace(PTRACE_POKEDATA, child_pid, peek_at, data);
1238 	pkey_assert(ret != -1);
1239 	dprintf1("poke at %p: %ld\n", peek_at, ret);
1240 	*/
1241 
1242 	/*
1243 	 * Try to access the pkey-protected "ptr" via ptrace:
1244 	 */
1245 	ret = ptrace(PTRACE_PEEKDATA, child_pid, ptr, ignored);
1246 	/* expect it to work, without an error: */
1247 	pkey_assert(ret != -1);
1248 	/* Now access from the current task, and expect an exception: */
1249 	peek_result = read_ptr(ptr);
1250 	expected_pkey_fault(pkey);
1251 
1252 	/*
1253 	 * Try to access the NON-pkey-protected "plain_ptr" via ptrace:
1254 	 */
1255 	ret = ptrace(PTRACE_PEEKDATA, child_pid, plain_ptr, ignored);
1256 	/* expect it to work, without an error: */
1257 	pkey_assert(ret != -1);
1258 	/* Now access from the current task, and expect NO exception: */
1259 	peek_result = read_ptr(plain_ptr);
1260 	do_not_expect_pkey_fault("read plain pointer after ptrace");
1261 
1262 	ret = ptrace(PTRACE_DETACH, child_pid, ignored, 0);
1263 	pkey_assert(ret != -1);
1264 
1265 	ret = kill(child_pid, SIGKILL);
1266 	pkey_assert(ret != -1);
1267 
1268 	wait(&status);
1269 
1270 	free(plain_ptr_unaligned);
1271 }
1272 
1273 static void *get_pointer_to_instructions(void)
1274 {
1275 	void *p1;
1276 
1277 	p1 = ALIGN_PTR_UP(&lots_o_noops_around_write, PAGE_SIZE);
1278 	dprintf3("&lots_o_noops: %p\n", &lots_o_noops_around_write);
1279 	/* lots_o_noops_around_write should be page-aligned already */
1280 	assert(p1 == &lots_o_noops_around_write);
1281 
1282 	/* Point 'p1' at the *second* page of the function: */
1283 	p1 += PAGE_SIZE;
1284 
1285 	/*
1286 	 * Try to ensure we fault this in on next touch to ensure
1287 	 * we get an instruction fault as opposed to a data one
1288 	 */
1289 	madvise(p1, PAGE_SIZE, MADV_DONTNEED);
1290 
1291 	return p1;
1292 }
1293 
1294 static void test_executing_on_unreadable_memory(int *ptr, u16 pkey)
1295 {
1296 	void *p1;
1297 	int scratch;
1298 	int ptr_contents;
1299 	int ret;
1300 
1301 	p1 = get_pointer_to_instructions();
1302 	lots_o_noops_around_write(&scratch);
1303 	ptr_contents = read_ptr(p1);
1304 	dprintf2("ptr (%p) contents@%d: %x\n", p1, __LINE__, ptr_contents);
1305 
1306 	ret = mprotect_pkey(p1, PAGE_SIZE, PROT_EXEC, (u64)pkey);
1307 	pkey_assert(!ret);
1308 	pkey_access_deny(pkey);
1309 
1310 	dprintf2("pkey_reg: %016llx\n", read_pkey_reg());
1311 
1312 	/*
1313 	 * Make sure this is an *instruction* fault
1314 	 */
1315 	madvise(p1, PAGE_SIZE, MADV_DONTNEED);
1316 	lots_o_noops_around_write(&scratch);
1317 	do_not_expect_pkey_fault("executing on PROT_EXEC memory");
1318 	expect_fault_on_read_execonly_key(p1, pkey);
1319 
1320 	// Reset back to PROT_EXEC | PROT_READ for architectures that support
1321 	// non-PKEY execute-only permissions.
1322 	ret = mprotect_pkey(p1, PAGE_SIZE, PROT_EXEC | PROT_READ, (u64)pkey);
1323 	pkey_assert(!ret);
1324 }
1325 
1326 static void test_implicit_mprotect_exec_only_memory(int *ptr, u16 pkey)
1327 {
1328 	void *p1;
1329 	int scratch;
1330 	int ptr_contents;
1331 	int ret;
1332 
1333 	dprintf1("%s() start\n", __func__);
1334 
1335 	p1 = get_pointer_to_instructions();
1336 	lots_o_noops_around_write(&scratch);
1337 	ptr_contents = read_ptr(p1);
1338 	dprintf2("ptr (%p) contents@%d: %x\n", p1, __LINE__, ptr_contents);
1339 
1340 	/* Use a *normal* mprotect(), not mprotect_pkey(): */
1341 	ret = mprotect(p1, PAGE_SIZE, PROT_EXEC);
1342 	pkey_assert(!ret);
1343 
1344 	/*
1345 	 * Reset the shadow, assuming that the above mprotect()
1346 	 * correctly changed PKRU, but to an unknown value since
1347 	 * the actual allocated pkey is unknown.
1348 	 */
1349 	shadow_pkey_reg = __read_pkey_reg();
1350 
1351 	dprintf2("pkey_reg: %016llx\n", read_pkey_reg());
1352 
1353 	/* Make sure this is an *instruction* fault */
1354 	madvise(p1, PAGE_SIZE, MADV_DONTNEED);
1355 	lots_o_noops_around_write(&scratch);
1356 	do_not_expect_pkey_fault("executing on PROT_EXEC memory");
1357 	expect_fault_on_read_execonly_key(p1, UNKNOWN_PKEY);
1358 
1359 	/*
1360 	 * Put the memory back to non-PROT_EXEC.  Should clear the
1361 	 * exec-only pkey off the VMA and allow it to be readable
1362 	 * again.  Go to PROT_NONE first to check for a kernel bug
1363 	 * that did not clear the pkey when doing PROT_NONE.
1364 	 */
1365 	ret = mprotect(p1, PAGE_SIZE, PROT_NONE);
1366 	pkey_assert(!ret);
1367 
1368 	ret = mprotect(p1, PAGE_SIZE, PROT_READ|PROT_EXEC);
1369 	pkey_assert(!ret);
1370 	ptr_contents = read_ptr(p1);
1371 	do_not_expect_pkey_fault("plain read on recently PROT_EXEC area");
1372 }
1373 
1374 #if defined(__i386__) || defined(__x86_64__)
1375 static void test_ptrace_modifies_pkru(int *ptr, u16 pkey)
1376 {
1377 	u32 new_pkru;
1378 	pid_t child;
1379 	int status, ret;
1380 	int pkey_offset = pkey_reg_xstate_offset();
1381 	size_t xsave_size = cpu_max_xsave_size();
1382 	void *xsave;
1383 	u32 *pkey_register;
1384 	u64 *xstate_bv;
1385 	struct iovec iov;
1386 
1387 	new_pkru = ~read_pkey_reg();
1388 	/* Don't make PROT_EXEC mappings inaccessible */
1389 	new_pkru &= ~3;
1390 
1391 	child = fork();
1392 	pkey_assert(child >= 0);
1393 	dprintf3("[%d] fork() ret: %d\n", getpid(), child);
1394 	if (!child) {
1395 		ptrace(PTRACE_TRACEME, 0, 0, 0);
1396 		/* Stop and allow the tracer to modify PKRU directly */
1397 		raise(SIGSTOP);
1398 
1399 		/*
1400 		 * need __read_pkey_reg() version so we do not do shadow_pkey_reg
1401 		 * checking
1402 		 */
1403 		if (__read_pkey_reg() != new_pkru)
1404 			_exit(1);
1405 
1406 		/* Stop and allow the tracer to clear XSTATE_BV for PKRU */
1407 		raise(SIGSTOP);
1408 
1409 		if (__read_pkey_reg() != 0)
1410 			_exit(1);
1411 
1412 		/* Stop and allow the tracer to examine PKRU */
1413 		raise(SIGSTOP);
1414 
1415 		_exit(0);
1416 	}
1417 
1418 	pkey_assert(child == waitpid(child, &status, 0));
1419 	dprintf3("[%d] waitpid(%d) status: %x\n", getpid(), child, status);
1420 	pkey_assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP);
1421 
1422 	xsave = (void *)malloc(xsave_size);
1423 	pkey_assert(xsave > 0);
1424 
1425 	/* Modify the PKRU register directly */
1426 	iov.iov_base = xsave;
1427 	iov.iov_len = xsave_size;
1428 	ret = ptrace(PTRACE_GETREGSET, child, (void *)NT_X86_XSTATE, &iov);
1429 	pkey_assert(ret == 0);
1430 
1431 	pkey_register = (u32 *)(xsave + pkey_offset);
1432 	pkey_assert(*pkey_register == read_pkey_reg());
1433 
1434 	*pkey_register = new_pkru;
1435 
1436 	ret = ptrace(PTRACE_SETREGSET, child, (void *)NT_X86_XSTATE, &iov);
1437 	pkey_assert(ret == 0);
1438 
1439 	/* Test that the modification is visible in ptrace before any execution */
1440 	memset(xsave, 0xCC, xsave_size);
1441 	ret = ptrace(PTRACE_GETREGSET, child, (void *)NT_X86_XSTATE, &iov);
1442 	pkey_assert(ret == 0);
1443 	pkey_assert(*pkey_register == new_pkru);
1444 
1445 	/* Execute the tracee */
1446 	ret = ptrace(PTRACE_CONT, child, 0, 0);
1447 	pkey_assert(ret == 0);
1448 
1449 	/* Test that the tracee saw the PKRU value change */
1450 	pkey_assert(child == waitpid(child, &status, 0));
1451 	dprintf3("[%d] waitpid(%d) status: %x\n", getpid(), child, status);
1452 	pkey_assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP);
1453 
1454 	/* Test that the modification is visible in ptrace after execution */
1455 	memset(xsave, 0xCC, xsave_size);
1456 	ret = ptrace(PTRACE_GETREGSET, child, (void *)NT_X86_XSTATE, &iov);
1457 	pkey_assert(ret == 0);
1458 	pkey_assert(*pkey_register == new_pkru);
1459 
1460 	/* Clear the PKRU bit from XSTATE_BV */
1461 	xstate_bv = (u64 *)(xsave + 512);
1462 	*xstate_bv &= ~(1 << 9);
1463 
1464 	ret = ptrace(PTRACE_SETREGSET, child, (void *)NT_X86_XSTATE, &iov);
1465 	pkey_assert(ret == 0);
1466 
1467 	/* Test that the modification is visible in ptrace before any execution */
1468 	memset(xsave, 0xCC, xsave_size);
1469 	ret = ptrace(PTRACE_GETREGSET, child, (void *)NT_X86_XSTATE, &iov);
1470 	pkey_assert(ret == 0);
1471 	pkey_assert(*pkey_register == 0);
1472 
1473 	ret = ptrace(PTRACE_CONT, child, 0, 0);
1474 	pkey_assert(ret == 0);
1475 
1476 	/* Test that the tracee saw the PKRU value go to 0 */
1477 	pkey_assert(child == waitpid(child, &status, 0));
1478 	dprintf3("[%d] waitpid(%d) status: %x\n", getpid(), child, status);
1479 	pkey_assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP);
1480 
1481 	/* Test that the modification is visible in ptrace after execution */
1482 	memset(xsave, 0xCC, xsave_size);
1483 	ret = ptrace(PTRACE_GETREGSET, child, (void *)NT_X86_XSTATE, &iov);
1484 	pkey_assert(ret == 0);
1485 	pkey_assert(*pkey_register == 0);
1486 
1487 	ret = ptrace(PTRACE_CONT, child, 0, 0);
1488 	pkey_assert(ret == 0);
1489 	pkey_assert(child == waitpid(child, &status, 0));
1490 	dprintf3("[%d] waitpid(%d) status: %x\n", getpid(), child, status);
1491 	pkey_assert(WIFEXITED(status));
1492 	pkey_assert(WEXITSTATUS(status) == 0);
1493 	free(xsave);
1494 }
1495 #endif
1496 
1497 #if defined(__aarch64__)
1498 static void test_ptrace_modifies_pkru(int *ptr, u16 pkey)
1499 {
1500 	pid_t child;
1501 	int status, ret;
1502 	struct iovec iov;
1503 	u64 trace_pkey;
1504 	/* Just a random pkey value.. */
1505 	u64 new_pkey = (POE_X << PKEY_BITS_PER_PKEY * 2) |
1506 			(POE_NONE << PKEY_BITS_PER_PKEY) |
1507 			POE_RWX;
1508 
1509 	child = fork();
1510 	pkey_assert(child >= 0);
1511 	dprintf3("[%d] fork() ret: %d\n", getpid(), child);
1512 	if (!child) {
1513 		ptrace(PTRACE_TRACEME, 0, 0, 0);
1514 
1515 		/* Stop and allow the tracer to modify PKRU directly */
1516 		raise(SIGSTOP);
1517 
1518 		/*
1519 		 * need __read_pkey_reg() version so we do not do shadow_pkey_reg
1520 		 * checking
1521 		 */
1522 		if (__read_pkey_reg() != new_pkey)
1523 			exit(1);
1524 
1525 		raise(SIGSTOP);
1526 
1527 		exit(0);
1528 	}
1529 
1530 	pkey_assert(child == waitpid(child, &status, 0));
1531 	dprintf3("[%d] waitpid(%d) status: %x\n", getpid(), child, status);
1532 	pkey_assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP);
1533 
1534 	iov.iov_base = &trace_pkey;
1535 	iov.iov_len = 8;
1536 	ret = ptrace(PTRACE_GETREGSET, child, (void *)NT_ARM_POE, &iov);
1537 	pkey_assert(ret == 0);
1538 	pkey_assert(trace_pkey == read_pkey_reg());
1539 
1540 	trace_pkey = new_pkey;
1541 
1542 	ret = ptrace(PTRACE_SETREGSET, child, (void *)NT_ARM_POE, &iov);
1543 	pkey_assert(ret == 0);
1544 
1545 	/* Test that the modification is visible in ptrace before any execution */
1546 	memset(&trace_pkey, 0, sizeof(trace_pkey));
1547 	ret = ptrace(PTRACE_GETREGSET, child, (void *)NT_ARM_POE, &iov);
1548 	pkey_assert(ret == 0);
1549 	pkey_assert(trace_pkey == new_pkey);
1550 
1551 	/* Execute the tracee */
1552 	ret = ptrace(PTRACE_CONT, child, 0, 0);
1553 	pkey_assert(ret == 0);
1554 
1555 	/* Test that the tracee saw the PKRU value change */
1556 	pkey_assert(child == waitpid(child, &status, 0));
1557 	dprintf3("[%d] waitpid(%d) status: %x\n", getpid(), child, status);
1558 	pkey_assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP);
1559 
1560 	/* Test that the modification is visible in ptrace after execution */
1561 	memset(&trace_pkey, 0, sizeof(trace_pkey));
1562 	ret = ptrace(PTRACE_GETREGSET, child, (void *)NT_ARM_POE, &iov);
1563 	pkey_assert(ret == 0);
1564 	pkey_assert(trace_pkey == new_pkey);
1565 
1566 	ret = ptrace(PTRACE_CONT, child, 0, 0);
1567 	pkey_assert(ret == 0);
1568 	pkey_assert(child == waitpid(child, &status, 0));
1569 	dprintf3("[%d] waitpid(%d) status: %x\n", getpid(), child, status);
1570 	pkey_assert(WIFEXITED(status));
1571 	pkey_assert(WEXITSTATUS(status) == 0);
1572 }
1573 #endif
1574 
1575 static void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey)
1576 {
1577 	int size = PAGE_SIZE;
1578 	int sret;
1579 
1580 	if (cpu_has_pkeys()) {
1581 		dprintf1("SKIP: %s: no CPU support\n", __func__);
1582 		return;
1583 	}
1584 
1585 	sret = syscall(__NR_pkey_mprotect, ptr, size, PROT_READ, pkey);
1586 	pkey_assert(sret < 0);
1587 }
1588 
1589 struct pkey_test {
1590 	void (*func)(int *ptr, u16 pkey);
1591 	const char *name;
1592 };
1593 
1594 #define PKEY_TEST(fn) { fn, #fn }
1595 
1596 static struct pkey_test pkey_tests[] = {
1597 	PKEY_TEST(test_read_of_write_disabled_region),
1598 	PKEY_TEST(test_read_of_access_disabled_region),
1599 	PKEY_TEST(test_read_of_access_disabled_region_with_page_already_mapped),
1600 	PKEY_TEST(test_write_of_write_disabled_region),
1601 	PKEY_TEST(test_write_of_write_disabled_region_with_page_already_mapped),
1602 	PKEY_TEST(test_write_of_access_disabled_region),
1603 	PKEY_TEST(test_write_of_access_disabled_region_with_page_already_mapped),
1604 	PKEY_TEST(test_kernel_write_of_access_disabled_region),
1605 	PKEY_TEST(test_kernel_write_of_write_disabled_region),
1606 	PKEY_TEST(test_kernel_gup_of_access_disabled_region),
1607 	PKEY_TEST(test_kernel_gup_write_to_write_disabled_region),
1608 	PKEY_TEST(test_executing_on_unreadable_memory),
1609 	PKEY_TEST(test_implicit_mprotect_exec_only_memory),
1610 	PKEY_TEST(test_mprotect_with_pkey_0),
1611 	PKEY_TEST(test_ptrace_of_child),
1612 	PKEY_TEST(test_pkey_init_state),
1613 	PKEY_TEST(test_pkey_syscalls_on_non_allocated_pkey),
1614 	PKEY_TEST(test_pkey_syscalls_bad_args),
1615 	PKEY_TEST(test_pkey_alloc_exhaust),
1616 	PKEY_TEST(test_pkey_alloc_free_attach_pkey0),
1617 #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__)
1618 	PKEY_TEST(test_ptrace_modifies_pkru),
1619 #endif
1620 };
1621 
1622 static void run_tests_once(void)
1623 {
1624 	int *ptr;
1625 	int prot = PROT_READ|PROT_WRITE;
1626 
1627 	for (test_nr = 0; test_nr < ARRAY_SIZE(pkey_tests); test_nr++) {
1628 		int pkey;
1629 		int orig_pkey_faults = pkey_faults;
1630 
1631 		dprintf1("======================\n");
1632 		dprintf1("test %d preparing...\n", test_nr);
1633 
1634 		tracing_on();
1635 		pkey = alloc_random_pkey();
1636 		dprintf1("test %d starting with pkey: %d\n", test_nr, pkey);
1637 		ptr = malloc_pkey(PAGE_SIZE, prot, pkey);
1638 		dprintf1("test %d starting...\n", test_nr);
1639 		pkey_tests[test_nr].func(ptr, pkey);
1640 		dprintf1("freeing test memory: %p\n", ptr);
1641 		free_pkey_malloc(ptr);
1642 		sys_pkey_free(pkey);
1643 
1644 		dprintf1("pkey_faults: %d\n", pkey_faults);
1645 		dprintf1("orig_pkey_faults: %d\n", orig_pkey_faults);
1646 
1647 		tracing_off();
1648 		close_test_fds();
1649 
1650 		ksft_test_result_pass("test %s (iteration %d)\n", pkey_tests[test_nr].name, iteration_nr);
1651 		dprintf1("======================\n\n");
1652 	}
1653 	iteration_nr++;
1654 }
1655 
1656 static void pkey_setup_shadow(void)
1657 {
1658 	shadow_pkey_reg = __read_pkey_reg();
1659 }
1660 
1661 int main(void)
1662 {
1663 	int nr_iterations = 22;
1664 	int pkeys_supported = is_pkeys_supported();
1665 
1666 	srand((unsigned int)time(NULL));
1667 
1668 	setup_handlers();
1669 
1670 	ksft_print_header();
1671 
1672 	if (!pkeys_supported) {
1673 		int size = PAGE_SIZE;
1674 		int *ptr;
1675 
1676 		ksft_set_plan(1);
1677 		ksft_print_msg("running PKEY tests for unsupported CPU/OS\n");
1678 
1679 		ptr  = mmap(NULL, size, PROT_NONE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
1680 		if (ptr == MAP_FAILED)
1681 			ksft_exit_fail_perror("mmap");
1682 		test_mprotect_pkey_on_unsupported_cpu(ptr, 1);
1683 		ksft_test_result_pass("pkey on unsupported CPU/OS\n");
1684 		ksft_finished();
1685 	}
1686 
1687 	ksft_set_plan(ARRAY_SIZE(pkey_tests) * nr_iterations);
1688 
1689 	pkey_setup_shadow();
1690 	ksft_print_msg("startup pkey_reg: %016llx\n", read_pkey_reg());
1691 	setup_hugetlbfs();
1692 
1693 	while (nr_iterations-- > 0)
1694 		run_tests_once();
1695 
1696 	ksft_finished();
1697 }
1698