summaryrefslogtreecommitdiff
path: root/tests/sys/vm/soxstack/soxstack.c
blob: ecb672c1b6dc846f047e13ba37dc2169dddfdf45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*-
 * Copyright (c) 2023 Dmitry Chagin <dchagin@FreeBSD.org>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#include <sys/param.h>
#include <sys/sysctl.h>
#include <sys/user.h>

#include <assert.h>
#include <libprocstat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int	checkstack(void);

#define	_STACK_FLAG_GROWS	(KVME_FLAG_GROWS_UP | KVME_FLAG_GROWS_DOWN)
int
checkstack(void)
{
	struct kinfo_vmentry *freep, *kve;
	struct kinfo_proc *p;
	struct procstat *prstat;
	uintptr_t stack;
	int i, cnt;

	prstat = procstat_open_sysctl();
	assert(prstat != NULL);
	p = procstat_getprocs(prstat, KERN_PROC_PID, getpid(), &cnt);
	assert(p != NULL);
	freep = procstat_getvmmap(prstat, p, &cnt);
	assert(freep != NULL);

	stack = (uintptr_t)&i;
	for (i = 0; i < cnt; i++) {
		kve = &freep[i];
		if (stack < kve->kve_start || stack > kve->kve_end)
			continue;
		if ((kve->kve_flags & _STACK_FLAG_GROWS) != 0 &&
		    (kve->kve_protection & KVME_PROT_EXEC) != 0)
			stack = 0;
		break;
	}

	free(freep);
	procstat_freeprocs(prstat, p);
	procstat_close(prstat);
	return (stack != 0);
}