commit: 7286f7e8e72e16819e1f4fb1f885abed7831ed85
parent 5ff4eb3e8f5b097ba43e93fa733c2c973abed365
Author: Michael Forney <mforney@mforney.org>
Date: Mon, 5 Apr 2021 19:19:17 -0700
openbsd: doas: Use PATH=/bin when cmd is not specified
This behavior matches what is documented doas(1) and was originally
changed in OpenBSD 6.6.
Take the opportunity to simplify handling of PATH a bit.
Diffstat:
2 files changed, 146 insertions(+), 19 deletions(-)
diff --git a/pkg/openbsd/patch/0016-doas-Port-to-linux-musl.patch b/pkg/openbsd/patch/0016-doas-Port-to-linux-musl.patch
@@ -1,4 +1,4 @@
-From c95443d87b64650823e41016c26b1f5a3b38e7b3 Mon Sep 17 00:00:00 2001
+From 6d212c71ee3f1a2068793cc416afbeabc0002184 Mon Sep 17 00:00:00 2001
From: Michael Forney <mforney@mforney.org>
Date: Sun, 26 Feb 2017 16:50:55 -0800
Subject: [PATCH] doas: Port to linux/musl
@@ -20,13 +20,19 @@ Remove call to closefrom.
Replace calls to errc with err after setting errno.
Call openlog at start to set syslog identity.
+
+Remove unveil/pledge since they aren't supported on Linux.
+
+Simplify handling of PATH in the environment since we don't have
+login.conf with per-user default PATH.
---
usr.bin/doas/doas.1 | 9 ---
- usr.bin/doas/doas.c | 97 ++++++++++++++++--------------
- usr.bin/doas/doas.h | 4 ++
+ usr.bin/doas/doas.c | 158 ++++++++++++++---------------------------
+ usr.bin/doas/doas.h | 6 +-
+ usr.bin/doas/env.c | 17 ++---
usr.bin/doas/parse.y | 1 +
- usr.bin/doas/persist.c | 133 +++++++++++++++++++++++++++++++++++++++++
- 5 files changed, 191 insertions(+), 53 deletions(-)
+ usr.bin/doas/persist.c | 133 ++++++++++++++++++++++++++++++++++
+ 6 files changed, 196 insertions(+), 128 deletions(-)
create mode 100644 usr.bin/doas/persist.c
diff --git a/usr.bin/doas/doas.1 b/usr.bin/doas/doas.1
@@ -57,7 +63,7 @@ index fc769bdb336..c7196e347a9 100644
Parse and check the configuration file
.Ar config ,
diff --git a/usr.bin/doas/doas.c b/usr.bin/doas/doas.c
-index a723c67a3eb..e7e3e639401 100644
+index a723c67a3eb..857c8202c39 100644
--- a/usr.bin/doas/doas.c
+++ b/usr.bin/doas/doas.c
@@ -20,8 +20,6 @@
@@ -140,7 +146,7 @@ index a723c67a3eb..e7e3e639401 100644
if (!challenge) {
char host[HOST_NAME_MAX + 1];
if (gethostname(host, sizeof(host)))
-@@ -225,21 +245,18 @@ authuser(char *myname, char *login_style, int persist)
+@@ -225,75 +245,31 @@ authuser(char *myname, char *login_style, int persist)
response = readpassphrase(challenge, rbuf, sizeof(rbuf),
RPP_REQUIRE_TTY);
if (response == NULL && errno == ENOTTY) {
@@ -166,17 +172,54 @@ index a723c67a3eb..e7e3e639401 100644
close(fd);
}
}
-@@ -285,15 +302,14 @@ done:
+
+-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 >= 0 && 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:"
- "/usr/local/bin:/usr/local/sbin";
-+ const char *safepath = "/bin";
const char *confpath = NULL;
char *shargv[] = { NULL, NULL };
char *sh;
- const char *p;
+- const char *p;
const char *cmd;
char cmdline[LINE_MAX];
- char mypwbuf[_PW_BUF_LEN], targpwbuf[_PW_BUF_LEN];
@@ -184,7 +227,7 @@ index a723c67a3eb..e7e3e639401 100644
struct passwd mypwstore, targpwstore;
struct passwd *mypw, *targpw;
const struct rule *rule;
-@@ -306,28 +322,20 @@ main(int argc, char **argv)
+@@ -306,28 +282,20 @@ main(int argc, char **argv)
int nflag = 0;
char cwdpath[PATH_MAX];
const char *cwd;
@@ -216,7 +259,7 @@ index a723c67a3eb..e7e3e639401 100644
case 'u':
if (parseuid(optarg, &target) != 0)
errx(1, "unknown user");
-@@ -395,16 +403,16 @@ main(int argc, char **argv)
+@@ -395,47 +363,30 @@ main(int argc, char **argv)
cmd = argv[0];
if (!permit(uid, groups, ngroups, &rule, target, cmd,
(const char **)argv + 1)) {
@@ -236,8 +279,27 @@ index a723c67a3eb..e7e3e639401 100644
+ authuser(mypw->pw_name, rule->options & PERSIST);
}
- if ((p = getenv("PATH")) != NULL)
-@@ -431,11 +439,12 @@ main(int argc, char **argv)
+- if ((p = getenv("PATH")) != NULL)
+- formerpath = strdup(p);
+- if (formerpath == NULL)
+- formerpath = "";
+-
+- if (unveil(_PATH_LOGIN_CONF, "r") == -1 ||
+- unveil(_PATH_LOGIN_CONF ".db", "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");
+-
+ rv = getpwuid_r(target, &targpwstore, targpwbuf, sizeof(targpwbuf), &targpw);
+ if (rv != 0)
+ err(1, "getpwuid_r failed");
if (targpw == NULL)
errx(1, "no passwd entry for target");
@@ -255,7 +317,7 @@ index a723c67a3eb..e7e3e639401 100644
if (pledge("stdio rpath exec", NULL) == -1)
err(1, "pledge");
-@@ -448,7 +457,7 @@ main(int argc, char **argv)
+@@ -448,21 +399,16 @@ main(int argc, char **argv)
if (pledge("stdio exec", NULL) == -1)
err(1, "pledge");
@@ -264,11 +326,33 @@ index a723c67a3eb..e7e3e639401 100644
mypw->pw_name, cmdline, targpw->pw_name, cwd);
envp = prepenv(rule, mypw, targpw);
+
+- /* setusercontext set path for the next process, so reset it for us */
+ if (rule->cmd) {
+ if (setenv("PATH", safepath, 1) == -1)
+ err(1, "failed to set PATH '%s'", safepath);
+- } else {
+- if (setenv("PATH", formerpath, 1) == -1)
+- err(1, "failed to set PATH '%s'", formerpath);
+ }
+ execvpe(cmd, argv, envp);
+-fail:
+ if (errno == ENOENT)
+ errx(1, "%s: command not found", cmd);
+ err(1, "%s", cmd);
diff --git a/usr.bin/doas/doas.h b/usr.bin/doas/doas.h
-index 6f50fc22869..c97986e3cf3 100644
+index 6f50fc22869..4e4e74476c1 100644
--- a/usr.bin/doas/doas.h
+++ b/usr.bin/doas/doas.h
-@@ -36,6 +36,10 @@ struct passwd;
+@@ -29,13 +29,17 @@ extern struct rule **rules;
+ extern int nrules;
+ extern int parse_errors;
+
+-extern const char *formerpath;
++extern const char *safepath;
+
+ struct passwd;
+
char **prepenv(const struct rule *, const struct passwd *,
const struct passwd *);
@@ -279,6 +363,49 @@ index 6f50fc22869..c97986e3cf3 100644
#define PERMIT 1
#define DENY 2
+diff --git a/usr.bin/doas/env.c b/usr.bin/doas/env.c
+index 2d93a4089b6..dc9be691955 100644
+--- a/usr.bin/doas/env.c
++++ b/usr.bin/doas/env.c
+@@ -28,7 +28,7 @@
+
+ #include "doas.h"
+
+-const char *formerpath;
++const char *safepath = "/bin";
+
+ struct envnode {
+ RB_ENTRY(envnode) node;
+@@ -103,7 +103,7 @@ createenv(const struct rule *rule, const struct passwd *mypw,
+ addnode(env, "DOAS_USER", mypw->pw_name);
+ addnode(env, "HOME", targpw->pw_dir);
+ addnode(env, "LOGNAME", targpw->pw_name);
+- addnode(env, "PATH", getenv("PATH"));
++ addnode(env, "PATH", safepath);
+ addnode(env, "SHELL", targpw->pw_shell);
+ addnode(env, "USER", targpw->pw_name);
+
+@@ -200,17 +200,10 @@ fillenv(struct env *env, const char **envlist)
+ /* assign value or inherit from environ */
+ if (eq) {
+ val = eq + 1;
+- if (*val == '$') {
+- if (strcmp(val + 1, "PATH") == 0)
+- val = formerpath;
+- else
+- val = getenv(val + 1);
+- }
++ if (*val == '$')
++ val = getenv(val + 1);
+ } else {
+- if (strcmp(name, "PATH") == 0)
+- val = formerpath;
+- else
+- val = getenv(name);
++ val = getenv(name);
+ }
+ /* at last, we have something to insert */
+ if (val) {
diff --git a/usr.bin/doas/parse.y b/usr.bin/doas/parse.y
index dd9466e5f13..d1f698c7679 100644
--- a/usr.bin/doas/parse.y
@@ -431,5 +558,5 @@ index 00000000000..4ad1bf1efbf
+ return 0;
+}
--
-2.27.0
+2.30.1
diff --git a/pkg/openbsd/ver b/pkg/openbsd/ver
@@ -1 +1 @@
-6.8 r0
+6.8 r1