Photo credit: Liam Quinn
This is going to be interesting as Planet Gentoo is currently unavailable as I write this. I’ll try to send this out further so that people know about it.
By now we have all been doing our best to update our laptops and servers to the new
bash version so that we are safe from the big scare of the quarter, shellshock. I say laptop because the way the vulnerability can be exploited limits the impact considerably if you have a desktop or otherwise connect only to trusted networks.
What remains to be done is to figure out how to avoid this repeats. And that’s a difficult topic, because a 25 years old bug is not easy to avoid, especially because there are probably plenty of siblings of it around, that we have not found yet, just like this last week. But there are things that we can do as a whole environment to reduce the chances of problems like this to either happen or at least avoid that they escalate so quickly.
In this post I want to look into some things that Gentoo and its developers can do to make things better.
The first obvious thing is to figure out why
/bin/sh for Gentoo is not dash or any other very limited shell such as BusyBox. The main answer lies in the init scripts that still use bashisms; this is not news, as I’ve pushed for that four years ago, while Roy insisted on it even before that. Interestingly enough, though, this excuse is getting less and less relevant thanks to systemd. It is indeed, among all the reasons, one I find very much good in Lennart’s design: we want declarative init systems, not imperative ones. Unfortunately, even systemd is not as declarative as it was originally supposed to be, so the init script problem is half unsolved — on the other hand, it does make things much easier, as you have to start afresh anyway.
If either all your init scripts are non-bash-requiring or you’re using systemd (like me on the laptops), then it’s mostly safe to switch to use
dash as the provider for
# emerge eselect-sh # eselect sh set dash
That will change your
/bin/sh and make it much less likely that you’d be vulnerable to this particular problem. Unfortunately as I said it’s mostly safe. I even found that some of the init scripts I wrote, that I checked with
checkbashisms did not work as intended with
dash, fixes are on their way. I also found that the
lsb_release command, while not requiring bash itself, uses non-POSIX features, resulting in garbage on the output — this breaks facter-2 but not facter-1, I found out when it broke my Puppet setup.
Interestingly it would be simpler for me to use
zsh, as then both the init script and
lsb_release would have worked. Unfortunately when I tried doing that, Emacs tramp-mode froze when trying to open files, both with
sudo modes. The same was true for using BusyBox, so I decided to just install dash everywhere and use that.
Unfortunately it does not mean you’ll be perfectly safe or that you can remove bash from your system. Especially in Gentoo, we have too many dependencies on it, the first being Portage of course, but
eselect also qualifies. Of the two I’m actually more concerned about
eselect: I have been saying this from the start, but designing such a major piece of software – that does not change that often – in bash sounds like insanity. I still think that is the case.
I think this is the main problem: in Gentoo especially, bash has always been considered a programming language. That’s bad. Not only because it only has one reference implementation, but it also seem to convince other people, new to coding, that it’s a good engineering practice. It is not. If you need to build something like eselect, you do it in Python, or Perl, or C, but not bash!
Gentoo is currently stagnating, and that’s hard to deny. I’ve stopped being active since I finally accepted stable employment – I’m almost thirty, it was time to stop playing around, I needed to make a living, even if I don’t really make a life – and QA has obviously taken a step back (I still have a non-working
dev-python/imaging on my laptop). So trying to push for getting rid of bash in Gentoo altogether is not a good deal. On the other hand, even though it’s going to be probably too late to be relevant, I’ll push for having a Summer of Code next year to convert eselect to Python or something along those lines.
Myself, I decided that the current bashisms in the init scripts I rely upon on my servers are simple enough that dash will work, so I pushed that through puppet to all my servers. It should be enough, for the moment. I expect more scrutiny to be spent on dash, zsh, ksh and the other shells in the next few months as people migrate around, or decide that a 25 years old bug is enough to think twice about all of them, o I’ll keep my options open.
This is actually why I like software biodiversity: it allows to have options to select different options when one components fail, and that is what worries me the most with systemd right now. I also hope that showing how bad
bash has been all this time with its closed development will make it possible to have a better syntax-compatible shell with a proper parser, even better with a proper librarised implementation. But that’s probably hoping too much.
Just one though about the suggested Bash-Dash-switch:It seems reasonable to switch /bin/sh to something leaner and smaller than Bash, however this opens up an obvious question: How healthy is Dash and what’s it’s code quality? I don’t know that and don’t want to judge it.But my point is: I think when the dust has settlet we will almost certainly have a better Bash. Because right now a lot of the best IT security people on earth have their eyes on its code. That’s a good thing, because even if Bash will be used less, it will not disappear. If Dash instead of Bash is supposed to be part of the solution then we should try to redirect some of the attention there is right now to Dash. Because we don’t want to wake up in three years noticing that we switched our systems to Dash and this opens up a completely unexpected new issue.
I have not looked into Dash code in a while, but the last time I had to deal with it, it was much cleaner than bash. So for me it’s still going to be a positive change to move to Dash, even with the inquiry.In particular I’m pretty sure that the security conscious people will look into dash soon as the Bash dust settles, because Debian at least has been using it for the system shell for years, so there is enough attack surface. And I would not be surprised if something comes up with busybox too — and that worries me more than bash or dash, as that one is *really* used everywhere in embedded systems.But what both Dash and BusyBox have, to redeem themselves, is that they are smaller and limited. So I’d rather trust a not-yet-fully-audited Dash than a not-completely-rewritten-in-the-open Bash.
eselect-sh you’ve got to be kidding me….
@three sixesWhat’s wrong with eselect-sh? Is it because it mainly (only?) updates a symlink, which could be done in one line?
I tear my hair out over the state of scripting languages. Bash–I find it about as easy to program in it as it would be to tie my shoes with a knife and fork. It works, but it sure is contorted and it sure wasn’t meant for writing programs. Then, trying to drop down from that to using just a POSIX shell, which is even *less* expressive really makes me tear my hair out.Perl’s use of punctuation-character soup is even worse than Bash’s. I tried to get the hang of it but couldn’t get anywhere. Python’s semantically significant whitespace leave me cold. Ah, Awk. That’s a fine language–a pleasure to use. It was designed by giants in the field and is super-widely available. Too bad it’s got a straightjacket on it.Having scripting languages that are expressive and flexible and allow for the use of small scripts is a critical thing. The one good thing I can say about systemd is that it wants to avoid Shell scripts because they are clunky and difficult. That’s right: Shell scripts *are* clunky and difficult. But the way out is not to stop using scripts! There are lots of places where systemd has to scramble a lot with custom C code to handle cases it should have handled with some kind of script.One thing I loved about OS/2 was Rexx: a real programming language that also served as a shell. We need something like that.
Excellent article! I expect Dash to get a thorough going over soon. A python eselect would be better.
Well, you could just patch openrc to use bash and live with /bin/sh as non-bash. I do have /bin/sh busybox-ash (ash-bb@foo-overlay), was dash for some time, for over three years with pretty much no problem, with a one-line openrc patchhttps://github.com/slashbea…From time to time something may fails to build, but if I adjust ebuild to run eautoreconf to rebuild configure script that has bashism, it goes away (didn’t did it a single time in past year), also glibc and I think cups have some bashism, beside that, everything works fine.
I’m not sure which was worse to hear the issues with bash or that Gentoo is not stagnating.
Gentoo is stagnating. Damn my internal autocorrect.
Good point, because bash is quite full of “feature” (bloat). I use NetBSD, too, and I find their /bin/sh and /bin/ksh very nice and compact compared to bash. Bash is OK as far as interactive shells go, but I wouldn’t rely on it for Bourne-shell scripting. Even then, there are better choices, such as zsh, as Diego mentioned, and even tcsh. But then, I wouldn’t rely on tcsh for scripting, because, well, C-shell syntax is plain crazy. 🙂