From: Harald van Dijk <harald@gigawatt.nl>
To: Craig Loomis <cploomis@gmail.com>, dash <dash@vger.kernel.org>
Subject: Re: "command -p" does not correctly limit search to a safe PATH
Date: Fri, 19 Jul 2013 23:49:31 +0200 [thread overview]
Message-ID: <51E9B46B.10401@gigawatt.nl> (raw)
In-Reply-To: <51E30212.3030901@gigawatt.nl>
[-- Attachment #1: Type: text/plain, Size: 1548 bytes --]
On 14/07/13 21:54, Harald van Dijk wrote:
> 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.
>>[...]
>> 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".
So, how about this, to be applied on top of my previous patch? It
defaults to using confstr() if available and reporting a hard error at
run time if that fails, but it can be configured to not use confstr(),
and/or fall back to a path specified at configuration time:
Use confstr() only, fail to configure if confstr is unavailable, fail at
runtime if confstr() does not return any path:
configure --enable-confstr
Use confstr(), fail to configure if confstr is unavailable, fall back to
/usr/bin:/bin if confstr() does not return any path:
configure --enable-confstr \
--with-fallback-standard-path='"/usr/bin:/bin"'
Use confstr() if available, use /usr/bin:/bin if confstr() is
unavailable or does not return any path:
configure \
--with-fallback-standard-path='"/usr/bin:/bin"'
Do no use confstr(), always use /usr/bin:/bin:
configure --disable-confstr \
--with-fallback-standard-path='"/usr/bin:/bin"'
Feedback welcome, there are several parts of this that I am not sure
about. Also, defpathvar is no longer used outside of var.c, so I made it
static and removed the references in var.h.
Cheers,
Harald
[-- Attachment #2: dash-confstr.patch --]
[-- Type: text/x-patch, Size: 3938 bytes --]
commit 008118857bdb34ea885d76cbddbb56290706dcd2
Author: Harald van Dijk <harald@gigawatt.nl>
Date: Fri Jul 19 23:29:55 2013 +0200
command: use confstr() for -p to get a safe path
diff --git a/configure.ac b/configure.ac
index c6fb401..e595e99 100644
--- a/configure.ac
+++ b/configure.ac
@@ -40,6 +40,36 @@ AC_ARG_ENABLE(fnmatch, AS_HELP_STRING(--enable-fnmatch, \
[Use fnmatch(3) from libc]))
AC_ARG_ENABLE(glob, AS_HELP_STRING(--enable-glob, [Use glob(3) from libc]))
+AC_ARG_ENABLE([confstr],
+[AS_HELP_STRING([--enable-confstr], [Use confstr(3) from libc (default=auto)])],,
+[enable_confstr=auto])
+
+if test x"$enable_confstr" != x"no"; then
+ have_confstr=no
+ AC_CHECK_FUNCS([confstr],[have_confstr=yes])
+ have_decl_confstr=no
+ AC_CHECK_DECL([confstr],[have_decl_confstr=yes
+ AC_DEFINE([HAVE_DECL_CONFSTR], [1], [Define as 1 if you have a declaration of confstr()])])
+ have_decl_cs_path=no
+ AC_CHECK_DECL([_CS_PATH],[have_decl_cs_path=yes
+ AC_DEFINE([HAVE_DECL_CS_PATH], [1], [Define as 1 if you have a declaration of _CS_PATH])])
+
+ if test "$have_confstr:$have_decl_confstr:$have_decl_cs_path" != "yes:yes:yes"; then
+ if test x"$enable_confstr" = x"yes"; then
+ AC_MSG_ERROR([cannot use confstr])
+ fi
+ fi
+fi
+
+AC_ARG_WITH([fallback-standard-path],
+[AS_HELP_STRING([--with-fallback-standard-path=\"ARG\"],
+[use ARG for command -p path lookups if confstr does not return anything (default: none)])],,
+[with_fallback_standard_path=no])
+
+if test x"$with_fallback_standard_path" != x"no"; then
+ AC_DEFINE_UNQUOTED([FALLBACK_STANDARD_PATH], [$with_fallback_standard_path], [Define to the path to use for command -p path lookups (ignored if confstr() is used)])
+fi
+
dnl Checks for libraries.
dnl Checks for header files.
diff --git a/src/eval.c b/src/eval.c
index c7358a6..1dba165 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -644,7 +644,7 @@ parse_command_args(char **argv, const char **path)
do {
switch (c) {
case 'p':
- *path = defpath;
+ *path = stdpath();
break;
default:
/* run 'typecmd' for other options */
diff --git a/src/exec.c b/src/exec.c
index e56e3f6..e32d48e 100644
--- a/src/exec.c
+++ b/src/exec.c
@@ -848,7 +848,7 @@ commandcmd(argc, argv)
else if (c == 'v')
verify |= VERIFY_BRIEF;
else if (c == 'p')
- path = defpath;
+ path = stdpath();
#ifdef DEBUG
else
abort();
@@ -860,3 +860,32 @@ commandcmd(argc, argv)
return 0;
}
+
+const char *
+stdpath(void)
+{
+ static const char *path = NULL;
+
+#if HAVE_CONFSTR && HAVE_DECL_CONFSTR && HAVE_DECL_CS_PATH
+ if (path == NULL) {
+ size_t size = confstr(_CS_PATH, NULL, 0);
+ if (size != 0) {
+ char *newpath = ckmalloc(size);
+ confstr(_CS_PATH, newpath, size);
+ path = newpath;
+ }
+ }
+#endif
+
+#ifdef FALLBACK_STANDARD_PATH
+ if (path == NULL) {
+ path = FALLBACK_STANDARD_PATH;
+ }
+#endif
+
+ if (path == NULL) {
+ exerror(EXEXIT, "%s", "no path for standard utilities");
+ }
+
+ return path;
+}
diff --git a/src/exec.h b/src/exec.h
index 9ccb305..a3f9314 100644
--- a/src/exec.h
+++ b/src/exec.h
@@ -75,3 +75,4 @@ void defun(union node *);
void unsetfunc(const char *);
int typecmd(int, char **);
int commandcmd(int, char **);
+const char *stdpath(void);
diff --git a/src/var.c b/src/var.c
index dc90249..653ba5b 100644
--- a/src/var.c
+++ b/src/var.c
@@ -73,7 +73,7 @@ struct localvar_list {
MKINIT struct localvar_list *localvar_stack;
-const char defpathvar[] =
+static const char defpathvar[] =
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
#ifdef IFS_BROKEN
const char defifsvar[] = "IFS= \t\n";
diff --git a/src/var.h b/src/var.h
index 79ee71a..71b85c9 100644
--- a/src/var.h
+++ b/src/var.h
@@ -106,8 +106,6 @@ extern const char defifsvar[];
#else
extern const char defifs[];
#endif
-extern const char defpathvar[];
-#define defpath (defpathvar + 5)
extern int lineno;
extern char linenovar[];
next prev parent reply other threads:[~2013-07-19 21:49 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-10 18:18 "command -p" does not correctly limit search to a safe PATH Craig Loomis
2013-07-14 19:54 ` Harald van Dijk
2013-07-19 21:49 ` Harald van Dijk [this message]
2014-09-26 9:19 ` Herbert Xu
2014-09-27 21:57 ` Jilles Tjoelker
2014-09-26 8:44 ` Herbert Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=51E9B46B.10401@gigawatt.nl \
--to=harald@gigawatt.nl \
--cc=cploomis@gmail.com \
--cc=dash@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox