summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorart <art@openbsd.org>2002-08-17 22:58:59 +0000
committerart <art@openbsd.org>2002-08-17 22:58:59 +0000
commit31bc67ca70481556b6116415c321321e1c04811f (patch)
tree19a9e2e1bfaa5113baad529e4196a64cd659f583
parentset default value for use_deprecated to 0, to avoid consequences with ftpd. (diff)
downloadwireguard-openbsd-31bc67ca70481556b6116415c321321e1c04811f.tar.xz
wireguard-openbsd-31bc67ca70481556b6116415c321321e1c04811f.zip
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).
-rw-r--r--regress/sys/kern/exec_self/Makefile5
-rw-r--r--regress/sys/kern/exec_self/exec_self.c44
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);
+}