summaryrefslogtreecommitdiff
path: root/regress/sys/kern/pledge
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2018-04-10 23:00:54 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2018-04-10 23:00:54 +0000
commit23485276f6dc73b044d1239bbddab30d9485abc6 (patch)
tree4bc42c1f76692b7dcd7ab83f7378a9cbedb9b7c9 /regress/sys/kern/pledge
parenta5e4bbad7624f811d7dfc1bdeaecd19f15916a01 (diff)
Check that a file descriptor's plegde flag is correctly propagated.
The test covers the system calls dup, dup2, dup3, open /dev/fd, and file descriptor passing. The fstat(1) output is analysed.
Diffstat (limited to 'regress/sys/kern/pledge')
-rw-r--r--regress/sys/kern/pledge/filedescriptor/Makefile87
-rw-r--r--regress/sys/kern/pledge/filedescriptor/dev.c44
-rw-r--r--regress/sys/kern/pledge/filedescriptor/dup.c30
-rw-r--r--regress/sys/kern/pledge/filedescriptor/dup2.c46
-rw-r--r--regress/sys/kern/pledge/filedescriptor/dup3.c47
-rw-r--r--regress/sys/kern/pledge/filedescriptor/header.h18
-rw-r--r--regress/sys/kern/pledge/filedescriptor/main.c57
-rw-r--r--regress/sys/kern/pledge/filedescriptor/pass.c97
8 files changed, 426 insertions, 0 deletions
diff --git a/regress/sys/kern/pledge/filedescriptor/Makefile b/regress/sys/kern/pledge/filedescriptor/Makefile
new file mode 100644
index 00000000000..af588425be4
--- /dev/null
+++ b/regress/sys/kern/pledge/filedescriptor/Makefile
@@ -0,0 +1,87 @@
+# $OpenBSD: Makefile,v 1.1.1.1 2018/04/10 23:00:53 bluhm Exp $
+
+# Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+PROGS = dup dup2 dup3 dev pass
+WARNINGS = yes
+CLEANFILES = *.fstat
+
+.if make (regress) || make (all)
+.BEGIN:
+ rm -f -- *.fstat
+.endif
+
+.for p in ${PROGS}
+
+SRCS_$p = main.c $p.c
+REGRESS_TARGETS += run-regress-$p
+
+$p.fstat: $p
+ ./$p >$@.tmp
+ mv $@.tmp $@
+ # file descriptor 3 has been opened before pledge
+ grep ' 3 /.* r ' $@
+ # file descriptor 4 has been opened after pledge
+ grep ' 4 /.* rp ' $@
+
+.endfor
+
+run-regress-dup: dup.fstat
+ # file descriptor 5 has been dup(2)ed from pre-pledge
+ grep ' 5 /.* r ' dup.fstat
+ # file descriptor 6 has been dup(2)ed from post-pledge
+ grep ' 6 /.* rp ' dup.fstat
+
+run-regress-dup2: dup2.fstat
+ # file descriptor 5 has been dup2(2)ed from pre-pledge
+ grep ' 5 /.* r ' dup2.fstat
+ # file descriptor 6 has been dup2(2)ed from post-pledge
+ grep ' 6 /.* rp ' dup2.fstat
+ # dup2(2) closes pre-pledge and overwrites with post-pledge
+ grep ' 7 /.* rp ' dup2.fstat
+ # dup2(2) closes post-pledge and overwrites with pre-pledge
+ grep ' 8 /.* r ' dup2.fstat
+ # dup2(2) pre-pledge onto itself
+ grep ' 9 /.* r ' dup2.fstat
+ # dup2(2) post-pledge onto itself
+ grep ' 10 /.* rp ' dup2.fstat
+
+run-regress-dup3: dup3.fstat
+ # file descriptor 5 has been dup3(2)ed from pre-pledge
+ grep ' 5 /.* re ' dup3.fstat
+ # file descriptor 6 has been dup3(2)ed from post-pledge
+ grep ' 6 /.* rep ' dup3.fstat
+ # dup3(2) closes pre-pledge and overwrites with post-pledge
+ grep ' 7 /.* rep ' dup3.fstat
+ # dup3(2) closes post-pledge and overwrites with pre-pledge
+ grep ' 8 /.* re ' dup3.fstat
+ # dup3(2) pre-pledge onto itself fails
+ grep ' 9 /.* r ' dup3.fstat
+ # dup3(2) post-pledge onto itself fails
+ grep ' 10 /.* rp ' dup3.fstat
+
+run-regress-dev: dev.fstat
+ # file descriptor 5 has been open(2)ed from pre-pledge /dev/fd/3
+ grep ' 5 /.* rp ' dev.fstat
+ # file descriptor 6 has been open(2)ed from post-pledge /dev/fd/4
+ grep ' 6 /.* rp ' dev.fstat
+
+run-regress-pass: pass.fstat
+ # file descriptor 7 has been passed from pre-pledge
+ grep ' 7 /.* r ' pass.fstat
+ # file descriptor 8 has been passed from post-pledge
+ grep ' 8 /.* rp ' pass.fstat
+
+.include <bsd.regress.mk>
diff --git a/regress/sys/kern/pledge/filedescriptor/dev.c b/regress/sys/kern/pledge/filedescriptor/dev.c
new file mode 100644
index 00000000000..bae95c8687d
--- /dev/null
+++ b/regress/sys/kern/pledge/filedescriptor/dev.c
@@ -0,0 +1,44 @@
+/* $OpenBSD: dev.c,v 1.1.1.1 2018/04/10 23:00:53 bluhm Exp $ */
+/*
+ * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "header.h"
+
+void
+fdops(int fdpre, int fdpost)
+{
+ char *devpre, *devpost;
+
+ if (asprintf(&devpre, "/dev/fd/%d", fdpre) == -1)
+ err(1, "asprintf fdpre");
+ if (asprintf(&devpost, "/dev/fd/%d", fdpost) == -1)
+ err(1, "asprintf fdpost");
+
+ if (open(devpre, O_RDONLY) == -1)
+ err(1, "open dev pre");
+ if (open(devpost, O_RDONLY) == -1)
+ err(1, "open dev post");
+
+ free(devpre);
+ free(devpost);
+}
diff --git a/regress/sys/kern/pledge/filedescriptor/dup.c b/regress/sys/kern/pledge/filedescriptor/dup.c
new file mode 100644
index 00000000000..ab8bc51c5b3
--- /dev/null
+++ b/regress/sys/kern/pledge/filedescriptor/dup.c
@@ -0,0 +1,30 @@
+/* $OpenBSD: dup.c,v 1.1.1.1 2018/04/10 23:00:53 bluhm Exp $ */
+/*
+ * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <err.h>
+#include <unistd.h>
+
+#include "header.h"
+
+void
+fdops(int fdpre, int fdpost)
+{
+ if (dup(fdpre) == -1)
+ err(1, "dup pre");
+ if (dup(fdpost) == -1)
+ err(1, "dup post");
+}
diff --git a/regress/sys/kern/pledge/filedescriptor/dup2.c b/regress/sys/kern/pledge/filedescriptor/dup2.c
new file mode 100644
index 00000000000..f4cb0a59ff0
--- /dev/null
+++ b/regress/sys/kern/pledge/filedescriptor/dup2.c
@@ -0,0 +1,46 @@
+/* $OpenBSD: dup2.c,v 1.1.1.1 2018/04/10 23:00:53 bluhm Exp $ */
+/*
+ * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <err.h>
+#include <unistd.h>
+
+#include "header.h"
+
+void
+fdops(int fdpre, int fdpost)
+{
+ if (dup2(fdpre, 5) == -1)
+ err(1, "dup2 pre");
+ if (dup2(fdpost, 6) == -1)
+ err(1, "dup2 post");
+ if (dup2(fdpre, 7) == -1)
+ err(1, "dup2 pepare post overwite");
+ if (dup2(fdpost, 7) == -1)
+ err(1, "dup2 post overwrite");
+ if (dup2(fdpost, 8) == -1)
+ err(1, "dup2 pepare pre overwrite");
+ if (dup2(fdpre, 8) == -1)
+ err(1, "dup2 pre overwite");
+ if (dup2(fdpre, 9) == -1)
+ err(1, "dup2 pepare pre equal");
+ if (dup2(9, 9) == -1)
+ err(1, "dup2 pre equal");
+ if (dup2(fdpost, 10) == -1)
+ err(1, "dup2 pepare post equal");
+ if (dup2(10, 10) == -1)
+ err(1, "dup2 post equal");
+}
diff --git a/regress/sys/kern/pledge/filedescriptor/dup3.c b/regress/sys/kern/pledge/filedescriptor/dup3.c
new file mode 100644
index 00000000000..1f6d8317f39
--- /dev/null
+++ b/regress/sys/kern/pledge/filedescriptor/dup3.c
@@ -0,0 +1,47 @@
+/* $OpenBSD: dup3.c,v 1.1.1.1 2018/04/10 23:00:53 bluhm Exp $ */
+/*
+ * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <err.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "header.h"
+
+void
+fdops(int fdpre, int fdpost)
+{
+ if (dup3(fdpre, 5, O_CLOEXEC) == -1)
+ err(1, "dup3 pre");
+ if (dup3(fdpost, 6, O_CLOEXEC) == -1)
+ err(1, "dup3 post");
+ if (dup3(fdpre, 7, O_CLOEXEC) == -1)
+ err(1, "dup3 pepare post overwite");
+ if (dup3(fdpost, 7, O_CLOEXEC) == -1)
+ err(1, "dup3 post overwrite");
+ if (dup3(fdpost, 8, O_CLOEXEC) == -1)
+ err(1, "dup3 pepare pre overwrite");
+ if (dup3(fdpre, 8, O_CLOEXEC) == -1)
+ err(1, "dup3 pre overwite");
+ if (dup3(fdpre, 9, 0) == -1)
+ err(1, "dup3 pepare pre equal");
+ if (dup3(9, 9, O_CLOEXEC) != -1)
+ errx(1, "dup3 pre equal succeeded");
+ if (dup3(fdpost, 10, 0) == -1)
+ err(1, "dup3 pepare post equal");
+ if (dup3(10, 10, O_CLOEXEC) != -1)
+ errx(1, "dup3 post equal succeeded");
+}
diff --git a/regress/sys/kern/pledge/filedescriptor/header.h b/regress/sys/kern/pledge/filedescriptor/header.h
new file mode 100644
index 00000000000..2af5c9f4112
--- /dev/null
+++ b/regress/sys/kern/pledge/filedescriptor/header.h
@@ -0,0 +1,18 @@
+/* $OpenBSD: header.h,v 1.1.1.1 2018/04/10 23:00:53 bluhm Exp $ */
+/*
+ * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+void fdops(int, int);
diff --git a/regress/sys/kern/pledge/filedescriptor/main.c b/regress/sys/kern/pledge/filedescriptor/main.c
new file mode 100644
index 00000000000..38f894d3611
--- /dev/null
+++ b/regress/sys/kern/pledge/filedescriptor/main.c
@@ -0,0 +1,57 @@
+/* $OpenBSD: main.c,v 1.1.1.1 2018/04/10 23:00:53 bluhm Exp $ */
+/*
+ * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "header.h"
+
+int
+main(int argc, char *argv[])
+{
+ char *cmd;
+ pid_t self;
+ int fdpre, fdpost, ret;
+
+ if ((fdpre = open("/dev/null", O_RDONLY)) == -1)
+ err(1, "open pre");
+ if (pledge("exec stdio proc recvfd rpath sendfd", NULL) == -1)
+ err(1, "pledge");
+ if ((fdpost = open("/dev/null", O_RDONLY)) == -1)
+ err(1, "open post");
+
+ fdops(fdpre, fdpost);
+
+ self = getpid();
+ if (asprintf(&cmd, "/usr/bin/fstat -p %d", self) == -1)
+ err(1, "asprintf");
+ ret = system(cmd);
+ switch (ret) {
+ case -1:
+ err(1, "system");
+ case 0:
+ break;
+ default:
+ errx(1, "'%s' failed: %d", cmd, ret);
+ }
+ free(cmd);
+
+ return 0;
+}
diff --git a/regress/sys/kern/pledge/filedescriptor/pass.c b/regress/sys/kern/pledge/filedescriptor/pass.c
new file mode 100644
index 00000000000..527842a6531
--- /dev/null
+++ b/regress/sys/kern/pledge/filedescriptor/pass.c
@@ -0,0 +1,97 @@
+/* $OpenBSD: pass.c,v 1.1.1.1 2018/04/10 23:00:53 bluhm Exp $ */
+/*
+ * Copyright (c) 2018 Alexander Bluhm <bluhm@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/socket.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "header.h"
+
+void
+fdops(int fdpre, int fdpost)
+{
+ struct msghdr msg;
+ struct iovec iov[1];
+ char buf[1];
+ struct cmsghdr *cmsg;
+ union {
+ struct cmsghdr hdr;
+ unsigned char buf[CMSG_SPACE(sizeof(int))];
+ } cmsgbuf;
+ pid_t child;
+ int pair[2], status;
+
+ if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) == -1)
+ err(1, "socketpair");
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_control = &cmsgbuf.buf;
+ msg.msg_controllen = sizeof(cmsgbuf.buf);
+
+ if ((child = fork()) == -1)
+ err(1, "fork");
+
+ if (child == 0) {
+
+ /* child process */
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+
+ *(int *)CMSG_DATA(cmsg) = fdpre;
+ if (sendmsg(pair[1], &msg, 0) == -1)
+ err(1, "sendmsg pre");
+
+ cmsg = CMSG_FIRSTHDR(&msg);
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+
+ *(int *)CMSG_DATA(cmsg) = fdpost;
+ if (sendmsg(pair[1], &msg, 0) == -1)
+ err(1, "sendmsg post");
+
+ _exit(0);
+ }
+
+ /* parent process */
+
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ iov[0].iov_base = buf;
+ iov[0].iov_len = sizeof(buf);
+
+ if (recvmsg(pair[0], &msg, 0) == -1)
+ err(1, "recvmsg pre");
+ if ((msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_CTRUNC))
+ errx(1, "trunk pre");
+
+ if (recvmsg(pair[0], &msg, 0) == -1)
+ err(1, "recvmsg post");
+ if ((msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_CTRUNC))
+ errx(1, "trunk post");
+
+ if (waitpid(child, &status, 0) == -1)
+ err(1, "waitpid");
+ if (status != 0)
+ errx(1, "child failed: %d", status);
+}