summaryrefslogtreecommitdiff
path: root/lib/libc/stdlib/exit.c
diff options
context:
space:
mode:
authorDaniel Hartmeier <dhartmei@cvs.openbsd.org>2002-07-29 19:54:43 +0000
committerDaniel Hartmeier <dhartmei@cvs.openbsd.org>2002-07-29 19:54:43 +0000
commitb44bddec975d44d19e71af201374cff9bd96f615 (patch)
tree30fcf41088a705268515031c2a31e7c96b65808e /lib/libc/stdlib/exit.c
parent865fdcdce92da25d834f892d6351e4cf1a54995d (diff)
Replace atexit handler. mprotect() the pages so an attempt to modify the
function pointers from the outside will segfault. Idea, hints and feedback from deraadt. ok deraadt.
Diffstat (limited to 'lib/libc/stdlib/exit.c')
-rw-r--r--lib/libc/stdlib/exit.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/lib/libc/stdlib/exit.c b/lib/libc/stdlib/exit.c
index ab53f9400bc..c16b33bd300 100644
--- a/lib/libc/stdlib/exit.c
+++ b/lib/libc/stdlib/exit.c
@@ -32,9 +32,11 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$OpenBSD: exit.c,v 1.4 2000/01/06 08:45:50 d Exp $";
+static char *rcsid = "$OpenBSD: exit.c,v 1.5 2002/07/29 19:54:42 dhartmei Exp $";
#endif /* LIBC_SCCS and not lint */
+#include <sys/types.h>
+#include <sys/mman.h>
#include <stdlib.h>
#include <unistd.h>
#include "atexit.h"
@@ -58,12 +60,19 @@ void
exit(status)
int status;
{
- register struct atexit *p;
- register int n;
+ register struct atexit *p, *q;
+ register int n, pgsize = getpagesize();
- for (p = __atexit; p; p = p->next)
- for (n = p->ind; --n >= 0;)
- (*p->fns[n])();
+ if (!__atexit_invalid) {
+ p = __atexit;
+ while (p != NULL) {
+ for (n = p->ind; --n >= 0;)
+ (*p->fns[n])();
+ q = p;
+ p = p->next;
+ munmap(q, pgsize);
+ }
+ }
if (__cleanup)
(*__cleanup)();
_exit(status);