diff options
author | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2016-03-31 23:00:47 +0000 |
---|---|---|
committer | Jeremie Courreges-Anglas <jca@cvs.openbsd.org> | 2016-03-31 23:00:47 +0000 |
commit | 3c1e2cbfefb7201e2c5ce086d0b4b4cc9527713d (patch) | |
tree | 8e5b86b00824269ea63fb68c894fc89ea09115c9 /usr.sbin | |
parent | c72e9d7421d8ee6b6c87822906d495370391a755 (diff) |
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@
Diffstat (limited to 'usr.sbin')
-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) { |