Discussion:
Bash security issue
Bob Friesenhahn
2014-09-25 13:51:12 UTC
Permalink
It may be that some users of 'autoconf' will be at risk due to the
dire bash security bug described at
"http://www.theregister.co.uk/2014/09/24/bash_shell_vuln/".

Take care that the environment is carefully vetted.

Bob
--
Bob Friesenhahn
***@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer, http://www.GraphicsMagick.org/
Eric Blake
2014-09-25 14:55:45 UTC
Permalink
It may be that some users of 'autoconf' will be at risk due to the dire
bash security bug described at
"http://www.theregister.co.uk/2014/09/24/bash_shell_vuln/".
Take care that the environment is carefully vetted.
There's nothing that ./configure can do to avoid the buggy bash, but it
may indeed be worth patching autoconf to generate configure scripts that
issue a loud warning if the buggy shell is detected on the user's
system. I'll look into doing that.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Eric Blake
2014-09-25 14:59:04 UTC
Permalink
Post by Eric Blake
It may be that some users of 'autoconf' will be at risk due to the dire
bash security bug described at
"http://www.theregister.co.uk/2014/09/24/bash_shell_vuln/".
Take care that the environment is carefully vetted.
There's nothing that ./configure can do to avoid the buggy bash,
I should explain that: the bash bug affects bash startup, _before_ it
starts running any commands in your script. So if you have a buggy
shell, and use it to invoke your script, then by the time your script is
running, the bug has already happened.

I also think autoconf has a mitigating factor - the _reason_ the bash
bug is such a huge security bug is that there are services that can be
easily fooled into defining user-defined environment variables and
handing it off to the shell. The escalation comes into play when you
get a service running as a different user or on a different machine to
do that on your behalf. But autoconf generates configure scripts which
are designed to run on a local machine under the local user's
credentials; while the bug is still ugly, configure's use of the shell
is not crossing user/machine boundaries, and thus is probably not
something that can be exploited for privilege escalation in a configure
script alone.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Shawn H Corey
2014-09-25 15:45:06 UTC
Permalink
On Thu, 25 Sep 2014 08:55:45 -0600
Post by Eric Blake
Post by Bob Friesenhahn
It may be that some users of 'autoconf' will be at risk due to the
dire bash security bug described at
"http://www.theregister.co.uk/2014/09/24/bash_shell_vuln/".
Take care that the environment is carefully vetted.
There's nothing that ./configure can do to avoid the buggy bash, but
it may indeed be worth patching autoconf to generate configure
scripts that issue a loud warning if the buggy shell is detected on
the user's system. I'll look into doing that.
You may be premature. I think the patch will be out before Monday. If
so, your effort will be wasted. :)
--
Don't stop where the ink does.
Shawn
Eric Blake
2014-09-25 15:53:14 UTC
Permalink
Post by Shawn H Corey
On Thu, 25 Sep 2014 08:55:45 -0600
Post by Eric Blake
Post by Bob Friesenhahn
It may be that some users of 'autoconf' will be at risk due to the
dire bash security bug described at
"http://www.theregister.co.uk/2014/09/24/bash_shell_vuln/".
Take care that the environment is carefully vetted.
There's nothing that ./configure can do to avoid the buggy bash, but
it may indeed be worth patching autoconf to generate configure
scripts that issue a loud warning if the buggy shell is detected on
the user's system. I'll look into doing that.
You may be premature. I think the patch will be out before Monday. If
so, your effort will be wasted. :)
Huh? There is no wasted effort in teaching configure scripts to warn
users that they are running on an unpatched vulnerable system. Just
because a fix may be available doesn't mean everyone is running the fix.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Shawn H Corey
2014-09-25 23:14:03 UTC
Permalink
On Thu, 25 Sep 2014 09:53:14 -0600
Post by Eric Blake
Post by Shawn H Corey
On Thu, 25 Sep 2014 08:55:45 -0600
Post by Eric Blake
Post by Bob Friesenhahn
It may be that some users of 'autoconf' will be at risk due to the
dire bash security bug described at
"http://www.theregister.co.uk/2014/09/24/bash_shell_vuln/".
Take care that the environment is carefully vetted.
There's nothing that ./configure can do to avoid the buggy bash,
but it may indeed be worth patching autoconf to generate configure
scripts that issue a loud warning if the buggy shell is detected on
the user's system. I'll look into doing that.
You may be premature. I think the patch will be out before Monday.
If so, your effort will be wasted. :)
Huh? There is no wasted effort in teaching configure scripts to warn
users that they are running on an unpatched vulnerable system. Just
because a fix may be available doesn't mean everyone is running the fix.
That's only a partial solution. The problem is with bash(1), not your
scripts. If you warn about one security issue, then people will count
on you to warn them about _all_ the security issues. People are lazy
and will jump to conclusions to avoid work.

You should only worry about security for the software you are directly
responsible for. Otherwise, people will expect you to fix everything
and complain unfairly when you can't.
--
Don't stop where the ink does.
Shawn
Nick Bowler
2014-09-26 15:02:35 UTC
Permalink
Post by Shawn H Corey
On Thu, 25 Sep 2014 09:53:14 -0600
Post by Eric Blake
Huh? There is no wasted effort in teaching configure scripts to warn
users that they are running on an unpatched vulnerable system. Just
because a fix may be available doesn't mean everyone is running the fix.
That's only a partial solution. The problem is with bash(1), not your
scripts. If you warn about one security issue, then people will count
on you to warn them about _all_ the security issues. People are lazy
and will jump to conclusions to avoid work.
C compilers issue warnings for some buggy code, but nobody reasonably
expects them to warn about all possible bugs.

In this case, the bug implies a compatibility issue as well. So it is
prudent to warn users that the configure script may not run correctly,
and that they should update their shells to a fixed version.

Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
Ralf Corsepius
2014-09-29 11:19:00 UTC
Permalink
Post by Eric Blake
Huh? There is no wasted effort in teaching configure scripts to warn
users that they are running on an unpatched vulnerable system. Just
because a fix may be available doesn't mean everyone is running the fix.
I do not see any sense in this at all, unless the bash bug itself would
impact configure scripts themselves.

Ralf
Eric Blake
2014-09-29 13:13:48 UTC
Permalink
Post by Ralf Corsepius
Post by Eric Blake
Huh? There is no wasted effort in teaching configure scripts to warn
users that they are running on an unpatched vulnerable system. Just
because a fix may be available doesn't mean everyone is running the fix.
I do not see any sense in this at all, unless the bash bug itself would
impact configure scripts themselves.
But it MIGHT impact configure scripts. One of the goals of configure is
to 'export' variables into the build environment prior to calling
config.status recipes. The whole point of the Shell Shock bug is that
there are some values that you cannot safely export, because doing so
risks your child misbehaving. As we cannot predict which child
processes will be run during config.status, configure scripts may indeed
be vulnerable.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Ralf Corsepius
2014-09-29 13:24:30 UTC
Permalink
Post by Eric Blake
Post by Ralf Corsepius
Post by Eric Blake
Huh? There is no wasted effort in teaching configure scripts to warn
users that they are running on an unpatched vulnerable system. Just
because a fix may be available doesn't mean everyone is running the fix.
I do not see any sense in this at all, unless the bash bug itself would
impact configure scripts themselves.
But it MIGHT impact configure scripts. One of the goals of configure is
to 'export' variables into the build environment prior to calling
config.status recipes.
Yes, but only those which are relevant. Not any arbitrary ones.
Post by Eric Blake
The whole point of the Shell Shock bug is that
there are some values that you cannot safely export, because doing so
risks your child misbehaving. As we cannot predict which child
processes will be run during config.status, configure scripts may indeed
be vulnerable.
Do you have proof or is this just paranoia/hysteria?

I am inclined to believe your action to be "hyperactivity" addressing a
temporary issue, which soon will be non important but be carried around
ad infinitum until nobody recalls the origin. It also won't help the
1000s of existing generated configure scripts.

Ralf
Paul Eggert
2014-09-29 13:51:26 UTC
Permalink
I don't think it's worth modifying Autoconf to warn about this. By the time a
new Autoconf version is released, and used to generate source packages
containing configure scripts that are themselves distributed, and these source
packages are built, he problem will no longer be important.

I'm currently having to deal with this sort of thing:

$ ssh random-Red-Hat-host
...
bash: BASH_FUNC_module(): line 0: syntax error near unexpected token `)'
bash: BASH_FUNC_module(): line 0: `BASH_FUNC_module() () { eval
`/usr/bin/modulecmd bash $*`'
bash: error importing function definition for `BASH_FUNC_module'
$

which is caused by a widely-distributed Bash fix that overreacted to the bug and
is causing me more problems than the bug did. Let's not do something like this
with Autoconf.
Henrique de Moraes Holschuh
2014-09-29 15:05:34 UTC
Permalink
Post by Paul Eggert
which is caused by a widely-distributed Bash fix that overreacted to
the bug and is causing me more problems than the bug did. Let's not
do something like this with Autoconf.
Hmm, that "overreaction" is currently mitigating two undisclosed RCE bugs in
bash:

http://lcamtuf.blogspot.co.nz/2014/09/bash-bug-apply-unofficial-patch-now.html
http://www.itnews.com.au/News/396256,further-flaws-render-shellshock-patch-ineffective.aspx

Which is going to trigger a third round of shellshock security updates
(because mitigated is not fixed) soon enough, at which point a lot of people
might well decide to patch bash to remove the functionality entirely.
NetBSD and FreeBSD already did.

But this doesn't affect autoconf, really.

What _could_ affect autoconf is that bash can add crap to the environment
which is illegal under POSIX, because bash functions are not as restricted
as POSIX environment variables. Sorry, I don't have the link to the
relevant oss-sec post right now.
--
"One disk to rule them all, One disk to find them. One disk to bring
them all and in the darkness grind them. In the Land of Redmond
where the shadows lie." -- The Silicon Valley Tarot
Henrique Holschuh
Eric Blake
2014-09-29 16:04:48 UTC
Permalink
Post by Henrique de Moraes Holschuh
Post by Paul Eggert
which is caused by a widely-distributed Bash fix that overreacted to
the bug and is causing me more problems than the bug did. Let's not
do something like this with Autoconf.
Hmm, that "overreaction" is currently mitigating two undisclosed RCE bugs in
http://lcamtuf.blogspot.co.nz/2014/09/bash-bug-apply-unofficial-patch-now.html
http://www.itnews.com.au/News/396256,further-flaws-render-shellshock-patch-ineffective.aspx
Which is going to trigger a third round of shellshock security updates
(because mitigated is not fixed) soon enough, at which point a lot of people
might well decide to patch bash to remove the functionality entirely.
NetBSD and FreeBSD already did.
But this doesn't affect autoconf, really.
What _could_ affect autoconf is that bash can add crap to the environment
which is illegal under POSIX, because bash functions are not as restricted
as POSIX environment variables. Sorry, I don't have the link to the
relevant oss-sec post right now.
Where does POSIX state that environment variable names must be shell
identifiers? Bash is doing no worse than what 'env' could already do.
ALL programs must be prepared to ignore garbage names in the environment.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Nick Bowler
2014-09-29 15:44:37 UTC
Permalink
Post by Ralf Corsepius
The whole point of the Shell Shock bug is that there are some values
that you cannot safely export, because doing so risks your child
misbehaving. As we cannot predict which child processes will be run
during config.status, configure scripts may indeed be vulnerable.
Do you have proof or is this just paranoia/hysteria?
It's pretty simple: current versions bash will fail to import any
variable whose value starts with the 4-character sequence '() {'.

% myvar='() {'; export myvar
% dash -c 'echo hello, ${myvar+"myvar is set"}'
myvar is set
% posh -c 'echo hello, ${myvar+"myvar is set"}'
myvar is set
% mksh -c 'echo hello, ${myvar+"myvar is set"}'
myvar is set
% jsh -c 'echo hello, ${myvar+"myvar is set"}'
myvar is set
% zsh -c 'echo hello, ${myvar+"myvar is set"}'
myvar is set
% bash -c 'echo hello, ${myvar+"myvar is set"}'
bash: myvar: line 1: syntax error: unexpected end of file
bash: error importing function definition for `myvar'
hello,

Now admittedly this is a pretty obscure limitation, but particularly
if the input comes from the user, it represents a rather arbitrary
restriction on what can be entered.

Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
Bob Friesenhahn
2014-09-25 16:14:30 UTC
Permalink
Post by Eric Blake
It may be that some users of 'autoconf' will be at risk due to the dire
bash security bug described at
"http://www.theregister.co.uk/2014/09/24/bash_shell_vuln/".
Take care that the environment is carefully vetted.
There's nothing that ./configure can do to avoid the buggy bash, but it
may indeed be worth patching autoconf to generate configure scripts that
issue a loud warning if the buggy shell is detected on the user's
system. I'll look into doing that.
As far as I can tell, the main issue would be for free software sites
which provide services via CGI scripts which expose CGI environment
variables to scripts running bash. It does not matter if the initial
CGI script is based on Python, Perl, or something else if a script
running bash eventually gets invoked with the problematic environment
variables. At least that is my understanding.

There are also issues when using ssh because ssh can invoke remote
scripts on behalf of the user while passing local environment
variables.

Bob
--
Bob Friesenhahn
***@simple.dallas.tx.us, http://www.simplesystems.org/users/bfriesen/
GraphicsMagick Maintainer, http://www.GraphicsMagick.org/
Nick Bowler
2014-09-25 17:21:58 UTC
Permalink
Post by Eric Blake
It may be that some users of 'autoconf' will be at risk due to the dire
bash security bug described at
"http://www.theregister.co.uk/2014/09/24/bash_shell_vuln/".
Take care that the environment is carefully vetted.
There's nothing that ./configure can do to avoid the buggy bash, but it
may indeed be worth patching autoconf to generate configure scripts that
issue a loud warning if the buggy shell is detected on the user's
system. I'll look into doing that.
The most surprising thing I learned from this whole ordeal is that
there are strings consisting entirely of printable characters that
are not portable to store in exported shell variables.

Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
Eric Blake
2014-09-25 17:42:33 UTC
Permalink
Post by Nick Bowler
Post by Eric Blake
It may be that some users of 'autoconf' will be at risk due to the dire
bash security bug described at
"http://www.theregister.co.uk/2014/09/24/bash_shell_vuln/".
Take care that the environment is carefully vetted.
There's nothing that ./configure can do to avoid the buggy bash, but it
may indeed be worth patching autoconf to generate configure scripts that
issue a loud warning if the buggy shell is detected on the user's
system. I'll look into doing that.
The most surprising thing I learned from this whole ordeal is that
there are strings consisting entirely of printable characters that
are not portable to store in exported shell variables.
And _that's_ what I want changed, by proposing that bash use 'f()=...'
rather than 'f=() {...' as the magic it uses for exporting functions
from parent to child.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Linda Walsh
2014-09-25 19:15:27 UTC
Permalink
Post by Eric Blake
And _that's_ what I want changed, by proposing that bash use 'f()=...'
rather than 'f=() {...' as the magic it uses for exporting functions
from parent to child.
---
That could still be put in the environment (though not as easily w/o
special code).

Not that it is any more secure but how about replacing '()' with
'ƒ(8-byte-hex-sig)'
that is some crypto-sig of the function? If it matches the function's
sig, then function
would be read in. Of course like any crypto function, it's crackable,
but to toss
in enough bits to really forestall that, would be prohibitive unless
done on a
whole 'block' of imported info, i.e.

For more security, one could use cryptographic signing of a sequence of
BASH keys with the public key left in the environment and private key left
in a trusted kernel tpm keyring...(god that sounds painful -- but would like
by the method to really tie this down if that was really needed). But
script
isn't supposed to be the last line defense against launching the missiles.
Eric Blake
2014-09-25 19:23:56 UTC
Permalink
Post by Linda Walsh
Post by Eric Blake
And _that's_ what I want changed, by proposing that bash use 'f()=...'
rather than 'f=() {...' as the magic it uses for exporting functions
from parent to child.
---
That could still be put in the environment (though not as easily w/o
special code).
Where I'm coming from is that in portable shell programming, you _can't_
assign a value to f()=... (yes, 'env' can be used to pass non-shell
variables, but that is already non-portable). The fact that portable
programs are now slammed with the notion that some values cannot be
portably assigned to a variable is what gets avoided by not using
portable variable names as the mechanism for passing function
definitions between parent and child.
Post by Linda Walsh
Not that it is any more secure but how about replacing '()' with
'ƒ(8-byte-hex-sig)'
that is some crypto-sig of the function? If it matches the function's
sig, then function
would be read in. Of course like any crypto function, it's crackable,
but to toss
in enough bits to really forestall that, would be prohibitive unless
done on a
whole 'block' of imported info, i.e.
Overkill. The security hole arises because the problem, as it currently
exists, is triggerable by ANY portable environment variable definition.
It is very easy to trick programs, particularly programs running on
other machines or with elevated privileges into defining a normal shell
variable environment variable of ANY name, and when that variable then
gets eval'd and triggers any bug in the bash parser, the attacker has
gained control. As soon as you've made function passing require
something that can't be used as a normal shell variable, you don't have
to go any further. Portable programs now no longer have to vet what
they store into regular variable names, and scrubbing an environment for
non-shell names is also fairly easy.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Linda Walsh
2014-09-25 22:08:42 UTC
Permalink
Post by Eric Blake
Where I'm coming from is that in portable shell programming, you _can't_
assign a value to f()=... The fact that portable
programs are now "slammed"[sic] with the notion that some values cannot be
portably assigned to a variable...
---
slammed? It's not like this is new...
Post by Eric Blake
Not much more secure, but ..'ƒ(8-byte-crypto-hex-sig)'
Overkill.
---
Ya think?

I mean isn't the world held together by duct-tape, bailing-
wire and bash (or -compat) scripts? Anyway, it was also meant
as a "if you really are serious about solving this and don't care
about the overhead or inconvenience..." illustration of panic-driven
design.
Post by Eric Blake
It's not backwards compatible, but who cares? only matters
if you are mixing old and new bash...
But the old bash behavior is so bad that people are unlikely to
want to have both shells installed.
---
Oh come on... "so bad"?

As other have said:

«Geir Hauge wrote: Bash has had this feature since "forever"»

«Pierre Gaston wrote: How many instance have you found since the
introduction of this feature more than 20 years ago?»



This behavior has been around for 20+ without it being judged "so bad",
so lets not be tempted toward knee-jerk reactions. That it is now known
about makes some protections more urgent, but panicking over security fixes
often results in stupid knee-jerk "fixes"[sic] that only need to be
re-fixed [fixed] later on.

That it is a bug that should be fixed, no argument.
Your idea of using "f()=" in the ENV is sounds reasonable (though
not nearly so elegant as using the unicode 'function' symbol, 'ƒ' instead of
empty parens, in memory (ENV) -- not as to what a user would type.
The '()' is already overloaded w/meaning, "null set", or "empty array
assignment", depending on context.
lolilolicon
2014-09-26 07:53:53 UTC
Permalink
Post by Linda Walsh
Post by Eric Blake
Where I'm coming from is that in portable shell programming, you _can't_
assign a value to f()=... The fact that portable
programs are now "slammed"[sic] with the notion that some values cannot be
portably assigned to a variable...
---
slammed? It's not like this is new...
I think it's new to the majority of people.
Post by Linda Walsh
Post by Eric Blake
Not much more secure, but ..'ƒ(8-byte-crypto-hex-sig)'
Overkill.
---
Ya think?
I mean isn't the world held together by duct-tape, bailing-
wire and bash (or -compat) scripts? Anyway, it was also meant
as a "if you really are serious about solving this and don't care
about the overhead or inconvenience..." illustration of panic-driven
design.
I sensed that ("ƒ(8-byte-crypto-hex-sig)") was sarcasm. Not cool :(

"panic-driven design" would be bad,
but a wise man once uttered,

"Just because you're paranoid, don't mean they're not after you."
Post by Linda Walsh
Post by Eric Blake
It's not backwards compatible, but who cares? only matters
if you are mixing old and new bash...
But the old bash behavior is so bad that people are unlikely to want to
have both shells installed.
---
Oh come on... "so bad"?
«Geir Hauge wrote: Bash has had this feature since "forever"»
«Pierre Gaston wrote: How many instance have you found since the
introduction of this feature more than 20 years ago?»
This behavior has been around for 20+ without it being judged "so bad",
I don't think that's a sufficient argument for "this is not so bad".

First, the fact that the bug has existed for so long, yet fails to be
discovered [disclosed] until now, is proof that this feature is very
little used and rarely tested, not an argument for "it's not so bad".

Second, this has been a dark corner of bash, a blind spot for most
people, including security people and crackers. Now it's in the
spotlight. And now we are seeing a can of worms crawling out of the
dark.
Post by Linda Walsh
so lets not be tempted toward knee-jerk reactions. That it is now known
about makes some protections more urgent, but panicking over security fixes
often results in stupid knee-jerk "fixes"[sic] that only need to be
re-fixed [fixed] later on.
Just as bad is the decision to introduce a poorly thought out "it would
be nice" feature, get busted 20 years later, and have to fix it trying
to maintain backward-compatibility.

The wisdom from above has taught,

"Unwritten code is debugged code."
"The most productive days was removing 1000 lines of code."

Unfortunately, when a project grows so popular, it gets trapped in its
own past.
Post by Linda Walsh
That it is a bug that should be fixed, no argument.
Your idea of using "f()=" in the ENV is sounds reasonable (though
not nearly so elegant as using the unicode 'function' symbol, 'ƒ' instead of
empty parens, in memory (ENV) -- not as to what a user would type.
The '()' is already overloaded w/meaning, "null set", or "empty array
assignment", depending on context.
And of course there is no such meaning. It's all in your head.
Zack Weinberg
2014-09-26 14:22:19 UTC
Permalink
Post by lolilolicon
Post by Linda Walsh
This behavior has been around for 20+ without it being judged "so
bad",
I don't think that's a sufficient argument for "this is not so bad".
First, the fact that the bug has existed for so long, yet fails to be
discovered [disclosed] until now, is proof that this feature is very
little used and rarely tested, not an argument for "it's not so bad".
The question in my mind is, is exporting functions a POSIX shell feature? If not, perhaps it should just be scrapped altogether.

zw
Eric Blake
2014-09-26 14:36:05 UTC
Permalink
Post by Zack Weinberg
Post by lolilolicon
Post by Linda Walsh
This behavior has been around for 20+ without it being judged "so
bad",
I don't think that's a sufficient argument for "this is not so bad".
First, the fact that the bug has existed for so long, yet fails to be
discovered [disclosed] until now, is proof that this feature is very
little used and rarely tested, not an argument for "it's not so bad".
The question in my mind is, is exporting functions a POSIX shell feature? If not, perhaps it should just be scrapped altogether.
Why not read POSIX and find out for yourself?
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#export

export -f is not required by POSIX, so it is a shell extension. But
people DO rely on it, so nuking it now would be a backwards incompatible
break. I'd still like to keep it, but with a smarter implementation.
Other messages on the list have suggested smarter implementations, such
as using 'BASH_FUNC_foo()=...' instead of 'foo=() {' as the magic for
doing the export, thus eliminating the collision.

I _also_ agree that since function exports are NOT required by POSIX,
that it would be okay if we let /bin/bash continue to import functions
by default, but have bash invoked as /bin/sh refuse to do imports by
default. If the ability to import functions becomes conditional on
argv[0], then I also suggest that bash have a 'set -o' option or 'shopt'
setting that can let the user override the default (a way to invoke
/bin/sh but with function imports, or a way to invoke /bin/bash but with
no functions).
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Steve Simmons
2014-09-26 14:51:36 UTC
Permalink
. . . I _also_ agree that since function exports are NOT required by POSIX,
that it would be okay if we let /bin/bash continue to import functions
by default, but have bash invoked as /bin/sh refuse to do imports by
default. . .
The more I see of how many bash-isms work when bash is invoked as /bin/sh, the more convinced I get that we need to either

1) make bash when invoked as /bin/sh fail those bash-isms

2) build a 'real' /bin/sh without those compiled in. This begs the definition of 'real', but IMHO if it's not in POSIX, it shouldn't be in 'real' /bin/sh

Why this is bothering me today? There has been at least one instance of a group building a new bash, installing it, and finding the hard way that it didn't work at boot time. If /bin/sh had been a separate pared-down thing, they could have at least booted.

I have always been unhappy with /bin/sh being a symlink to /bin/bash rather than a separate pared-down executable or with bash features turned off). The last couple of days only reinforces that opinion.

Yours in haste,

Steve
Paul Smith
2014-09-26 15:08:30 UTC
Permalink
Post by Steve Simmons
2) build a 'real' /bin/sh without those compiled in. This begs the
definition of 'real', but IMHO if it's not in POSIX, it shouldn't be
in 'real' /bin/sh
Ubuntu and it's derivatives have been doing this since 2006. /bin/sh on
these systems is dash:

https://wiki.ubuntu.com/DashAsBinSh

They get a lot flak for it amongst people who care more about having
things work than having things portable, but they've stuck to their guns
so far. Probably this current situation leaves them feeling justified
and even more resolute. As someone who develops a lot of embedded
software and is constantly burned by people throwing badly-written
bash-specific scripts into their packages, I have really appreciated
them taking this stand.

It would be great if Red Hat would also join in, but I cannot imagine
that happening, ever: way too much would break for too little gain.
Chet Ramey
2014-09-27 22:21:30 UTC
Permalink
Post by Steve Simmons
. . . I _also_ agree that since function exports are NOT required by POSIX,
that it would be okay if we let /bin/bash continue to import functions
by default, but have bash invoked as /bin/sh refuse to do imports by
default. . .
The more I see of how many bash-isms work when bash is invoked as /bin/sh, the more convinced I get that we need to either
1) make bash when invoked as /bin/sh fail those bash-isms
It's come up before, and it's not something that bash has ever been
intended to do. When invoked as /bin/sh, bash will behave as a posix
superset. Posix allows this.
Post by Steve Simmons
2) build a 'real' /bin/sh without those compiled in. This begs the definition of 'real', but IMHO if it's not in POSIX, it shouldn't be in 'real' /bin/sh
This is dash's niche.

Chet
--
``The lyf so short, the craft so long to lerne.'' - Chaucer
``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, ITS, CWRU ***@case.edu http://cnswww.cns.cwru.edu/~chet/
Eric Blake
2014-09-27 22:51:34 UTC
Permalink
Post by Chet Ramey
Post by Steve Simmons
1) make bash when invoked as /bin/sh fail those bash-isms
It's come up before, and it's not something that bash has ever been
intended to do. When invoked as /bin/sh, bash will behave as a posix
superset. Posix allows this.
Even dash is a posix superset. Although dash tries to be more
minimalistic at not adding new features without first getting those
features specified by posix, there are definite existing extensions in
the code base that the dash maintainer is unwilling to remove because of
the risk of breaking backward compatibility.
Post by Chet Ramey
Post by Steve Simmons
2) build a 'real' /bin/sh without those compiled in. This begs the definition of 'real', but IMHO if it's not in POSIX, it shouldn't be in 'real' /bin/sh
This is dash's niche.
If you want a truly minimalist shell that will loudly complain at
attempts to use extensions, use 'posh' instead of 'dash'.

But Chet's point remains - there's no need to dumb down bash to serve as
a minimalist shell, because that's a maintenance burden, and there are
already other projects that have decided to take on that role.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Steve Simmons
2014-09-28 00:07:36 UTC
Permalink
Post by Eric Blake
Post by Chet Ramey
Post by Steve Simmons
2) build a 'real' /bin/sh without those compiled in. This begs the definition of 'real', but IMHO if it's not in POSIX, it shouldn't be in 'real' /bin/sh
This is dash's niche.
If you want a truly minimalist shell that will loudly complain at
attempts to use extensions, use 'posh' instead of 'dash'.
But Chet's point remains - there's no need to dumb down bash to serve as
a minimalist shell, because that's a maintenance burden, and there are
already other projects that have decided to take on that role.
Noted. Thanks.

Steve
Zack Weinberg
2014-09-26 15:42:49 UTC
Permalink
Post by Eric Blake
Post by Zack Weinberg
The question in my mind is, is exporting functions a POSIX shell feature?
If not, perhaps it should just be scrapped altogether.
Why not read POSIX and find out for yourself?
I would normally, but I am traveling right now and limited to things
that work on my phone. The Open Group's site is not one of those
things, unfortunately. Thanks for checking for me.
Post by Eric Blake
export -f is not required by POSIX, so it is a shell extension. But
people DO rely on it, so nuking it now would be a backwards incompatible
break. I'd still like to keep it, but with a smarter implementation.
Fair enough...
Post by Eric Blake
Other messages on the list have suggested smarter implementations, such
as using 'BASH_FUNC_foo()=...' instead of 'foo=() {' as the magic for
doing the export, thus eliminating the collision.
That should help. I might be a bit more aggressive, e.g.

_BASH_FUNC_<8 random hex chars>_<name>() = body of function

The 8 random hex chars come from something unpredictable but stable in
the filesystem, so even if an attacker can somehow put () in an
environment variable name they can't reasonably generate these names.
(I think 2^-64 is probably improbable enough for this.)

And I'd take the curly braces off the function body, too, to ensure
the original bug can't possibly come back.
Post by Eric Blake
it would be okay if we let /bin/bash continue to import functions
by default, but have bash invoked as /bin/sh refuse to do imports by
default. If the ability to import functions becomes conditional on
argv[0], then I also suggest that bash have a 'set -o' option or 'shopt'
setting that can let the user override the default (a way to invoke
/bin/sh but with function imports, or a way to invoke /bin/bash but with
no functions).
Sure.

zw
Eric Blake
2014-09-26 14:51:02 UTC
Permalink
Post by Linda Walsh
Post by Eric Blake
Where I'm coming from is that in portable shell programming, you _can't_
assign a value to f()=... The fact that portable programs are now
slammed with the notion that some values cannot be portably assigned
to a variable...
---
slammed? It's not like this is new...
[...]
Post by Linda Walsh
«Geir Hauge wrote: Bash has had this feature since "forever"»
«Pierre Gaston wrote: How many instance have you found since the
introduction of this feature more than 20 years ago?»
Since I don't use bash it's not surprising that I've never noticed any
problem.
But I try to write scripts that are portable to bash, because I know
that many people do use it. What I learned from this is that bog-
foo=$1; export foo
are not portable to bash, and may fail to work correctly depending on
the user's input.
They are not portable to broken bash. But the argument in these threads
is that bash's implementation of function exports should be changed so
that _fixed_ bash will once again be POSIX compliant and let this
bog-standard assignment work regardless of contents. If Chet accepts
Florian's patch [1] to change function exports to use BASH_FUNC_foo()=
instead of foo= (which is what Red Hat is already using in their fixes
pushed today), then this POSIX compliance bug in broken bash will be
avoided.

[1] http://www.openwall.com/lists/oss-security/2014/09/25/13
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Nick Bowler
2014-09-26 14:56:29 UTC
Permalink
Post by Eric Blake
Post by Linda Walsh
Post by Eric Blake
Where I'm coming from is that in portable shell programming, you _can't_
assign a value to f()=... The fact that portable programs are now
slammed with the notion that some values cannot be portably assigned
to a variable...
---
slammed? It's not like this is new...
[...]
Post by Linda Walsh
«Geir Hauge wrote: Bash has had this feature since "forever"»
«Pierre Gaston wrote: How many instance have you found since the
introduction of this feature more than 20 years ago?»
Since I don't use bash it's not surprising that I've never noticed any
problem.
But I try to write scripts that are portable to bash, because I know
that many people do use it. What I learned from this is that bog-
foo=$1; export foo
are not portable to bash, and may fail to work correctly depending on
the user's input.
They are not portable to broken bash. But the argument in these threads
is that bash's implementation of function exports should be changed so
that _fixed_ bash will once again be POSIX compliant and let this
bog-standard assignment work regardless of contents. If Chet accepts
Florian's patch [1] to change function exports to use BASH_FUNC_foo()=
instead of foo= (which is what Red Hat is already using in their fixes
pushed today), then this POSIX compliance bug in broken bash will be
avoided.
I agree. This sounds like a simple and effective solution.

Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
Linda Walsh
2014-09-26 20:22:11 UTC
Permalink
Post by Eric Blake
They are not portable to broken bash. But the argument in these threads
is that bash's implementation of function exports should be changed so
that _fixed_ bash will once again be POSIX compliant and let this
bog-standard assignment work regardless of contents. If Chet accepts
Florian's patch [1] to change function exports to use BASH_FUNC_foo()=
instead of foo= (which is what Red Hat is already using in their fixes
pushed today), then this POSIX compliance bug in broken bash will be
avoided.
[1] http://www.openwall.com/lists/oss-security/2014/09/25/13
----
IS this added only in memory? I.e. no changes to source code?

What prevents BASH_FUNC_foo = '(){ :; ...';

Why is there a need for a long prefix on top of switching
the ()/= order?
Eric Blake
2014-09-26 21:04:14 UTC
Permalink
Post by Linda Walsh
Post by Eric Blake
They are not portable to broken bash. But the argument in these threads
is that bash's implementation of function exports should be changed so
that _fixed_ bash will once again be POSIX compliant and let this
bog-standard assignment work regardless of contents. If Chet accepts
Florian's patch [1] to change function exports to use BASH_FUNC_foo()=
instead of foo= (which is what Red Hat is already using in their fixes
pushed today), then this POSIX compliance bug in broken bash will be
avoided.
[1] http://www.openwall.com/lists/oss-security/2014/09/25/13
----
IS this added only in memory? I.e. no changes to source code?
What prevents BASH_FUNC_foo = '(){ :; ...';
Nothing, as you wrote it, because you have no () on the left of the
equal. Florian's patch makes it so that the child bash sees your
example as a NORMAL variable, and so you get "echo $BASH_FUNC_foo"
outputting "(){...". What matters is that 'export -f foo' results in
'BASH_FUNC_foo()=...' in the environment (note the parens on the left of
the equal). As this is NOT a valid shell variable name, you have now
cleanly separated the namespace, and arbitrary contents of a shell
variable can no longer be coerced into a function.

And yes, you could still pass this arbitrary name via env or other
means, but remember that this exploit is not about the NAME of the
variable, but that arbitrary CONTENTS of a fixed name in the environment
were parsed rather than being treated as a string literal (in violation
of POSIX). By separating namespaces, bash no longer violates POSIX, and
programs like apache that stick arbitrary contents into fixed-name
variables (but which do NOT create arbitrary-name variables) are no
longer subject to the parser intercepting their contents.
Post by Linda Walsh
Why is there a need for a long prefix on top of switching
the ()/= order?
only to make it all the more clear that this is a hand-shaking mechanism
between bash parent and child, and NOT something that most other
processes will care about.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
Linda Walsh
2014-09-27 16:05:54 UTC
Permalink
Post by Eric Blake
Post by Linda Walsh
What prevents BASH_FUNC_foo = '(){ :; ...';
Nothing, as you wrote it, because you have no () on the left of the
equal.
----
Then what is wrong with
foo()={ :; ... ;}... That cannot be a legal variable name either.

Other languages like PERL rely on ENV vars and will fail badly if
something messes with the ENV. (Try making perl with
PERL5OPT='-Mutf8 -CSA -I/home/mylib'). If you mess with the env
prior to a interpreter that depends on the ENV, its going to cause
problems and it will be a short while before exploits can be developed
from such.

Besides, if you want to make it illegal, why not ƒfoo:{function def}
That makes for an impossible ENVvar AND only costs 1 more byte of memory
than adding 10 bytes.
Nick Bowler
2014-09-26 14:45:05 UTC
Permalink
Post by Linda Walsh
Post by Eric Blake
Where I'm coming from is that in portable shell programming, you _can't_
assign a value to f()=... The fact that portable programs are now
slammed with the notion that some values cannot be portably assigned
to a variable...
---
slammed? It's not like this is new...
[...]
Post by Linda Walsh
«Geir Hauge wrote: Bash has had this feature since "forever"»
«Pierre Gaston wrote: How many instance have you found since the
introduction of this feature more than 20 years ago?»
Since I don't use bash it's not surprising that I've never noticed any
problem.

But I try to write scripts that are portable to bash, because I know
that many people do use it. What I learned from this is that bog-
standard assignments like this:

foo=$1; export foo

are not portable to bash, and may fail to work correctly depending on
the user's input.

Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
Andreas Schwab
2014-09-26 07:43:07 UTC
Permalink
Post by Eric Blake
Overkill. The security hole arises because the problem, as it currently
exists, is triggerable by ANY portable environment variable definition.
In the context of security you need to forget about portable. You need
to think about the improbable.

Andreas.
--
Andreas Schwab, ***@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."
Eric Blake
2014-09-28 00:26:43 UTC
Permalink
There has been a LOT of news about bash's Shell Shock bug lately.
Document some of the ramifications it has on portable scripting.

* doc/autoconf.texi (Limitations of Builtins) <export>: Add some
details about Shell Shock CVE-2014-6271.

Signed-off-by: Eric Blake <***@redhat.com>
---

I'm still debating about adding a sniffer to configure scripts that
warns users if they still have a vulnerable bash on their system,
but that's a bigger project, and makes the most sense only if I can
releast autoconf 2.70 in the near future. But I'd like to apply
this patch no matter what.

doc/autoconf.texi | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index e2137ae..b3fabfd 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -17668,6 +17668,15 @@ Limitations of Builtins
bar
@end example

+Posix requires @command{export} to work with any arbitrary value for the
+contents of the variable being exported, but some versions of Bash
+(including all builds prior to September 2014) are vulnerable to the
+``Shell Shock'' remote execution bug (CVE-2014-6271 and friends), where
+exporting a variable with the initial substring of @code{() @{} could
+trigger a number of undesirable behaviors at the startup of a child
+bash. Bash has an extension that allows the export of function
+definitions, but this is not portable to other shells.
+
@item @command{false}
@c ------------------
@prindex @command{false}
--
1.9.3
Nick Bowler
2014-09-29 16:03:54 UTC
Permalink
Post by Eric Blake
There has been a LOT of news about bash's Shell Shock bug lately.
Document some of the ramifications it has on portable scripting.
[..]
Post by Eric Blake
+contents of the variable being exported, but some versions of Bash
+(including all builds prior to September 2014) are vulnerable to the
+``Shell Shock'' remote execution bug (CVE-2014-6271 and friends), where
+trigger a number of undesirable behaviors at the startup of a child
+bash. Bash has an extension that allows the export of function
+definitions, but this is not portable to other shells.
Hm, this text seems a bit unclear... the problem is not "export", but in
the way bash startup assigns shell variables from the environment. POSIX
doesn't say very much about how this process is supposed to work. As
far as I can see, it just says:

"[shell] variables shall be initialized from the environment ... if a
variable was initialized from the environment, it shall be marked for
export immediately".

Nevertheless, we can export these values in bash just fine, and they
will be correctly written to the environment:

% cat >test.sh <<'EOF'
foo='() {'
echo "$foo"

export foo
dash -c 'echo "$foo"'
EOF

% bash test.sh
() {
() {

Cheers,
--
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
Loading...