oss-sec mailing list archives

Re: wordexp(3)


From: Rich Felker <dalias () libc org>
Date: Wed, 11 Feb 2015 01:15:55 -0500

On Tue, Feb 10, 2015 at 12:57:05PM -0500, Rich Felker wrote:
On Tue, Feb 10, 2015 at 08:27:56PM +0300, Solar Designer wrote:
Hi,

I found this curious and relevant to this list, off Twitter:

(x250) <%worr> RT @FioraAeterna: oh my gosh, Apple's libc literally implements "wordexp" by shelling out to perl: 
https://github.com/Apple-FOSS-Mirror/Libc/blob/2ca2ae74647714acfc18674c3114b1a5d3325d7d/gen/wordexp.c#L192

<worr> So yesterday, @FioraAeterna tweeted this: 
https://github.com/Apple-FOSS-Mirror/Libc/blob/2ca2ae74647714acfc18674c3114b1a5d3325d7d/gen/wordexp.c#L192. I've 
decided to take a tour of wordexp(3) implementations
<@worr> They can't all be that bad
(x2) <@worr> NetBSD and FreeBSD both use a sh builtin to implement wordexp(3): 
http://svnweb.freebsd.org/base/head/lib/libc/gen/wordexp.c?revision=254977&view=markup 
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/gen/wordexp.c?rev=1.3&content-type=text/x-cvsweb-markup&only_with_tag=MAIN
(x5) <@worr> OpenBSD wins the wordexp(3) contest, by refusing to implement it altogether.
<@worr> Correction: glibc implements a huge recursive descent parser, and only shells out when it needs to do 
subshell expansions.
<@worr> tbh, wordexp(3) is an antifeature. Maybe even a misfeature.
<@worr> Here's the implementation, btw: 
https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/wordexp.c;h=26f3a2653feba2b1a5904937d9d6b58c32109e24;hb=a39208bd7fb76c1b01c127b4c61f9bfd915bfe7c#l872
<@worr> Continuing on my tour of wordexp(3) implementations, here's Illumos': 
https://github.com/joyent/illumos-joyent/blob/master/usr/src/lib/libc/port/regex/wordexp.c#L218-L290 It constructs 
a small shell script and runs it

POSIX is explict that the wordexp interface is designed such that
invoking a shell is one valid implementation choice. My view on all
this is that pretty much anything wordexp-related is not CVE-worthy;
wordexp simply is not a proper tool to be using in programs dealing
with untrusted inputs -- either untrusted input strings, or untrusted
environment contents. Obviously implementations using /bin/sh were
vulnerable to shellshock on systems where /bin/sh is bash.

To elaborate on the above, the RATIONALE text reads:

    "While wordexp() could be implemented entirely as a library
    routine, it is expected that most implementations run a shell in a
    subprocess to do the expansion."

Source:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/wordexp.html

In addition to the allowance of shell-based implementations, the text
of the standard puts a burden on the calling application not to pass
certain dangerous strings:

    "... Therefore, the application shall ensure that words does not
    contain an unquoted <newline> character or any of the unquoted
    shell special characters '|', '&', ';', '<', '>' except in the
    context of command substitution as specified in XCU Command
    Substitution."

However, later in the DESCRIPTION, the following text appears, which
seems to specify a behavior for this case:

    "If the implementation supports the utilities defined in the Shell
    and Utilities volume of POSIX.1-2008, and words contains an
    unquoted character- <newline>, '|', '&', ';', '<', '>' , '(', ')',
    '{', '}' - in an inappropriate context, wordexp() shall fail, and
    the number of expanded words shall be 0."

Read together, this seems to require conforming implementations to
detect bad characters, but also requires conforming applications not
to pass them; one or the other of these requirements is rather
useless, then.

In any case, I would hope all of the above serves as sufficient
warning that you should not pass untrusted input to wordexp. :-)

Rich


Current thread: