[klibc] [klibc:update-dash] dash: [BUILTIN] command: allow combining -p with -v

klibc-bot for Harald van Dijk harald at gigawatt.nl
Sat Mar 28 14:48:14 PDT 2020

Commit-ID:  7e96bd023e7a381115727e16d9e3e57e1201d412
Gitweb:     http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=7e96bd023e7a381115727e16d9e3e57e1201d412
Author:     Harald van Dijk <harald at gigawatt.nl>
AuthorDate: Fri, 26 Sep 2014 16:35:15 +0800
Committer:  Ben Hutchings <ben at decadent.org.uk>
CommitDate: Sat, 28 Mar 2020 21:42:54 +0000

[klibc] dash: [BUILTIN] command: allow combining -p with -v

[ dash commit 65ae84b3d67425e16b85273e566d06ae942dcce9 ]

On 10/07/13 20:18, Craig Loomis wrote:
>   Dash (0.5.7 and git master) does not implement 'command -p'
> according to the standard, and opens an intriguing security hole to
> anyone trying this scheme.
>   When using 'command -v' to simply print the path to an executable,
> '-p' has no effect:

You're right. dash has never supported combining -p with -v, but back in
2005 this was seemingly accidentally changed from reporting a syntax
error to silently ignoring the -p option, only about a month after dash
moved to git.

Making sure that -p is respected even when -v is used is easy enough,
see attached patch. Tested even with explicit PATH overrides:
  PATH=/path/to/some/other/dash command -pv dash
correctly outputs /bin/dash on my system.

> the path that 'command -p cmd' uses is a compiled-in constant
> from dash's src/var.c:defpathvar, which starts with
> "/usr/local/sbin:/usr/local/bin". To me, that is both completely
> unexpected and pretty scary -- /usr/local/bin is (very) often less
> well secured or checked than, say, /bin:

Agreed. However, IMO, it does make sense for defpathvar to start with
/usr/local/*: it has two separate functions, it also serves as the
default path (hence the name) when dash is started with no PATH set at
all. I think fixing this should be done in a way so that command -p does
not use defpathvar, not by changing defpathvar. bash uses the same
confstr function for this that getconf uses, and it shouldn't be too
much work to make dash use that too. If no one else comes up with a
working patch or a better approach, I'll try to get that working.

Signed-off-by: Herbert Xu <herbert at gondor.apana.org.au>
Signed-off-by: Ben Hutchings <ben at decadent.org.uk>

 usr/dash/exec.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/usr/dash/exec.c b/usr/dash/exec.c
index 79e20074..e56e3f67 100644
--- a/usr/dash/exec.c
+++ b/usr/dash/exec.c
@@ -96,7 +96,7 @@ STATIC void clearcmdentry(int);
 STATIC struct tblentry *cmdlookup(const char *, int);
 STATIC void delete_cmd_entry(void);
 STATIC void addcmdentry(char *, struct cmdentry *);
-STATIC int describe_command(struct output *, char *, int);
+STATIC int describe_command(struct output *, char *, const char *, int);
@@ -727,21 +727,21 @@ typecmd(int argc, char **argv)
 	int err = 0;
 	for (i = 1; i < argc; i++) {
-		err |= describe_command(out1, argv[i], 1);
+		err |= describe_command(out1, argv[i], pathval(), 1);
 	return err;
-describe_command(out, command, verbose)
+describe_command(out, command, path, verbose)
 	struct output *out;
 	char *command;
+	const char *path;
 	int verbose;
 	struct cmdentry entry;
 	struct tblentry *cmdp;
 	const struct alias *ap;
-	const char *path = pathval();
 	if (verbose) {
 		outstr(command, out);
@@ -840,20 +840,23 @@ commandcmd(argc, argv)
 	} verify = 0;
+	const char *path = pathval();
 	while ((c = nextopt("pvV")) != '\0')
 		if (c == 'V')
 			verify |= VERIFY_VERBOSE;
 		else if (c == 'v')
 			verify |= VERIFY_BRIEF;
+		else if (c == 'p')
+			path = defpath;
 #ifdef DEBUG
-		else if (c != 'p')
+		else
 	cmd = *argptr;
 	if (verify && cmd)
-		return describe_command(out1, cmd, verify - VERIFY_BRIEF);
+		return describe_command(out1, cmd, path, verify - VERIFY_BRIEF);
 	return 0;

More information about the klibc mailing list