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