diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2002-08-17 22:59:00 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2002-08-17 22:59:00 +0000 |
commit | 7f2b2a365a362b001f712a8a345f416d49e6d6c7 (patch) | |
tree | 17851c809d9c905f2743a7fc7f561d373658c0a6 /regress | |
parent | aaccdca47a058c200f2afff68b3ae39a04aebc77 (diff) |
Test for a nasty complication in the exec code.
What happens is that if an executable tries to exec itself (happens all
the time on the ramdisk, among others) and needs to page in a page from
the data segment (or rodata) it will need to perform a pagein operation
on the vnode that's execing right now. exec keeps that vnode locked and
fails (no deadlock, that part was fixed a long time ago).
Diffstat (limited to 'regress')
-rw-r--r-- | regress/sys/kern/exec_self/Makefile | 5 | ||||
-rw-r--r-- | regress/sys/kern/exec_self/exec_self.c | 44 |
2 files changed, 49 insertions, 0 deletions
diff --git a/regress/sys/kern/exec_self/Makefile b/regress/sys/kern/exec_self/Makefile new file mode 100644 index 00000000000..ef8635b6d4d --- /dev/null +++ b/regress/sys/kern/exec_self/Makefile @@ -0,0 +1,5 @@ +# $OpenBSD: Makefile,v 1.1 2002/08/17 22:58:59 art Exp $ + +PROG= exec_self + +.include <bsd.regress.mk> diff --git a/regress/sys/kern/exec_self/exec_self.c b/regress/sys/kern/exec_self/exec_self.c new file mode 100644 index 00000000000..4bf39af5f7c --- /dev/null +++ b/regress/sys/kern/exec_self/exec_self.c @@ -0,0 +1,44 @@ +/* $OpenBSD: exec_self.c,v 1.1 2002/08/17 22:58:59 art Exp $ */ +/* + * Written by Artur Grabowski <art@openbsd.org> 2002 Public Domain. + */ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <err.h> +#include <sys/types.h> +#include <sys/mman.h> + +struct { + const char pad1[256*1024]; /* avoid read-ahead. */ + const char string[256*1024]; /* at least one page */ + const char pad2[256*1024]; /* avoid read-behind. */ +} const blob = { + "padding1", + "the_test", + "padding2" +}; + +int +main(int argc, char **argv) +{ + int pgsz = getpagesize(); + vaddr_t va, off; + + if (argc > 1) { + return (0); + } + va = (vaddr_t)&blob; + off = va & (pgsz - 1); + + /* Make sure that nothing in the "blob" is cached. */ + if (madvise((void *)(va - off), sizeof(blob) + (off > 0 ? pgsz : 0), + MADV_FREE)) + err(1, "madvise"); + + if (execl(argv[0], argv[0], &blob.string, NULL)) + err(1, "execl"); + + /* NOTREACHED */ + return (1); +} |