Hi,

Since the last email I sent, mentioned at the bottom, dhclient(8) has dropped
support for re-execing itself on SIGHUP and so what path, hardcoded or not,
should be unveiled for the executable is out of this conversation.

Please check a new diff which unveils /etc/resolv.conf with write/create
permissions and /etc/resolv.conf.tail with read.

Comments? OK?

Index: dhclient.c
===================================================================
RCS file: /cvs/src/sbin/dhclient/dhclient.c,v
retrieving revision 1.641
diff -u -p -u -r1.641 dhclient.c
--- dhclient.c  1 Jul 2019 16:53:59 -0000       1.641
+++ dhclient.c  10 Jul 2019 14:36:31 -0000
@@ -2232,6 +2232,13 @@ fork_privchld(struct interface_info *ifi
        if ((routefd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1)
                fatal("socket(AF_ROUTE, SOCK_RAW)");
 
+       if (unveil(_PATH_RESOLV_CONF, "wc") == -1)
+               fatal("unveil");
+       if (unveil(_PATH_RESOLV_CONF_TAIL, "r") == -1)
+               fatal("unveil");
+       if (unveil(NULL, NULL) == -1)
+               fatal("unveil");
+
        while (quit == 0) {
                pfd[0].fd = priv_ibuf->fd;
                pfd[0].events = POLLIN;
Index: dhcpd.h
===================================================================
RCS file: /cvs/src/sbin/dhclient/dhcpd.h,v
retrieving revision 1.278
diff -u -p -u -r1.278 dhcpd.h
--- dhcpd.h     22 May 2019 12:56:31 -0000      1.278
+++ dhcpd.h     10 Jul 2019 14:36:31 -0000
@@ -153,6 +153,8 @@ struct interface_info {
 
 #define        _PATH_DHCLIENT_CONF     "/etc/dhclient.conf"
 #define        _PATH_LEASE_DB          "/var/db/dhclient.leases"
+#define        _PATH_RESOLV_CONF       "/etc/resolv.conf"
+#define        _PATH_RESOLV_CONF_TAIL  "/etc/resolv.conf.tail"
 
 /* options.c */
 int                     pack_options(unsigned char *, int,
Index: kroute.c
===================================================================
RCS file: /cvs/src/sbin/dhclient/kroute.c,v
retrieving revision 1.164
diff -u -p -u -r1.164 kroute.c
--- kroute.c    30 Jun 2019 19:19:08 -0000      1.164
+++ kroute.c    10 Jul 2019 14:36:31 -0000
@@ -655,31 +655,31 @@ char *
 resolv_conf_tail(void)
 {
        struct stat              sb;
-       const char              *tail_path = "/etc/resolv.conf.tail";
        char                    *tailcontents = NULL;
        ssize_t                  tailn;
        int                      tailfd;
 
-       tailfd = open(tail_path, O_RDONLY);
+       tailfd = open(_PATH_RESOLV_CONF_TAIL, O_RDONLY);
        if (tailfd == -1) {
                if (errno != ENOENT)
-                       log_warn("%s: open(%s)", log_procname, tail_path);
+                       log_warn("%s: open(%s)", log_procname,
+                           _PATH_RESOLV_CONF_TAIL);
        } else if (fstat(tailfd, &sb) == -1) {
-               log_warn("%s: fstat(%s)", log_procname, tail_path);
+               log_warn("%s: fstat(%s)", log_procname, _PATH_RESOLV_CONF_TAIL);
        } else if (sb.st_size > 0 && sb.st_size < LLONG_MAX) {
                tailcontents = calloc(1, sb.st_size + 1);
                if (tailcontents == NULL)
-                       fatal("%s contents", tail_path);
+                       fatal("%s contents", _PATH_RESOLV_CONF_TAIL);
                tailn = read(tailfd, tailcontents, sb.st_size);
                if (tailn == -1)
                        log_warn("%s: read(%s)", log_procname,
-                           tail_path);
+                           _PATH_RESOLV_CONF_TAIL);
                else if (tailn == 0)
                        log_warnx("%s: got no data from %s",
-                           log_procname,tail_path);
+                           log_procname, _PATH_RESOLV_CONF_TAIL);
                else if (tailn != sb.st_size)
                        log_warnx("%s: short read of %s",
-                           log_procname, tail_path);
+                           log_procname, _PATH_RESOLV_CONF_TAIL);
                else {
                        close(tailfd);
                        return tailcontents;
@@ -861,7 +861,6 @@ void
 priv_write_resolv_conf(int index, int routefd, int rdomain, char *contents,
     int *lastidx)
 {
-       const char      *path = "/etc/resolv.conf";
        ssize_t          n;
        size_t           sz;
        int              fd, retries, newidx;
@@ -878,21 +877,21 @@ priv_write_resolv_conf(int index, int ro
                return;
        *lastidx = newidx;
 
-       fd = open(path, O_WRONLY | O_CREAT | O_TRUNC,
+       fd = open(_PATH_RESOLV_CONF, O_WRONLY | O_CREAT | O_TRUNC,
            S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
 
        if (fd == -1) {
-               log_warn("%s: open(%s)", log_procname, path);
+               log_warn("%s: open(%s)", log_procname, _PATH_RESOLV_CONF);
                return;
        }
 
        sz = strlen(contents);
        n = write(fd, contents, sz);
        if (n == -1)
-               log_warn("%s: write(%s)", log_procname, path);
+               log_warn("%s: write(%s)", log_procname, _PATH_RESOLV_CONF);
        else if ((size_t)n < sz)
                log_warnx("%s: write(%s): %zd of %zu bytes", log_procname,
-                   path, n, sz);
+                   _PATH_RESOLV_CONF, n, sz);
 
        close(fd);
 }


On 14:04 Tue 06 Nov     , Ricardo Mestre wrote:
> I guess dhclient is a special one, the others need to re-exec themselves but 
> at
> fork+exec time, not again. does this suits you better? don't want to keep
> bothering you with silly diffs.
> 
> On 08:38 Tue 06 Nov     , [email protected] wrote:
> > My objection is to having "/sbin/dhclient" coded anywhere. This makes it 
> > difficult to test different versions. Do these other daemons restart 
> > themselves as part of their normal operation?
> > 
> > Why not take argv[0] and run it through realpath() on startup to get rid of 
> > symlinks, etc.?
> > 
> > .... Ken

Reply via email to