1 // SPDX-License-Identifier: GPL-2.0
2 #define _GNU_SOURCE
3 #include <linux/mman.h>
4 #include <sys/mman.h>
5 #include <stdint.h>
6 #include <asm-generic/unistd.h>
7 #include <string.h>
8 #include <sys/time.h>
9 #include <sys/resource.h>
10 #include <stdbool.h>
11 #include "../kselftest.h"
12 #include <syscall.h>
13 #include <errno.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <fcntl.h>
17 #include <sys/ioctl.h>
18 #include <sys/vfs.h>
19 #include <sys/stat.h>
20 #include "mseal_helpers.h"
21
get_vma_size(void * addr,int * prot)22 static unsigned long get_vma_size(void *addr, int *prot)
23 {
24 FILE *maps;
25 char line[256];
26 int size = 0;
27 uintptr_t addr_start, addr_end;
28 char protstr[5];
29 *prot = 0;
30
31 maps = fopen("/proc/self/maps", "r");
32 if (!maps)
33 return 0;
34
35 while (fgets(line, sizeof(line), maps)) {
36 if (sscanf(line, "%lx-%lx %4s", &addr_start, &addr_end, protstr) == 3) {
37 if (addr_start == (uintptr_t) addr) {
38 size = addr_end - addr_start;
39 if (protstr[0] == 'r')
40 *prot |= 0x4;
41 if (protstr[1] == 'w')
42 *prot |= 0x2;
43 if (protstr[2] == 'x')
44 *prot |= 0x1;
45 break;
46 }
47 }
48 }
49 fclose(maps);
50 return size;
51 }
52
53 /*
54 * define sys_xyx to call syscall directly.
55 */
sys_mseal(void * start,size_t len)56 static int sys_mseal(void *start, size_t len)
57 {
58 int sret;
59
60 errno = 0;
61 sret = syscall(__NR_mseal, start, len, 0);
62 return sret;
63 }
64
sys_mprotect(void * ptr,size_t size,unsigned long prot)65 static int sys_mprotect(void *ptr, size_t size, unsigned long prot)
66 {
67 int sret;
68
69 errno = 0;
70 sret = syscall(__NR_mprotect, ptr, size, prot);
71 return sret;
72 }
73
sys_mprotect_pkey(void * ptr,size_t size,unsigned long orig_prot,unsigned long pkey)74 static int sys_mprotect_pkey(void *ptr, size_t size, unsigned long orig_prot,
75 unsigned long pkey)
76 {
77 int sret;
78
79 errno = 0;
80 sret = syscall(__NR_pkey_mprotect, ptr, size, orig_prot, pkey);
81 return sret;
82 }
83
sys_munmap(void * ptr,size_t size)84 static int sys_munmap(void *ptr, size_t size)
85 {
86 int sret;
87
88 errno = 0;
89 sret = syscall(__NR_munmap, ptr, size);
90 return sret;
91 }
92
sys_madvise(void * start,size_t len,int types)93 static int sys_madvise(void *start, size_t len, int types)
94 {
95 int sret;
96
97 errno = 0;
98 sret = syscall(__NR_madvise, start, len, types);
99 return sret;
100 }
101
sys_mremap(void * addr,size_t old_len,size_t new_len,unsigned long flags,void * new_addr)102 static void *sys_mremap(void *addr, size_t old_len, size_t new_len,
103 unsigned long flags, void *new_addr)
104 {
105 void *sret;
106
107 errno = 0;
108 sret = (void *) syscall(__NR_mremap, addr, old_len, new_len, flags, new_addr);
109 return sret;
110 }
111
sys_pkey_alloc(unsigned long flags,unsigned long init_val)112 static int sys_pkey_alloc(unsigned long flags, unsigned long init_val)
113 {
114 int ret = syscall(__NR_pkey_alloc, flags, init_val);
115
116 return ret;
117 }
118
__read_pkey_reg(void)119 static unsigned int __read_pkey_reg(void)
120 {
121 unsigned int pkey_reg = 0;
122 #if defined(__i386__) || defined(__x86_64__) /* arch */
123 unsigned int eax, edx;
124 unsigned int ecx = 0;
125
126 asm volatile(".byte 0x0f,0x01,0xee\n\t"
127 : "=a" (eax), "=d" (edx)
128 : "c" (ecx));
129 pkey_reg = eax;
130 #endif
131 return pkey_reg;
132 }
133
__write_pkey_reg(u64 pkey_reg)134 static void __write_pkey_reg(u64 pkey_reg)
135 {
136 #if defined(__i386__) || defined(__x86_64__) /* arch */
137 unsigned int eax = pkey_reg;
138 unsigned int ecx = 0;
139 unsigned int edx = 0;
140
141 asm volatile(".byte 0x0f,0x01,0xef\n\t"
142 : : "a" (eax), "c" (ecx), "d" (edx));
143 #endif
144 }
145
pkey_bit_position(int pkey)146 static unsigned long pkey_bit_position(int pkey)
147 {
148 return pkey * PKEY_BITS_PER_PKEY;
149 }
150
set_pkey_bits(u64 reg,int pkey,u64 flags)151 static u64 set_pkey_bits(u64 reg, int pkey, u64 flags)
152 {
153 unsigned long shift = pkey_bit_position(pkey);
154
155 /* mask out bits from pkey in old value */
156 reg &= ~((u64)PKEY_MASK << shift);
157 /* OR in new bits for pkey */
158 reg |= (flags & PKEY_MASK) << shift;
159 return reg;
160 }
161
set_pkey(int pkey,unsigned long pkey_value)162 static void set_pkey(int pkey, unsigned long pkey_value)
163 {
164 u64 new_pkey_reg;
165
166 new_pkey_reg = set_pkey_bits(__read_pkey_reg(), pkey, pkey_value);
167 __write_pkey_reg(new_pkey_reg);
168 }
169
setup_single_address(int size,void ** ptrOut)170 static void setup_single_address(int size, void **ptrOut)
171 {
172 void *ptr;
173
174 ptr = mmap(NULL, size, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
175 *ptrOut = ptr;
176 }
177
setup_single_address_rw(int size,void ** ptrOut)178 static void setup_single_address_rw(int size, void **ptrOut)
179 {
180 void *ptr;
181 unsigned long mapflags = MAP_ANONYMOUS | MAP_PRIVATE;
182
183 ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, mapflags, -1, 0);
184 *ptrOut = ptr;
185 }
186
clean_single_address(void * ptr,int size)187 static int clean_single_address(void *ptr, int size)
188 {
189 int ret;
190 ret = munmap(ptr, size);
191 return ret;
192 }
193
seal_single_address(void * ptr,int size)194 static int seal_single_address(void *ptr, int size)
195 {
196 int ret;
197 ret = sys_mseal(ptr, size);
198 return ret;
199 }
200
seal_support(void)201 bool seal_support(void)
202 {
203 int ret;
204 void *ptr;
205 unsigned long page_size = getpagesize();
206
207 ptr = mmap(NULL, page_size, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
208 if (ptr == (void *) -1)
209 return false;
210
211 ret = sys_mseal(ptr, page_size);
212 if (ret < 0)
213 return false;
214
215 return true;
216 }
217
pkey_supported(void)218 bool pkey_supported(void)
219 {
220 #if defined(__i386__) || defined(__x86_64__) /* arch */
221 int pkey = sys_pkey_alloc(0, 0);
222
223 if (pkey > 0)
224 return true;
225 #endif
226 return false;
227 }
228
test_seal_addseal(void)229 static void test_seal_addseal(void)
230 {
231 int ret;
232 void *ptr;
233 unsigned long page_size = getpagesize();
234 unsigned long size = 4 * page_size;
235
236 setup_single_address(size, &ptr);
237 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
238
239 ret = sys_mseal(ptr, size);
240 FAIL_TEST_IF_FALSE(!ret);
241
242 REPORT_TEST_PASS();
243 }
244
test_seal_unmapped_start(void)245 static void test_seal_unmapped_start(void)
246 {
247 int ret;
248 void *ptr;
249 unsigned long page_size = getpagesize();
250 unsigned long size = 4 * page_size;
251
252 setup_single_address(size, &ptr);
253 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
254
255 /* munmap 2 pages from ptr. */
256 ret = sys_munmap(ptr, 2 * page_size);
257 FAIL_TEST_IF_FALSE(!ret);
258
259 /* mprotect will fail because 2 pages from ptr are unmapped. */
260 ret = sys_mprotect(ptr, size, PROT_READ | PROT_WRITE);
261 FAIL_TEST_IF_FALSE(ret < 0);
262
263 /* mseal will fail because 2 pages from ptr are unmapped. */
264 ret = sys_mseal(ptr, size);
265 FAIL_TEST_IF_FALSE(ret < 0);
266
267 ret = sys_mseal(ptr + 2 * page_size, 2 * page_size);
268 FAIL_TEST_IF_FALSE(!ret);
269
270 REPORT_TEST_PASS();
271 }
272
test_seal_unmapped_middle(void)273 static void test_seal_unmapped_middle(void)
274 {
275 int ret;
276 void *ptr;
277 unsigned long page_size = getpagesize();
278 unsigned long size = 4 * page_size;
279
280 setup_single_address(size, &ptr);
281 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
282
283 /* munmap 2 pages from ptr + page. */
284 ret = sys_munmap(ptr + page_size, 2 * page_size);
285 FAIL_TEST_IF_FALSE(!ret);
286
287 /* mprotect will fail, since middle 2 pages are unmapped. */
288 ret = sys_mprotect(ptr, size, PROT_READ | PROT_WRITE);
289 FAIL_TEST_IF_FALSE(ret < 0);
290
291 /* mseal will fail as well. */
292 ret = sys_mseal(ptr, size);
293 FAIL_TEST_IF_FALSE(ret < 0);
294
295 /* we still can add seal to the first page and last page*/
296 ret = sys_mseal(ptr, page_size);
297 FAIL_TEST_IF_FALSE(!ret);
298
299 ret = sys_mseal(ptr + 3 * page_size, page_size);
300 FAIL_TEST_IF_FALSE(!ret);
301
302 REPORT_TEST_PASS();
303 }
304
test_seal_unmapped_end(void)305 static void test_seal_unmapped_end(void)
306 {
307 int ret;
308 void *ptr;
309 unsigned long page_size = getpagesize();
310 unsigned long size = 4 * page_size;
311
312 setup_single_address(size, &ptr);
313 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
314
315 /* unmap last 2 pages. */
316 ret = sys_munmap(ptr + 2 * page_size, 2 * page_size);
317 FAIL_TEST_IF_FALSE(!ret);
318
319 /* mprotect will fail since last 2 pages are unmapped. */
320 ret = sys_mprotect(ptr, size, PROT_READ | PROT_WRITE);
321 FAIL_TEST_IF_FALSE(ret < 0);
322
323 /* mseal will fail as well. */
324 ret = sys_mseal(ptr, size);
325 FAIL_TEST_IF_FALSE(ret < 0);
326
327 /* The first 2 pages is not sealed, and can add seals */
328 ret = sys_mseal(ptr, 2 * page_size);
329 FAIL_TEST_IF_FALSE(!ret);
330
331 REPORT_TEST_PASS();
332 }
333
test_seal_multiple_vmas(void)334 static void test_seal_multiple_vmas(void)
335 {
336 int ret;
337 void *ptr;
338 unsigned long page_size = getpagesize();
339 unsigned long size = 4 * page_size;
340
341 setup_single_address(size, &ptr);
342 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
343
344 /* use mprotect to split the vma into 3. */
345 ret = sys_mprotect(ptr + page_size, 2 * page_size,
346 PROT_READ | PROT_WRITE);
347 FAIL_TEST_IF_FALSE(!ret);
348
349 /* mprotect will get applied to all 4 pages - 3 VMAs. */
350 ret = sys_mprotect(ptr, size, PROT_READ);
351 FAIL_TEST_IF_FALSE(!ret);
352
353 /* use mprotect to split the vma into 3. */
354 ret = sys_mprotect(ptr + page_size, 2 * page_size,
355 PROT_READ | PROT_WRITE);
356 FAIL_TEST_IF_FALSE(!ret);
357
358 /* mseal get applied to all 4 pages - 3 VMAs. */
359 ret = sys_mseal(ptr, size);
360 FAIL_TEST_IF_FALSE(!ret);
361
362 REPORT_TEST_PASS();
363 }
364
test_seal_split_start(void)365 static void test_seal_split_start(void)
366 {
367 int ret;
368 void *ptr;
369 unsigned long page_size = getpagesize();
370 unsigned long size = 4 * page_size;
371
372 setup_single_address(size, &ptr);
373 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
374
375 /* use mprotect to split at middle */
376 ret = sys_mprotect(ptr, 2 * page_size, PROT_READ | PROT_WRITE);
377 FAIL_TEST_IF_FALSE(!ret);
378
379 /* seal the first page, this will split the VMA */
380 ret = sys_mseal(ptr, page_size);
381 FAIL_TEST_IF_FALSE(!ret);
382
383 /* add seal to the remain 3 pages */
384 ret = sys_mseal(ptr + page_size, 3 * page_size);
385 FAIL_TEST_IF_FALSE(!ret);
386
387 REPORT_TEST_PASS();
388 }
389
test_seal_split_end(void)390 static void test_seal_split_end(void)
391 {
392 int ret;
393 void *ptr;
394 unsigned long page_size = getpagesize();
395 unsigned long size = 4 * page_size;
396
397 setup_single_address(size, &ptr);
398 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
399
400 /* use mprotect to split at middle */
401 ret = sys_mprotect(ptr, 2 * page_size, PROT_READ | PROT_WRITE);
402 FAIL_TEST_IF_FALSE(!ret);
403
404 /* seal the last page */
405 ret = sys_mseal(ptr + 3 * page_size, page_size);
406 FAIL_TEST_IF_FALSE(!ret);
407
408 /* Adding seals to the first 3 pages */
409 ret = sys_mseal(ptr, 3 * page_size);
410 FAIL_TEST_IF_FALSE(!ret);
411
412 REPORT_TEST_PASS();
413 }
414
test_seal_invalid_input(void)415 static void test_seal_invalid_input(void)
416 {
417 void *ptr;
418 unsigned long page_size = getpagesize();
419 unsigned long size = 4 * page_size;
420 int ret;
421
422 setup_single_address(8 * page_size, &ptr);
423 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
424 ret = clean_single_address(ptr + 4 * page_size, 4 * page_size);
425 FAIL_TEST_IF_FALSE(!ret);
426
427 /* invalid flag */
428 ret = syscall(__NR_mseal, ptr, size, 0x20);
429 FAIL_TEST_IF_FALSE(ret < 0);
430
431 /* unaligned address */
432 ret = sys_mseal(ptr + 1, 2 * page_size);
433 FAIL_TEST_IF_FALSE(ret < 0);
434
435 /* length too big */
436 ret = sys_mseal(ptr, 5 * page_size);
437 FAIL_TEST_IF_FALSE(ret < 0);
438
439 /* length overflow */
440 ret = sys_mseal(ptr, UINT64_MAX/page_size);
441 FAIL_TEST_IF_FALSE(ret < 0);
442
443 /* start is not in a valid VMA */
444 ret = sys_mseal(ptr - page_size, 5 * page_size);
445 FAIL_TEST_IF_FALSE(ret < 0);
446
447 REPORT_TEST_PASS();
448 }
449
test_seal_zero_length(void)450 static void test_seal_zero_length(void)
451 {
452 void *ptr;
453 unsigned long page_size = getpagesize();
454 unsigned long size = 4 * page_size;
455 int ret;
456
457 setup_single_address(size, &ptr);
458 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
459
460 ret = sys_mprotect(ptr, 0, PROT_READ | PROT_WRITE);
461 FAIL_TEST_IF_FALSE(!ret);
462
463 /* seal 0 length will be OK, same as mprotect */
464 ret = sys_mseal(ptr, 0);
465 FAIL_TEST_IF_FALSE(!ret);
466
467 /* verify the 4 pages are not sealed by previous call. */
468 ret = sys_mprotect(ptr, size, PROT_READ | PROT_WRITE);
469 FAIL_TEST_IF_FALSE(!ret);
470
471 REPORT_TEST_PASS();
472 }
473
test_seal_zero_address(void)474 static void test_seal_zero_address(void)
475 {
476 void *ptr;
477 unsigned long page_size = getpagesize();
478 unsigned long size = 4 * page_size;
479 int ret;
480 int prot;
481
482 /* use mmap to change protection. */
483 ptr = mmap(0, size, PROT_NONE,
484 MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
485 FAIL_TEST_IF_FALSE(ptr == 0);
486
487 size = get_vma_size(ptr, &prot);
488 FAIL_TEST_IF_FALSE(size == 4 * page_size);
489
490 ret = sys_mseal(ptr, size);
491 FAIL_TEST_IF_FALSE(!ret);
492
493 /* verify the 4 pages are sealed by previous call. */
494 ret = sys_mprotect(ptr, size, PROT_READ | PROT_WRITE);
495 FAIL_TEST_IF_FALSE(ret);
496
497 REPORT_TEST_PASS();
498 }
499
test_seal_twice(void)500 static void test_seal_twice(void)
501 {
502 int ret;
503 void *ptr;
504 unsigned long page_size = getpagesize();
505 unsigned long size = 4 * page_size;
506
507 setup_single_address(size, &ptr);
508 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
509
510 ret = sys_mseal(ptr, size);
511 FAIL_TEST_IF_FALSE(!ret);
512
513 /* apply the same seal will be OK. idempotent. */
514 ret = sys_mseal(ptr, size);
515 FAIL_TEST_IF_FALSE(!ret);
516
517 REPORT_TEST_PASS();
518 }
519
test_seal_mprotect(bool seal)520 static void test_seal_mprotect(bool seal)
521 {
522 void *ptr;
523 unsigned long page_size = getpagesize();
524 unsigned long size = 4 * page_size;
525 int ret;
526
527 setup_single_address(size, &ptr);
528 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
529
530 if (seal) {
531 ret = seal_single_address(ptr, size);
532 FAIL_TEST_IF_FALSE(!ret);
533 }
534
535 ret = sys_mprotect(ptr, size, PROT_READ | PROT_WRITE);
536 if (seal)
537 FAIL_TEST_IF_FALSE(ret < 0);
538 else
539 FAIL_TEST_IF_FALSE(!ret);
540
541 REPORT_TEST_PASS();
542 }
543
test_seal_start_mprotect(bool seal)544 static void test_seal_start_mprotect(bool seal)
545 {
546 void *ptr;
547 unsigned long page_size = getpagesize();
548 unsigned long size = 4 * page_size;
549 int ret;
550
551 setup_single_address(size, &ptr);
552 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
553
554 if (seal) {
555 ret = seal_single_address(ptr, page_size);
556 FAIL_TEST_IF_FALSE(!ret);
557 }
558
559 /* the first page is sealed. */
560 ret = sys_mprotect(ptr, page_size, PROT_READ | PROT_WRITE);
561 if (seal)
562 FAIL_TEST_IF_FALSE(ret < 0);
563 else
564 FAIL_TEST_IF_FALSE(!ret);
565
566 /* pages after the first page is not sealed. */
567 ret = sys_mprotect(ptr + page_size, page_size * 3,
568 PROT_READ | PROT_WRITE);
569 FAIL_TEST_IF_FALSE(!ret);
570
571 REPORT_TEST_PASS();
572 }
573
test_seal_end_mprotect(bool seal)574 static void test_seal_end_mprotect(bool seal)
575 {
576 void *ptr;
577 unsigned long page_size = getpagesize();
578 unsigned long size = 4 * page_size;
579 int ret;
580
581 setup_single_address(size, &ptr);
582 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
583
584 if (seal) {
585 ret = seal_single_address(ptr + page_size, 3 * page_size);
586 FAIL_TEST_IF_FALSE(!ret);
587 }
588
589 /* first page is not sealed */
590 ret = sys_mprotect(ptr, page_size, PROT_READ | PROT_WRITE);
591 FAIL_TEST_IF_FALSE(!ret);
592
593 /* last 3 page are sealed */
594 ret = sys_mprotect(ptr + page_size, page_size * 3,
595 PROT_READ | PROT_WRITE);
596 if (seal)
597 FAIL_TEST_IF_FALSE(ret < 0);
598 else
599 FAIL_TEST_IF_FALSE(!ret);
600
601 REPORT_TEST_PASS();
602 }
603
test_seal_mprotect_unalign_len(bool seal)604 static void test_seal_mprotect_unalign_len(bool seal)
605 {
606 void *ptr;
607 unsigned long page_size = getpagesize();
608 unsigned long size = 4 * page_size;
609 int ret;
610
611 setup_single_address(size, &ptr);
612 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
613
614 if (seal) {
615 ret = seal_single_address(ptr, page_size * 2 - 1);
616 FAIL_TEST_IF_FALSE(!ret);
617 }
618
619 /* 2 pages are sealed. */
620 ret = sys_mprotect(ptr, page_size * 2, PROT_READ | PROT_WRITE);
621 if (seal)
622 FAIL_TEST_IF_FALSE(ret < 0);
623 else
624 FAIL_TEST_IF_FALSE(!ret);
625
626 ret = sys_mprotect(ptr + page_size * 2, page_size,
627 PROT_READ | PROT_WRITE);
628 FAIL_TEST_IF_FALSE(!ret);
629
630 REPORT_TEST_PASS();
631 }
632
test_seal_mprotect_unalign_len_variant_2(bool seal)633 static void test_seal_mprotect_unalign_len_variant_2(bool seal)
634 {
635 void *ptr;
636 unsigned long page_size = getpagesize();
637 unsigned long size = 4 * page_size;
638 int ret;
639
640 setup_single_address(size, &ptr);
641 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
642 if (seal) {
643 ret = seal_single_address(ptr, page_size * 2 + 1);
644 FAIL_TEST_IF_FALSE(!ret);
645 }
646
647 /* 3 pages are sealed. */
648 ret = sys_mprotect(ptr, page_size * 3, PROT_READ | PROT_WRITE);
649 if (seal)
650 FAIL_TEST_IF_FALSE(ret < 0);
651 else
652 FAIL_TEST_IF_FALSE(!ret);
653
654 ret = sys_mprotect(ptr + page_size * 3, page_size,
655 PROT_READ | PROT_WRITE);
656 FAIL_TEST_IF_FALSE(!ret);
657
658 REPORT_TEST_PASS();
659 }
660
test_seal_mprotect_two_vma(bool seal)661 static void test_seal_mprotect_two_vma(bool seal)
662 {
663 void *ptr;
664 unsigned long page_size = getpagesize();
665 unsigned long size = 4 * page_size;
666 int ret;
667
668 setup_single_address(size, &ptr);
669 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
670
671 /* use mprotect to split */
672 ret = sys_mprotect(ptr, page_size * 2, PROT_READ | PROT_WRITE);
673 FAIL_TEST_IF_FALSE(!ret);
674
675 if (seal) {
676 ret = seal_single_address(ptr, page_size * 4);
677 FAIL_TEST_IF_FALSE(!ret);
678 }
679
680 ret = sys_mprotect(ptr, page_size * 2, PROT_READ | PROT_WRITE);
681 if (seal)
682 FAIL_TEST_IF_FALSE(ret < 0);
683 else
684 FAIL_TEST_IF_FALSE(!ret);
685
686 ret = sys_mprotect(ptr + page_size * 2, page_size * 2,
687 PROT_READ | PROT_WRITE);
688 if (seal)
689 FAIL_TEST_IF_FALSE(ret < 0);
690 else
691 FAIL_TEST_IF_FALSE(!ret);
692
693 REPORT_TEST_PASS();
694 }
695
test_seal_mprotect_two_vma_with_split(bool seal)696 static void test_seal_mprotect_two_vma_with_split(bool seal)
697 {
698 void *ptr;
699 unsigned long page_size = getpagesize();
700 unsigned long size = 4 * page_size;
701 int ret;
702
703 setup_single_address(size, &ptr);
704 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
705
706 /* use mprotect to split as two vma. */
707 ret = sys_mprotect(ptr, page_size * 2, PROT_READ | PROT_WRITE);
708 FAIL_TEST_IF_FALSE(!ret);
709
710 /* mseal can apply across 2 vma, also split them. */
711 if (seal) {
712 ret = seal_single_address(ptr + page_size, page_size * 2);
713 FAIL_TEST_IF_FALSE(!ret);
714 }
715
716 /* the first page is not sealed. */
717 ret = sys_mprotect(ptr, page_size, PROT_READ | PROT_WRITE);
718 FAIL_TEST_IF_FALSE(!ret);
719
720 /* the second page is sealed. */
721 ret = sys_mprotect(ptr + page_size, page_size, PROT_READ | PROT_WRITE);
722 if (seal)
723 FAIL_TEST_IF_FALSE(ret < 0);
724 else
725 FAIL_TEST_IF_FALSE(!ret);
726
727 /* the third page is sealed. */
728 ret = sys_mprotect(ptr + 2 * page_size, page_size,
729 PROT_READ | PROT_WRITE);
730 if (seal)
731 FAIL_TEST_IF_FALSE(ret < 0);
732 else
733 FAIL_TEST_IF_FALSE(!ret);
734
735 /* the fouth page is not sealed. */
736 ret = sys_mprotect(ptr + 3 * page_size, page_size,
737 PROT_READ | PROT_WRITE);
738 FAIL_TEST_IF_FALSE(!ret);
739
740 REPORT_TEST_PASS();
741 }
742
test_seal_mprotect_partial_mprotect(bool seal)743 static void test_seal_mprotect_partial_mprotect(bool seal)
744 {
745 void *ptr;
746 unsigned long page_size = getpagesize();
747 unsigned long size = 4 * page_size;
748 int ret;
749
750 setup_single_address(size, &ptr);
751 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
752
753 /* seal one page. */
754 if (seal) {
755 ret = seal_single_address(ptr, page_size);
756 FAIL_TEST_IF_FALSE(!ret);
757 }
758
759 /* mprotect first 2 page will fail, since the first page are sealed. */
760 ret = sys_mprotect(ptr, 2 * page_size, PROT_READ | PROT_WRITE);
761 if (seal)
762 FAIL_TEST_IF_FALSE(ret < 0);
763 else
764 FAIL_TEST_IF_FALSE(!ret);
765
766 REPORT_TEST_PASS();
767 }
768
test_seal_mprotect_partial_mprotect_tail(bool seal)769 static void test_seal_mprotect_partial_mprotect_tail(bool seal)
770 {
771 void *ptr;
772 unsigned long page_size = getpagesize();
773 unsigned long size = 2 * page_size;
774 int ret;
775 int prot;
776
777 /*
778 * Check if a partial mseal (that results in two vmas) works correctly.
779 * It might mprotect the first, but it'll never touch the second (msealed) vma.
780 */
781
782 setup_single_address(size, &ptr);
783 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
784
785 if (seal) {
786 ret = sys_mseal(ptr + page_size, page_size);
787 FAIL_TEST_IF_FALSE(!ret);
788 }
789
790 ret = sys_mprotect(ptr, size, PROT_EXEC);
791 if (seal)
792 FAIL_TEST_IF_FALSE(ret < 0);
793 else
794 FAIL_TEST_IF_FALSE(!ret);
795
796 if (seal) {
797 FAIL_TEST_IF_FALSE(get_vma_size(ptr + page_size, &prot) > 0);
798 FAIL_TEST_IF_FALSE(prot == 0x4);
799 }
800
801 REPORT_TEST_PASS();
802 }
803
804
test_seal_mprotect_two_vma_with_gap(bool seal)805 static void test_seal_mprotect_two_vma_with_gap(bool seal)
806 {
807 void *ptr;
808 unsigned long page_size = getpagesize();
809 unsigned long size = 4 * page_size;
810 int ret;
811
812 setup_single_address(size, &ptr);
813 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
814
815 /* use mprotect to split. */
816 ret = sys_mprotect(ptr, page_size, PROT_READ | PROT_WRITE);
817 FAIL_TEST_IF_FALSE(!ret);
818
819 /* use mprotect to split. */
820 ret = sys_mprotect(ptr + 3 * page_size, page_size,
821 PROT_READ | PROT_WRITE);
822 FAIL_TEST_IF_FALSE(!ret);
823
824 /* use munmap to free two pages in the middle */
825 ret = sys_munmap(ptr + page_size, 2 * page_size);
826 FAIL_TEST_IF_FALSE(!ret);
827
828 /* mprotect will fail, because there is a gap in the address. */
829 /* notes, internally mprotect still updated the first page. */
830 ret = sys_mprotect(ptr, 4 * page_size, PROT_READ);
831 FAIL_TEST_IF_FALSE(ret < 0);
832
833 /* mseal will fail as well. */
834 ret = sys_mseal(ptr, 4 * page_size);
835 FAIL_TEST_IF_FALSE(ret < 0);
836
837 /* the first page is not sealed. */
838 ret = sys_mprotect(ptr, page_size, PROT_READ);
839 FAIL_TEST_IF_FALSE(ret == 0);
840
841 /* the last page is not sealed. */
842 ret = sys_mprotect(ptr + 3 * page_size, page_size, PROT_READ);
843 FAIL_TEST_IF_FALSE(ret == 0);
844
845 REPORT_TEST_PASS();
846 }
847
test_seal_mprotect_split(bool seal)848 static void test_seal_mprotect_split(bool seal)
849 {
850 void *ptr;
851 unsigned long page_size = getpagesize();
852 unsigned long size = 4 * page_size;
853 int ret;
854
855 setup_single_address(size, &ptr);
856 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
857
858 /* use mprotect to split. */
859 ret = sys_mprotect(ptr, page_size, PROT_READ | PROT_WRITE);
860 FAIL_TEST_IF_FALSE(!ret);
861
862 /* seal all 4 pages. */
863 if (seal) {
864 ret = sys_mseal(ptr, 4 * page_size);
865 FAIL_TEST_IF_FALSE(!ret);
866 }
867
868 /* mprotect is sealed. */
869 ret = sys_mprotect(ptr, 2 * page_size, PROT_READ);
870 if (seal)
871 FAIL_TEST_IF_FALSE(ret < 0);
872 else
873 FAIL_TEST_IF_FALSE(!ret);
874
875
876 ret = sys_mprotect(ptr + 2 * page_size, 2 * page_size, PROT_READ);
877 if (seal)
878 FAIL_TEST_IF_FALSE(ret < 0);
879 else
880 FAIL_TEST_IF_FALSE(!ret);
881
882 REPORT_TEST_PASS();
883 }
884
test_seal_mprotect_merge(bool seal)885 static void test_seal_mprotect_merge(bool seal)
886 {
887 void *ptr;
888 unsigned long page_size = getpagesize();
889 unsigned long size = 4 * page_size;
890 int ret;
891
892 setup_single_address(size, &ptr);
893 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
894
895 /* use mprotect to split one page. */
896 ret = sys_mprotect(ptr, page_size, PROT_READ | PROT_WRITE);
897 FAIL_TEST_IF_FALSE(!ret);
898
899 /* seal first two pages. */
900 if (seal) {
901 ret = sys_mseal(ptr, 2 * page_size);
902 FAIL_TEST_IF_FALSE(!ret);
903 }
904
905 /* 2 pages are sealed. */
906 ret = sys_mprotect(ptr, 2 * page_size, PROT_READ);
907 if (seal)
908 FAIL_TEST_IF_FALSE(ret < 0);
909 else
910 FAIL_TEST_IF_FALSE(!ret);
911
912 /* last 2 pages are not sealed. */
913 ret = sys_mprotect(ptr + 2 * page_size, 2 * page_size, PROT_READ);
914 FAIL_TEST_IF_FALSE(ret == 0);
915
916 REPORT_TEST_PASS();
917 }
918
test_seal_munmap(bool seal)919 static void test_seal_munmap(bool seal)
920 {
921 void *ptr;
922 unsigned long page_size = getpagesize();
923 unsigned long size = 4 * page_size;
924 int ret;
925
926 setup_single_address(size, &ptr);
927 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
928
929 if (seal) {
930 ret = sys_mseal(ptr, size);
931 FAIL_TEST_IF_FALSE(!ret);
932 }
933
934 /* 4 pages are sealed. */
935 ret = sys_munmap(ptr, size);
936 if (seal)
937 FAIL_TEST_IF_FALSE(ret < 0);
938 else
939 FAIL_TEST_IF_FALSE(!ret);
940
941 REPORT_TEST_PASS();
942 }
943
944 /*
945 * allocate 4 pages,
946 * use mprotect to split it as two VMAs
947 * seal the whole range
948 * munmap will fail on both
949 */
test_seal_munmap_two_vma(bool seal)950 static void test_seal_munmap_two_vma(bool seal)
951 {
952 void *ptr;
953 unsigned long page_size = getpagesize();
954 unsigned long size = 4 * page_size;
955 int ret;
956
957 setup_single_address(size, &ptr);
958 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
959
960 /* use mprotect to split */
961 ret = sys_mprotect(ptr, page_size * 2, PROT_READ | PROT_WRITE);
962 FAIL_TEST_IF_FALSE(!ret);
963
964 if (seal) {
965 ret = sys_mseal(ptr, size);
966 FAIL_TEST_IF_FALSE(!ret);
967 }
968
969 ret = sys_munmap(ptr, page_size * 2);
970 if (seal)
971 FAIL_TEST_IF_FALSE(ret < 0);
972 else
973 FAIL_TEST_IF_FALSE(!ret);
974
975 ret = sys_munmap(ptr + page_size, page_size * 2);
976 if (seal)
977 FAIL_TEST_IF_FALSE(ret < 0);
978 else
979 FAIL_TEST_IF_FALSE(!ret);
980
981 REPORT_TEST_PASS();
982 }
983
984 /*
985 * allocate a VMA with 4 pages.
986 * munmap the middle 2 pages.
987 * seal the whole 4 pages, will fail.
988 * munmap the first page will be OK.
989 * munmap the last page will be OK.
990 */
test_seal_munmap_vma_with_gap(bool seal)991 static void test_seal_munmap_vma_with_gap(bool seal)
992 {
993 void *ptr;
994 unsigned long page_size = getpagesize();
995 unsigned long size = 4 * page_size;
996 int ret;
997
998 setup_single_address(size, &ptr);
999 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1000
1001 ret = sys_munmap(ptr + page_size, page_size * 2);
1002 FAIL_TEST_IF_FALSE(!ret);
1003
1004 if (seal) {
1005 /* can't have gap in the middle. */
1006 ret = sys_mseal(ptr, size);
1007 FAIL_TEST_IF_FALSE(ret < 0);
1008 }
1009
1010 ret = sys_munmap(ptr, page_size);
1011 FAIL_TEST_IF_FALSE(!ret);
1012
1013 ret = sys_munmap(ptr + page_size * 2, page_size);
1014 FAIL_TEST_IF_FALSE(!ret);
1015
1016 ret = sys_munmap(ptr, size);
1017 FAIL_TEST_IF_FALSE(!ret);
1018
1019 REPORT_TEST_PASS();
1020 }
1021
test_seal_munmap_partial_across_vmas(bool seal)1022 static void test_seal_munmap_partial_across_vmas(bool seal)
1023 {
1024 void *ptr;
1025 unsigned long page_size = getpagesize();
1026 unsigned long size = 2 * page_size;
1027 int ret;
1028 int prot;
1029
1030 setup_single_address(size, &ptr);
1031 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1032
1033 if (seal) {
1034 ret = sys_mseal(ptr + page_size, page_size);
1035 FAIL_TEST_IF_FALSE(!ret);
1036 }
1037
1038 ret = sys_munmap(ptr, size);
1039 if (seal)
1040 FAIL_TEST_IF_FALSE(ret < 0);
1041 else
1042 FAIL_TEST_IF_FALSE(!ret);
1043
1044 if (seal) {
1045 FAIL_TEST_IF_FALSE(get_vma_size(ptr + page_size, &prot) > 0);
1046 FAIL_TEST_IF_FALSE(prot == 0x4);
1047 }
1048
1049 REPORT_TEST_PASS();
1050 }
1051
test_munmap_start_freed(bool seal)1052 static void test_munmap_start_freed(bool seal)
1053 {
1054 void *ptr;
1055 unsigned long page_size = getpagesize();
1056 unsigned long size = 4 * page_size;
1057 int ret;
1058 int prot;
1059
1060 setup_single_address(size, &ptr);
1061 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1062
1063 /* unmap the first page. */
1064 ret = sys_munmap(ptr, page_size);
1065 FAIL_TEST_IF_FALSE(!ret);
1066
1067 /* seal the last 3 pages. */
1068 if (seal) {
1069 ret = sys_mseal(ptr + page_size, 3 * page_size);
1070 FAIL_TEST_IF_FALSE(!ret);
1071 }
1072
1073 /* unmap from the first page. */
1074 ret = sys_munmap(ptr, size);
1075 if (seal) {
1076 FAIL_TEST_IF_FALSE(ret < 0);
1077
1078 size = get_vma_size(ptr + page_size, &prot);
1079 FAIL_TEST_IF_FALSE(size == page_size * 3);
1080 } else {
1081 /* note: this will be OK, even the first page is */
1082 /* already unmapped. */
1083 FAIL_TEST_IF_FALSE(!ret);
1084
1085 size = get_vma_size(ptr + page_size, &prot);
1086 FAIL_TEST_IF_FALSE(size == 0);
1087 }
1088
1089 REPORT_TEST_PASS();
1090 }
1091
test_munmap_end_freed(bool seal)1092 static void test_munmap_end_freed(bool seal)
1093 {
1094 void *ptr;
1095 unsigned long page_size = getpagesize();
1096 unsigned long size = 4 * page_size;
1097 int ret;
1098
1099 setup_single_address(size, &ptr);
1100 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1101
1102 /* unmap last page. */
1103 ret = sys_munmap(ptr + page_size * 3, page_size);
1104 FAIL_TEST_IF_FALSE(!ret);
1105
1106 /* seal the first 3 pages. */
1107 if (seal) {
1108 ret = sys_mseal(ptr, 3 * page_size);
1109 FAIL_TEST_IF_FALSE(!ret);
1110 }
1111
1112 /* unmap all pages. */
1113 ret = sys_munmap(ptr, size);
1114 if (seal)
1115 FAIL_TEST_IF_FALSE(ret < 0);
1116 else
1117 FAIL_TEST_IF_FALSE(!ret);
1118
1119 REPORT_TEST_PASS();
1120 }
1121
test_munmap_middle_freed(bool seal)1122 static void test_munmap_middle_freed(bool seal)
1123 {
1124 void *ptr;
1125 unsigned long page_size = getpagesize();
1126 unsigned long size = 4 * page_size;
1127 int ret;
1128 int prot;
1129
1130 setup_single_address(size, &ptr);
1131 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1132
1133 /* unmap 2 pages in the middle. */
1134 ret = sys_munmap(ptr + page_size, page_size * 2);
1135 FAIL_TEST_IF_FALSE(!ret);
1136
1137 /* seal the first page. */
1138 if (seal) {
1139 ret = sys_mseal(ptr, page_size);
1140 FAIL_TEST_IF_FALSE(!ret);
1141 }
1142
1143 /* munmap all 4 pages. */
1144 ret = sys_munmap(ptr, size);
1145 if (seal) {
1146 FAIL_TEST_IF_FALSE(ret < 0);
1147
1148 size = get_vma_size(ptr, &prot);
1149 FAIL_TEST_IF_FALSE(size == page_size);
1150
1151 size = get_vma_size(ptr + page_size * 3, &prot);
1152 FAIL_TEST_IF_FALSE(size == page_size);
1153 } else {
1154 FAIL_TEST_IF_FALSE(!ret);
1155
1156 size = get_vma_size(ptr, &prot);
1157 FAIL_TEST_IF_FALSE(size == 0);
1158
1159 size = get_vma_size(ptr + page_size * 3, &prot);
1160 FAIL_TEST_IF_FALSE(size == 0);
1161 }
1162
1163 REPORT_TEST_PASS();
1164 }
1165
test_seal_mremap_shrink(bool seal)1166 static void test_seal_mremap_shrink(bool seal)
1167 {
1168 void *ptr;
1169 unsigned long page_size = getpagesize();
1170 unsigned long size = 4 * page_size;
1171 int ret;
1172 void *ret2;
1173
1174 setup_single_address(size, &ptr);
1175 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1176
1177 if (seal) {
1178 ret = sys_mseal(ptr, size);
1179 FAIL_TEST_IF_FALSE(!ret);
1180 }
1181
1182 /* shrink from 4 pages to 2 pages. */
1183 ret2 = sys_mremap(ptr, size, 2 * page_size, 0, 0);
1184 if (seal) {
1185 FAIL_TEST_IF_FALSE(ret2 == (void *) MAP_FAILED);
1186 FAIL_TEST_IF_FALSE(errno == EPERM);
1187 } else {
1188 FAIL_TEST_IF_FALSE(ret2 != (void *) MAP_FAILED);
1189
1190 }
1191
1192 REPORT_TEST_PASS();
1193 }
1194
test_seal_mremap_expand(bool seal)1195 static void test_seal_mremap_expand(bool seal)
1196 {
1197 void *ptr;
1198 unsigned long page_size = getpagesize();
1199 unsigned long size = 4 * page_size;
1200 int ret;
1201 void *ret2;
1202
1203 setup_single_address(size, &ptr);
1204 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1205 /* ummap last 2 pages. */
1206 ret = sys_munmap(ptr + 2 * page_size, 2 * page_size);
1207 FAIL_TEST_IF_FALSE(!ret);
1208
1209 if (seal) {
1210 ret = sys_mseal(ptr, 2 * page_size);
1211 FAIL_TEST_IF_FALSE(!ret);
1212 }
1213
1214 /* expand from 2 page to 4 pages. */
1215 ret2 = sys_mremap(ptr, 2 * page_size, 4 * page_size, 0, 0);
1216 if (seal) {
1217 FAIL_TEST_IF_FALSE(ret2 == MAP_FAILED);
1218 FAIL_TEST_IF_FALSE(errno == EPERM);
1219 } else {
1220 FAIL_TEST_IF_FALSE(ret2 == ptr);
1221
1222 }
1223
1224 REPORT_TEST_PASS();
1225 }
1226
test_seal_mremap_move(bool seal)1227 static void test_seal_mremap_move(bool seal)
1228 {
1229 void *ptr, *newPtr;
1230 unsigned long page_size = getpagesize();
1231 unsigned long size = page_size;
1232 int ret;
1233 void *ret2;
1234
1235 setup_single_address(size, &ptr);
1236 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1237 setup_single_address(size, &newPtr);
1238 FAIL_TEST_IF_FALSE(newPtr != (void *)-1);
1239 ret = clean_single_address(newPtr, size);
1240 FAIL_TEST_IF_FALSE(!ret);
1241
1242 if (seal) {
1243 ret = sys_mseal(ptr, size);
1244 FAIL_TEST_IF_FALSE(!ret);
1245 }
1246
1247 /* move from ptr to fixed address. */
1248 ret2 = sys_mremap(ptr, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, newPtr);
1249 if (seal) {
1250 FAIL_TEST_IF_FALSE(ret2 == MAP_FAILED);
1251 FAIL_TEST_IF_FALSE(errno == EPERM);
1252 } else {
1253 FAIL_TEST_IF_FALSE(ret2 != MAP_FAILED);
1254
1255 }
1256
1257 REPORT_TEST_PASS();
1258 }
1259
test_seal_mmap_overwrite_prot(bool seal)1260 static void test_seal_mmap_overwrite_prot(bool seal)
1261 {
1262 void *ptr;
1263 unsigned long page_size = getpagesize();
1264 unsigned long size = page_size;
1265 int ret;
1266 void *ret2;
1267
1268 setup_single_address(size, &ptr);
1269 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1270
1271 if (seal) {
1272 ret = sys_mseal(ptr, size);
1273 FAIL_TEST_IF_FALSE(!ret);
1274 }
1275
1276 /* use mmap to change protection. */
1277 ret2 = mmap(ptr, size, PROT_NONE,
1278 MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
1279 if (seal) {
1280 FAIL_TEST_IF_FALSE(ret2 == MAP_FAILED);
1281 FAIL_TEST_IF_FALSE(errno == EPERM);
1282 } else
1283 FAIL_TEST_IF_FALSE(ret2 == ptr);
1284
1285 REPORT_TEST_PASS();
1286 }
1287
test_seal_mmap_expand(bool seal)1288 static void test_seal_mmap_expand(bool seal)
1289 {
1290 void *ptr;
1291 unsigned long page_size = getpagesize();
1292 unsigned long size = 12 * page_size;
1293 int ret;
1294 void *ret2;
1295
1296 setup_single_address(size, &ptr);
1297 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1298 /* ummap last 4 pages. */
1299 ret = sys_munmap(ptr + 8 * page_size, 4 * page_size);
1300 FAIL_TEST_IF_FALSE(!ret);
1301
1302 if (seal) {
1303 ret = sys_mseal(ptr, 8 * page_size);
1304 FAIL_TEST_IF_FALSE(!ret);
1305 }
1306
1307 /* use mmap to expand. */
1308 ret2 = mmap(ptr, size, PROT_READ,
1309 MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
1310 if (seal) {
1311 FAIL_TEST_IF_FALSE(ret2 == MAP_FAILED);
1312 FAIL_TEST_IF_FALSE(errno == EPERM);
1313 } else
1314 FAIL_TEST_IF_FALSE(ret2 == ptr);
1315
1316 REPORT_TEST_PASS();
1317 }
1318
test_seal_mmap_shrink(bool seal)1319 static void test_seal_mmap_shrink(bool seal)
1320 {
1321 void *ptr;
1322 unsigned long page_size = getpagesize();
1323 unsigned long size = 12 * page_size;
1324 int ret;
1325 void *ret2;
1326
1327 setup_single_address(size, &ptr);
1328 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1329
1330 if (seal) {
1331 ret = sys_mseal(ptr, size);
1332 FAIL_TEST_IF_FALSE(!ret);
1333 }
1334
1335 /* use mmap to shrink. */
1336 ret2 = mmap(ptr, 8 * page_size, PROT_READ,
1337 MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, -1, 0);
1338 if (seal) {
1339 FAIL_TEST_IF_FALSE(ret2 == MAP_FAILED);
1340 FAIL_TEST_IF_FALSE(errno == EPERM);
1341 } else
1342 FAIL_TEST_IF_FALSE(ret2 == ptr);
1343
1344 REPORT_TEST_PASS();
1345 }
1346
test_seal_mremap_shrink_fixed(bool seal)1347 static void test_seal_mremap_shrink_fixed(bool seal)
1348 {
1349 void *ptr;
1350 void *newAddr;
1351 unsigned long page_size = getpagesize();
1352 unsigned long size = 4 * page_size;
1353 int ret;
1354 void *ret2;
1355
1356 setup_single_address(size, &ptr);
1357 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1358 setup_single_address(size, &newAddr);
1359 FAIL_TEST_IF_FALSE(newAddr != (void *)-1);
1360
1361 if (seal) {
1362 ret = sys_mseal(ptr, size);
1363 FAIL_TEST_IF_FALSE(!ret);
1364 }
1365
1366 /* mremap to move and shrink to fixed address */
1367 ret2 = sys_mremap(ptr, size, 2 * page_size, MREMAP_MAYMOVE | MREMAP_FIXED,
1368 newAddr);
1369 if (seal) {
1370 FAIL_TEST_IF_FALSE(ret2 == MAP_FAILED);
1371 FAIL_TEST_IF_FALSE(errno == EPERM);
1372 } else
1373 FAIL_TEST_IF_FALSE(ret2 == newAddr);
1374
1375 REPORT_TEST_PASS();
1376 }
1377
test_seal_mremap_expand_fixed(bool seal)1378 static void test_seal_mremap_expand_fixed(bool seal)
1379 {
1380 void *ptr;
1381 void *newAddr;
1382 unsigned long page_size = getpagesize();
1383 unsigned long size = 4 * page_size;
1384 int ret;
1385 void *ret2;
1386
1387 setup_single_address(page_size, &ptr);
1388 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1389 setup_single_address(size, &newAddr);
1390 FAIL_TEST_IF_FALSE(newAddr != (void *)-1);
1391
1392 if (seal) {
1393 ret = sys_mseal(newAddr, size);
1394 FAIL_TEST_IF_FALSE(!ret);
1395 }
1396
1397 /* mremap to move and expand to fixed address */
1398 ret2 = sys_mremap(ptr, page_size, size, MREMAP_MAYMOVE | MREMAP_FIXED,
1399 newAddr);
1400 if (seal) {
1401 FAIL_TEST_IF_FALSE(ret2 == MAP_FAILED);
1402 FAIL_TEST_IF_FALSE(errno == EPERM);
1403 } else
1404 FAIL_TEST_IF_FALSE(ret2 == newAddr);
1405
1406 REPORT_TEST_PASS();
1407 }
1408
test_seal_mremap_move_fixed(bool seal)1409 static void test_seal_mremap_move_fixed(bool seal)
1410 {
1411 void *ptr;
1412 void *newAddr;
1413 unsigned long page_size = getpagesize();
1414 unsigned long size = 4 * page_size;
1415 int ret;
1416 void *ret2;
1417
1418 setup_single_address(size, &ptr);
1419 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1420 setup_single_address(size, &newAddr);
1421 FAIL_TEST_IF_FALSE(newAddr != (void *)-1);
1422
1423 if (seal) {
1424 ret = sys_mseal(newAddr, size);
1425 FAIL_TEST_IF_FALSE(!ret);
1426 }
1427
1428 /* mremap to move to fixed address */
1429 ret2 = sys_mremap(ptr, size, size, MREMAP_MAYMOVE | MREMAP_FIXED, newAddr);
1430 if (seal) {
1431 FAIL_TEST_IF_FALSE(ret2 == MAP_FAILED);
1432 FAIL_TEST_IF_FALSE(errno == EPERM);
1433 } else
1434 FAIL_TEST_IF_FALSE(ret2 == newAddr);
1435
1436 REPORT_TEST_PASS();
1437 }
1438
test_seal_mremap_move_fixed_zero(bool seal)1439 static void test_seal_mremap_move_fixed_zero(bool seal)
1440 {
1441 void *ptr;
1442 unsigned long page_size = getpagesize();
1443 unsigned long size = 4 * page_size;
1444 int ret;
1445 void *ret2;
1446
1447 setup_single_address(size, &ptr);
1448 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1449
1450 if (seal) {
1451 ret = sys_mseal(ptr, size);
1452 FAIL_TEST_IF_FALSE(!ret);
1453 }
1454
1455 /*
1456 * MREMAP_FIXED can move the mapping to zero address
1457 */
1458 ret2 = sys_mremap(ptr, size, 2 * page_size, MREMAP_MAYMOVE | MREMAP_FIXED,
1459 0);
1460 if (seal) {
1461 FAIL_TEST_IF_FALSE(ret2 == MAP_FAILED);
1462 FAIL_TEST_IF_FALSE(errno == EPERM);
1463 } else {
1464 FAIL_TEST_IF_FALSE(ret2 == 0);
1465 }
1466
1467 REPORT_TEST_PASS();
1468 }
1469
test_seal_mremap_move_dontunmap(bool seal)1470 static void test_seal_mremap_move_dontunmap(bool seal)
1471 {
1472 void *ptr;
1473 unsigned long page_size = getpagesize();
1474 unsigned long size = 4 * page_size;
1475 int ret;
1476 void *ret2;
1477
1478 setup_single_address(size, &ptr);
1479 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1480
1481 if (seal) {
1482 ret = sys_mseal(ptr, size);
1483 FAIL_TEST_IF_FALSE(!ret);
1484 }
1485
1486 /* mremap to move, and don't unmap src addr. */
1487 ret2 = sys_mremap(ptr, size, size, MREMAP_MAYMOVE | MREMAP_DONTUNMAP, 0);
1488 if (seal) {
1489 FAIL_TEST_IF_FALSE(ret2 == MAP_FAILED);
1490 FAIL_TEST_IF_FALSE(errno == EPERM);
1491 } else {
1492 /* kernel will allocate a new address */
1493 FAIL_TEST_IF_FALSE(ret2 != MAP_FAILED);
1494 }
1495
1496 REPORT_TEST_PASS();
1497 }
1498
test_seal_mremap_move_dontunmap_anyaddr(bool seal)1499 static void test_seal_mremap_move_dontunmap_anyaddr(bool seal)
1500 {
1501 void *ptr, *ptr2;
1502 unsigned long page_size = getpagesize();
1503 unsigned long size = 4 * page_size;
1504 int ret;
1505 void *ret2;
1506
1507 setup_single_address(size, &ptr);
1508 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1509
1510 if (seal) {
1511 ret = sys_mseal(ptr, size);
1512 FAIL_TEST_IF_FALSE(!ret);
1513 }
1514
1515 /*
1516 * The new address is any address that not allocated.
1517 * use allocate/free to similate that.
1518 */
1519 setup_single_address(size, &ptr2);
1520 FAIL_TEST_IF_FALSE(ptr2 != (void *)-1);
1521 ret = sys_munmap(ptr2, size);
1522 FAIL_TEST_IF_FALSE(!ret);
1523
1524 /*
1525 * remap to any address.
1526 */
1527 ret2 = sys_mremap(ptr, size, size, MREMAP_MAYMOVE | MREMAP_DONTUNMAP,
1528 (void *) ptr2);
1529 if (seal) {
1530 FAIL_TEST_IF_FALSE(ret2 == MAP_FAILED);
1531 FAIL_TEST_IF_FALSE(errno == EPERM);
1532 } else {
1533 /* remap success and return ptr2 */
1534 FAIL_TEST_IF_FALSE(ret2 == ptr2);
1535 }
1536
1537 REPORT_TEST_PASS();
1538 }
1539
test_seal_merge_and_split(void)1540 static void test_seal_merge_and_split(void)
1541 {
1542 void *ptr;
1543 unsigned long page_size = getpagesize();
1544 unsigned long size;
1545 int ret;
1546 int prot;
1547
1548 /* (24 RO) */
1549 setup_single_address(24 * page_size, &ptr);
1550 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1551
1552 /* use mprotect(NONE) to set out boundary */
1553 /* (1 NONE) (22 RO) (1 NONE) */
1554 ret = sys_mprotect(ptr, page_size, PROT_NONE);
1555 FAIL_TEST_IF_FALSE(!ret);
1556 ret = sys_mprotect(ptr + 23 * page_size, page_size, PROT_NONE);
1557 FAIL_TEST_IF_FALSE(!ret);
1558 size = get_vma_size(ptr + page_size, &prot);
1559 FAIL_TEST_IF_FALSE(size == 22 * page_size);
1560 FAIL_TEST_IF_FALSE(prot == 4);
1561
1562 /* use mseal to split from beginning */
1563 /* (1 NONE) (1 RO_SEAL) (21 RO) (1 NONE) */
1564 ret = sys_mseal(ptr + page_size, page_size);
1565 FAIL_TEST_IF_FALSE(!ret);
1566 size = get_vma_size(ptr + page_size, &prot);
1567 FAIL_TEST_IF_FALSE(size == page_size);
1568 FAIL_TEST_IF_FALSE(prot == 0x4);
1569 size = get_vma_size(ptr + 2 * page_size, &prot);
1570 FAIL_TEST_IF_FALSE(size == 21 * page_size);
1571 FAIL_TEST_IF_FALSE(prot == 0x4);
1572
1573 /* use mseal to split from the end. */
1574 /* (1 NONE) (1 RO_SEAL) (20 RO) (1 RO_SEAL) (1 NONE) */
1575 ret = sys_mseal(ptr + 22 * page_size, page_size);
1576 FAIL_TEST_IF_FALSE(!ret);
1577 size = get_vma_size(ptr + 22 * page_size, &prot);
1578 FAIL_TEST_IF_FALSE(size == page_size);
1579 FAIL_TEST_IF_FALSE(prot == 0x4);
1580 size = get_vma_size(ptr + 2 * page_size, &prot);
1581 FAIL_TEST_IF_FALSE(size == 20 * page_size);
1582 FAIL_TEST_IF_FALSE(prot == 0x4);
1583
1584 /* merge with prev. */
1585 /* (1 NONE) (2 RO_SEAL) (19 RO) (1 RO_SEAL) (1 NONE) */
1586 ret = sys_mseal(ptr + 2 * page_size, page_size);
1587 FAIL_TEST_IF_FALSE(!ret);
1588 size = get_vma_size(ptr + page_size, &prot);
1589 FAIL_TEST_IF_FALSE(size == 2 * page_size);
1590 FAIL_TEST_IF_FALSE(prot == 0x4);
1591
1592 /* merge with after. */
1593 /* (1 NONE) (2 RO_SEAL) (18 RO) (2 RO_SEALS) (1 NONE) */
1594 ret = sys_mseal(ptr + 21 * page_size, page_size);
1595 FAIL_TEST_IF_FALSE(!ret);
1596 size = get_vma_size(ptr + 21 * page_size, &prot);
1597 FAIL_TEST_IF_FALSE(size == 2 * page_size);
1598 FAIL_TEST_IF_FALSE(prot == 0x4);
1599
1600 /* split and merge from prev */
1601 /* (1 NONE) (3 RO_SEAL) (17 RO) (2 RO_SEALS) (1 NONE) */
1602 ret = sys_mseal(ptr + 2 * page_size, 2 * page_size);
1603 FAIL_TEST_IF_FALSE(!ret);
1604 size = get_vma_size(ptr + 1 * page_size, &prot);
1605 FAIL_TEST_IF_FALSE(size == 3 * page_size);
1606 FAIL_TEST_IF_FALSE(prot == 0x4);
1607 ret = sys_munmap(ptr + page_size, page_size);
1608 FAIL_TEST_IF_FALSE(ret < 0);
1609 ret = sys_mprotect(ptr + 2 * page_size, page_size, PROT_NONE);
1610 FAIL_TEST_IF_FALSE(ret < 0);
1611
1612 /* split and merge from next */
1613 /* (1 NONE) (3 RO_SEAL) (16 RO) (3 RO_SEALS) (1 NONE) */
1614 ret = sys_mseal(ptr + 20 * page_size, 2 * page_size);
1615 FAIL_TEST_IF_FALSE(!ret);
1616 FAIL_TEST_IF_FALSE(prot == 0x4);
1617 size = get_vma_size(ptr + 20 * page_size, &prot);
1618 FAIL_TEST_IF_FALSE(size == 3 * page_size);
1619 FAIL_TEST_IF_FALSE(prot == 0x4);
1620
1621 /* merge from middle of prev and middle of next. */
1622 /* (1 NONE) (22 RO_SEAL) (1 NONE) */
1623 ret = sys_mseal(ptr + 2 * page_size, 20 * page_size);
1624 FAIL_TEST_IF_FALSE(!ret);
1625 size = get_vma_size(ptr + page_size, &prot);
1626 FAIL_TEST_IF_FALSE(size == 22 * page_size);
1627 FAIL_TEST_IF_FALSE(prot == 0x4);
1628
1629 REPORT_TEST_PASS();
1630 }
1631
test_seal_discard_ro_anon_on_rw(bool seal)1632 static void test_seal_discard_ro_anon_on_rw(bool seal)
1633 {
1634 void *ptr;
1635 unsigned long page_size = getpagesize();
1636 unsigned long size = 4 * page_size;
1637 int ret;
1638
1639 setup_single_address_rw(size, &ptr);
1640 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1641
1642 if (seal) {
1643 ret = sys_mseal(ptr, size);
1644 FAIL_TEST_IF_FALSE(!ret);
1645 }
1646
1647 /* sealing doesn't take effect on RW memory. */
1648 ret = sys_madvise(ptr, size, MADV_DONTNEED);
1649 FAIL_TEST_IF_FALSE(!ret);
1650
1651 /* base seal still apply. */
1652 ret = sys_munmap(ptr, size);
1653 if (seal)
1654 FAIL_TEST_IF_FALSE(ret < 0);
1655 else
1656 FAIL_TEST_IF_FALSE(!ret);
1657
1658 REPORT_TEST_PASS();
1659 }
1660
test_seal_discard_ro_anon_on_pkey(bool seal)1661 static void test_seal_discard_ro_anon_on_pkey(bool seal)
1662 {
1663 void *ptr;
1664 unsigned long page_size = getpagesize();
1665 unsigned long size = 4 * page_size;
1666 int ret;
1667 int pkey;
1668
1669 SKIP_TEST_IF_FALSE(pkey_supported());
1670
1671 setup_single_address_rw(size, &ptr);
1672 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1673
1674 pkey = sys_pkey_alloc(0, 0);
1675 FAIL_TEST_IF_FALSE(pkey > 0);
1676
1677 ret = sys_mprotect_pkey((void *)ptr, size, PROT_READ | PROT_WRITE, pkey);
1678 FAIL_TEST_IF_FALSE(!ret);
1679
1680 if (seal) {
1681 ret = sys_mseal(ptr, size);
1682 FAIL_TEST_IF_FALSE(!ret);
1683 }
1684
1685 /* sealing doesn't take effect if PKRU allow write. */
1686 set_pkey(pkey, 0);
1687 ret = sys_madvise(ptr, size, MADV_DONTNEED);
1688 FAIL_TEST_IF_FALSE(!ret);
1689
1690 /* sealing will take effect if PKRU deny write. */
1691 set_pkey(pkey, PKEY_DISABLE_WRITE);
1692 ret = sys_madvise(ptr, size, MADV_DONTNEED);
1693 if (seal)
1694 FAIL_TEST_IF_FALSE(ret < 0);
1695 else
1696 FAIL_TEST_IF_FALSE(!ret);
1697
1698 /* base seal still apply. */
1699 ret = sys_munmap(ptr, size);
1700 if (seal)
1701 FAIL_TEST_IF_FALSE(ret < 0);
1702 else
1703 FAIL_TEST_IF_FALSE(!ret);
1704
1705 REPORT_TEST_PASS();
1706 }
1707
test_seal_discard_ro_anon_on_filebacked(bool seal)1708 static void test_seal_discard_ro_anon_on_filebacked(bool seal)
1709 {
1710 void *ptr;
1711 unsigned long page_size = getpagesize();
1712 unsigned long size = 4 * page_size;
1713 int ret;
1714 int fd;
1715 unsigned long mapflags = MAP_PRIVATE;
1716
1717 fd = memfd_create("test", 0);
1718 FAIL_TEST_IF_FALSE(fd > 0);
1719
1720 ret = fallocate(fd, 0, 0, size);
1721 FAIL_TEST_IF_FALSE(!ret);
1722
1723 ptr = mmap(NULL, size, PROT_READ, mapflags, fd, 0);
1724 FAIL_TEST_IF_FALSE(ptr != MAP_FAILED);
1725
1726 if (seal) {
1727 ret = sys_mseal(ptr, size);
1728 FAIL_TEST_IF_FALSE(!ret);
1729 }
1730
1731 /* sealing doesn't apply for file backed mapping. */
1732 ret = sys_madvise(ptr, size, MADV_DONTNEED);
1733 FAIL_TEST_IF_FALSE(!ret);
1734
1735 ret = sys_munmap(ptr, size);
1736 if (seal)
1737 FAIL_TEST_IF_FALSE(ret < 0);
1738 else
1739 FAIL_TEST_IF_FALSE(!ret);
1740 close(fd);
1741
1742 REPORT_TEST_PASS();
1743 }
1744
test_seal_discard_ro_anon_on_shared(bool seal)1745 static void test_seal_discard_ro_anon_on_shared(bool seal)
1746 {
1747 void *ptr;
1748 unsigned long page_size = getpagesize();
1749 unsigned long size = 4 * page_size;
1750 int ret;
1751 unsigned long mapflags = MAP_ANONYMOUS | MAP_SHARED;
1752
1753 ptr = mmap(NULL, size, PROT_READ, mapflags, -1, 0);
1754 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1755
1756 if (seal) {
1757 ret = sys_mseal(ptr, size);
1758 FAIL_TEST_IF_FALSE(!ret);
1759 }
1760
1761 /* sealing doesn't apply for shared mapping. */
1762 ret = sys_madvise(ptr, size, MADV_DONTNEED);
1763 FAIL_TEST_IF_FALSE(!ret);
1764
1765 ret = sys_munmap(ptr, size);
1766 if (seal)
1767 FAIL_TEST_IF_FALSE(ret < 0);
1768 else
1769 FAIL_TEST_IF_FALSE(!ret);
1770
1771 REPORT_TEST_PASS();
1772 }
1773
test_seal_discard_ro_anon(bool seal)1774 static void test_seal_discard_ro_anon(bool seal)
1775 {
1776 void *ptr;
1777 unsigned long page_size = getpagesize();
1778 unsigned long size = 4 * page_size;
1779 int ret;
1780
1781 setup_single_address(size, &ptr);
1782 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1783
1784 if (seal) {
1785 ret = seal_single_address(ptr, size);
1786 FAIL_TEST_IF_FALSE(!ret);
1787 }
1788
1789 ret = sys_madvise(ptr, size, MADV_DONTNEED);
1790 if (seal)
1791 FAIL_TEST_IF_FALSE(ret < 0);
1792 else
1793 FAIL_TEST_IF_FALSE(!ret);
1794
1795 ret = sys_munmap(ptr, size);
1796 if (seal)
1797 FAIL_TEST_IF_FALSE(ret < 0);
1798 else
1799 FAIL_TEST_IF_FALSE(!ret);
1800
1801 REPORT_TEST_PASS();
1802 }
1803
test_seal_discard_across_vmas(bool seal)1804 static void test_seal_discard_across_vmas(bool seal)
1805 {
1806 void *ptr;
1807 unsigned long page_size = getpagesize();
1808 unsigned long size = 2 * page_size;
1809 int ret;
1810
1811 setup_single_address(size, &ptr);
1812 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1813
1814 if (seal) {
1815 ret = seal_single_address(ptr + page_size, page_size);
1816 FAIL_TEST_IF_FALSE(!ret);
1817 }
1818
1819 ret = sys_madvise(ptr, size, MADV_DONTNEED);
1820 if (seal)
1821 FAIL_TEST_IF_FALSE(ret < 0);
1822 else
1823 FAIL_TEST_IF_FALSE(!ret);
1824
1825 ret = sys_munmap(ptr, size);
1826 if (seal)
1827 FAIL_TEST_IF_FALSE(ret < 0);
1828 else
1829 FAIL_TEST_IF_FALSE(!ret);
1830
1831 REPORT_TEST_PASS();
1832 }
1833
1834
test_seal_madvise_nodiscard(bool seal)1835 static void test_seal_madvise_nodiscard(bool seal)
1836 {
1837 void *ptr;
1838 unsigned long page_size = getpagesize();
1839 unsigned long size = 4 * page_size;
1840 int ret;
1841
1842 setup_single_address(size, &ptr);
1843 FAIL_TEST_IF_FALSE(ptr != (void *)-1);
1844
1845 if (seal) {
1846 ret = seal_single_address(ptr, size);
1847 FAIL_TEST_IF_FALSE(!ret);
1848 }
1849
1850 /*
1851 * Test a random madvise flag like MADV_RANDOM that does not touch page
1852 * contents (and thus should work for msealed VMAs). RANDOM also happens to
1853 * share bits with other discard-ish flags like REMOVE.
1854 */
1855 ret = sys_madvise(ptr, size, MADV_RANDOM);
1856 FAIL_TEST_IF_FALSE(!ret);
1857
1858 ret = sys_munmap(ptr, size);
1859 if (seal)
1860 FAIL_TEST_IF_FALSE(ret < 0);
1861 else
1862 FAIL_TEST_IF_FALSE(!ret);
1863
1864 REPORT_TEST_PASS();
1865 }
1866
main(int argc,char ** argv)1867 int main(int argc, char **argv)
1868 {
1869 bool test_seal = seal_support();
1870
1871 ksft_print_header();
1872
1873 if (!test_seal)
1874 ksft_exit_skip("sealing not supported, check CONFIG_64BIT\n");
1875
1876 if (!pkey_supported())
1877 ksft_print_msg("PKEY not supported\n");
1878
1879 ksft_set_plan(88);
1880
1881 test_seal_addseal();
1882 test_seal_unmapped_start();
1883 test_seal_unmapped_middle();
1884 test_seal_unmapped_end();
1885 test_seal_multiple_vmas();
1886 test_seal_split_start();
1887 test_seal_split_end();
1888 test_seal_invalid_input();
1889 test_seal_zero_length();
1890 test_seal_twice();
1891
1892 test_seal_mprotect(false);
1893 test_seal_mprotect(true);
1894
1895 test_seal_start_mprotect(false);
1896 test_seal_start_mprotect(true);
1897
1898 test_seal_end_mprotect(false);
1899 test_seal_end_mprotect(true);
1900
1901 test_seal_mprotect_unalign_len(false);
1902 test_seal_mprotect_unalign_len(true);
1903
1904 test_seal_mprotect_unalign_len_variant_2(false);
1905 test_seal_mprotect_unalign_len_variant_2(true);
1906
1907 test_seal_mprotect_two_vma(false);
1908 test_seal_mprotect_two_vma(true);
1909
1910 test_seal_mprotect_two_vma_with_split(false);
1911 test_seal_mprotect_two_vma_with_split(true);
1912
1913 test_seal_mprotect_partial_mprotect(false);
1914 test_seal_mprotect_partial_mprotect(true);
1915
1916 test_seal_mprotect_two_vma_with_gap(false);
1917 test_seal_mprotect_two_vma_with_gap(true);
1918
1919 test_seal_mprotect_merge(false);
1920 test_seal_mprotect_merge(true);
1921
1922 test_seal_mprotect_split(false);
1923 test_seal_mprotect_split(true);
1924
1925 test_seal_mprotect_partial_mprotect_tail(false);
1926 test_seal_mprotect_partial_mprotect_tail(true);
1927
1928 test_seal_munmap(false);
1929 test_seal_munmap(true);
1930 test_seal_munmap_two_vma(false);
1931 test_seal_munmap_two_vma(true);
1932 test_seal_munmap_vma_with_gap(false);
1933 test_seal_munmap_vma_with_gap(true);
1934 test_seal_munmap_partial_across_vmas(false);
1935 test_seal_munmap_partial_across_vmas(true);
1936
1937 test_munmap_start_freed(false);
1938 test_munmap_start_freed(true);
1939 test_munmap_middle_freed(false);
1940 test_munmap_middle_freed(true);
1941 test_munmap_end_freed(false);
1942 test_munmap_end_freed(true);
1943
1944 test_seal_mremap_shrink(false);
1945 test_seal_mremap_shrink(true);
1946 test_seal_mremap_expand(false);
1947 test_seal_mremap_expand(true);
1948 test_seal_mremap_move(false);
1949 test_seal_mremap_move(true);
1950
1951 test_seal_mremap_shrink_fixed(false);
1952 test_seal_mremap_shrink_fixed(true);
1953 test_seal_mremap_expand_fixed(false);
1954 test_seal_mremap_expand_fixed(true);
1955 test_seal_mremap_move_fixed(false);
1956 test_seal_mremap_move_fixed(true);
1957 test_seal_mremap_move_dontunmap(false);
1958 test_seal_mremap_move_dontunmap(true);
1959 test_seal_mremap_move_fixed_zero(false);
1960 test_seal_mremap_move_fixed_zero(true);
1961 test_seal_mremap_move_dontunmap_anyaddr(false);
1962 test_seal_mremap_move_dontunmap_anyaddr(true);
1963 test_seal_madvise_nodiscard(false);
1964 test_seal_madvise_nodiscard(true);
1965 test_seal_discard_ro_anon(false);
1966 test_seal_discard_ro_anon(true);
1967 test_seal_discard_across_vmas(false);
1968 test_seal_discard_across_vmas(true);
1969 test_seal_discard_ro_anon_on_rw(false);
1970 test_seal_discard_ro_anon_on_rw(true);
1971 test_seal_discard_ro_anon_on_shared(false);
1972 test_seal_discard_ro_anon_on_shared(true);
1973 test_seal_discard_ro_anon_on_filebacked(false);
1974 test_seal_discard_ro_anon_on_filebacked(true);
1975 test_seal_mmap_overwrite_prot(false);
1976 test_seal_mmap_overwrite_prot(true);
1977 test_seal_mmap_expand(false);
1978 test_seal_mmap_expand(true);
1979 test_seal_mmap_shrink(false);
1980 test_seal_mmap_shrink(true);
1981
1982 test_seal_merge_and_split();
1983 test_seal_zero_address();
1984
1985 test_seal_discard_ro_anon_on_pkey(false);
1986 test_seal_discard_ro_anon_on_pkey(true);
1987
1988 ksft_finished();
1989 }
1990