How compatible is LibreSSL?
devsonacid.wordpress.com
devsonacid.wordpress.com
LibreSSL is an OpenSSL fork done by the OpenBSD team primarily because they don't think OpenSSL is the right software to include in their OS. That's their decision, if you don't use OpenBSD, you don't have to care. They have done an insane amout of work in pretty short time, and since that work might benefit the larger OS community, they kindly decided to start work on a portable version, which you don't have to use.
Even if you don't use LibreSSL, you might still benefit from their work as there is a healthy collaboration between OpenBSD/LibreSSL and Google/Adam Langley/BoringSSL.
Now, there's a first preview release of portable LibreSSL, and nitpicks are used to demonstrate how supposedly incapable the OpenBSD team must be. They hardcode -Werror, they obviously don't know how to write a configure script. They don't provide a PGP signature for the preview release, they obviously don't know how to distribute software securely. They use Comic Sans, they can't be taken seriously at all.
If you think LibreSSL will benefit you personally, you might consider showing a little gratitude. If you don't think LibreSSL is of any use to you, why do you even bother to write about it?
All the points in the blog posts are real problems. Pointing them out just means that fixes can be made and software can be improved.
No, sober problem reports (preferably sent to bugs@openbsd.org or openbsd-tech) are obviously exactly what the preview release is meant for.
As I wrote, I am surprised about the tone. Not of any particular comment or blogpost, but there's a tendency that I perceive lately.
You reap what you sow, as they say.
On the other hand, when using free software from other people, it does seem a little rude to demand anything from them. Kind of like "gee, thanks for the free cake, but I prefer my icing on the side, waahhhh sob sob sob [ throws toys from the pram ]"
I think they've earned that right, and this attitude may be necessary to scare away the kind of developers who might (with perfectly good intentions) end up making the job of the OpenBSD developers a lot harder.
OpenBSD is amazing software. By far the best OS I've ever used in my life. If the cost of that is a bad attitude, so be it. Whatever they're doing, it's working.
I like to judge a developer's attitude by reading the manpage that he or she kindly wrote for me. OpenBSD manpages are comprehensive and still concise. So the devs respect my time. I really appreciate that. (Actually, I want to throw money at them just for providing such excellent Unix documentation.)
Yes, they tend to be brusque when you mail them about some issue and obviously didn't RTFM before. They are right: You show them that you don't respect their time. Why should they be nice to you?
I think, in order to find hostility in that, you'd have to be looking for it.
I think that is exactly the point; if the thing does not build, people are going to complain loudly and things are going to get fixed. Warnings are usually just run-time problems waiting to happen, so they may as well be considered bugs.
As a trivial example, -Wunused will warn when a function has a parameter but doesn't use it. But you do this whenever you need to provide a callback that really doesn't care about one of the parameters. Still, -Wunused is helpful to find errors elsewhere in the code, so in these cases you might do something like
unused_param = unused_param;
just to make that one compiler warning go away. (That might work for one version of a compiler, but not another!) In other cases, the error the warning catches is so much more uncommon than the spurious warnings, you might disable that one warning type for your project. The linux kernel does this for a couple of them.
Anyway, the best way is to enable as many warnings as you can, and have the discipline to fix the ones you see, without forcing yourself or anyone with -Werror. In any non-trivial codebase, you guarantee that the next major release of gcc will not be able to build your code if you use -Werror, due to some truly spurious warnings. Again, this isn't because gcc sucks, just because the problem of guessing where what you wanted is different from what you did is extremely difficult in C.
The language often (always?) has facilities to remove those warnings on a case by case basis. For example when you don't want to use a parameter you can actively let the compiler know without assigning the variable to itself: you can only include the type and not the name:
int fn(int, void*);
int fn(int num, void* /*extra*/) {
// If the name extra is commented out the compiler will
// not warn that you are not using it. Now it is very
// clear that not using this variable was an active choice
// and not a mistake.
return num;
}
edit: as pbsd pointed out commenting out extra is not portable C code, though I believe the wider point still stands. These warnings can be very useful and should be be reviewed before ignoring them. (void)extra;
to shut the compiler up.Seeing as how easy it is to zap the -Werror from the configure script, I don't think that anyone is being forced to use it. However, making it the default helps avoid the opposite scenario where a growing amount of warnings (some potentially critical!) whizz past and nobody gives a shit.
So, the fact that warnings are enabled, they break built for some people, these people fix the issue and/or shout about it on the Internet (preferrably bugs@), it all is exactly what needs to happen. The problems get noticed and fixed this way. They don't just pile up. Yes it can be annoying, yes there are some stupid warnings -- ideally there'd be a flag -Wuseful-warnings. Yes people are free to zap the -Werror if they don't care about these warnings. Hopefully they know what they are doing because it really is possible that a bug in LibreSSL or in their system headers for example is calling for attention.
Consider how much discussion there was around goto fail and the like -- about the fact that static analysis (or smart compilers) would've caught these things. Why didn't they listen to the compiler?! So passing -Werror is one way towards making sure people look at the issues.
It is better to comment out the name of the argument in the function header:
void foo( int x, int /* unused */)
{
…
}
C compilers know not to complain about that second argument (http://stackoverflow.com/questions/1486904/how-do-i-best-sil...)/dev/urandom is the favored entropy gathering method. But if you can't open it (not there, rlimit restriction, etc.) it falls back to the bobo code. If the linux kernel provided a random number source that was reliable and could not fail, this wouldn't be an issue.
In the former case they are sacrificing portability for increased confidence of correctness, and in the latter they are sacrificing confidence or correctness for increased portability.
0. sshd will fork() and chroot() into /var/empty. After the fork(), you can't use the entropy you have because it's shared with the parent (i.e., it's not "entropic").
1. Where should it get entropy from?
2. Where does OpenSSL get entropy from in this case?
Anyway, I don't even work on portable libressl because I don't want to deal with shit like this, but I think the quoted text erroneously gives the impression that /dev/urandom isn't used. I wanted to correct that impression.
I really think that LibreSSL's RAND_poll() should have similar behavior to ensure maximum compatibility with OpenSSL and to provide a means to use chroot() safely without the risk of falling back to the "bobo" code. (Also, a means of safely reseeding after a fork on systems without minherit(MAP_INHERIT_ZERO)).
(Incidentally, libsodium has a similar API: you can explicitly call randombytes_stir() to cause the library to open (and keep open) a file descriptor to /dev/urandom, so subsequent calls to the PRNG work in a chroot.)
The presence or need for a stir() function should be considered a serious design flaw.
(forks are detected by calling getpid() if you don't have inheritzero.)
Also, getpid() isn't airtight - if you fork and fork again there's a risk of PID wraparound.
What's wrong with generating some random numbers using the parent's entropy pool before fork and using that as the child's entropy pool?
> An error occurs if the PRNG has not been seeded with enough randomness to ensure an unpredictable byte sequence.
https://www.openssl.org/docs/crypto/RAND_bytes.html
But there is also this:
> Pseudo-random byte sequences generated by RAND_pseudo_bytes() will be unique if they are of sufficient length, but are not necessarily unpredictable.
ie falling back on braindead methods when sane ones failed.
You can disable the fallback code with a define, so if your distributors are sure your system should always be able to provide a good entropy source in normal use, they'll flip that switch.
Most of these could be easily worked around with a few #ifdefs but they've also managed to make that a bit problematic by reusing the OPENSSL_VERSION_NUMBER macro without providing some sort of complementary IS_LIBRESSL flag. Fortunately OpenSSL hasn't hit version 2 yet so the version numbers don't overlap at all.
This is surprising for me. Can you provide an example?
Seems like this is already fixed: http://marc.info/?l=openbsd-tech&m=140511451408331&w=2
Yes, -Werror is normally going to break things badly and cause far too much unnecessary work... for most projects. There are a handful of projects, on the other hand, that I would argue -Werror is absolutely necessary. Crypto libraries such as openssl/libressl/gnutls and tools like gnupg are at the top of that list. This list might also include key-handling utils such as {gpg,ssh}-agent and maybe pinentry.
Breaking on new GCC features is a good thing, because for these important packages you shouldn't ever be guessing about the programmer intention or assuming that some new warning is safe.
Several people brought up -Wunused. We already know about that warning, and so libressl should expect it and compile cleanly. Yes, this might be annoying at times, but cleaning up the code was the goal anyway. What about future versions of GCC? There are only a few possibilities:
0) The warning actually is about an important bug.
Obviously you don't want the build in this case. 1) Some new -W flag was added.
Broken build are important here. The GCC authors probably added that flag for a reason, and you can't guarantee[1] the warning is a false-positive. 2) No flags have changed, but some other component has caused
a warning where there wasn't one previously.
This means something else changed: 2a) A function prototype changed. (does it even compile properly?)
2b) Some defined type or macro changed. (could easily be a new bug)
Yes, in many cases, these are probably trivial. The point is that for some software, forcing someone to actually check is the goal. The problems with openssl that were recently exposed by heartbleed was that nobody was actually checking security-critical components, and simply assuming those checks were being done by somebody else.With -Werror, the fact that it doesn't compile will force someone to either fix some bug or silence the warning by adding the necessary cast or #ifdef or whatever. Really, I have to wonder about anybody who advocates for allowing unchecked builds: why are you ok with the kind of unchecked code that lead to heartbleed and many other security problems? As DJB[2] and PHK[3] both warned: are you trying to prevent a high-security environment?
[1] Why can't we guarantee such things? Because answering that would req1uire solving the Halting Problem.
[2] https://news.ycombinator.com/item?id=8023812
[3] http://ftp.belnet.be/FOSDEM/2014/Janson/Sunday/NSA_operation...
Yeah, if your program uses undefined behaviour or your cc is crazy. I think the point is to catch undefined behaviour and make sure it isn't ignored.
In the case of Gentoo, this would manifest itself as packages compiling cleanly with one compiler version, then suddenly lots of packages failing to compile because the build processes were stopped due to the, now reported, unused variable. If these were just warnings, then the packages would still compile, someone would notice (or even the original dev), and the problem can be fixed. Note that before the compiler upgrade, there was no bug - the program worked fine.
Except for a case such as libressl (preview release so they can get comments), having -Werror hardcoded in the build process clearly makes no sense.