Add a check whether the stack is executable when needed, and one whether

the stack is non-executable if not explicitely enabled.
The latter one is not enabled in the Makefile yet because it cannot
succeed on platforms where the non-exec stack is not implemented.
Both checks rely on the fact that gcc puts trampoline onto the stack
for nested functions. On platforms where no such trampolines are used,
no meaningful results can be expected.
While not perfect, this is much easier than hand-coding trampolines for
each CPU type.
This commit is contained in:
drochner 2003-12-10 13:24:59 +00:00
parent d11f9c3d61
commit 7e4c34eca1
5 changed files with 127 additions and 2 deletions

View File

@ -1,5 +1,5 @@
# $NetBSD: Makefile,v 1.1 1999/06/19 00:53:32 thorpej Exp $
# $NetBSD: Makefile,v 1.2 2003/12/10 13:24:59 drochner Exp $
SUBDIR+= mmap
SUBDIR+= mmap stack_exec
.include <bsd.subdir.mk>

View File

@ -0,0 +1,14 @@
# $NetBSD: Makefile,v 1.1 2003/12/10 13:24:59 drochner Exp $
NOMAN= #
PROG= tramptest
LDADD= -lpthread
regress:
@if ./tramptest; then \
echo "PASSED"; \
else \
echo "FAILED"; \
fi
.include <bsd.prog.mk>

View File

@ -0,0 +1,44 @@
/* $NetBSD: tramptest.c,v 1.1 2003/12/10 13:24:59 drochner Exp $ */
#include <stdlib.h>
#include <pthread.h>
#include <signal.h>
/*
* This test checks whether processes/threads get execute permission
* on the stack if needed, in particular for multiple threads.
* It depends on the fact that gcc puts trampoline code for
* nested functions on the stack and requests execution permission
* for that address internally, at least on some architectures.
* (On the other architectures, the test is just insignificant.)
* Actually, it would be better if gcc wouldn't use stack trampolines,
* at all, but for now it allows for an easy portable check whether the
* kernel handles permissions correctly.
*/
void
buserr(int s)
{
exit(1);
}
int
main()
{
pthread_t t1, t2;
void *mist(void *p)
{
return (0);
}
signal(SIGBUS, buserr);
pthread_create(&t1, 0, mist, 0);
pthread_create(&t2, 0, mist, 0);
pthread_join(t1, 0);
pthread_join(t2, 0);
exit(0);
}

View File

@ -0,0 +1,13 @@
# $NetBSD: Makefile,v 1.1 2003/12/10 13:24:59 drochner Exp $
NOMAN= #
PROG= tramptest
regress:
@if ./tramptest; then \
echo "PASSED"; \
else \
echo "FAILED"; \
fi
.include <bsd.prog.mk>

View File

@ -0,0 +1,54 @@
/* $NetBSD: tramptest.c,v 1.1 2003/12/10 13:24:59 drochner Exp $ */
#include <stdlib.h>
#include <signal.h>
/*
* This test checks that the stack has no execute permission.
* It depends on the fact that gcc puts trampoline code for
* nested functions on the stack, at least on some architectures.
* (On the other architectures, the test will fail, as on platforms
* where execution permissions cannot be controlled.)
* Actually, it would be better if gcc wouldn't use stack trampolines,
* at all, but for now it allows for an easy portable check whether the
* stack is executable.
*/
void
__enable_execute_stack()
{
/* replace gcc's internal function by a noop */
}
void
buserr(int s)
{
exit(0);
}
void (*f)(void);
void do_f()
{
(*f)();
}
int
main()
{
void mist()
{
return;
}
signal(SIGBUS, buserr);
f = mist;
do_f();
exit(1);
}