Hi,

this adds pledge(2) to ftpd(8).

Unfortunately, the main process and its children "[priv pre-auth]" need
a lot of rights. The unprivileged process is better to pledge, as it
does not need that much rights. But, I try to find other strategic points
where pledge(2) could take place.

Maybe it's possible to avoid some rights, with a solution like this one:
http://marc.info/?l=openbsd-tech&m=145954965514619&w=2

If anyone could test this diff in different constellations, I'm happy
to get feedback as I don't cover them all.

--f.

Index: ftpd.c
===================================================================
RCS file: /cvs/src/libexec/ftpd/ftpd.c,v
retrieving revision 1.213
diff -u -r1.213 ftpd.c
--- ftpd.c      16 Mar 2016 15:41:10 -0000      1.213
+++ ftpd.c      2 Apr 2016 14:14:02 -0000
@@ -80,6 +80,7 @@
 #include <bsd_auth.h>
 #include <ctype.h>
 #include <dirent.h>
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <glob.h>
@@ -375,6 +376,9 @@
                syslog(LOG_ERR, "options 'U' and 'W' are mutually exclusive");
                exit(1);
        }
+
+       if (pledge("stdio wpath cpath getpw proc rpath dns inet id ioctl sendfd 
recvfd", NULL) == -1)
+               err(1, "pledge");
 
        (void) freopen(_PATH_DEVNULL, "w", stderr);
 
Index: monitor.c
===================================================================
RCS file: /cvs/src/libexec/ftpd/monitor.c,v
retrieving revision 1.23
diff -u -r1.23 monitor.c
--- monitor.c   16 Nov 2015 17:31:14 -0000      1.23
+++ monitor.c   2 Apr 2016 14:14:02 -0000
@@ -21,6 +21,7 @@
 #include <sys/wait.h>
 #include <netinet/in.h>
 
+#include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <paths.h>
@@ -169,6 +170,9 @@
                fatalx("fork of unprivileged slave failed");
        if (slave_pid == 0) {
                /* Unprivileged slave */
+               if (pledge("stdio proc getpw id rpath", NULL) == -1)
+                       err(1, "pledge");       
+
                set_slave_signals();
 
                if ((pw = getpwnam(FTPD_PRIVSEP_USER)) == NULL)
@@ -193,6 +197,10 @@
 
                endpwent();
                close(fd_slave);
+
+               if (pledge("stdio", NULL) == -1)
+                       err(1, "pledge");
+       
                return (1);
        }
 

Reply via email to