
Apple's libc shells out to Perl to implement wordexp - devbug
https://github.com/Apple-FOSS-Mirror/Libc/blob/2ca2ae74647714acfc18674c3114b1a5d3325d7d/gen/wordexp.c#L192
======
dxq
This is source code from 2011. Checking
[http://opensource.apple.com](http://opensource.apple.com) will show that it's
not longer implemented this way in 10.10.

Here's the current implementation:
[http://opensource.apple.com/source/Libc/Libc-1044.1.2/gen/Fr...](http://opensource.apple.com/source/Libc/Libc-1044.1.2/gen/FreeBSD/wordexp.c)

~~~
mrpippy
The current one is a derivative of NetBSD's implementation (where it shells
out to use a sh builtin)

~~~
lloeki
License-wise:

\- this piece of code is 2BSD-licensed

\- it calls out to /bin/sh

\- on OS X, /bin/sh is hardlinked to /bin/bash

\- OS X's bash is GPLv2

Forking to shell is the only way to reuse bash's code. More often than not I
really wish _sh_ were not _bash_.

~~~
_ZeD_
"Forking to shell is the only way to reuse bash's code."

well, the other obvius way is to license this piece of code as GPLv2.

~~~
yetihehe
AFAIK this is THE reason for GPL. So that you either release your code and
contribute to open source or suffer from slower access methods.

~~~
feld
The BSDs doesn't ship with bash and their wordexp shelling out to /bin/sh
doesn't suffer, so I don't see how this is a reason for the GPL.

~~~
yetihehe
Probably I've written it not clearly enough: "Reason for GPL not allowing you
to use code in your own programs, but allowing use through exec: you either
release your code and contribute to open source or suffer from slower access
methods."

~~~
feld
ahh, ok; that's clearer

------
cnvogel
As it's already written in the manual...

[http://linux.die.net/man/3/wordexp](http://linux.die.net/man/3/wordexp)

wordexp, wordfree - perform word expansion like a posix-shell

So, the implementer decided to take the short route, and just spawn a shell
which, essentially, gets passed the input data to wordexp(), to do the work.
But, of course, having something that starts with such a comment...

/* XXX this is _not_ designed to be fast (...) wordexp is also rife with
security "challenges", unless you pass it WRDE_NOCMD it _must_ support
subshell expansion, and even if you don't beause it has to support so much of
the standard shell (all the odd little variable expansion options for example)
it is hard to do without a subshell). It is probably just plan a Bad Idea to
call in anything setuid, or executing remotely. */

...in your standard C library wasn't such a smart idea to start with. Scroll
down, there are many more gems in the comments!

Sometimes it's better to just implement it as

    
    
            void wordexp() {
                    fprintf(stderr,"wordexp() is a security nightmare. Not implemented.\n");
                    assert(0);
            }
    

or decide to deliberately only implement a safe subset of the full
functionality specified (e.g. only ~user-homedir expansion and $VARIABLES), to
at least cover the common use-cases without creating a security nightmare.

(EDIT: typos)

~~~
Luyt
_Scroll down, there are many more gems in the comments!_

...and what a spelling errors:

"This kludge is needed because /bin/sh seems to set IFS to the defualt even if
you have set it; We also can't just ignore it because it is hard/unplesent to
code around or even a potential security problem because the test suiete
explicitly checks to make sure setting IFS 'works'"

ESR writes about sloppy spelling: "Write in clear, grammatical, correctly-
spelled language. We've found by experience that people who are careless and
sloppy writers are usually also careless and sloppy at thinking and coding
(often enough to bet on, anyway)."

~~~
coldtea
ESR hasn't been a role model for anything related to programming since, like,
1998.

------
comex
Here is a vulnerability in the current version [1] for your amusement:

    
    
        #include <wordexp.h>
        #include <stdio.h>
        int main() {
            wordexp_t we;
            char *s = "$(($(sleep 10)))";
            printf("->%d\n", wordexp(s, &we, WRDE_NOCMD));
        }
    

(Since the manual page strongly recommends not trusting wordexp with untrusted
input even with WRDE_NOCMD, and based on a code search the function is rarely
used in the first place, I don't think it's really sensitive.)

[http://opensource.apple.com/source/Libc/Libc-1044.1.2/gen/Fr...](http://opensource.apple.com/source/Libc/Libc-1044.1.2/gen/FreeBSD/wordexp.c)

------
melling
Well, you are warned: /* XXX this is _not_ designed to be fast */

~~~
nandemo
Performance is the least of my worries here. I'd be more worried about
security, and plain dependency management.

I mean, let's say this libc thing is supposed to be installed in quite a lot
of systems, are we really sure that perl thing is installed in _all_ of those
systems? And what if, by some crazy coincidence, perl happens to depend on
libc?

~~~
vertex-four
> I mean, let's say this libc thing is supposed to be installed in quite a lot
> of systems

Apple's libc is not an independent thing to them - it's a part of OSX and iOS.
You're not supposed to be able to take it out and use it for other things.

~~~
nandemo
Fair enough.

------
Intermernet
Sorry, I don't have a Mac to check, but does the OSX build of Perl depend on
libc?

Also, that code seems to be from 2008 (or at least that's the latest year in
the copyright header) despite the commit being from 2012. Does anyone know if
this has been updated? Inserting a NUL byte between each word, and at the end
doesn't sound like it requires Perl...

~~~
adamnemecek
> otool -L /usr/bin/perl

/usr/bin/perl:

/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation
(compatibility version 150.0.0, current version 1151.14.0)

/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version
1213.0.0)

~~~
Intermernet
Thanks, much appreciated.

I thought there may be some strange cyclic dependency going on, but it seems
not.

~~~
ksherlock
It would only be a problem if that specific perl command (perl -e 'print
join(chr(0), @ARGV), chr(0)' \-- args....) or the shell invoking it depended
on wordexp(). Recursion is fine as long as it terminates.

------
dunham
They appear to be using a "wordexp-helper" in Yosemite. I found this in
/usr/lib/system/libsystem_c.dylib (and no references to perl).

    
    
        [ $# -gt 0 ] && export IFS="$1";/usr/lib/system/wordexp-helper

~~~
dxq
Source to wordexp-helper here:
[http://opensource.apple.com/source/system_cmds/system_cmds-6...](http://opensource.apple.com/source/system_cmds/system_cmds-643.1.1/wordexp-
helper.tproj/wordexp-helper.c)

Also the source to the Yosemite implementation is available at:
[http://opensource.apple.com/source/Libc/Libc-1044.1.2/gen/Fr...](http://opensource.apple.com/source/Libc/Libc-1044.1.2/gen/FreeBSD/wordexp.c)

------
ryan0x00
sometimes you have to get shit done

~~~
_pmf_
> sometimes you have to get shit done

And Apple have always been masters in selling polished, nicely packages shit
as the most advanced technology ever conceived.

~~~
jes
With respect, is there evidence to support your claim?

My direct experience is that I have received value far in excess of what I
have had to pay for the Apple products and services I have purchased over the
years.

For example, I'm typing this reply on my PowerBook, which I use all day, every
day in my work. I also have my iPhone with me constantly, and use it heavily.

Finally, the Apple brand was said to be worth about $104.7B vs. $62.8B for
Microsoft in 2014. [1]

So, I am not saying you are wrong, only that I think some evidence would be
helpful in making your case.

[1] [http://bgr.com/2014/03/19/apple-vs-google-vs-microsoft-
brand...](http://bgr.com/2014/03/19/apple-vs-google-vs-microsoft-brand-value/)

~~~
smcl
OT, but you're still using a Powerbook? That's pretty impressive. Which
generation\year was it? I'm guessing you've had to swap out batteries and
upgrade hard drive - have you had to modify anything else?

~~~
coldtea
He meant MacBook Pro.

That said, I still have an iBook G4 from 2004 in perfect operation for
mail/web/music (though one button is missing).

