summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjca <jca@openbsd.org>2016-03-31 23:00:46 +0000
committerjca <jca@openbsd.org>2016-03-31 23:00:46 +0000
commiteaf6a821b6b7a2c84d4641e7c5912a76e70adfe2 (patch)
treeeef4926ccc0ae24164f09313356f7cfdc06da141
parentIncrease size of the clone bitmap. A limit of only 64 device clones (diff)
downloadwireguard-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.c42
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)
{