=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/doas/doas.c,v retrieving revision 1.72 retrieving revision 1.73 diff -c -r1.72 -r1.73 *** src/usr.bin/doas/doas.c 2017/05/27 09:51:07 1.72 --- src/usr.bin/doas/doas.c 2018/08/08 18:32:51 1.73 *************** *** 1,4 **** ! /* $OpenBSD: doas.c,v 1.72 2017/05/27 09:51:07 tedu Exp $ */ /* * Copyright (c) 2015 Ted Unangst * --- 1,4 ---- ! /* $OpenBSD: doas.c,v 1.73 2018/08/08 18:32:51 deraadt Exp $ */ /* * Copyright (c) 2015 Ted Unangst * *************** *** 240,245 **** --- 240,283 ---- } int + unveilcommands(const char *ipath, const char *cmd) + { + char *path = NULL, *p; + int unveils = 0; + + if (strchr(cmd, '/') != NULL) { + if (unveil(cmd, "x") != -1) + unveils++; + goto done; + } + + if (!ipath) { + errno = ENOENT; + goto done; + } + path = strdup(ipath); + if (!path) { + errno = ENOENT; + goto done; + } + for (p = path; p && *p; ) { + char buf[PATH_MAX]; + char *cp = strsep(&p, ":"); + + if (cp) { + int r = snprintf(buf, sizeof buf, "%s/%s", cp, cmd); + if (r != -1 && r < sizeof buf) { + if (unveil(buf, "x") != -1) + unveils++; + } + } + } + done: + free(path); + return (unveils); + } + + int main(int argc, char **argv) { const char *safepath = "/bin:/sbin:/usr/bin:/usr/sbin:" *************** *** 364,369 **** --- 402,416 ---- authuser(myname, login_style, rule->options & PERSIST); } + if (unveil(_PATH_LOGIN_CONF, "r") == -1) + err(1, "unveil"); + if (rule->cmd) { + if (setenv("PATH", safepath, 1) == -1) + err(1, "failed to set PATH '%s'", safepath); + } + if (unveilcommands(getenv("PATH"), cmd) == 0) + goto fail; + if (pledge("stdio rpath getpw exec id", NULL) == -1) err(1, "pledge"); *************** *** 392,402 **** envp = prepenv(rule); - if (rule->cmd) { - if (setenv("PATH", safepath, 1) == -1) - err(1, "failed to set PATH '%s'", safepath); - } execvpe(cmd, argv, envp); if (errno == ENOENT) errx(1, "%s: command not found", cmd); err(1, "%s", cmd); --- 439,446 ---- envp = prepenv(rule); execvpe(cmd, argv, envp); + fail: if (errno == ENOENT) errx(1, "%s: command not found", cmd); err(1, "%s", cmd);