diff options
author | 2016-03-31 23:00:46 +0000 | |
---|---|---|
committer | 2016-03-31 23:00:46 +0000 | |
commit | eaf6a821b6b7a2c84d4641e7c5912a76e70adfe2 (patch) | |
tree | eef4926ccc0ae24164f09313356f7cfdc06da141 | |
parent | Increase size of the clone bitmap. A limit of only 64 device clones (diff) | |
download | wireguard-openbsd-eaf6a821b6b7a2c84d4641e7c5912a76e70adfe2.tar.xz wireguard-openbsd-eaf6a821b6b7a2c84d4641e7c5912a76e70adfe2.zip |
Go in the background much later, to reduce possible silent failures.
rev. 1.34 moved the call to daemon() before the chroot, thus hiding
errors if the target directory or _tftpd user don't exist. To go in the
background later we need to preopen /dev/null. The code is put in
a daemon(3) like function that could be used in other daemons.
Lack of error reporting spotted by ajacoutot@, initial diff from dlg@.
rdaemon() "concept" discussed with semarie@. ok ajacoutot@ dlg@
-rw-r--r-- | usr.sbin/tftpd/tftpd.c | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/usr.sbin/tftpd/tftpd.c b/usr.sbin/tftpd/tftpd.c index d3d4ecbade6..5c4ac7a4830 100644 --- a/usr.sbin/tftpd/tftpd.c +++ b/usr.sbin/tftpd/tftpd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tftpd.c,v 1.34 2015/12/14 16:34:55 semarie Exp $ */ +/* $OpenBSD: tftpd.c,v 1.35 2016/03/31 23:00:46 jca Exp $ */ /* * Copyright (c) 2012 David Gwynne <dlg@uq.edu.au> @@ -74,6 +74,7 @@ #include <errno.h> #include <event.h> #include <fcntl.h> +#include <paths.h> #include <poll.h> #include <pwd.h> #include <stdio.h> @@ -152,6 +153,7 @@ struct tftp_client { __dead void usage(void); const char *getip(void *); +int rdaemon(int devnull); void rewrite_connect(const char *); void rewrite_events(void); @@ -285,6 +287,7 @@ main(int argc, char *argv[]) char *addr = NULL; char *port = "tftp"; int family = AF_UNSPEC; + int devnull = -1; while ((c = getopt(argc, argv, "46cdl:p:r:v")) != -1) { switch (c) { @@ -337,6 +340,9 @@ main(int argc, char *argv[]) openlog(__progname, LOG_PID|LOG_NDELAY, LOG_DAEMON); tzset(); logger = &syslogger; + devnull = open(_PATH_DEVNULL, O_RDWR, 0); + if (devnull == -1) + err(1, "open %s", _PATH_DEVNULL); } if (rewrite != NULL) @@ -344,9 +350,6 @@ main(int argc, char *argv[]) tftpd_listen(addr, port, family); - if (!debug && daemon(1, 0) == -1) - err(1, "unable to daemonize"); - if (chroot(dir)) err(1, "chroot %s", dir); if (chdir("/")) @@ -358,8 +361,11 @@ main(int argc, char *argv[]) setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) errx(1, "can't drop privileges"); + if (!debug && rdaemon(devnull) == -1) + err(1, "unable to daemonize"); + if (pledge("stdio rpath wpath cpath fattr dns inet", NULL) == -1) - err(1, "pledge"); + lerr(1, "pledge"); event_init(); @@ -1556,6 +1562,32 @@ getip(void *s) return(hbuf); } +/* daemon(3) clone, intended to be used in a "r"estricted environment */ +int +rdaemon(int devnull) +{ + + switch (fork()) { + case -1: + return (-1); + case 0: + break; + default: + _exit(0); + } + + if (setsid() == -1) + return (-1); + + (void)dup2(devnull, STDIN_FILENO); + (void)dup2(devnull, STDOUT_FILENO); + (void)dup2(devnull, STDERR_FILENO); + if (devnull > 2) + (void)close(devnull); + + return (0); +} + void syslog_vstrerror(int e, int priority, const char *fmt, va_list ap) { |