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;
> 

Reply via email to