12 ms·
LibreSSL's PRNG is Unsafe on Linux
- dobbsbob 12y ago>First, LibreSSL should raise an error if it can't get a good source of entropy. Comments for getentropy_linux.c explain this http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libcrypto/crypto/getentropy_linux.c?rev=1.2;content-type=text%2Fplain http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libcrypto/cryp... We have very few options: - Even syslog_r is unsafe to call at this low level, so there is no way to alert the user or program. - Cannot call abort() because some systems have unsafe corefiles.
- agwa 12y agoThe comments don't justify why going to the sketchy entropy is better than SIGKILLing the process, except with: > This code path exists to bring light to the issue that Linux does not provide a failsafe API for entropy collection. Trying to make a point about Linux doesn't seem like a very good reason to me.
- dobbsbob 12y agoThe sketchy entropy is only an example, and is a work in progress. Comments read "XXX Should be replaced with a proper entropy measure." and is only called if entropy collection via /dev/urandom and sysctl have failed. If the sysctl method is depreciated it does raise(SIGKILL). They also rearranged getentroy_linux.c so that the main function with the important comments is at the top in hopes whoever is porting reads it. If you were porting this to a GNU/Linux distro, you can read their list of options and raise (SIGKILL) resulting in silent termination if that's what your platform decided to do if both entropy methods fail, or test for it earlier and fail. Since they are BSD developers they leave it up to whoever is porting to decide.
- vidarh 12y agoIt seems to be working, given the number of articles I've seen about this issue so far.
- quotemstr 12y ago> cannot call abort() because some systems have unsafe corefiles. This logic seems specious. It's not the job of a library to solve that problem. If a system has crash dump collection configured insecurely, the problem is going to extend well past the SSL library. > * This can fail if the process is inside a chroot or if file * descriptors are exhausted. The right solution is to pre-open the file descriptor. SSL_library_init can fail. Do it there.
- dobbsbob 12y agoNSS does something similar since NSS will not be able to access /dev/urandom via file system after the sandbox activates the chroot so they reserve it first and fails with a log warning if no descriptors are available.
- quotemstr 12y agoWarn? Hell, I'd hard-fail. Libraries need resources to do their jobs. The key is to acquire resources in places that can fail and use them in places that can't. I'm amazed and disappointed that the LibreSSL people aren't following this basic principle.
- agwa 12y ago> The key is to acquire resources in places that can fail and use them in places that can't. I'm amazed and disappointed that the LibreSSL people aren't following this basic principle. To be fair to the LIbreSSL devs, the Linux-specific /dev/urandom code is currently encapsulated rather nicely behind an interface that's compatible with the OpenBSD getentropy() syscall. Following your suggestion would create a layer violation and move LibreSSL closer toward the (much maligned) OpenSSL approach to cross platform compatibility. I don't think this is a great excuse for the current design, but it's an explanation.
- quotemstr 12y ago> Following your suggestion would create a layer violation and move LibreSSL closer toward the (much maligned) OpenSSL approach to cross platform compatibility. The OpenSSL approach to portability is doomed: it can only deal with cosmetic differences between platforms. I appreciate the principle of using compatibility functions instead of #ifdef, but at some point, you need to incorporate the panoply of architectures into your design. It galls me to see the OpenBSD people claim that Linux is broken merely because it is different. That's incredibly arrogance.
- lcampbell 12y ago> Cannot call abort() because some systems have unsafe corefiles. Huh, FreeBSD has MAP_NOCORE which allows the program to map pages that will explicitly not be included in the core file. I never realized that this was FreeBSD-specific extension (added in 2007?). I'm really surprised other platforms haven't adopted it, though I surmise there's a good technical reason or two. (EDIT: or maybe there's similar functionality via another API? I haven't been able to turn up anything).
- tcoppi 12y agoLinux since 3.4 has MADV_DONTDUMP [1], and there also appears to be a /proc filter file you can use to exclude general segments of memory from being dumped [2]. 1. http://man7.org/linux/man-pages/man2/madvise.2.html http://man7.org/linux/man-pages/man2/madvise.2.html 2. http://man7.org/linux/man-pages/man5/core.5.html http://man7.org/linux/man-pages/man5/core.5.html
- quotemstr 12y agoIt's hard to blacklist every piece of memory that might be sensitive. It's a much better idea, IMHO, to just put corefiles in a location accessible only to root. That's how Windows, OS X, Ubuntu, Android, and lots of other commercial systems work.
- xorcist 12y ago.. which you need to do anyway. The SSL library, and the program linked against it, can fail in a thousand more ways that generate them.
- floatboth 12y agoWell, there is a way to disable core dumps entirely: setrlimit RLIMIT_CORE to 0
- tormeh 12y agoCan't the LibreSSL process just reseed whenever it is started? I guess forks don't actually copy the program counter so they'll have to go through main, right?
- agwa 12y agoNope, forks actually do copy the program counter.
- cjg_ 12y agoIt does copy the PC. Actually it just return from the fork call twice, one in the parent and one in the child, with different return values, the pid of the child to the parent and zero to the child. See http://linux.die.net/man/2/fork http://linux.die.net/man/2/fork for more details
- Raphael_Amiard 12y ago> I guess forks don't actually copy the program counter so they'll have to go through main, right? This is the way the fork syscall works on all Unices, the fork will start execution right after the fork system call.
- syncsynchalt 12y agoAs a developer who's integrated with openssl several times (generally on Linux), I couldn't be more pleased with the results coming out of the libreSSL effort. Even if we end up with a list of linux-specific gotchas (and I don't think we will), it is more a case of ten steps forward, one step back.
- quotemstr 12y agoThere's also pthread_atfork. Use that to reset the PRNG. It's a bad interface, but it'll work for this purpose. It bothers me when people very solemnly and seriously condemn systems for problems that are, in fact, amenable to reasonable solutions.
- agwa 12y ago> There's also pthread_atfork. That requires linking with libpthread, which a single-threaded program would not normally do. Otherwise, it's not a bad suggestion. Still, on top of everything LibreSSL does to automatically detect forks, it should still expose a way to explicitly reseed the PRNG in an OpenSSL-compatible way, since OpenSSL has made guarantees that certain functions will re-seed the PRNG, and there may be some scenarios where even the best automatic fork detection fails (imagine a program calling the clone syscall directly for whatever reason, in which case pthread_atfork handlers won't be called). Since LibreSSL is billed as a drop-in replacement for OpenSSL, you should not be able to write a valid program that's safe under OpenSSL's guarantees but not when linked with LibreSSL.
- quotemstr 12y agoThe libc on my system, Ubuntu 14.04, exports __register_atfork, which is documented here: > http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/baselib--register-atfork.html http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB... pthread_atfork itself really should be moved into libc, however. (And POSIX should stop treating it as a redheaded stepchild: it's useful!)
- pavpanchekha 12y agoA threading interface was standardized into C 2011, so pthreads should eventually stop being necessary. In a sense, not just POSIX, but C proper has adopted a threading interface.
- quotemstr 12y ago
- darthsitius 12y agoHow can 2 processes have the same PID, even if it is grandparent and grandchild? When I try killing a process using the PID, how the kernel know which to kill?
- quotemstr 12y ago> How can 2 processes have the same PID, PID namespaces?
- agwa 12y agoThat's not what I was thinking but it sounds like yet another case where you could fool LibreSSL's fork detection.
- _kst_ 12y agoThey can't have the same PID at the same time. I think the scenario here is that process X forks, creating process Y, then process X terminates, then process Y repeatedly forks until it creates a process Z with the same PID as X.
- agwa 12y agoPrecisely.
- ryan-c 12y agoAssume a fairly busy system * Original process with PID 17519 * PID 17519 forks producing a new process with PID 26606 * PID 17519 produces some "random" bytes then exits * PID 26606 forks producing a new process with the now unused PID 17519 * New PID 17519 produces some "random" bytes, which will be the same as the "random" bytes produced by original PID 17519, causing a raptor to attack the user.
- pbhjpbhj 12y agoSo, PID is used as part of the CSPRNG? If I get a block from /dev/urandom, then another one at some later time, what are the chances it's identical? Isn't that what you're saying here (or was the whole post intended to be comical and not just the last line). [If only it had been raining it would have taken days longer for the raptor to attack, or something /random]
- amalcon 12y agoNote that the usual post-fork catch-all security advice (having the child process exec() to wipe process state, thereby making a state leak really hard) solves the fork safety problem by giving the child a whole new PRNG instance, but actually makes it harder to solve the chroot safety problem. There are various tricks to get a limited number of bytes from /dev/urandom into the chroot jail (such as by writing them to a regular file and secure-erasing that file when finished) to get around that.
- agwa 12y agoHow about passing the /dev/urandom file descriptor to the new process? That seems like the most robust solution to me.
- deleted 12y ago[deleted]
- rlpb 12y agoWhy must it have its own PRNG? Is there a problem asking the kernel (via /dev/urandom) for all required entropy, at the time it is needed? Or would this cause a real-world performance problem? Surely this is an obvious first question that all commentators are stepping over?
- orik 12y agoIt isn't about performance, but instead /dev/urandom is believed to be a poor source of entropy by the OpenBSD developers. I believe the heart of the issue it that /dev/urandom will give you a string even if it has very low entropy at the time. You can find all sorts of articles for and against /dev/urandom and I don't really know enough to comment on it's security, but I trust the that the team working on this fork more than I trust the OpenSSL foundation.
- elithrar 12y ago> I believe the heart of the issue it that /dev/urandom will give you a string even if it has very low entropy at the time. On OpenBSD, /dev/urandom does the right thing, unlike Linux. As per http://www.2uo.de/myths-about-urandom/ http://www.2uo.de/myths-about-urandom/ - > FreeBSD does the right thing: they don't have the distinction between /dev/random and /dev/urandom, both are the same device. At startup /dev/random blocks once until enough starting entropy has been gathered. Then it won't block ever again.
- vidarh 12y agoThe issue is not that they believe /dev/urandom to be bad, but that it flat out isn't guaranteed to be available: If you're chroot'ed, chances are you won't have read access (or see) /dev/urandom. Furthermore, if you've run out of file handles (maybe intentionally - because someone figures they can try to DOS you to attack the PRNG), it is not a given you'll be able to open it even if it's visible. LibreSSL tries /dev/urandom first, then falls back on a deprecated sysctl() interface, then tries it's own "last resort fallback".
- xorcist 12y ago
- hsivonen 12y agoCan we, please, have a syscall in Linux that returns random bytes from the system CSPRNG or blocks if not seeded yet and doesn't involve dealing with file descriptors? But even while one isn't available, why is LibreSSL trying to use a userland CSPRNG instead of always reading from /dev/urandom and aborting when that fails?
- AlyssaRowan 12y agoYes. Actually, the relevant IETF list is now calling for that: Linux needs getentropy(2). I may cook up my own and submit it to LKML, or perhaps someone else can, but there's no way out of this one without kernel support. I don't know why the rest of the function even exists. It's the kind of cruft libReSSL is trying to get rid of. I am not entirely sure a PRNG should even exist in the library, and personally, I'd pass it onto /dev/urandom or /dev/random or the relevant syscall. I agree with making it (154-156) a hard kill for a TLS library not to be able to get entropy. And, this is great! This is exactly the kind of thing we're able to find now that some of the code isn't a hedge-maze.
- agwa 12y agoYeah, if LibreSSL continues to implement its own PRNG in userspace, a getentropy syscall only solves the chroot issue, not the fork issue. You're probably right that a PRNG should not exist in the library.
- quotemstr 12y ago> there's no way out of this one without kernel support This problem is due to LibreSSL's internal architecture being too closely matched to OpenBSD, not a fundamental problem with Linux.
- vidarh 12y agoThe comments in the code makes it exceedingly clear that a part of the reason for this code to exist is to make a point, and it seems they've succeeded very well at that.
- lomnakkus 12y ago
- bydo 12y agoSchadenfreude?
- talideon 12y agoHardly. LibreSSL works just fine on OpenBSD and doesn't have this issue. Portability to Linux is a secondary concern, and this is only an initial stab at the portability layer for Linux.
- ars 12y agoIs LibreSSL written by the same team that wrote this incorrect article? https://news.ycombinator.com/item?id=7700312 https://news.ycombinator.com/item?id=7700312
- blahrf 12y agoYou can't simply seed it before a chroot. Look at the code. chacha adds entropy periodically and folds it in. You need entropy in the chroot. The author should probably read 10 lines below the same code he posted in the article. While I'd love to see a solution for this particular contrived example, considering in the much more common use cases it actually is more secure than OpenSSL's. Especially so if your kernel has sysctl in it.
- agwa 12y ago> chacha adds entropy periodically and folds it in. You need entropy in the chroot. If that's the case then the fix will not be as simple as I envisioned it. Still, the point stands that LibreSSL should allow you to initialize the PRNG once, before you chroot, so that you can use the PRNG safely once inside the chroot. This could be accomplished by keeping a file descriptor to /dev/urandom open.
- blahrf 12y ago"If that's the case?" - Didn't you read the code? :) Sounds like you would prefer no stirring of any new entropy after you chroot... Looks to me like they're trying to require that additional entropy be available, always. (and if you don't have a completely hacked up kernel sysctl is still there..) - maybe we might get something better before it (sysctl) goes away for real instead of just in c-library-du-jour.
- agwa 12y agoYou're correct :-) - it does periodically stir in new entropy. I'm fine with stirring in new entropy after chrooting - I just don't want to see sketchy entropy being used, especially for the initial entropy source. If you could make LibreSSL open (and keep open) /dev/urandom before you chroot, LibreSSL could read additional entropy from the already open file descriptor, even after chrooting. In any case, note that the chroot issue is a bit of a sideshow compared to the much more serious fork issue.
- 12y ago
- meshko 12y agoIt is not entirely clear what is the risk of this strange scenario involving a grandchild process and pids wrapping around in an alarmingly quick way.
- pavpanchekha 12y agoThe risk is that in some situations (it should not matter how often; the environment might be somewhat attacker-controlled) two processes produce identical random numbers. This is bad, because this breaks the assumption that random numbers are independent. A program may reasonably fork into two processes, one which uses random numbers to generate RSA keys and one which outputs random numbers to anyone who wants them. LibreSSL's flaw may allow these two processes to destroy each other's security guarantee.
- blahrf 12y agoAhh, not really - while the process thing the author describes is real - what you're saying is that any two processes show the same values, and that isn't the case. the bad guy needs to control one process to read the values in a useful way, have it exit, and be able to maniuplate the system by killing or creating processes until his intended victim comes up on his selected PID. While that's far from impossible to do (just as the author's program does it) It is likely going to imply enough access to your system by the attacker that you're already pretty much p0wned.
- agwa 12y agoAn attacker doesn't necessarily need to know the random values themselves to pull off an attack. For example, if a nonce is re-used, an attacker might be able to decrypt data sniffed from the network. Also, creating processes to force a PID wraparound might be as simple as making repeated requests to a server.
- jodiscr 12y agoGiven things like the Debian OpenSSL fiasco and Heartbleed, can we honestly put as much faith into open source crypto as it's well-funded proprietary counterparts? I honestly prefer open source and recognize the problem the author points out as clearly significant problem - as well as the benefits of LibreSSL, but I'm just not convinced there are enough eyeballs looking at open source crypto.
- wbl 12y agoEver hear of BSAFE? They took a million dollars from the NSA to implant a backdoor. How do you evaluate code you cannot see?
- jodiscr 12y agoyes, but I'm talking about RNG from likes of Microsoft or Apple...
- nitrogen 12y agoIf you can't evaluate it, you can't trust it. Plus, Apple had gotofail, and MS has had its share of issues as well.
- jodiscr 12y agocan't evaluate > not enough funds to evaluate In other words, with proprietary sw, at least SOMEBODY evaluated it and placed their seal/name on it. With open source, you are relying on a hope that somebody out there somewhere does it. And in various cases, we've seen how that turned out.
- boomlinde 12y ago... and in some cases, we've seen how using proprietary software turned out. You're not making a substantial argument, but if someone has a track record of writing completely safe software that doesn't have to be secured through third party products, like Microsoft, I will be willing to listen.
- _pmf_ 12y agoDon't rain on their parade. OpenSSL has been determined to be a laughing stock by super-informed internet forum people, and we need to keep up pretending that a rewrite of a major piece of internet infrastructure is feasible and makes sense.
- blahrf 12y agoEven though it looks like it won't get called, I'm wondering how bad the voodoo is? Anyone looked at what it is spitting into that hash function? How predictable are those clocks as they change between the memory fetches. Will Linux have predictable memory access times where those pages land?
- algorithm_dk 12y agoWe need to stop useless forks.
- nwmcsween 12y agoThis is just due to ignorance, Linux provides a AT_RANDOM auxv on process creation that could be used to seed the prng.
- enjolras 12y agolook at the code. AT_RANDOM is. used when it's avaible in the fallback function. For some reason, the devs don't seem to trust it much, according to the comment.
- edwintorok 12y agoIs it guaranteed to at least be different for different processes? They could use that in addition to the PID test to know when to reseed.
- wahern 12y agoNo. It's only filled on execve, not fork.
- waterhouse 12y agoLooks like this issue has been addressed and fixes have been pushed. The fix involves something similar to the pthread_atfork solution a couple of people have suggested. http://opensslrampage.org/post/91910269738/fix-for-the-libressl-prng-issue-under-linux http://opensslrampage.org/post/91910269738/fix-for-the-libre...
- cnst 12y agoWhat agwa wants from LibreSSL is to behave in every little bit exactly as OpenSSL does, even though OpenSSL itself is a complete and utter mess. OpenSSL allowed developers to interfere with RNG freely, so LibreSSL must do that, too? [Even if times have changed?](http://permalink.gmane.org/gmane.os.openbsd.cvs/129485 http://permalink.gmane.org/gmane.os.openbsd.cvs/129485) Well, you can't really go at improving and cleaning up the library if you have to keep up all the old bugs and the whole crusty API around. It's inconceivable to expect LibreSSL to be both better than OpenSSL, yet to have the exact same API and the exact same set of bugs and nuances as the original OpenSSL. LibreSSL is meant to be a simple-enough replacement of OpenSSL for most modern software out there (http://ports.su/ http://ports.su/) — possibly with some minimal patching (http://permalink.gmane.org/gmane.os.openbsd.tech/37599 http://permalink.gmane.org/gmane.os.openbsd.tech/37599) of some of the outside software — and not a one-to-one drop-in-replacement for random edge cases that depend on random and deprecated OpenSSL craft.