diff options
Diffstat (limited to 'tests/sys/vm/soxstack/soxstack.c')
-rw-r--r-- | tests/sys/vm/soxstack/soxstack.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/tests/sys/vm/soxstack/soxstack.c b/tests/sys/vm/soxstack/soxstack.c new file mode 100644 index 000000000000..ecb672c1b6dc --- /dev/null +++ b/tests/sys/vm/soxstack/soxstack.c @@ -0,0 +1,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); +} |