xref: /freebsd/tests/sys/vm/soxstack/soxstack.c (revision eb5fd01b53a6579f3bd5769ed41964683335a7fc)
1 /*-
2  * Copyright (c) 2023 Dmitry Chagin <dchagin@FreeBSD.org>
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #include <sys/param.h>
8 #include <sys/sysctl.h>
9 #include <sys/user.h>
10 
11 #include <assert.h>
12 #include <libprocstat.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <unistd.h>
16 
17 int	checkstack(void);
18 
19 #define	_STACK_FLAG_GROWS	(KVME_FLAG_GROWS_UP | KVME_FLAG_GROWS_DOWN)
20 int
checkstack(void)21 checkstack(void)
22 {
23 	struct kinfo_vmentry *freep, *kve;
24 	struct kinfo_proc *p;
25 	struct procstat *prstat;
26 	uintptr_t stack;
27 	int i, cnt;
28 
29 	prstat = procstat_open_sysctl();
30 	assert(prstat != NULL);
31 	p = procstat_getprocs(prstat, KERN_PROC_PID, getpid(), &cnt);
32 	assert(p != NULL);
33 	freep = procstat_getvmmap(prstat, p, &cnt);
34 	assert(freep != NULL);
35 
36 	stack = (uintptr_t)&i;
37 	for (i = 0; i < cnt; i++) {
38 		kve = &freep[i];
39 		if (stack < kve->kve_start || stack > kve->kve_end)
40 			continue;
41 		if ((kve->kve_flags & _STACK_FLAG_GROWS) != 0 &&
42 		    (kve->kve_protection & KVME_PROT_EXEC) != 0)
43 			stack = 0;
44 		break;
45 	}
46 
47 	free(freep);
48 	procstat_freeprocs(prstat, p);
49 	procstat_close(prstat);
50 	return (stack != 0);
51 }
52