Hello! Any testers out there that could provide some feedback on this?
I tested it and didn't have any problems with any parameters, except UDP that I don't have how to test it, although it kept running without problems as well. On 02/12/2015 12:14, Ricardo Mestre wrote: > Hi tech@ > > This is a revised version of pledging dhcpd(8) with earler pledging. > > Hoist up sync_init() due to a multicast setsockopt(2) (IP_MULTICAST_TTL) that > pledge doesn't allow, also hoist up the daemon(3) section, getpwnam(3) and the > check if arguments -A, -C or -L were used (pf table handling) since it calls > 2 ioctl(2)'s that pledge pf doesn't allow. > > After this if !udpsockmode then apply the following annotations: > > "rpath": > icmp_startup()->getprotobyname(3)->read /etc/protocols > "inet": > icmp_startup()->socket(2) > "sendfd": > for sendmsg(2) in ICMP echo request > "proc/id" > chroot(2) and privdrop section > > If in udpsockmode then the pledge needs to happen inside udpsock_startup() > instead of main() since setsockopt(2) IP_RECVIF is not allowed by pledge. > After > that happens then apply the same pledge with the annotations above, although > additionally this code path also needs "route" for ioctl(2) SIOCGIFADDR. > > Just before the main loop of the program then it can drop to "stdio inet route > sendfd" if in udpsockmode or else just to "stdio inet sendfd". > > Any comments with this implementation? Specifically for the UDP code path > since > I don't have at the moment a way to test DHCPINFORM requests on non Ethernet > packets? > > Index: dhcpd.c > =================================================================== > RCS file: /cvs/src/usr.sbin/dhcpd/dhcpd.c,v > retrieving revision 1.48 > diff -u -p -u -r1.48 dhcpd.c > --- dhcpd.c 10 Feb 2015 23:06:13 -0000 1.48 > +++ dhcpd.c 2 Dec 2015 11:28:50 -0000 > @@ -45,7 +45,7 @@ > #include <err.h> > #include <pwd.h> > > -void usage(void); > +__dead void usage(void); > > time_t cur_time, last_scan; > struct group root_group; > @@ -187,22 +187,18 @@ main(int argc, char *argv[]) > if (setrtable(rdomain) == -1) > error("setrtable (%m)"); > > - if (udpsockmode) > - udpsock_startup(udpaddr); > - icmp_startup(1, lease_pinged); > - > if (syncsend || syncrecv) { > syncfd = sync_init(sync_iface, sync_baddr, sync_port); > if (syncfd == -1) > err(1, "sync init"); > } > > - if ((pw = getpwnam("_dhcp")) == NULL) > - error("user \"_dhcp\" not found"); > - > if (daemonize) > daemon(0, 0); > > + if ((pw = getpwnam("_dhcp")) == NULL) > + error("user \"_dhcp\" not found"); > + > /* don't go near /dev/pf unless we actually intend to use it */ > if ((abandoned_tab != NULL) || > (changedmac_tab != NULL) || > @@ -227,6 +223,15 @@ main(int argc, char *argv[]) > } > } > > + if (udpsockmode) { > + udpsock_startup(udpaddr); > + } else { > + if (pledge("stdio rpath inet sendfd proc id", NULL) == -1) > + err(1, "pledge"); > + } > + > + icmp_startup(1, lease_pinged); > + > if (chroot(_PATH_VAREMPTY) == -1) > error("chroot %s: %m", _PATH_VAREMPTY); > if (chdir("/") == -1) > @@ -236,6 +241,14 @@ main(int argc, char *argv[]) > setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) > error("can't drop privileges: %m"); > > + if (udpsockmode) { > + if (pledge("stdio inet route sendfd", NULL) == -1) > + err(1, "pledge"); > + } else { > + if (pledge("stdio inet sendfd", NULL) == -1) > + err(1, "pledge"); > + } > + > add_timeout(cur_time + 5, periodic_scan, NULL); > dispatch(); > > @@ -243,7 +256,7 @@ main(int argc, char *argv[]) > exit(0); > } > > -void > +__dead void > usage(void) > { > extern char *__progname; > Index: udpsock.c > =================================================================== > RCS file: /cvs/src/usr.sbin/dhcpd/udpsock.c,v > retrieving revision 1.2 > diff -u -p -u -r1.2 udpsock.c > --- udpsock.c 16 Jan 2015 06:40:16 -0000 1.2 > +++ udpsock.c 2 Dec 2015 11:28:55 -0000 > @@ -56,6 +56,9 @@ udpsock_startup(struct in_addr bindaddr) > error("setsocketopt IP_RECVIF failed for udp: %s", > strerror(errno)); > > + if (pledge("stdio rpath inet route sendfd proc id", NULL) == -1) > + error("pledge: %s", strerror(errno)); > + > sin4.sin_family = AF_INET; > sin4.sin_len = sizeof(sin4); > sin4.sin_addr = bindaddr; >