1 /*-
2  * Copyright (c) 2023 Dmitry Chagin <dchagin@FreeBSD.org>
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  *
6  * PR:	272585
7  * Test provided by John F. Carr
8  */
9 
10 #include <sys/systm.h>
11 #include <sys/mman.h>
12 #include <vm/vm_param.h>
13 
14 #include <atf-c.h>
15 #include <signal.h>
16 #include <unistd.h>
17 
18 static void
19 sigsegv_handler(int sig __unused)
20 {
21 
22 	atf_tc_fail("Invalid stack protection mode after grows");
23 }
24 
25 ATF_TC_WITHOUT_HEAD(mprotect_exec_test);
26 ATF_TC_BODY(mprotect_exec_test, tc)
27 {
28 	long pagesize;
29 	char *addr, *guard;
30 	size_t alloc_size;
31 
32 	signal(SIGSEGV, sigsegv_handler);
33 
34 	pagesize = sysconf(_SC_PAGESIZE);
35 	ATF_REQUIRE(pagesize > 0);
36 
37 	alloc_size = SGROWSIZ * 2;
38 	addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE,
39 	    MAP_STACK | MAP_PRIVATE | MAP_ANON, -1, 0);
40 	ATF_REQUIRE(addr != MAP_FAILED);
41 
42 	/*
43 	 * Change prot of the last page in the mmaped stack area.
44 	 */
45 	guard = addr + alloc_size - SGROWSIZ;
46 	ATF_REQUIRE(mprotect(guard, pagesize, PROT_NONE) == 0);
47 
48 	((volatile char *)guard)[-1];
49 }
50 
51 ATF_TP_ADD_TCS(tp)
52 {
53 
54 	ATF_TP_ADD_TC(tp, mprotect_exec_test);
55 
56 	return (atf_no_error());
57 }
58