-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Add support for getrandom(2), add type check on file descriptor #1513
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
You mean the |
@@ -85,8 +89,29 @@ static int php_random_bytes(void *bytes, size_t size) | |||
} | |||
#elif HAVE_DECL_ARC4RANDOM_BUF | |||
arc4random_buf(bytes, size); | |||
#elif defined SYS_getrandom | |||
/* Linux getrandom(2) syscall */ | |||
size_t read_bytes = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although we mainly do this on Windows, but declarations at first but I'm not sure there is any recent (and sane) compiler that will complain here, but not a biggie.
Yeha I mean the double slash, but else its fine. I added an inline comment note as well |
Okay, discussing this in room 11 and making a few tweaks. Will send a squashed commit as soon as the test pass locally. |
(Closed & reopened because Travis appeared to be sticking.) |
Oh hey, the tests passed. Neat. :) |
Had getrandom(2) in originally and removed it for unremembered reasons. Probably due to lack of kernel support back then, but here we are in the future. |
The future is a wonderful place, indeed. :) The original patch was just going to be checking the |
All: The latest commit also removes |
Found the quote from @ircmaxell while discussing original RFC:
|
| | | | ||
[#######=============] (we're going to write over the = region) | ||
\\\\\\\\\\\\\ | ||
amount_to_read |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm digging the ascii art comments!
So apparently the 256 byte limit is about checking return results, and not a fundamental design limit. So +1 from me. |
(Travis was stuck.) |
I've recently become aware of the fact that arc4random_buf on many operating systems (including current OSX) is still an actual RC4 generator (skipping some initial values), with potentially bad seeding at that. I'd suggest we drop this as well and only use getrandom or /dev/urandom. |
@@ -30,6 +30,10 @@ | |||
#if PHP_WIN32 | |||
# include "win32/winutil.h" | |||
#endif | |||
#ifdef __linux__ | |||
# include <sys/syscall.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This header shouldn't be necessary anymore, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I forgot to remove that.
I'm sure I read somewhere that OSX actually uses arc4random for urandom. Will have a quick look around to see if I can find evidence of that. Aside from older BSDs which other OS are you aware of? (so we can research the truth there too) |
@lt Wikipedia says:
And the OSX implementation was just turned up in my Twitter feed: https://opensource.apple.com/source/Libc/Libc-1044.10.1/gen/FreeBSD/arc4random.c |
Discarding (at least) the initial 256 bytes mitigates the known biasing weaknesses in RC4 as far as I am aware. So is the only issue here the dodgy seeding? |
@lt I'm not up to date on RC4 research, but as far as I remember multi-byte biases (unlike the single-byte ones) recur periodically and affect more than the first few bytes. |
The 256-byte issue with RC4 is for encrypting information as a stream cipher. It probably doesn't degrade the security of Fortuna implementations, especially since the kernel will reseed it frequently. That said, there are still exploitable RC4 biases even after discarding the first N bytes of output. ChaCha20 should be the standard these days. |
The |
Fix to_read, throw exception if syscall fails Fixes thanks to feedback from sarnold at ##crypto on freenode Correction on error conditions Remove dead code (thanks @defuse) It turns out getrandom can take >256, getentropy refuses. Better semantics Thanks @defuse for catching my silly mistake here Cast to size_t to be explicit Let's simplify the logic a bit Let's be consistent; define everything before we do any logic Continuously check that the file descriptor is still a valid one Add device type check on fd initialization
} | ||
#ifdef __linux__ | ||
// Make sure that /dev/urandom is the proper urandom device on Linux | ||
if (st.st_rdev != makedev(1, 9)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like hardcoding this. Does it come from some standard that /dev/urandom on Linux always must be the same? Why we need to check this anyway? If someone has permissions to mess with /dev to fool us, the system has way more problems than PHP could fix. Checking if the file has been opened successfully, e.g. to see if we aren't in broken chroot() env or broken permissions - that's fine, but beyond that I don't think we should bother, and especially hardcode device numbers inside the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it come from some standard that /dev/urandom on Linux always must be the same?
http://insanecoding.blogspot.co.uk/2014/05/a-good-idea-with-bad-usage-devurandom.html
The Linux user manual page for the random devices explicitly informs the reader of these magic numbers, so hopefully they won't change. I have no official sources for the magic numbers on the other OSs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm removing it for now. If this turns out to be a source for security issues down the line, I'd be surprised. But if it does, we can always look back and have a reference point for how to re-implement it.
@jedisct1 made a similar argument against |
Comment on behalf of ab at php.net: Merged into 7.0. Thanks. |
Comment on behalf of ab at php.net: and closed :) |
🎉 |
👍 |
Could you please take a look at https://bugs.php.net/bug.php?id=70641? |
Including Also, regarding the file type check: jedisct1/libsodium#302 :( |
Enhancements for
random_bytes()
. cc @SammyK @ircmaxell @lt