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)21checkstack(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