1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 #define _GNU_SOURCE
4 #include "../kselftest_harness.h"
5 #include <asm-generic/mman.h> /* Force the import of the tools version. */
6 #include <assert.h>
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <linux/limits.h>
10 #include <linux/userfaultfd.h>
11 #include <setjmp.h>
12 #include <signal.h>
13 #include <stdbool.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <sys/ioctl.h>
18 #include <sys/mman.h>
19 #include <sys/syscall.h>
20 #include <sys/uio.h>
21 #include <unistd.h>
22 #include "vm_util.h"
23 
24 #include "../pidfd/pidfd.h"
25 
26 /*
27  * Ignore the checkpatch warning, as per the C99 standard, section 7.14.1.1:
28  *
29  * "If the signal occurs other than as the result of calling the abort or raise
30  *  function, the behavior is undefined if the signal handler refers to any
31  *  object with static storage duration other than by assigning a value to an
32  *  object declared as volatile sig_atomic_t"
33  */
34 static volatile sig_atomic_t signal_jump_set;
35 static sigjmp_buf signal_jmp_buf;
36 
37 /*
38  * Ignore the checkpatch warning, we must read from x but don't want to do
39  * anything with it in order to trigger a read page fault. We therefore must use
40  * volatile to stop the compiler from optimising this away.
41  */
42 #define FORCE_READ(x) (*(volatile typeof(x) *)x)
43 
44 /*
45  * How is the test backing the mapping being tested?
46  */
47 enum backing_type {
48 	ANON_BACKED,
49 	SHMEM_BACKED,
50 	LOCAL_FILE_BACKED,
51 };
52 
FIXTURE(guard_regions)53 FIXTURE(guard_regions)
54 {
55 	unsigned long page_size;
56 	char path[PATH_MAX];
57 	int fd;
58 };
59 
FIXTURE_VARIANT(guard_regions)60 FIXTURE_VARIANT(guard_regions)
61 {
62 	enum backing_type backing;
63 };
64 
FIXTURE_VARIANT_ADD(guard_regions,anon)65 FIXTURE_VARIANT_ADD(guard_regions, anon)
66 {
67 	.backing = ANON_BACKED,
68 };
69 
FIXTURE_VARIANT_ADD(guard_regions,shmem)70 FIXTURE_VARIANT_ADD(guard_regions, shmem)
71 {
72 	.backing = SHMEM_BACKED,
73 };
74 
FIXTURE_VARIANT_ADD(guard_regions,file)75 FIXTURE_VARIANT_ADD(guard_regions, file)
76 {
77 	.backing = LOCAL_FILE_BACKED,
78 };
79 
is_anon_backed(const FIXTURE_VARIANT (guard_regions)* variant)80 static bool is_anon_backed(const FIXTURE_VARIANT(guard_regions) * variant)
81 {
82 	switch (variant->backing) {
83 	case  ANON_BACKED:
84 	case  SHMEM_BACKED:
85 		return true;
86 	default:
87 		return false;
88 	}
89 }
90 
mmap_(FIXTURE_DATA (guard_regions)* self,const FIXTURE_VARIANT (guard_regions)* variant,void * addr,size_t length,int prot,int extra_flags,off_t offset)91 static void *mmap_(FIXTURE_DATA(guard_regions) * self,
92 		   const FIXTURE_VARIANT(guard_regions) * variant,
93 		   void *addr, size_t length, int prot, int extra_flags,
94 		   off_t offset)
95 {
96 	int fd;
97 	int flags = extra_flags;
98 
99 	switch (variant->backing) {
100 	case ANON_BACKED:
101 		flags |= MAP_PRIVATE | MAP_ANON;
102 		fd = -1;
103 		break;
104 	case SHMEM_BACKED:
105 	case LOCAL_FILE_BACKED:
106 		flags |= MAP_SHARED;
107 		fd = self->fd;
108 		break;
109 	default:
110 		ksft_exit_fail();
111 		break;
112 	}
113 
114 	return mmap(addr, length, prot, flags, fd, offset);
115 }
116 
userfaultfd(int flags)117 static int userfaultfd(int flags)
118 {
119 	return syscall(SYS_userfaultfd, flags);
120 }
121 
handle_fatal(int c)122 static void handle_fatal(int c)
123 {
124 	if (!signal_jump_set)
125 		return;
126 
127 	siglongjmp(signal_jmp_buf, c);
128 }
129 
sys_process_madvise(int pidfd,const struct iovec * iovec,size_t n,int advice,unsigned int flags)130 static ssize_t sys_process_madvise(int pidfd, const struct iovec *iovec,
131 				   size_t n, int advice, unsigned int flags)
132 {
133 	return syscall(__NR_process_madvise, pidfd, iovec, n, advice, flags);
134 }
135 
136 /*
137  * Enable our signal catcher and try to read/write the specified buffer. The
138  * return value indicates whether the read/write succeeds without a fatal
139  * signal.
140  */
try_access_buf(char * ptr,bool write)141 static bool try_access_buf(char *ptr, bool write)
142 {
143 	bool failed;
144 
145 	/* Tell signal handler to jump back here on fatal signal. */
146 	signal_jump_set = true;
147 	/* If a fatal signal arose, we will jump back here and failed is set. */
148 	failed = sigsetjmp(signal_jmp_buf, 0) != 0;
149 
150 	if (!failed) {
151 		if (write)
152 			*ptr = 'x';
153 		else
154 			FORCE_READ(ptr);
155 	}
156 
157 	signal_jump_set = false;
158 	return !failed;
159 }
160 
161 /* Try and read from a buffer, return true if no fatal signal. */
try_read_buf(char * ptr)162 static bool try_read_buf(char *ptr)
163 {
164 	return try_access_buf(ptr, false);
165 }
166 
167 /* Try and write to a buffer, return true if no fatal signal. */
try_write_buf(char * ptr)168 static bool try_write_buf(char *ptr)
169 {
170 	return try_access_buf(ptr, true);
171 }
172 
173 /*
174  * Try and BOTH read from AND write to a buffer, return true if BOTH operations
175  * succeed.
176  */
try_read_write_buf(char * ptr)177 static bool try_read_write_buf(char *ptr)
178 {
179 	return try_read_buf(ptr) && try_write_buf(ptr);
180 }
181 
setup_sighandler(void)182 static void setup_sighandler(void)
183 {
184 	struct sigaction act = {
185 		.sa_handler = &handle_fatal,
186 		.sa_flags = SA_NODEFER,
187 	};
188 
189 	sigemptyset(&act.sa_mask);
190 	if (sigaction(SIGSEGV, &act, NULL))
191 		ksft_exit_fail_perror("sigaction");
192 }
193 
teardown_sighandler(void)194 static void teardown_sighandler(void)
195 {
196 	struct sigaction act = {
197 		.sa_handler = SIG_DFL,
198 		.sa_flags = SA_NODEFER,
199 	};
200 
201 	sigemptyset(&act.sa_mask);
202 	sigaction(SIGSEGV, &act, NULL);
203 }
204 
open_file(const char * prefix,char * path)205 static int open_file(const char *prefix, char *path)
206 {
207 	int fd;
208 
209 	snprintf(path, PATH_MAX, "%sguard_regions_test_file_XXXXXX", prefix);
210 	fd = mkstemp(path);
211 	if (fd < 0)
212 		ksft_exit_fail_perror("mkstemp");
213 
214 	return fd;
215 }
216 
217 /* Establish a varying pattern in a buffer. */
set_pattern(char * ptr,size_t num_pages,size_t page_size)218 static void set_pattern(char *ptr, size_t num_pages, size_t page_size)
219 {
220 	size_t i;
221 
222 	for (i = 0; i < num_pages; i++) {
223 		char *ptr2 = &ptr[i * page_size];
224 
225 		memset(ptr2, 'a' + (i % 26), page_size);
226 	}
227 }
228 
229 /*
230  * Check that a buffer contains the pattern set by set_pattern(), starting at a
231  * page offset of pgoff within the buffer.
232  */
check_pattern_offset(char * ptr,size_t num_pages,size_t page_size,size_t pgoff)233 static bool check_pattern_offset(char *ptr, size_t num_pages, size_t page_size,
234 				 size_t pgoff)
235 {
236 	size_t i;
237 
238 	for (i = 0; i < num_pages * page_size; i++) {
239 		size_t offset = pgoff * page_size + i;
240 		char actual = ptr[offset];
241 		char expected = 'a' + ((offset / page_size) % 26);
242 
243 		if (actual != expected)
244 			return false;
245 	}
246 
247 	return true;
248 }
249 
250 /* Check that a buffer contains the pattern set by set_pattern(). */
check_pattern(char * ptr,size_t num_pages,size_t page_size)251 static bool check_pattern(char *ptr, size_t num_pages, size_t page_size)
252 {
253 	return check_pattern_offset(ptr, num_pages, page_size, 0);
254 }
255 
256 /* Determine if a buffer contains only repetitions of a specified char. */
is_buf_eq(char * buf,size_t size,char chr)257 static bool is_buf_eq(char *buf, size_t size, char chr)
258 {
259 	size_t i;
260 
261 	for (i = 0; i < size; i++) {
262 		if (buf[i] != chr)
263 			return false;
264 	}
265 
266 	return true;
267 }
268 
FIXTURE_SETUP(guard_regions)269 FIXTURE_SETUP(guard_regions)
270 {
271 	self->page_size = (unsigned long)sysconf(_SC_PAGESIZE);
272 	setup_sighandler();
273 
274 	switch (variant->backing) {
275 	case ANON_BACKED:
276 		return;
277 	case LOCAL_FILE_BACKED:
278 		self->fd = open_file("", self->path);
279 		break;
280 	case SHMEM_BACKED:
281 		self->fd = memfd_create(self->path, 0);
282 		break;
283 	}
284 
285 	/* We truncate file to at least 100 pages, tests can modify as needed. */
286 	ASSERT_EQ(ftruncate(self->fd, 100 * self->page_size), 0);
287 };
288 
FIXTURE_TEARDOWN_PARENT(guard_regions)289 FIXTURE_TEARDOWN_PARENT(guard_regions)
290 {
291 	teardown_sighandler();
292 
293 	if (variant->backing == ANON_BACKED)
294 		return;
295 
296 	if (self->fd >= 0)
297 		close(self->fd);
298 
299 	if (self->path[0] != '\0')
300 		unlink(self->path);
301 }
302 
TEST_F(guard_regions,basic)303 TEST_F(guard_regions, basic)
304 {
305 	const unsigned long NUM_PAGES = 10;
306 	const unsigned long page_size = self->page_size;
307 	char *ptr;
308 	int i;
309 
310 	ptr = mmap_(self, variant, NULL, NUM_PAGES * page_size,
311 		    PROT_READ | PROT_WRITE, 0, 0);
312 	ASSERT_NE(ptr, MAP_FAILED);
313 
314 	/* Trivially assert we can touch the first page. */
315 	ASSERT_TRUE(try_read_write_buf(ptr));
316 
317 	ASSERT_EQ(madvise(ptr, page_size, MADV_GUARD_INSTALL), 0);
318 
319 	/* Establish that 1st page SIGSEGV's. */
320 	ASSERT_FALSE(try_read_write_buf(ptr));
321 
322 	/* Ensure we can touch everything else.*/
323 	for (i = 1; i < NUM_PAGES; i++) {
324 		char *curr = &ptr[i * page_size];
325 
326 		ASSERT_TRUE(try_read_write_buf(curr));
327 	}
328 
329 	/* Establish a guard page at the end of the mapping. */
330 	ASSERT_EQ(madvise(&ptr[(NUM_PAGES - 1) * page_size], page_size,
331 			  MADV_GUARD_INSTALL), 0);
332 
333 	/* Check that both guard pages result in SIGSEGV. */
334 	ASSERT_FALSE(try_read_write_buf(ptr));
335 	ASSERT_FALSE(try_read_write_buf(&ptr[(NUM_PAGES - 1) * page_size]));
336 
337 	/* Remove the first guard page. */
338 	ASSERT_FALSE(madvise(ptr, page_size, MADV_GUARD_REMOVE));
339 
340 	/* Make sure we can touch it. */
341 	ASSERT_TRUE(try_read_write_buf(ptr));
342 
343 	/* Remove the last guard page. */
344 	ASSERT_FALSE(madvise(&ptr[(NUM_PAGES - 1) * page_size], page_size,
345 			     MADV_GUARD_REMOVE));
346 
347 	/* Make sure we can touch it. */
348 	ASSERT_TRUE(try_read_write_buf(&ptr[(NUM_PAGES - 1) * page_size]));
349 
350 	/*
351 	 *  Test setting a _range_ of pages, namely the first 3. The first of
352 	 *  these be faulted in, so this also tests that we can install guard
353 	 *  pages over backed pages.
354 	 */
355 	ASSERT_EQ(madvise(ptr, 3 * page_size, MADV_GUARD_INSTALL), 0);
356 
357 	/* Make sure they are all guard pages. */
358 	for (i = 0; i < 3; i++) {
359 		char *curr = &ptr[i * page_size];
360 
361 		ASSERT_FALSE(try_read_write_buf(curr));
362 	}
363 
364 	/* Make sure the rest are not. */
365 	for (i = 3; i < NUM_PAGES; i++) {
366 		char *curr = &ptr[i * page_size];
367 
368 		ASSERT_TRUE(try_read_write_buf(curr));
369 	}
370 
371 	/* Remove guard pages. */
372 	ASSERT_EQ(madvise(ptr, NUM_PAGES * page_size, MADV_GUARD_REMOVE), 0);
373 
374 	/* Now make sure we can touch everything. */
375 	for (i = 0; i < NUM_PAGES; i++) {
376 		char *curr = &ptr[i * page_size];
377 
378 		ASSERT_TRUE(try_read_write_buf(curr));
379 	}
380 
381 	/*
382 	 * Now remove all guard pages, make sure we don't remove existing
383 	 * entries.
384 	 */
385 	ASSERT_EQ(madvise(ptr, NUM_PAGES * page_size, MADV_GUARD_REMOVE), 0);
386 
387 	for (i = 0; i < NUM_PAGES * page_size; i += page_size) {
388 		char chr = ptr[i];
389 
390 		ASSERT_EQ(chr, 'x');
391 	}
392 
393 	ASSERT_EQ(munmap(ptr, NUM_PAGES * page_size), 0);
394 }
395 
396 /* Assert that operations applied across multiple VMAs work as expected. */
TEST_F(guard_regions,multi_vma)397 TEST_F(guard_regions, multi_vma)
398 {
399 	const unsigned long page_size = self->page_size;
400 	char *ptr_region, *ptr, *ptr1, *ptr2, *ptr3;
401 	int i;
402 
403 	/* Reserve a 100 page region over which we can install VMAs. */
404 	ptr_region = mmap_(self, variant, NULL, 100 * page_size,
405 			   PROT_NONE, 0, 0);
406 	ASSERT_NE(ptr_region, MAP_FAILED);
407 
408 	/* Place a VMA of 10 pages size at the start of the region. */
409 	ptr1 = mmap_(self, variant, ptr_region, 10 * page_size,
410 		     PROT_READ | PROT_WRITE, MAP_FIXED, 0);
411 	ASSERT_NE(ptr1, MAP_FAILED);
412 
413 	/* Place a VMA of 5 pages size 50 pages into the region. */
414 	ptr2 = mmap_(self, variant, &ptr_region[50 * page_size], 5 * page_size,
415 		     PROT_READ | PROT_WRITE, MAP_FIXED, 0);
416 	ASSERT_NE(ptr2, MAP_FAILED);
417 
418 	/* Place a VMA of 20 pages size at the end of the region. */
419 	ptr3 = mmap_(self, variant, &ptr_region[80 * page_size], 20 * page_size,
420 		     PROT_READ | PROT_WRITE, MAP_FIXED, 0);
421 	ASSERT_NE(ptr3, MAP_FAILED);
422 
423 	/* Unmap gaps. */
424 	ASSERT_EQ(munmap(&ptr_region[10 * page_size], 40 * page_size), 0);
425 	ASSERT_EQ(munmap(&ptr_region[55 * page_size], 25 * page_size), 0);
426 
427 	/*
428 	 * We end up with VMAs like this:
429 	 *
430 	 * 0    10 .. 50   55 .. 80   100
431 	 * [---]      [---]      [---]
432 	 */
433 
434 	/*
435 	 * Now mark the whole range as guard pages and make sure all VMAs are as
436 	 * such.
437 	 */
438 
439 	/*
440 	 * madvise() is certifiable and lets you perform operations over gaps,
441 	 * everything works, but it indicates an error and errno is set to
442 	 * -ENOMEM. Also if anything runs out of memory it is set to
443 	 * -ENOMEM. You are meant to guess which is which.
444 	 */
445 	ASSERT_EQ(madvise(ptr_region, 100 * page_size, MADV_GUARD_INSTALL), -1);
446 	ASSERT_EQ(errno, ENOMEM);
447 
448 	for (i = 0; i < 10; i++) {
449 		char *curr = &ptr1[i * page_size];
450 
451 		ASSERT_FALSE(try_read_write_buf(curr));
452 	}
453 
454 	for (i = 0; i < 5; i++) {
455 		char *curr = &ptr2[i * page_size];
456 
457 		ASSERT_FALSE(try_read_write_buf(curr));
458 	}
459 
460 	for (i = 0; i < 20; i++) {
461 		char *curr = &ptr3[i * page_size];
462 
463 		ASSERT_FALSE(try_read_write_buf(curr));
464 	}
465 
466 	/* Now remove guar pages over range and assert the opposite. */
467 
468 	ASSERT_EQ(madvise(ptr_region, 100 * page_size, MADV_GUARD_REMOVE), -1);
469 	ASSERT_EQ(errno, ENOMEM);
470 
471 	for (i = 0; i < 10; i++) {
472 		char *curr = &ptr1[i * page_size];
473 
474 		ASSERT_TRUE(try_read_write_buf(curr));
475 	}
476 
477 	for (i = 0; i < 5; i++) {
478 		char *curr = &ptr2[i * page_size];
479 
480 		ASSERT_TRUE(try_read_write_buf(curr));
481 	}
482 
483 	for (i = 0; i < 20; i++) {
484 		char *curr = &ptr3[i * page_size];
485 
486 		ASSERT_TRUE(try_read_write_buf(curr));
487 	}
488 
489 	/* Now map incompatible VMAs in the gaps. */
490 	ptr = mmap_(self, variant, &ptr_region[10 * page_size], 40 * page_size,
491 		    PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED, 0);
492 	ASSERT_NE(ptr, MAP_FAILED);
493 	ptr = mmap_(self, variant, &ptr_region[55 * page_size], 25 * page_size,
494 		    PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED, 0);
495 	ASSERT_NE(ptr, MAP_FAILED);
496 
497 	/*
498 	 * We end up with VMAs like this:
499 	 *
500 	 * 0    10 .. 50   55 .. 80   100
501 	 * [---][xxxx][---][xxxx][---]
502 	 *
503 	 * Where 'x' signifies VMAs that cannot be merged with those adjacent to
504 	 * them.
505 	 */
506 
507 	/* Multiple VMAs adjacent to one another should result in no error. */
508 	ASSERT_EQ(madvise(ptr_region, 100 * page_size, MADV_GUARD_INSTALL), 0);
509 	for (i = 0; i < 100; i++) {
510 		char *curr = &ptr_region[i * page_size];
511 
512 		ASSERT_FALSE(try_read_write_buf(curr));
513 	}
514 	ASSERT_EQ(madvise(ptr_region, 100 * page_size, MADV_GUARD_REMOVE), 0);
515 	for (i = 0; i < 100; i++) {
516 		char *curr = &ptr_region[i * page_size];
517 
518 		ASSERT_TRUE(try_read_write_buf(curr));
519 	}
520 
521 	/* Cleanup. */
522 	ASSERT_EQ(munmap(ptr_region, 100 * page_size), 0);
523 }
524 
525 /*
526  * Assert that batched operations performed using process_madvise() work as
527  * expected.
528  */
TEST_F(guard_regions,process_madvise)529 TEST_F(guard_regions, process_madvise)
530 {
531 	const unsigned long page_size = self->page_size;
532 	char *ptr_region, *ptr1, *ptr2, *ptr3;
533 	ssize_t count;
534 	struct iovec vec[6];
535 
536 	/* Reserve region to map over. */
537 	ptr_region = mmap_(self, variant, NULL, 100 * page_size,
538 			   PROT_NONE, 0, 0);
539 	ASSERT_NE(ptr_region, MAP_FAILED);
540 
541 	/*
542 	 * 10 pages offset 1 page into reserve region. We MAP_POPULATE so we
543 	 * overwrite existing entries and test this code path against
544 	 * overwriting existing entries.
545 	 */
546 	ptr1 = mmap_(self, variant, &ptr_region[page_size], 10 * page_size,
547 		     PROT_READ | PROT_WRITE, MAP_FIXED | MAP_POPULATE, 0);
548 	ASSERT_NE(ptr1, MAP_FAILED);
549 	/* We want guard markers at start/end of each VMA. */
550 	vec[0].iov_base = ptr1;
551 	vec[0].iov_len = page_size;
552 	vec[1].iov_base = &ptr1[9 * page_size];
553 	vec[1].iov_len = page_size;
554 
555 	/* 5 pages offset 50 pages into reserve region. */
556 	ptr2 = mmap_(self, variant, &ptr_region[50 * page_size], 5 * page_size,
557 		     PROT_READ | PROT_WRITE, MAP_FIXED, 0);
558 	ASSERT_NE(ptr2, MAP_FAILED);
559 	vec[2].iov_base = ptr2;
560 	vec[2].iov_len = page_size;
561 	vec[3].iov_base = &ptr2[4 * page_size];
562 	vec[3].iov_len = page_size;
563 
564 	/* 20 pages offset 79 pages into reserve region. */
565 	ptr3 = mmap_(self, variant, &ptr_region[79 * page_size], 20 * page_size,
566 		    PROT_READ | PROT_WRITE, MAP_FIXED, 0);
567 	ASSERT_NE(ptr3, MAP_FAILED);
568 	vec[4].iov_base = ptr3;
569 	vec[4].iov_len = page_size;
570 	vec[5].iov_base = &ptr3[19 * page_size];
571 	vec[5].iov_len = page_size;
572 
573 	/* Free surrounding VMAs. */
574 	ASSERT_EQ(munmap(ptr_region, page_size), 0);
575 	ASSERT_EQ(munmap(&ptr_region[11 * page_size], 39 * page_size), 0);
576 	ASSERT_EQ(munmap(&ptr_region[55 * page_size], 24 * page_size), 0);
577 	ASSERT_EQ(munmap(&ptr_region[99 * page_size], page_size), 0);
578 
579 	/* Now guard in one step. */
580 	count = sys_process_madvise(PIDFD_SELF, vec, 6, MADV_GUARD_INSTALL, 0);
581 
582 	/* OK we don't have permission to do this, skip. */
583 	if (count == -1 && errno == EPERM)
584 		ksft_exit_skip("No process_madvise() permissions, try running as root.\n");
585 
586 	/* Returns the number of bytes advised. */
587 	ASSERT_EQ(count, 6 * page_size);
588 
589 	/* Now make sure the guarding was applied. */
590 
591 	ASSERT_FALSE(try_read_write_buf(ptr1));
592 	ASSERT_FALSE(try_read_write_buf(&ptr1[9 * page_size]));
593 
594 	ASSERT_FALSE(try_read_write_buf(ptr2));
595 	ASSERT_FALSE(try_read_write_buf(&ptr2[4 * page_size]));
596 
597 	ASSERT_FALSE(try_read_write_buf(ptr3));
598 	ASSERT_FALSE(try_read_write_buf(&ptr3[19 * page_size]));
599 
600 	/* Now do the same with unguard... */
601 	count = sys_process_madvise(PIDFD_SELF, vec, 6, MADV_GUARD_REMOVE, 0);
602 
603 	/* ...and everything should now succeed. */
604 
605 	ASSERT_TRUE(try_read_write_buf(ptr1));
606 	ASSERT_TRUE(try_read_write_buf(&ptr1[9 * page_size]));
607 
608 	ASSERT_TRUE(try_read_write_buf(ptr2));
609 	ASSERT_TRUE(try_read_write_buf(&ptr2[4 * page_size]));
610 
611 	ASSERT_TRUE(try_read_write_buf(ptr3));
612 	ASSERT_TRUE(try_read_write_buf(&ptr3[19 * page_size]));
613 
614 	/* Cleanup. */
615 	ASSERT_EQ(munmap(ptr1, 10 * page_size), 0);
616 	ASSERT_EQ(munmap(ptr2, 5 * page_size), 0);
617 	ASSERT_EQ(munmap(ptr3, 20 * page_size), 0);
618 }
619 
620 /* Assert that unmapping ranges does not leave guard markers behind. */
TEST_F(guard_regions,munmap)621 TEST_F(guard_regions, munmap)
622 {
623 	const unsigned long page_size = self->page_size;
624 	char *ptr, *ptr_new1, *ptr_new2;
625 
626 	ptr = mmap_(self, variant, NULL, 10 * page_size,
627 		    PROT_READ | PROT_WRITE, 0, 0);
628 	ASSERT_NE(ptr, MAP_FAILED);
629 
630 	/* Guard first and last pages. */
631 	ASSERT_EQ(madvise(ptr, page_size, MADV_GUARD_INSTALL), 0);
632 	ASSERT_EQ(madvise(&ptr[9 * page_size], page_size, MADV_GUARD_INSTALL), 0);
633 
634 	/* Assert that they are guarded. */
635 	ASSERT_FALSE(try_read_write_buf(ptr));
636 	ASSERT_FALSE(try_read_write_buf(&ptr[9 * page_size]));
637 
638 	/* Unmap them. */
639 	ASSERT_EQ(munmap(ptr, page_size), 0);
640 	ASSERT_EQ(munmap(&ptr[9 * page_size], page_size), 0);
641 
642 	/* Map over them.*/
643 	ptr_new1 = mmap_(self, variant, ptr, page_size, PROT_READ | PROT_WRITE,
644 			 MAP_FIXED, 0);
645 	ASSERT_NE(ptr_new1, MAP_FAILED);
646 	ptr_new2 = mmap_(self, variant, &ptr[9 * page_size], page_size,
647 			 PROT_READ | PROT_WRITE, MAP_FIXED, 0);
648 	ASSERT_NE(ptr_new2, MAP_FAILED);
649 
650 	/* Assert that they are now not guarded. */
651 	ASSERT_TRUE(try_read_write_buf(ptr_new1));
652 	ASSERT_TRUE(try_read_write_buf(ptr_new2));
653 
654 	/* Cleanup. */
655 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
656 }
657 
658 /* Assert that mprotect() operations have no bearing on guard markers. */
TEST_F(guard_regions,mprotect)659 TEST_F(guard_regions, mprotect)
660 {
661 	const unsigned long page_size = self->page_size;
662 	char *ptr;
663 	int i;
664 
665 	ptr = mmap_(self, variant, NULL, 10 * page_size,
666 		    PROT_READ | PROT_WRITE, 0, 0);
667 	ASSERT_NE(ptr, MAP_FAILED);
668 
669 	/* Guard the middle of the range. */
670 	ASSERT_EQ(madvise(&ptr[5 * page_size], 2 * page_size,
671 			  MADV_GUARD_INSTALL), 0);
672 
673 	/* Assert that it is indeed guarded. */
674 	ASSERT_FALSE(try_read_write_buf(&ptr[5 * page_size]));
675 	ASSERT_FALSE(try_read_write_buf(&ptr[6 * page_size]));
676 
677 	/* Now make these pages read-only. */
678 	ASSERT_EQ(mprotect(&ptr[5 * page_size], 2 * page_size, PROT_READ), 0);
679 
680 	/* Make sure the range is still guarded. */
681 	ASSERT_FALSE(try_read_buf(&ptr[5 * page_size]));
682 	ASSERT_FALSE(try_read_buf(&ptr[6 * page_size]));
683 
684 	/* Make sure we can guard again without issue.*/
685 	ASSERT_EQ(madvise(&ptr[5 * page_size], 2 * page_size,
686 			  MADV_GUARD_INSTALL), 0);
687 
688 	/* Make sure the range is, yet again, still guarded. */
689 	ASSERT_FALSE(try_read_buf(&ptr[5 * page_size]));
690 	ASSERT_FALSE(try_read_buf(&ptr[6 * page_size]));
691 
692 	/* Now unguard the whole range. */
693 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_REMOVE), 0);
694 
695 	/* Make sure the whole range is readable. */
696 	for (i = 0; i < 10; i++) {
697 		char *curr = &ptr[i * page_size];
698 
699 		ASSERT_TRUE(try_read_buf(curr));
700 	}
701 
702 	/* Cleanup. */
703 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
704 }
705 
706 /* Split and merge VMAs and make sure guard pages still behave. */
TEST_F(guard_regions,split_merge)707 TEST_F(guard_regions, split_merge)
708 {
709 	const unsigned long page_size = self->page_size;
710 	char *ptr, *ptr_new;
711 	int i;
712 
713 	ptr = mmap_(self, variant, NULL, 10 * page_size,
714 		    PROT_READ | PROT_WRITE, 0, 0);
715 	ASSERT_NE(ptr, MAP_FAILED);
716 
717 	/* Guard the whole range. */
718 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_INSTALL), 0);
719 
720 	/* Make sure the whole range is guarded. */
721 	for (i = 0; i < 10; i++) {
722 		char *curr = &ptr[i * page_size];
723 
724 		ASSERT_FALSE(try_read_write_buf(curr));
725 	}
726 
727 	/* Now unmap some pages in the range so we split. */
728 	ASSERT_EQ(munmap(&ptr[2 * page_size], page_size), 0);
729 	ASSERT_EQ(munmap(&ptr[5 * page_size], page_size), 0);
730 	ASSERT_EQ(munmap(&ptr[8 * page_size], page_size), 0);
731 
732 	/* Make sure the remaining ranges are guarded post-split. */
733 	for (i = 0; i < 2; i++) {
734 		char *curr = &ptr[i * page_size];
735 
736 		ASSERT_FALSE(try_read_write_buf(curr));
737 	}
738 	for (i = 2; i < 5; i++) {
739 		char *curr = &ptr[i * page_size];
740 
741 		ASSERT_FALSE(try_read_write_buf(curr));
742 	}
743 	for (i = 6; i < 8; i++) {
744 		char *curr = &ptr[i * page_size];
745 
746 		ASSERT_FALSE(try_read_write_buf(curr));
747 	}
748 	for (i = 9; i < 10; i++) {
749 		char *curr = &ptr[i * page_size];
750 
751 		ASSERT_FALSE(try_read_write_buf(curr));
752 	}
753 
754 	/* Now map them again - the unmap will have cleared the guards. */
755 	ptr_new = mmap_(self, variant, &ptr[2 * page_size], page_size,
756 			PROT_READ | PROT_WRITE, MAP_FIXED, 0);
757 	ASSERT_NE(ptr_new, MAP_FAILED);
758 	ptr_new = mmap_(self, variant, &ptr[5 * page_size], page_size,
759 			PROT_READ | PROT_WRITE, MAP_FIXED, 0);
760 	ASSERT_NE(ptr_new, MAP_FAILED);
761 	ptr_new = mmap_(self, variant, &ptr[8 * page_size], page_size,
762 			PROT_READ | PROT_WRITE, MAP_FIXED, 0);
763 	ASSERT_NE(ptr_new, MAP_FAILED);
764 
765 	/* Now make sure guard pages are established. */
766 	for (i = 0; i < 10; i++) {
767 		char *curr = &ptr[i * page_size];
768 		bool result = try_read_write_buf(curr);
769 		bool expect_true = i == 2 || i == 5 || i == 8;
770 
771 		ASSERT_TRUE(expect_true ? result : !result);
772 	}
773 
774 	/* Now guard everything again. */
775 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_INSTALL), 0);
776 
777 	/* Make sure the whole range is guarded. */
778 	for (i = 0; i < 10; i++) {
779 		char *curr = &ptr[i * page_size];
780 
781 		ASSERT_FALSE(try_read_write_buf(curr));
782 	}
783 
784 	/* Now split the range into three. */
785 	ASSERT_EQ(mprotect(ptr, 3 * page_size, PROT_READ), 0);
786 	ASSERT_EQ(mprotect(&ptr[7 * page_size], 3 * page_size, PROT_READ), 0);
787 
788 	/* Make sure the whole range is guarded for read. */
789 	for (i = 0; i < 10; i++) {
790 		char *curr = &ptr[i * page_size];
791 
792 		ASSERT_FALSE(try_read_buf(curr));
793 	}
794 
795 	/* Now reset protection bits so we merge the whole thing. */
796 	ASSERT_EQ(mprotect(ptr, 3 * page_size, PROT_READ | PROT_WRITE), 0);
797 	ASSERT_EQ(mprotect(&ptr[7 * page_size], 3 * page_size,
798 			   PROT_READ | PROT_WRITE), 0);
799 
800 	/* Make sure the whole range is still guarded. */
801 	for (i = 0; i < 10; i++) {
802 		char *curr = &ptr[i * page_size];
803 
804 		ASSERT_FALSE(try_read_write_buf(curr));
805 	}
806 
807 	/* Split range into 3 again... */
808 	ASSERT_EQ(mprotect(ptr, 3 * page_size, PROT_READ), 0);
809 	ASSERT_EQ(mprotect(&ptr[7 * page_size], 3 * page_size, PROT_READ), 0);
810 
811 	/* ...and unguard the whole range. */
812 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_REMOVE), 0);
813 
814 	/* Make sure the whole range is remedied for read. */
815 	for (i = 0; i < 10; i++) {
816 		char *curr = &ptr[i * page_size];
817 
818 		ASSERT_TRUE(try_read_buf(curr));
819 	}
820 
821 	/* Merge them again. */
822 	ASSERT_EQ(mprotect(ptr, 3 * page_size, PROT_READ | PROT_WRITE), 0);
823 	ASSERT_EQ(mprotect(&ptr[7 * page_size], 3 * page_size,
824 			   PROT_READ | PROT_WRITE), 0);
825 
826 	/* Now ensure the merged range is remedied for read/write. */
827 	for (i = 0; i < 10; i++) {
828 		char *curr = &ptr[i * page_size];
829 
830 		ASSERT_TRUE(try_read_write_buf(curr));
831 	}
832 
833 	/* Cleanup. */
834 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
835 }
836 
837 /* Assert that MADV_DONTNEED does not remove guard markers. */
TEST_F(guard_regions,dontneed)838 TEST_F(guard_regions, dontneed)
839 {
840 	const unsigned long page_size = self->page_size;
841 	char *ptr;
842 	int i;
843 
844 	ptr = mmap_(self, variant, NULL, 10 * page_size,
845 		    PROT_READ | PROT_WRITE, 0, 0);
846 	ASSERT_NE(ptr, MAP_FAILED);
847 
848 	/* Back the whole range. */
849 	for (i = 0; i < 10; i++) {
850 		char *curr = &ptr[i * page_size];
851 
852 		*curr = 'y';
853 	}
854 
855 	/* Guard every other page. */
856 	for (i = 0; i < 10; i += 2) {
857 		char *curr = &ptr[i * page_size];
858 		int res = madvise(curr, page_size, MADV_GUARD_INSTALL);
859 
860 		ASSERT_EQ(res, 0);
861 	}
862 
863 	/* Indicate that we don't need any of the range. */
864 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_DONTNEED), 0);
865 
866 	/* Check to ensure guard markers are still in place. */
867 	for (i = 0; i < 10; i++) {
868 		char *curr = &ptr[i * page_size];
869 		bool result = try_read_buf(curr);
870 
871 		if (i % 2 == 0) {
872 			ASSERT_FALSE(result);
873 		} else {
874 			ASSERT_TRUE(result);
875 			switch (variant->backing) {
876 			case ANON_BACKED:
877 				/* If anon, then we get a zero page. */
878 				ASSERT_EQ(*curr, '\0');
879 				break;
880 			default:
881 				/* Otherwise, we get the file data. */
882 				ASSERT_EQ(*curr, 'y');
883 				break;
884 			}
885 		}
886 
887 		/* Now write... */
888 		result = try_write_buf(&ptr[i * page_size]);
889 
890 		/* ...and make sure same result. */
891 		ASSERT_TRUE(i % 2 != 0 ? result : !result);
892 	}
893 
894 	/* Cleanup. */
895 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
896 }
897 
898 /* Assert that mlock()'ed pages work correctly with guard markers. */
TEST_F(guard_regions,mlock)899 TEST_F(guard_regions, mlock)
900 {
901 	const unsigned long page_size = self->page_size;
902 	char *ptr;
903 	int i;
904 
905 	ptr = mmap_(self, variant, NULL, 10 * page_size,
906 		    PROT_READ | PROT_WRITE, 0, 0);
907 	ASSERT_NE(ptr, MAP_FAILED);
908 
909 	/* Populate. */
910 	for (i = 0; i < 10; i++) {
911 		char *curr = &ptr[i * page_size];
912 
913 		*curr = 'y';
914 	}
915 
916 	/* Lock. */
917 	ASSERT_EQ(mlock(ptr, 10 * page_size), 0);
918 
919 	/* Now try to guard, should fail with EINVAL. */
920 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_INSTALL), -1);
921 	ASSERT_EQ(errno, EINVAL);
922 
923 	/* OK unlock. */
924 	ASSERT_EQ(munlock(ptr, 10 * page_size), 0);
925 
926 	/* Guard first half of range, should now succeed. */
927 	ASSERT_EQ(madvise(ptr, 5 * page_size, MADV_GUARD_INSTALL), 0);
928 
929 	/* Make sure guard works. */
930 	for (i = 0; i < 10; i++) {
931 		char *curr = &ptr[i * page_size];
932 		bool result = try_read_write_buf(curr);
933 
934 		if (i < 5) {
935 			ASSERT_FALSE(result);
936 		} else {
937 			ASSERT_TRUE(result);
938 			ASSERT_EQ(*curr, 'x');
939 		}
940 	}
941 
942 	/*
943 	 * Now lock the latter part of the range. We can't lock the guard pages,
944 	 * as this would result in the pages being populated and the guarding
945 	 * would cause this to error out.
946 	 */
947 	ASSERT_EQ(mlock(&ptr[5 * page_size], 5 * page_size), 0);
948 
949 	/*
950 	 * Now remove guard pages, we permit mlock()'d ranges to have guard
951 	 * pages removed as it is a non-destructive operation.
952 	 */
953 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_REMOVE), 0);
954 
955 	/* Now check that no guard pages remain. */
956 	for (i = 0; i < 10; i++) {
957 		char *curr = &ptr[i * page_size];
958 
959 		ASSERT_TRUE(try_read_write_buf(curr));
960 	}
961 
962 	/* Cleanup. */
963 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
964 }
965 
966 /*
967  * Assert that moving, extending and shrinking memory via mremap() retains
968  * guard markers where possible.
969  *
970  * - Moving a mapping alone should retain markers as they are.
971  */
TEST_F(guard_regions,mremap_move)972 TEST_F(guard_regions, mremap_move)
973 {
974 	const unsigned long page_size = self->page_size;
975 	char *ptr, *ptr_new;
976 
977 	/* Map 5 pages. */
978 	ptr = mmap_(self, variant, NULL, 5 * page_size,
979 		    PROT_READ | PROT_WRITE, 0, 0);
980 	ASSERT_NE(ptr, MAP_FAILED);
981 
982 	/* Place guard markers at both ends of the 5 page span. */
983 	ASSERT_EQ(madvise(ptr, page_size, MADV_GUARD_INSTALL), 0);
984 	ASSERT_EQ(madvise(&ptr[4 * page_size], page_size, MADV_GUARD_INSTALL), 0);
985 
986 	/* Make sure the guard pages are in effect. */
987 	ASSERT_FALSE(try_read_write_buf(ptr));
988 	ASSERT_FALSE(try_read_write_buf(&ptr[4 * page_size]));
989 
990 	/* Map a new region we will move this range into. Doing this ensures
991 	 * that we have reserved a range to map into.
992 	 */
993 	ptr_new = mmap_(self, variant, NULL, 5 * page_size, PROT_NONE, 0, 0);
994 	ASSERT_NE(ptr_new, MAP_FAILED);
995 
996 	ASSERT_EQ(mremap(ptr, 5 * page_size, 5 * page_size,
997 			 MREMAP_MAYMOVE | MREMAP_FIXED, ptr_new), ptr_new);
998 
999 	/* Make sure the guard markers are retained. */
1000 	ASSERT_FALSE(try_read_write_buf(ptr_new));
1001 	ASSERT_FALSE(try_read_write_buf(&ptr_new[4 * page_size]));
1002 
1003 	/*
1004 	 * Clean up - we only need reference the new pointer as we overwrote the
1005 	 * PROT_NONE range and moved the existing one.
1006 	 */
1007 	munmap(ptr_new, 5 * page_size);
1008 }
1009 
1010 /*
1011  * Assert that moving, extending and shrinking memory via mremap() retains
1012  * guard markers where possible.
1013  *
1014  * Expanding should retain guard pages, only now in different position. The user
1015  * will have to remove guard pages manually to fix up (they'd have to do the
1016  * same if it were a PROT_NONE mapping).
1017  */
TEST_F(guard_regions,mremap_expand)1018 TEST_F(guard_regions, mremap_expand)
1019 {
1020 	const unsigned long page_size = self->page_size;
1021 	char *ptr, *ptr_new;
1022 
1023 	/* Map 10 pages... */
1024 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1025 		    PROT_READ | PROT_WRITE, 0, 0);
1026 	ASSERT_NE(ptr, MAP_FAILED);
1027 	/* ...But unmap the last 5 so we can ensure we can expand into them. */
1028 	ASSERT_EQ(munmap(&ptr[5 * page_size], 5 * page_size), 0);
1029 
1030 	/* Place guard markers at both ends of the 5 page span. */
1031 	ASSERT_EQ(madvise(ptr, page_size, MADV_GUARD_INSTALL), 0);
1032 	ASSERT_EQ(madvise(&ptr[4 * page_size], page_size, MADV_GUARD_INSTALL), 0);
1033 
1034 	/* Make sure the guarding is in effect. */
1035 	ASSERT_FALSE(try_read_write_buf(ptr));
1036 	ASSERT_FALSE(try_read_write_buf(&ptr[4 * page_size]));
1037 
1038 	/* Now expand to 10 pages. */
1039 	ptr = mremap(ptr, 5 * page_size, 10 * page_size, 0);
1040 	ASSERT_NE(ptr, MAP_FAILED);
1041 
1042 	/*
1043 	 * Make sure the guard markers are retained in their original positions.
1044 	 */
1045 	ASSERT_FALSE(try_read_write_buf(ptr));
1046 	ASSERT_FALSE(try_read_write_buf(&ptr[4 * page_size]));
1047 
1048 	/* Reserve a region which we can move to and expand into. */
1049 	ptr_new = mmap_(self, variant, NULL, 20 * page_size, PROT_NONE, 0, 0);
1050 	ASSERT_NE(ptr_new, MAP_FAILED);
1051 
1052 	/* Now move and expand into it. */
1053 	ptr = mremap(ptr, 10 * page_size, 20 * page_size,
1054 		     MREMAP_MAYMOVE | MREMAP_FIXED, ptr_new);
1055 	ASSERT_EQ(ptr, ptr_new);
1056 
1057 	/*
1058 	 * Again, make sure the guard markers are retained in their original positions.
1059 	 */
1060 	ASSERT_FALSE(try_read_write_buf(ptr));
1061 	ASSERT_FALSE(try_read_write_buf(&ptr[4 * page_size]));
1062 
1063 	/*
1064 	 * A real user would have to remove guard markers, but would reasonably
1065 	 * expect all characteristics of the mapping to be retained, including
1066 	 * guard markers.
1067 	 */
1068 
1069 	/* Cleanup. */
1070 	munmap(ptr, 20 * page_size);
1071 }
1072 /*
1073  * Assert that moving, extending and shrinking memory via mremap() retains
1074  * guard markers where possible.
1075  *
1076  * Shrinking will result in markers that are shrunk over being removed. Again,
1077  * if the user were using a PROT_NONE mapping they'd have to manually fix this
1078  * up also so this is OK.
1079  */
TEST_F(guard_regions,mremap_shrink)1080 TEST_F(guard_regions, mremap_shrink)
1081 {
1082 	const unsigned long page_size = self->page_size;
1083 	char *ptr;
1084 	int i;
1085 
1086 	/* Map 5 pages. */
1087 	ptr = mmap_(self, variant, NULL, 5 * page_size,
1088 		    PROT_READ | PROT_WRITE, 0, 0);
1089 	ASSERT_NE(ptr, MAP_FAILED);
1090 
1091 	/* Place guard markers at both ends of the 5 page span. */
1092 	ASSERT_EQ(madvise(ptr, page_size, MADV_GUARD_INSTALL), 0);
1093 	ASSERT_EQ(madvise(&ptr[4 * page_size], page_size, MADV_GUARD_INSTALL), 0);
1094 
1095 	/* Make sure the guarding is in effect. */
1096 	ASSERT_FALSE(try_read_write_buf(ptr));
1097 	ASSERT_FALSE(try_read_write_buf(&ptr[4 * page_size]));
1098 
1099 	/* Now shrink to 3 pages. */
1100 	ptr = mremap(ptr, 5 * page_size, 3 * page_size, MREMAP_MAYMOVE);
1101 	ASSERT_NE(ptr, MAP_FAILED);
1102 
1103 	/* We expect the guard marker at the start to be retained... */
1104 	ASSERT_FALSE(try_read_write_buf(ptr));
1105 
1106 	/* ...But remaining pages will not have guard markers. */
1107 	for (i = 1; i < 3; i++) {
1108 		char *curr = &ptr[i * page_size];
1109 
1110 		ASSERT_TRUE(try_read_write_buf(curr));
1111 	}
1112 
1113 	/*
1114 	 * As with expansion, a real user would have to remove guard pages and
1115 	 * fixup. But you'd have to do similar manual things with PROT_NONE
1116 	 * mappings too.
1117 	 */
1118 
1119 	/*
1120 	 * If we expand back to the original size, the end marker will, of
1121 	 * course, no longer be present.
1122 	 */
1123 	ptr = mremap(ptr, 3 * page_size, 5 * page_size, 0);
1124 	ASSERT_NE(ptr, MAP_FAILED);
1125 
1126 	/* Again, we expect the guard marker at the start to be retained... */
1127 	ASSERT_FALSE(try_read_write_buf(ptr));
1128 
1129 	/* ...But remaining pages will not have guard markers. */
1130 	for (i = 1; i < 5; i++) {
1131 		char *curr = &ptr[i * page_size];
1132 
1133 		ASSERT_TRUE(try_read_write_buf(curr));
1134 	}
1135 
1136 	/* Cleanup. */
1137 	munmap(ptr, 5 * page_size);
1138 }
1139 
1140 /*
1141  * Assert that forking a process with VMAs that do not have VM_WIPEONFORK set
1142  * retain guard pages.
1143  */
TEST_F(guard_regions,fork)1144 TEST_F(guard_regions, fork)
1145 {
1146 	const unsigned long page_size = self->page_size;
1147 	char *ptr;
1148 	pid_t pid;
1149 	int i;
1150 
1151 	/* Map 10 pages. */
1152 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1153 		    PROT_READ | PROT_WRITE, 0, 0);
1154 	ASSERT_NE(ptr, MAP_FAILED);
1155 
1156 	/* Establish guard pages in the first 5 pages. */
1157 	ASSERT_EQ(madvise(ptr, 5 * page_size, MADV_GUARD_INSTALL), 0);
1158 
1159 	pid = fork();
1160 	ASSERT_NE(pid, -1);
1161 	if (!pid) {
1162 		/* This is the child process now. */
1163 
1164 		/* Assert that the guarding is in effect. */
1165 		for (i = 0; i < 10; i++) {
1166 			char *curr = &ptr[i * page_size];
1167 			bool result = try_read_write_buf(curr);
1168 
1169 			ASSERT_TRUE(i >= 5 ? result : !result);
1170 		}
1171 
1172 		/* Now unguard the range.*/
1173 		ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_REMOVE), 0);
1174 
1175 		exit(0);
1176 	}
1177 
1178 	/* Parent process. */
1179 
1180 	/* Parent simply waits on child. */
1181 	waitpid(pid, NULL, 0);
1182 
1183 	/* Child unguard does not impact parent page table state. */
1184 	for (i = 0; i < 10; i++) {
1185 		char *curr = &ptr[i * page_size];
1186 		bool result = try_read_write_buf(curr);
1187 
1188 		ASSERT_TRUE(i >= 5 ? result : !result);
1189 	}
1190 
1191 	/* Cleanup. */
1192 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1193 }
1194 
1195 /*
1196  * Assert expected behaviour after we fork populated ranges of anonymous memory
1197  * and then guard and unguard the range.
1198  */
TEST_F(guard_regions,fork_cow)1199 TEST_F(guard_regions, fork_cow)
1200 {
1201 	const unsigned long page_size = self->page_size;
1202 	char *ptr;
1203 	pid_t pid;
1204 	int i;
1205 
1206 	if (variant->backing != ANON_BACKED)
1207 		SKIP(return, "CoW only supported on anon mappings");
1208 
1209 	/* Map 10 pages. */
1210 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1211 		    PROT_READ | PROT_WRITE, 0, 0);
1212 	ASSERT_NE(ptr, MAP_FAILED);
1213 
1214 	/* Populate range. */
1215 	for (i = 0; i < 10 * page_size; i++) {
1216 		char chr = 'a' + (i % 26);
1217 
1218 		ptr[i] = chr;
1219 	}
1220 
1221 	pid = fork();
1222 	ASSERT_NE(pid, -1);
1223 	if (!pid) {
1224 		/* This is the child process now. */
1225 
1226 		/* Ensure the range is as expected. */
1227 		for (i = 0; i < 10 * page_size; i++) {
1228 			char expected = 'a' + (i % 26);
1229 			char actual = ptr[i];
1230 
1231 			ASSERT_EQ(actual, expected);
1232 		}
1233 
1234 		/* Establish guard pages across the whole range. */
1235 		ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_INSTALL), 0);
1236 		/* Remove it. */
1237 		ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_REMOVE), 0);
1238 
1239 		/*
1240 		 * By removing the guard pages, the page tables will be
1241 		 * cleared. Assert that we are looking at the zero page now.
1242 		 */
1243 		for (i = 0; i < 10 * page_size; i++) {
1244 			char actual = ptr[i];
1245 
1246 			ASSERT_EQ(actual, '\0');
1247 		}
1248 
1249 		exit(0);
1250 	}
1251 
1252 	/* Parent process. */
1253 
1254 	/* Parent simply waits on child. */
1255 	waitpid(pid, NULL, 0);
1256 
1257 	/* Ensure the range is unchanged in parent anon range. */
1258 	for (i = 0; i < 10 * page_size; i++) {
1259 		char expected = 'a' + (i % 26);
1260 		char actual = ptr[i];
1261 
1262 		ASSERT_EQ(actual, expected);
1263 	}
1264 
1265 	/* Cleanup. */
1266 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1267 }
1268 
1269 /*
1270  * Assert that forking a process with VMAs that do have VM_WIPEONFORK set
1271  * behave as expected.
1272  */
TEST_F(guard_regions,fork_wipeonfork)1273 TEST_F(guard_regions, fork_wipeonfork)
1274 {
1275 	const unsigned long page_size = self->page_size;
1276 	char *ptr;
1277 	pid_t pid;
1278 	int i;
1279 
1280 	if (variant->backing != ANON_BACKED)
1281 		SKIP(return, "Wipe on fork only supported on anon mappings");
1282 
1283 	/* Map 10 pages. */
1284 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1285 		    PROT_READ | PROT_WRITE, 0, 0);
1286 	ASSERT_NE(ptr, MAP_FAILED);
1287 
1288 	/* Mark wipe on fork. */
1289 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_WIPEONFORK), 0);
1290 
1291 	/* Guard the first 5 pages. */
1292 	ASSERT_EQ(madvise(ptr, 5 * page_size, MADV_GUARD_INSTALL), 0);
1293 
1294 	pid = fork();
1295 	ASSERT_NE(pid, -1);
1296 	if (!pid) {
1297 		/* This is the child process now. */
1298 
1299 		/* Guard will have been wiped. */
1300 		for (i = 0; i < 10; i++) {
1301 			char *curr = &ptr[i * page_size];
1302 
1303 			ASSERT_TRUE(try_read_write_buf(curr));
1304 		}
1305 
1306 		exit(0);
1307 	}
1308 
1309 	/* Parent process. */
1310 
1311 	waitpid(pid, NULL, 0);
1312 
1313 	/* Guard markers should be in effect.*/
1314 	for (i = 0; i < 10; i++) {
1315 		char *curr = &ptr[i * page_size];
1316 		bool result = try_read_write_buf(curr);
1317 
1318 		ASSERT_TRUE(i >= 5 ? result : !result);
1319 	}
1320 
1321 	/* Cleanup. */
1322 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1323 }
1324 
1325 /* Ensure that MADV_FREE retains guard entries as expected. */
TEST_F(guard_regions,lazyfree)1326 TEST_F(guard_regions, lazyfree)
1327 {
1328 	const unsigned long page_size = self->page_size;
1329 	char *ptr;
1330 	int i;
1331 
1332 	if (variant->backing != ANON_BACKED)
1333 		SKIP(return, "MADV_FREE only supported on anon mappings");
1334 
1335 	/* Map 10 pages. */
1336 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1337 		    PROT_READ | PROT_WRITE, 0, 0);
1338 	ASSERT_NE(ptr, MAP_FAILED);
1339 
1340 	/* Guard range. */
1341 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_INSTALL), 0);
1342 
1343 	/* Ensure guarded. */
1344 	for (i = 0; i < 10; i++) {
1345 		char *curr = &ptr[i * page_size];
1346 
1347 		ASSERT_FALSE(try_read_write_buf(curr));
1348 	}
1349 
1350 	/* Lazyfree range. */
1351 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_FREE), 0);
1352 
1353 	/* This should leave the guard markers in place. */
1354 	for (i = 0; i < 10; i++) {
1355 		char *curr = &ptr[i * page_size];
1356 
1357 		ASSERT_FALSE(try_read_write_buf(curr));
1358 	}
1359 
1360 	/* Cleanup. */
1361 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1362 }
1363 
1364 /* Ensure that MADV_POPULATE_READ, MADV_POPULATE_WRITE behave as expected. */
TEST_F(guard_regions,populate)1365 TEST_F(guard_regions, populate)
1366 {
1367 	const unsigned long page_size = self->page_size;
1368 	char *ptr;
1369 
1370 	/* Map 10 pages. */
1371 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1372 		    PROT_READ | PROT_WRITE, 0, 0);
1373 	ASSERT_NE(ptr, MAP_FAILED);
1374 
1375 	/* Guard range. */
1376 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_INSTALL), 0);
1377 
1378 	/* Populate read should error out... */
1379 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_POPULATE_READ), -1);
1380 	ASSERT_EQ(errno, EFAULT);
1381 
1382 	/* ...as should populate write. */
1383 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_POPULATE_WRITE), -1);
1384 	ASSERT_EQ(errno, EFAULT);
1385 
1386 	/* Cleanup. */
1387 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1388 }
1389 
1390 /* Ensure that MADV_COLD, MADV_PAGEOUT do not remove guard markers. */
TEST_F(guard_regions,cold_pageout)1391 TEST_F(guard_regions, cold_pageout)
1392 {
1393 	const unsigned long page_size = self->page_size;
1394 	char *ptr;
1395 	int i;
1396 
1397 	/* Map 10 pages. */
1398 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1399 		    PROT_READ | PROT_WRITE, 0, 0);
1400 	ASSERT_NE(ptr, MAP_FAILED);
1401 
1402 	/* Guard range. */
1403 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_INSTALL), 0);
1404 
1405 	/* Ensured guarded. */
1406 	for (i = 0; i < 10; i++) {
1407 		char *curr = &ptr[i * page_size];
1408 
1409 		ASSERT_FALSE(try_read_write_buf(curr));
1410 	}
1411 
1412 	/* Now mark cold. This should have no impact on guard markers. */
1413 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_COLD), 0);
1414 
1415 	/* Should remain guarded. */
1416 	for (i = 0; i < 10; i++) {
1417 		char *curr = &ptr[i * page_size];
1418 
1419 		ASSERT_FALSE(try_read_write_buf(curr));
1420 	}
1421 
1422 	/* OK, now page out. This should equally, have no effect on markers. */
1423 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_PAGEOUT), 0);
1424 
1425 	/* Should remain guarded. */
1426 	for (i = 0; i < 10; i++) {
1427 		char *curr = &ptr[i * page_size];
1428 
1429 		ASSERT_FALSE(try_read_write_buf(curr));
1430 	}
1431 
1432 	/* Cleanup. */
1433 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1434 }
1435 
1436 /* Ensure that guard pages do not break userfaultd. */
TEST_F(guard_regions,uffd)1437 TEST_F(guard_regions, uffd)
1438 {
1439 	const unsigned long page_size = self->page_size;
1440 	int uffd;
1441 	char *ptr;
1442 	int i;
1443 	struct uffdio_api api = {
1444 		.api = UFFD_API,
1445 		.features = 0,
1446 	};
1447 	struct uffdio_register reg;
1448 	struct uffdio_range range;
1449 
1450 	if (!is_anon_backed(variant))
1451 		SKIP(return, "uffd only works on anon backing");
1452 
1453 	/* Set up uffd. */
1454 	uffd = userfaultfd(0);
1455 	if (uffd == -1 && errno == EPERM)
1456 		ksft_exit_skip("No userfaultfd permissions, try running as root.\n");
1457 	ASSERT_NE(uffd, -1);
1458 
1459 	ASSERT_EQ(ioctl(uffd, UFFDIO_API, &api), 0);
1460 
1461 	/* Map 10 pages. */
1462 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1463 		    PROT_READ | PROT_WRITE, 0, 0);
1464 	ASSERT_NE(ptr, MAP_FAILED);
1465 
1466 	/* Register the range with uffd. */
1467 	range.start = (unsigned long)ptr;
1468 	range.len = 10 * page_size;
1469 	reg.range = range;
1470 	reg.mode = UFFDIO_REGISTER_MODE_MISSING;
1471 	ASSERT_EQ(ioctl(uffd, UFFDIO_REGISTER, &reg), 0);
1472 
1473 	/* Guard the range. This should not trigger the uffd. */
1474 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_INSTALL), 0);
1475 
1476 	/* The guarding should behave as usual with no uffd intervention. */
1477 	for (i = 0; i < 10; i++) {
1478 		char *curr = &ptr[i * page_size];
1479 
1480 		ASSERT_FALSE(try_read_write_buf(curr));
1481 	}
1482 
1483 	/* Cleanup. */
1484 	ASSERT_EQ(ioctl(uffd, UFFDIO_UNREGISTER, &range), 0);
1485 	close(uffd);
1486 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1487 }
1488 
1489 /*
1490  * Mark a region within a file-backed mapping using MADV_SEQUENTIAL so we
1491  * aggressively read-ahead, then install guard regions and assert that it
1492  * behaves correctly.
1493  *
1494  * We page out using MADV_PAGEOUT before checking guard regions so we drop page
1495  * cache folios, meaning we maximise the possibility of some broken readahead.
1496  */
TEST_F(guard_regions,madvise_sequential)1497 TEST_F(guard_regions, madvise_sequential)
1498 {
1499 	char *ptr;
1500 	int i;
1501 	const unsigned long page_size = self->page_size;
1502 
1503 	if (variant->backing == ANON_BACKED)
1504 		SKIP(return, "MADV_SEQUENTIAL meaningful only for file-backed");
1505 
1506 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1507 		    PROT_READ | PROT_WRITE, 0, 0);
1508 	ASSERT_NE(ptr, MAP_FAILED);
1509 
1510 	/* Establish a pattern of data in the file. */
1511 	set_pattern(ptr, 10, page_size);
1512 	ASSERT_TRUE(check_pattern(ptr, 10, page_size));
1513 
1514 	/* Mark it as being accessed sequentially. */
1515 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_SEQUENTIAL), 0);
1516 
1517 	/* Mark every other page a guard page. */
1518 	for (i = 0; i < 10; i += 2) {
1519 		char *ptr2 = &ptr[i * page_size];
1520 
1521 		ASSERT_EQ(madvise(ptr2, page_size, MADV_GUARD_INSTALL), 0);
1522 	}
1523 
1524 	/* Now page it out. */
1525 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_PAGEOUT), 0);
1526 
1527 	/* Now make sure pages are as expected. */
1528 	for (i = 0; i < 10; i++) {
1529 		char *chrp = &ptr[i * page_size];
1530 
1531 		if (i % 2 == 0) {
1532 			bool result = try_read_write_buf(chrp);
1533 
1534 			ASSERT_FALSE(result);
1535 		} else {
1536 			ASSERT_EQ(*chrp, 'a' + i);
1537 		}
1538 	}
1539 
1540 	/* Now remove guard pages. */
1541 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_REMOVE), 0);
1542 
1543 	/* Now make sure all data is as expected. */
1544 	if (!check_pattern(ptr, 10, page_size))
1545 		ASSERT_TRUE(false);
1546 
1547 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1548 }
1549 
1550 /*
1551  * Check that file-backed mappings implement guard regions with MAP_PRIVATE
1552  * correctly.
1553  */
TEST_F(guard_regions,map_private)1554 TEST_F(guard_regions, map_private)
1555 {
1556 	const unsigned long page_size = self->page_size;
1557 	char *ptr_shared, *ptr_private;
1558 	int i;
1559 
1560 	if (variant->backing == ANON_BACKED)
1561 		SKIP(return, "MAP_PRIVATE test specific to file-backed");
1562 
1563 	ptr_shared = mmap_(self, variant, NULL, 10 * page_size, PROT_READ | PROT_WRITE, 0, 0);
1564 	ASSERT_NE(ptr_shared, MAP_FAILED);
1565 
1566 	/* Manually mmap(), do not use mmap_() wrapper so we can force MAP_PRIVATE. */
1567 	ptr_private = mmap(NULL, 10 * page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, self->fd, 0);
1568 	ASSERT_NE(ptr_private, MAP_FAILED);
1569 
1570 	/* Set pattern in shared mapping. */
1571 	set_pattern(ptr_shared, 10, page_size);
1572 
1573 	/* Install guard regions in every other page in the shared mapping. */
1574 	for (i = 0; i < 10; i += 2) {
1575 		char *ptr = &ptr_shared[i * page_size];
1576 
1577 		ASSERT_EQ(madvise(ptr, page_size, MADV_GUARD_INSTALL), 0);
1578 	}
1579 
1580 	for (i = 0; i < 10; i++) {
1581 		/* Every even shared page should be guarded. */
1582 		ASSERT_EQ(try_read_buf(&ptr_shared[i * page_size]), i % 2 != 0);
1583 		/* Private mappings should always be readable. */
1584 		ASSERT_TRUE(try_read_buf(&ptr_private[i * page_size]));
1585 	}
1586 
1587 	/* Install guard regions in every other page in the private mapping. */
1588 	for (i = 0; i < 10; i += 2) {
1589 		char *ptr = &ptr_private[i * page_size];
1590 
1591 		ASSERT_EQ(madvise(ptr, page_size, MADV_GUARD_INSTALL), 0);
1592 	}
1593 
1594 	for (i = 0; i < 10; i++) {
1595 		/* Every even shared page should be guarded. */
1596 		ASSERT_EQ(try_read_buf(&ptr_shared[i * page_size]), i % 2 != 0);
1597 		/* Every odd private page should be guarded. */
1598 		ASSERT_EQ(try_read_buf(&ptr_private[i * page_size]), i % 2 != 0);
1599 	}
1600 
1601 	/* Remove guard regions from shared mapping. */
1602 	ASSERT_EQ(madvise(ptr_shared, 10 * page_size, MADV_GUARD_REMOVE), 0);
1603 
1604 	for (i = 0; i < 10; i++) {
1605 		/* Shared mappings should always be readable. */
1606 		ASSERT_TRUE(try_read_buf(&ptr_shared[i * page_size]));
1607 		/* Every even private page should be guarded. */
1608 		ASSERT_EQ(try_read_buf(&ptr_private[i * page_size]), i % 2 != 0);
1609 	}
1610 
1611 	/* Remove guard regions from private mapping. */
1612 	ASSERT_EQ(madvise(ptr_private, 10 * page_size, MADV_GUARD_REMOVE), 0);
1613 
1614 	for (i = 0; i < 10; i++) {
1615 		/* Shared mappings should always be readable. */
1616 		ASSERT_TRUE(try_read_buf(&ptr_shared[i * page_size]));
1617 		/* Private mappings should always be readable. */
1618 		ASSERT_TRUE(try_read_buf(&ptr_private[i * page_size]));
1619 	}
1620 
1621 	/* Ensure patterns are intact. */
1622 	ASSERT_TRUE(check_pattern(ptr_shared, 10, page_size));
1623 	ASSERT_TRUE(check_pattern(ptr_private, 10, page_size));
1624 
1625 	/* Now write out every other page to MAP_PRIVATE. */
1626 	for (i = 0; i < 10; i += 2) {
1627 		char *ptr = &ptr_private[i * page_size];
1628 
1629 		memset(ptr, 'a' + i, page_size);
1630 	}
1631 
1632 	/*
1633 	 * At this point the mapping is:
1634 	 *
1635 	 * 0123456789
1636 	 * SPSPSPSPSP
1637 	 *
1638 	 * Where S = shared, P = private mappings.
1639 	 */
1640 
1641 	/* Now mark the beginning of the mapping guarded. */
1642 	ASSERT_EQ(madvise(ptr_private, 5 * page_size, MADV_GUARD_INSTALL), 0);
1643 
1644 	/*
1645 	 * This renders the mapping:
1646 	 *
1647 	 * 0123456789
1648 	 * xxxxxPSPSP
1649 	 */
1650 
1651 	for (i = 0; i < 10; i++) {
1652 		char *ptr = &ptr_private[i * page_size];
1653 
1654 		/* Ensure guard regions as expected. */
1655 		ASSERT_EQ(try_read_buf(ptr), i >= 5);
1656 		/* The shared mapping should always succeed. */
1657 		ASSERT_TRUE(try_read_buf(&ptr_shared[i * page_size]));
1658 	}
1659 
1660 	/* Remove the guard regions altogether. */
1661 	ASSERT_EQ(madvise(ptr_private, 10 * page_size, MADV_GUARD_REMOVE), 0);
1662 
1663 	/*
1664 	 *
1665 	 * We now expect the mapping to be:
1666 	 *
1667 	 * 0123456789
1668 	 * SSSSSPSPSP
1669 	 *
1670 	 * As we removed guard regions, the private pages from the first 5 will
1671 	 * have been zapped, so on fault will reestablish the shared mapping.
1672 	 */
1673 
1674 	for (i = 0; i < 10; i++) {
1675 		char *ptr = &ptr_private[i * page_size];
1676 
1677 		/*
1678 		 * Assert that shared mappings in the MAP_PRIVATE mapping match
1679 		 * the shared mapping.
1680 		 */
1681 		if (i < 5 || i % 2 == 0) {
1682 			char *ptr_s = &ptr_shared[i * page_size];
1683 
1684 			ASSERT_EQ(memcmp(ptr, ptr_s, page_size), 0);
1685 			continue;
1686 		}
1687 
1688 		/* Everything else is a private mapping. */
1689 		ASSERT_TRUE(is_buf_eq(ptr, page_size, 'a' + i));
1690 	}
1691 
1692 	ASSERT_EQ(munmap(ptr_shared, 10 * page_size), 0);
1693 	ASSERT_EQ(munmap(ptr_private, 10 * page_size), 0);
1694 }
1695 
1696 /* Test that guard regions established over a read-only mapping function correctly. */
TEST_F(guard_regions,readonly_file)1697 TEST_F(guard_regions, readonly_file)
1698 {
1699 	const unsigned long page_size = self->page_size;
1700 	char *ptr;
1701 	int i;
1702 
1703 	if (variant->backing != LOCAL_FILE_BACKED)
1704 		SKIP(return, "Read-only test specific to file-backed");
1705 
1706 	/* Map shared so we can populate with pattern, populate it, unmap. */
1707 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1708 		    PROT_READ | PROT_WRITE, 0, 0);
1709 	ASSERT_NE(ptr, MAP_FAILED);
1710 	set_pattern(ptr, 10, page_size);
1711 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1712 	/* Close the fd so we can re-open read-only. */
1713 	ASSERT_EQ(close(self->fd), 0);
1714 
1715 	/* Re-open read-only. */
1716 	self->fd = open(self->path, O_RDONLY);
1717 	ASSERT_NE(self->fd, -1);
1718 	/* Re-map read-only. */
1719 	ptr = mmap_(self, variant, NULL, 10 * page_size, PROT_READ, 0, 0);
1720 	ASSERT_NE(ptr, MAP_FAILED);
1721 
1722 	/* Mark every other page guarded. */
1723 	for (i = 0; i < 10; i += 2) {
1724 		char *ptr_pg = &ptr[i * page_size];
1725 
1726 		ASSERT_EQ(madvise(ptr_pg, page_size, MADV_GUARD_INSTALL), 0);
1727 	}
1728 
1729 	/* Assert that the guard regions are in place.*/
1730 	for (i = 0; i < 10; i++) {
1731 		char *ptr_pg = &ptr[i * page_size];
1732 
1733 		ASSERT_EQ(try_read_buf(ptr_pg), i % 2 != 0);
1734 	}
1735 
1736 	/* Remove guard regions. */
1737 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_REMOVE), 0);
1738 
1739 	/* Ensure the data is as expected. */
1740 	ASSERT_TRUE(check_pattern(ptr, 10, page_size));
1741 
1742 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1743 }
1744 
TEST_F(guard_regions,fault_around)1745 TEST_F(guard_regions, fault_around)
1746 {
1747 	const unsigned long page_size = self->page_size;
1748 	char *ptr;
1749 	int i;
1750 
1751 	if (variant->backing == ANON_BACKED)
1752 		SKIP(return, "Fault-around test specific to file-backed");
1753 
1754 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1755 		    PROT_READ | PROT_WRITE, 0, 0);
1756 	ASSERT_NE(ptr, MAP_FAILED);
1757 
1758 	/* Establish a pattern in the backing file. */
1759 	set_pattern(ptr, 10, page_size);
1760 
1761 	/*
1762 	 * Now drop it from the page cache so we get major faults when next we
1763 	 * map it.
1764 	 */
1765 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_PAGEOUT), 0);
1766 
1767 	/* Unmap and remap 'to be sure'. */
1768 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1769 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1770 		    PROT_READ | PROT_WRITE, 0, 0);
1771 	ASSERT_NE(ptr, MAP_FAILED);
1772 
1773 	/* Now make every even page guarded. */
1774 	for (i = 0; i < 10; i += 2) {
1775 		char *ptr_p = &ptr[i * page_size];
1776 
1777 		ASSERT_EQ(madvise(ptr_p, page_size, MADV_GUARD_INSTALL), 0);
1778 	}
1779 
1780 	/* Now fault in every odd page. This should trigger fault-around. */
1781 	for (i = 1; i < 10; i += 2) {
1782 		char *ptr_p = &ptr[i * page_size];
1783 
1784 		ASSERT_TRUE(try_read_buf(ptr_p));
1785 	}
1786 
1787 	/* Finally, ensure that guard regions are intact as expected. */
1788 	for (i = 0; i < 10; i++) {
1789 		char *ptr_p = &ptr[i * page_size];
1790 
1791 		ASSERT_EQ(try_read_buf(ptr_p), i % 2 != 0);
1792 	}
1793 
1794 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1795 }
1796 
TEST_F(guard_regions,truncation)1797 TEST_F(guard_regions, truncation)
1798 {
1799 	const unsigned long page_size = self->page_size;
1800 	char *ptr;
1801 	int i;
1802 
1803 	if (variant->backing == ANON_BACKED)
1804 		SKIP(return, "Truncation test specific to file-backed");
1805 
1806 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1807 		    PROT_READ | PROT_WRITE, 0, 0);
1808 	ASSERT_NE(ptr, MAP_FAILED);
1809 
1810 	/*
1811 	 * Establish a pattern in the backing file, just so there is data
1812 	 * there.
1813 	 */
1814 	set_pattern(ptr, 10, page_size);
1815 
1816 	/* Now make every even page guarded. */
1817 	for (i = 0; i < 10; i += 2) {
1818 		char *ptr_p = &ptr[i * page_size];
1819 
1820 		ASSERT_EQ(madvise(ptr_p, page_size, MADV_GUARD_INSTALL), 0);
1821 	}
1822 
1823 	/* Now assert things are as expected. */
1824 	for (i = 0; i < 10; i++) {
1825 		char *ptr_p = &ptr[i * page_size];
1826 
1827 		ASSERT_EQ(try_read_write_buf(ptr_p), i % 2 != 0);
1828 	}
1829 
1830 	/* Now truncate to actually used size (initialised to 100). */
1831 	ASSERT_EQ(ftruncate(self->fd, 10 * page_size), 0);
1832 
1833 	/* Here the guard regions will remain intact. */
1834 	for (i = 0; i < 10; i++) {
1835 		char *ptr_p = &ptr[i * page_size];
1836 
1837 		ASSERT_EQ(try_read_write_buf(ptr_p), i % 2 != 0);
1838 	}
1839 
1840 	/* Now truncate to half the size, then truncate again to the full size. */
1841 	ASSERT_EQ(ftruncate(self->fd, 5 * page_size), 0);
1842 	ASSERT_EQ(ftruncate(self->fd, 10 * page_size), 0);
1843 
1844 	/* Again, guard pages will remain intact. */
1845 	for (i = 0; i < 10; i++) {
1846 		char *ptr_p = &ptr[i * page_size];
1847 
1848 		ASSERT_EQ(try_read_write_buf(ptr_p), i % 2 != 0);
1849 	}
1850 
1851 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1852 }
1853 
TEST_F(guard_regions,hole_punch)1854 TEST_F(guard_regions, hole_punch)
1855 {
1856 	const unsigned long page_size = self->page_size;
1857 	char *ptr;
1858 	int i;
1859 
1860 	if (variant->backing == ANON_BACKED)
1861 		SKIP(return, "Truncation test specific to file-backed");
1862 
1863 	/* Establish pattern in mapping. */
1864 	ptr = mmap_(self, variant, NULL, 10 * page_size,
1865 		    PROT_READ | PROT_WRITE, 0, 0);
1866 	ASSERT_NE(ptr, MAP_FAILED);
1867 	set_pattern(ptr, 10, page_size);
1868 
1869 	/* Install a guard region in the middle of the mapping. */
1870 	ASSERT_EQ(madvise(&ptr[3 * page_size], 4 * page_size,
1871 			  MADV_GUARD_INSTALL), 0);
1872 
1873 	/*
1874 	 * The buffer will now be:
1875 	 *
1876 	 * 0123456789
1877 	 * ***xxxx***
1878 	 *
1879 	 * Where * is data and x is the guard region.
1880 	 */
1881 
1882 	/* Ensure established. */
1883 	for (i = 0; i < 10; i++) {
1884 		char *ptr_p = &ptr[i * page_size];
1885 
1886 		ASSERT_EQ(try_read_buf(ptr_p), i < 3 || i >= 7);
1887 	}
1888 
1889 	/* Now hole punch the guarded region. */
1890 	ASSERT_EQ(madvise(&ptr[3 * page_size], 4 * page_size,
1891 			  MADV_REMOVE), 0);
1892 
1893 	/* Ensure guard regions remain. */
1894 	for (i = 0; i < 10; i++) {
1895 		char *ptr_p = &ptr[i * page_size];
1896 
1897 		ASSERT_EQ(try_read_buf(ptr_p), i < 3 || i >= 7);
1898 	}
1899 
1900 	/* Now remove guard region throughout. */
1901 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_REMOVE), 0);
1902 
1903 	/* Check that the pattern exists in non-hole punched region. */
1904 	ASSERT_TRUE(check_pattern(ptr, 3, page_size));
1905 	/* Check that hole punched region is zeroed. */
1906 	ASSERT_TRUE(is_buf_eq(&ptr[3 * page_size], 4 * page_size, '\0'));
1907 	/* Check that the pattern exists in the remainder of the file. */
1908 	ASSERT_TRUE(check_pattern_offset(ptr, 3, page_size, 7));
1909 
1910 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1911 }
1912 
1913 /*
1914  * Ensure that a memfd works correctly with guard regions, that we can write
1915  * seal it then open the mapping read-only and still establish guard regions
1916  * within, remove those guard regions and have everything work correctly.
1917  */
TEST_F(guard_regions,memfd_write_seal)1918 TEST_F(guard_regions, memfd_write_seal)
1919 {
1920 	const unsigned long page_size = self->page_size;
1921 	char *ptr;
1922 	int i;
1923 
1924 	if (variant->backing != SHMEM_BACKED)
1925 		SKIP(return, "memfd write seal test specific to shmem");
1926 
1927 	/* OK, we need a memfd, so close existing one. */
1928 	ASSERT_EQ(close(self->fd), 0);
1929 
1930 	/* Create and truncate memfd. */
1931 	self->fd = memfd_create("guard_regions_memfd_seals_test",
1932 				MFD_ALLOW_SEALING);
1933 	ASSERT_NE(self->fd, -1);
1934 	ASSERT_EQ(ftruncate(self->fd, 10 * page_size), 0);
1935 
1936 	/* Map, set pattern, unmap. */
1937 	ptr = mmap_(self, variant, NULL, 10 * page_size, PROT_READ | PROT_WRITE, 0, 0);
1938 	ASSERT_NE(ptr, MAP_FAILED);
1939 	set_pattern(ptr, 10, page_size);
1940 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1941 
1942 	/* Write-seal the memfd. */
1943 	ASSERT_EQ(fcntl(self->fd, F_ADD_SEALS, F_SEAL_WRITE), 0);
1944 
1945 	/* Now map the memfd readonly. */
1946 	ptr = mmap_(self, variant, NULL, 10 * page_size, PROT_READ, 0, 0);
1947 	ASSERT_NE(ptr, MAP_FAILED);
1948 
1949 	/* Ensure pattern is as expected. */
1950 	ASSERT_TRUE(check_pattern(ptr, 10, page_size));
1951 
1952 	/* Now make every even page guarded. */
1953 	for (i = 0; i < 10; i += 2) {
1954 		char *ptr_p = &ptr[i * page_size];
1955 
1956 		ASSERT_EQ(madvise(ptr_p, page_size, MADV_GUARD_INSTALL), 0);
1957 	}
1958 
1959 	/* Now assert things are as expected. */
1960 	for (i = 0; i < 10; i++) {
1961 		char *ptr_p = &ptr[i * page_size];
1962 
1963 		ASSERT_EQ(try_read_buf(ptr_p), i % 2 != 0);
1964 	}
1965 
1966 	/* Now remove guard regions. */
1967 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_REMOVE), 0);
1968 
1969 	/* Ensure pattern is as expected. */
1970 	ASSERT_TRUE(check_pattern(ptr, 10, page_size));
1971 
1972 	/* Ensure write seal intact. */
1973 	for (i = 0; i < 10; i++) {
1974 		char *ptr_p = &ptr[i * page_size];
1975 
1976 		ASSERT_FALSE(try_write_buf(ptr_p));
1977 	}
1978 
1979 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
1980 }
1981 
1982 
1983 /*
1984  * Since we are now permitted to establish guard regions in read-only anonymous
1985  * mappings, for the sake of thoroughness, though it probably has no practical
1986  * use, test that guard regions function with a mapping to the anonymous zero
1987  * page.
1988  */
TEST_F(guard_regions,anon_zeropage)1989 TEST_F(guard_regions, anon_zeropage)
1990 {
1991 	const unsigned long page_size = self->page_size;
1992 	char *ptr;
1993 	int i;
1994 
1995 	if (!is_anon_backed(variant))
1996 		SKIP(return, "anon zero page test specific to anon/shmem");
1997 
1998 	/* Obtain a read-only i.e. anon zero page mapping. */
1999 	ptr = mmap_(self, variant, NULL, 10 * page_size, PROT_READ, 0, 0);
2000 	ASSERT_NE(ptr, MAP_FAILED);
2001 
2002 	/* Now make every even page guarded. */
2003 	for (i = 0; i < 10; i += 2) {
2004 		char *ptr_p = &ptr[i * page_size];
2005 
2006 		ASSERT_EQ(madvise(ptr_p, page_size, MADV_GUARD_INSTALL), 0);
2007 	}
2008 
2009 	/* Now assert things are as expected. */
2010 	for (i = 0; i < 10; i++) {
2011 		char *ptr_p = &ptr[i * page_size];
2012 
2013 		ASSERT_EQ(try_read_buf(ptr_p), i % 2 != 0);
2014 	}
2015 
2016 	/* Now remove all guard regions. */
2017 	ASSERT_EQ(madvise(ptr, 10 * page_size, MADV_GUARD_REMOVE), 0);
2018 
2019 	/* Now assert things are as expected. */
2020 	for (i = 0; i < 10; i++) {
2021 		char *ptr_p = &ptr[i * page_size];
2022 
2023 		ASSERT_TRUE(try_read_buf(ptr_p));
2024 	}
2025 
2026 	/* Ensure zero page...*/
2027 	ASSERT_TRUE(is_buf_eq(ptr, 10 * page_size, '\0'));
2028 
2029 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
2030 }
2031 
2032 /*
2033  * Assert that /proc/$pid/pagemap correctly identifies guard region ranges.
2034  */
TEST_F(guard_regions,pagemap)2035 TEST_F(guard_regions, pagemap)
2036 {
2037 	const unsigned long page_size = self->page_size;
2038 	int proc_fd;
2039 	char *ptr;
2040 	int i;
2041 
2042 	proc_fd = open("/proc/self/pagemap", O_RDONLY);
2043 	ASSERT_NE(proc_fd, -1);
2044 
2045 	ptr = mmap_(self, variant, NULL, 10 * page_size,
2046 		    PROT_READ | PROT_WRITE, 0, 0);
2047 	ASSERT_NE(ptr, MAP_FAILED);
2048 
2049 	/* Read from pagemap, and assert no guard regions are detected. */
2050 	for (i = 0; i < 10; i++) {
2051 		char *ptr_p = &ptr[i * page_size];
2052 		unsigned long entry = pagemap_get_entry(proc_fd, ptr_p);
2053 		unsigned long masked = entry & PM_GUARD_REGION;
2054 
2055 		ASSERT_EQ(masked, 0);
2056 	}
2057 
2058 	/* Install a guard region in every other page. */
2059 	for (i = 0; i < 10; i += 2) {
2060 		char *ptr_p = &ptr[i * page_size];
2061 
2062 		ASSERT_EQ(madvise(ptr_p, page_size, MADV_GUARD_INSTALL), 0);
2063 	}
2064 
2065 	/* Re-read from pagemap, and assert guard regions are detected. */
2066 	for (i = 0; i < 10; i++) {
2067 		char *ptr_p = &ptr[i * page_size];
2068 		unsigned long entry = pagemap_get_entry(proc_fd, ptr_p);
2069 		unsigned long masked = entry & PM_GUARD_REGION;
2070 
2071 		ASSERT_EQ(masked, i % 2 == 0 ? PM_GUARD_REGION : 0);
2072 	}
2073 
2074 	ASSERT_EQ(close(proc_fd), 0);
2075 	ASSERT_EQ(munmap(ptr, 10 * page_size), 0);
2076 }
2077 
2078 TEST_HARNESS_MAIN
2079