On Sun, Dec 25, 2016 at 09:47:16AM -0700, Todd C. Miller wrote:
> Another alternative is to use realpath(3) to resolve the path
> so it can be used after the chdir(2).

Good idea.  I have moved all the path handling to privsep.c.

ok?

bluhm

Index: usr.sbin/syslogd/privsep.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/privsep.c,v
retrieving revision 1.64
diff -u -p -r1.64 privsep.c
--- usr.sbin/syslogd/privsep.c  16 Oct 2016 22:12:50 -0000      1.64
+++ usr.sbin/syslogd/privsep.c  26 Dec 2016 17:12:40 -0000
@@ -97,7 +97,7 @@ priv_init(int lockfd, int nullfd, int ar
 {
        int i, socks[2];
        struct passwd *pw;
-       char childnum[11], **privargv;
+       char *execpath, childnum[11], **privargv;
 
        /* Create sockets */
        if (socketpair(AF_LOCAL, SOCK_STREAM, PF_UNSPEC, socks) == -1)
@@ -114,9 +114,9 @@ priv_init(int lockfd, int nullfd, int ar
        if (!child_pid) {
                /* Child - drop privileges and return */
                if (chroot(pw->pw_dir) != 0)
-                       err(1, "unable to chroot");
+                       err(1, "chroot %s", pw->pw_dir);
                if (chdir("/") != 0)
-                       err(1, "unable to chdir");
+                       err(1, "chdir %s", pw->pw_dir);
 
                if (setgroups(1, &pw->pw_gid) == -1)
                        err(1, "setgroups() failed");
@@ -130,6 +130,11 @@ priv_init(int lockfd, int nullfd, int ar
        }
        close(socks[1]);
 
+       if ((execpath = realpath(argv[0], NULL)) == NULL)
+               err(1, "realpath %s", argv[0]);
+       if (chdir("/") != 0)
+               err(1, "chdir /");
+
        if (!Debug) {
                close(lockfd);
                dup2(nullfd, STDIN_FILENO);
@@ -147,7 +152,8 @@ priv_init(int lockfd, int nullfd, int ar
        snprintf(childnum, sizeof(childnum), "%d", child_pid);
        if ((privargv = reallocarray(NULL, argc + 3, sizeof(char *))) == NULL)
                err(1, "alloc priv argv failed");
-       for (i = 0; i < argc; i++)
+       privargv[0] = execpath;
+       for (i = 1; i < argc; i++)
                privargv[i] = argv[i];
        privargv[i++] = "-P";
        privargv[i++] = childnum;
Index: usr.sbin/syslogd/syslogd.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/usr.sbin/syslogd/syslogd.c,v
retrieving revision 1.224
diff -u -p -r1.224 syslogd.c
--- usr.sbin/syslogd/syslogd.c  23 Dec 2016 23:01:48 -0000      1.224
+++ usr.sbin/syslogd/syslogd.c  26 Dec 2016 16:46:32 -0000
@@ -685,8 +685,6 @@ main(int argc, char *argv[])
 
        logdebug("off & running....\n");
 
-       chdir("/");
-
        tzset();
 
        if (!Debug && !Foreground) {

Reply via email to