/*- * Copyright (c) 2023 Dmitry Chagin * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include #include #include #include #include #include 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); }