aboutsummaryrefslogtreecommitdiff
path: root/tests/sys/vm/soxstack/soxstack.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/sys/vm/soxstack/soxstack.c')
-rw-r--r--tests/sys/vm/soxstack/soxstack.c51
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);
+}