On Thu, Jul 26, 2018 at 10:22:28AM -0600, Theo de Raadt wrote:
> This mail includes a large diff of userland which demonstrates how
> unveil() will be used in base.
> 
[...]
> 
> And here is the userland diff, applying to about 37 programs.  There will
> be weaknesses and errors in here.  This is not perfect yet.

Here, a quick review of some possible problems, unrelated diff hunks or
others comments.

I didn't check for the accuracy of the unveiled paths.

> Index: libexec/fingerd/fingerd.c
> ===================================================================
> RCS file: /cvs/src/libexec/fingerd/fingerd.c,v
> retrieving revision 1.39
> diff -u -p -u -r1.39 fingerd.c
> --- libexec/fingerd/fingerd.c 13 Nov 2015 01:26:33 -0000      1.39
> +++ libexec/fingerd/fingerd.c 12 Jul 2018 16:18:13 -0000
> @@ -68,7 +68,7 @@ main(int argc, char *argv[])
>       char **ap, *av[ENTRIES + 1], line[8192], *lp, *hname;
>       char hostbuf[HOST_NAME_MAX+1];
>  
> -     if (pledge("stdio inet dns proc exec", NULL) == -1)
> +     if (pledge("stdio unveil inet dns proc exec", NULL) == -1)
>               err(1, "pledge");
>  
>       prog = _PATH_FINGER;
> @@ -110,6 +110,9 @@ main(int argc, char *argv[])
>               default:
>                       usage();
>               }
> +
> +     if (unveil(_PATH_FINGER, "x") == -1)
> +             err(1, "unveil");
>  
>       if (logging) {
>               struct sockaddr_storage ss;

unveil(2) call (with static name _PATH_FINGER) should be before
pledge(2). alternatively another call of pledge(2) without "unveil"
should be done after.

> Index: libexec/spamd-setup/spamd-setup.c
> ===================================================================
> RCS file: /cvs/src/libexec/spamd-setup/spamd-setup.c,v
> retrieving revision 1.50
> diff -u -p -u -r1.50 spamd-setup.c
> --- libexec/spamd-setup/spamd-setup.c 7 Jul 2017 00:10:15 -0000       1.50
> +++ libexec/spamd-setup/spamd-setup.c 12 Jul 2018 16:18:13 -0000
> @@ -851,13 +851,24 @@ main(int argc, char *argv[])
>       spamd_uid = pw->pw_uid;
>       spamd_gid = pw->pw_gid;
>  
> -     if (pledge("stdio rpath inet proc exec id", NULL) == -1)
> +     if (pledge("stdio unveil rpath inet proc exec id", NULL) == -1)
>               err(1, "pledge");
>  
>       if (daemonize)
>               daemon(0, 0);
>       else if (chdir("/") != 0)
>               err(1, "chdir(\"/\")");
> +
> +     if (unveil(PATH_FTP, "x") == -1)
> +             err(1, "unveil");
> +     if (unveil(PATH_PFCTL, "x") == -1)
> +             err(1, "unveil");
> +     if (unveil(PATH_SPAMD_CONF, "r") == -1)
> +             err(1, "unveil");
> +     if (unveil(_PATH_SERVICES, "r") == -1)
> +             err(1, "unveil");
> +     if (pledge("stdio rpath inet proc exec id", NULL) == -1)
> +             err(1, "pledge");
>  
>       if ((ent = getservbyname("spamd-cfg", "tcp")) == NULL)
>               errx(1, "cannot find service \"spamd-cfg\" in /etc/services");

I would perfer to see all unveil(2) calls before pledge(2), instead of
calling pledge(2) twice (here it is possible: all unveiled paths are
known in advance).

> Index: sbin/scan_ffs/scan_ffs.c
> ===================================================================
> RCS file: /cvs/src/sbin/scan_ffs/scan_ffs.c,v
> retrieving revision 1.22
> diff -u -p -u -r1.22 scan_ffs.c
> --- sbin/scan_ffs/scan_ffs.c  26 Apr 2018 15:55:14 -0000      1.22
> +++ sbin/scan_ffs/scan_ffs.c  12 Jul 2018 16:18:13 -0000
> @@ -139,7 +139,7 @@ main(int argc, char *argv[])
>       daddr_t beg = 0, end = -1;
>       const char *errstr;
>  
> -     if (pledge("stdio rpath disklabel", NULL) == -1)
> +     if (pledge("stdio unveil rpath disklabel", NULL) == -1)
>               err(1, "pledge");
>  
>       while ((ch = getopt(argc, argv, "lsvb:e:")) != -1)

hum. Makefile doesn't show it would search source code somewhere else.
The change (adding "unveil" promise without unveil(2) calls) is
suspirious.

> Index: usr.bin/doas/doas.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/doas/doas.c,v
> retrieving revision 1.72
> diff -u -p -u -r1.72 doas.c
> --- usr.bin/doas/doas.c       27 May 2017 09:51:07 -0000      1.72
> +++ usr.bin/doas/doas.c       12 Jul 2018 16:18:13 -0000
> @@ -239,6 +239,30 @@ good:
>       }
>  }
>  
> +void
> +pledgecommands(const char *ipath, const char *cmd)

cosmetic: unveilcommands() would be a better name :)

> +{
> +     char *path;
> +     char buf[PATH_MAX];
> +     char *p, *cp;
> +
> +     path = strdup(ipath);
> +     if (!path)
> +             err(1, "copying path");
> +
> +     for (p = path; p && *p;) {
> +             cp = strsep(&p, ":");
> +             if (cp) {
> +                     int r = snprintf(buf, sizeof buf, "%s/%s", cp, cmd);
> +                     if (r == -1 || r >= sizeof buf)
> +                             errx(1, "snprintf");
> +                     if (unveil(buf, "x") == -1)
> +                             err(1, "unveil");
> +             }
> +     }
> +     free(path);
> +}
> +
>  int
>  main(int argc, char **argv)
>  {
> @@ -364,6 +388,7 @@ main(int argc, char **argv)
>               authuser(myname, login_style, rule->options & PERSIST);
>       }
>  
> +     pledgecommands(safepath, cmd);
>       if (pledge("stdio rpath getpw exec id", NULL) == -1)
>               err(1, "pledge");
>  
> Index: usr.bin/ftp/main.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/ftp/main.c,v
> retrieving revision 1.120
> diff -u -p -u -r1.120 main.c
> --- usr.bin/ftp/main.c        10 Feb 2018 06:25:16 -0000      1.120
> +++ usr.bin/ftp/main.c        12 Jul 2018 16:18:13 -0000
> @@ -273,6 +273,7 @@ main(volatile int argc, char *argv[])
>       }
>  
>       ttyout = stdout;
> +// espie: fw_update, ^T not working.  due to no TERM= while in rc script?
>       if (isatty(fileno(ttyout)) && !dumb_terminal && foregroundproc())
>               progress = 1;           /* progress bar on if tty is usable */
>  

unrelated to unveil(2)

> Index: usr.bin/top/top.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/top/top.c,v
> retrieving revision 1.89
> diff -u -p -u -r1.89 top.c
> --- usr.bin/top/top.c 15 Mar 2017 04:24:14 -0000      1.89
> +++ usr.bin/top/top.c 12 Jul 2018 16:18:13 -0000
> @@ -412,6 +412,8 @@ main(int argc, char *argv[])
>       sigprocmask(SIG_BLOCK, &mask, &oldmask);
>       if (interactive)
>               init_screen();
> +     if (pledge("stdio getpw tty proc ps vminfo", NULL) == -1)
> +             err(1, "pledge");       
>       (void) signal(SIGINT, leave);
>       siginterrupt(SIGINT, 1);
>       (void) signal(SIGQUIT, leave);

unrelated to unveil(2)

> Index: usr.sbin/bgpctl/bgpctl.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/bgpctl/bgpctl.c,v
> retrieving revision 1.209
> diff -u -p -u -r1.209 bgpctl.c
> --- usr.sbin/bgpctl/bgpctl.c  22 Jul 2018 17:07:53 -0000      1.209
> +++ usr.sbin/bgpctl/bgpctl.c  25 Jul 2018 17:04:18 -0000
> @@ -192,7 +192,9 @@ main(int argc, char *argv[])
>               break;
>       }
>  
> -     if (pledge("stdio rpath wpath unix", NULL) == -1)
> +     if (unveil(sockname, "r") == -1)
> +             err(1, "unveil");
> +     if (pledge("stdio unix", NULL) == -1)
>               err(1, "pledge");
>  
>       if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)

suspirious change in pledge(2)
- before: "stdio rpath wpath unix"
- after:  "stdio unix"

> Index: usr.sbin/portmap/portmap.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/portmap/portmap.c,v
> retrieving revision 1.48
> diff -u -p -u -r1.48 portmap.c
> --- usr.sbin/portmap/portmap.c        14 Oct 2015 13:32:44 -0000      1.48
> +++ usr.sbin/portmap/portmap.c        12 Jul 2018 16:18:13 -0000
> @@ -609,7 +609,7 @@ callit(struct svc_req *rqstp, SVCXPRT *x
>               return;
>       }
>  
> -     if (pledge("stdio rpath inet", NULL) == -1)
> +     if (pledge("stdio inet", NULL) == -1)
>               err(1, "pledge");
>  
>       port = pml->pml_map.pm_port;

suspirious change in pledge(2)
- before: "stdio rpath inet"
- after:  "stdio inet"

(and diff unrelated to unveil(2))

> Index: usr.sbin/vmctl/main.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/vmctl/main.c,v
> retrieving revision 1.39
> diff -u -p -u -r1.39 main.c
> --- usr.sbin/vmctl/main.c     12 Jul 2018 14:53:37 -0000      1.39
> +++ usr.sbin/vmctl/main.c     25 Jul 2018 17:04:20 -0000
> @@ -158,9 +166,14 @@ parse(int argc, char *argv[])
>       res.action = ctl->action;
>       res.ctl = ctl;
>  
> +     if (unveil(SOCKET_NAME, "r") == -1)
> +             err(1, "unveil");
> +     
>       if (!ctl->has_pledge) {
>               /* pledge(2) default if command doesn't have its own pledge */
> -             if (pledge("stdio rpath exec unix getpw", NULL) == -1)
> +             if (unveil(VMCTL_CU, "x") == -1)
> +                     err(1, "unveil");
> +             if (pledge("stdio rpath exec unix getpw paths", NULL) == -1)
>                       err(1, "pledge");

"paths" isn't a know promise name (it should be "unveil")

>       }
>       if (ctl->main(&res, argc, argv) != 0)

-- 
Sebastien Marie

Reply via email to