tests: Add stack grows tests
Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D41320 MFC after: 2 weeks
This commit is contained in:
parent
58a46cfd75
commit
8920c5f2a1
@ -897,6 +897,8 @@
|
|||||||
vfs
|
vfs
|
||||||
..
|
..
|
||||||
vm
|
vm
|
||||||
|
stack
|
||||||
|
..
|
||||||
..
|
..
|
||||||
vmm
|
vmm
|
||||||
..
|
..
|
||||||
|
@ -17,4 +17,9 @@ ATF_TESTS_SH+= mmap_map_32bit_test
|
|||||||
PROGS+= mmap_map_32bit_helper
|
PROGS+= mmap_map_32bit_helper
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
|
SUBDIR= soxstack
|
||||||
|
TESTS_SUBDIRS+= stack
|
||||||
|
|
||||||
|
SUBDIR_DEPENDS_stack=soxstack
|
||||||
|
|
||||||
.include <bsd.test.mk>
|
.include <bsd.test.mk>
|
||||||
|
17
tests/sys/vm/soxstack/Makefile
Normal file
17
tests/sys/vm/soxstack/Makefile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
SHLIB= soxstack
|
||||||
|
SHLIB_NAME= libsoxstack.so
|
||||||
|
SHLIB_MAJOR= 1
|
||||||
|
|
||||||
|
WITHOUT_STATIC=
|
||||||
|
WITHOUT_PROFILE=
|
||||||
|
WITHOUT_PIC=
|
||||||
|
|
||||||
|
SRCS= soxstack.c
|
||||||
|
LDFLAGS+= -Wl,-z,execstack
|
||||||
|
LIBADD+= procstat
|
||||||
|
|
||||||
|
LIBDIR= ${TESTSBASE}/sys/vm/stack
|
||||||
|
|
||||||
|
.include <bsd.lib.mk>
|
51
tests/sys/vm/soxstack/soxstack.c
Normal file
51
tests/sys/vm/soxstack/soxstack.c
Normal file
@ -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;
|
||||||
|
uint64_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 = (uint64_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);
|
||||||
|
}
|
15
tests/sys/vm/stack/Makefile
Normal file
15
tests/sys/vm/stack/Makefile
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
PACKAGE= tests
|
||||||
|
|
||||||
|
TESTSDIR= ${TESTSBASE}/sys/vm/stack
|
||||||
|
|
||||||
|
ATF_TESTS_C+= stack_dt_need_exec_test
|
||||||
|
ATF_TESTS_C+= stack_dlopen_exec_test
|
||||||
|
ATF_TESTS_C+= stack_mprotect_exec_test
|
||||||
|
|
||||||
|
LDFLAGS.stack_dt_need_exec_test+= -Wl,-rpath,${TESTSDIR} -L${.OBJDIR:H}/soxstack
|
||||||
|
LDADD.stack_dt_need_exec_test+= -lsoxstack
|
||||||
|
LDFLAGS.stack_dlopen_exec_test+= -Wl,-rpath,${TESTSDIR}
|
||||||
|
|
||||||
|
.include <bsd.test.mk>
|
64
tests/sys/vm/stack/stack_dlopen_exec_test.c
Normal file
64
tests/sys/vm/stack/stack_dlopen_exec_test.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2023 Dmitry Chagin <dchagin@FreeBSD.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <vm/vm_param.h>
|
||||||
|
|
||||||
|
#include <atf-c.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
static int jumpstack0(void) __noinline;
|
||||||
|
static int jumpstack1(void) __noinline;
|
||||||
|
|
||||||
|
static int (*socheckstack)(void) = NULL;
|
||||||
|
|
||||||
|
static int
|
||||||
|
checkstack(void)
|
||||||
|
{
|
||||||
|
void *fh;
|
||||||
|
|
||||||
|
if (socheckstack == NULL) {
|
||||||
|
fh = dlopen("libsoxstack.so", RTLD_LAZY);
|
||||||
|
ATF_REQUIRE(fh != NULL);
|
||||||
|
socheckstack = dlsym(fh, "checkstack");
|
||||||
|
ATF_REQUIRE(socheckstack != NULL);
|
||||||
|
}
|
||||||
|
return (socheckstack());
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
jumpstack0(void)
|
||||||
|
{
|
||||||
|
char stack[SGROWSIZ];
|
||||||
|
|
||||||
|
explicit_bzero(stack, sizeof(stack));
|
||||||
|
return (checkstack());
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
jumpstack1(void)
|
||||||
|
{
|
||||||
|
char stack[SGROWSIZ * 2];
|
||||||
|
|
||||||
|
explicit_bzero(stack, sizeof(stack));
|
||||||
|
return (checkstack());
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC_WITHOUT_HEAD(dlopen_test);
|
||||||
|
ATF_TC_BODY(dlopen_test, tc)
|
||||||
|
{
|
||||||
|
|
||||||
|
ATF_REQUIRE(jumpstack0() == 0);
|
||||||
|
ATF_REQUIRE(jumpstack1() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TP_ADD_TCS(tp)
|
||||||
|
{
|
||||||
|
|
||||||
|
ATF_TP_ADD_TC(tp, dlopen_test);
|
||||||
|
|
||||||
|
return (atf_no_error());
|
||||||
|
}
|
50
tests/sys/vm/stack/stack_dt_need_exec_test.c
Normal file
50
tests/sys/vm/stack/stack_dt_need_exec_test.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2023 Dmitry Chagin <dchagin@FreeBSD.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <vm/vm_param.h>
|
||||||
|
|
||||||
|
#include <atf-c.h>
|
||||||
|
|
||||||
|
extern int checkstack(void);
|
||||||
|
|
||||||
|
static int jumpstack0(void) __noinline;
|
||||||
|
static int jumpstack1(void) __noinline;
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
jumpstack0(void)
|
||||||
|
{
|
||||||
|
char stack[SGROWSIZ];
|
||||||
|
|
||||||
|
explicit_bzero(stack, sizeof(stack));
|
||||||
|
return (checkstack());
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
jumpstack1(void)
|
||||||
|
{
|
||||||
|
char stack[SGROWSIZ * 2];
|
||||||
|
|
||||||
|
explicit_bzero(stack, sizeof(stack));
|
||||||
|
return (checkstack());
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TC_WITHOUT_HEAD(dt_need_test);
|
||||||
|
ATF_TC_BODY(dt_need_test, tc)
|
||||||
|
{
|
||||||
|
|
||||||
|
ATF_REQUIRE(jumpstack0() == 0);
|
||||||
|
ATF_REQUIRE(jumpstack1() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TP_ADD_TCS(tp)
|
||||||
|
{
|
||||||
|
|
||||||
|
ATF_TP_ADD_TC(tp, dt_need_test);
|
||||||
|
|
||||||
|
return (atf_no_error());
|
||||||
|
}
|
48
tests/sys/vm/stack/stack_mprotect_exec_test.c
Normal file
48
tests/sys/vm/stack/stack_mprotect_exec_test.c
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2023 Dmitry Chagin <dchagin@FreeBSD.org>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* PR: 272585
|
||||||
|
* Test provided by John F. Carr
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <vm/vm_param.h>
|
||||||
|
|
||||||
|
#include <atf-c.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
ATF_TC_WITHOUT_HEAD(mprotect_exec_test);
|
||||||
|
ATF_TC_BODY(mprotect_exec_test, tc)
|
||||||
|
{
|
||||||
|
long pagesize;
|
||||||
|
char *addr, *guard;
|
||||||
|
size_t alloc_size;
|
||||||
|
|
||||||
|
pagesize = sysconf(_SC_PAGESIZE);
|
||||||
|
ATF_REQUIRE(pagesize > 0);
|
||||||
|
|
||||||
|
alloc_size = SGROWSIZ * 2;
|
||||||
|
addr = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE,
|
||||||
|
MAP_STACK | MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||||
|
ATF_REQUIRE(addr != MAP_FAILED);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change prot of the last page in the mmaped stack area.
|
||||||
|
*/
|
||||||
|
guard = addr + alloc_size - SGROWSIZ;
|
||||||
|
ATF_REQUIRE(mprotect(guard, pagesize, PROT_NONE) == 0);
|
||||||
|
|
||||||
|
((volatile char *)guard)[-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
ATF_TP_ADD_TCS(tp)
|
||||||
|
{
|
||||||
|
|
||||||
|
ATF_TP_ADD_TC(tp, mprotect_exec_test);
|
||||||
|
|
||||||
|
return (atf_no_error());
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user