On Mon, Dec 26, 2016 at 09:08:22PM +0100, Jeremie Courreges-Anglas wrote:
> Alexander Bluhm <[email protected]> writes:
> Your last diff has a drawback: you can't simply start the daemon like
> this:
>
> # syslogd
>
> realpath will resolve "syslogd" to "/path/to/current/directory/syslogd".
>
> Maybe call realpath only if argv[0] contains a slash?
better?
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 22:24:44 -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,13 @@ priv_init(int lockfd, int nullfd, int ar
}
close(socks[1]);
+ if (strchr(argv[0], '/') == NULL)
+ execpath = argv[0];
+ else 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 +154,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) {