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
crypto/rand: does not verify /dev/urandom is a character device #15850
Comments
CC @agl |
Sure, but if the attacker can substitute a file for /dev/urandom he/she could also substitute a character device. /dev/zero would be just as bad as hello world, right? |
@randall77 it would be. However, I'm under the impression it's common practice. Or, at least good practice. And https://twitter.com/CiPHPerCoder/status/733904477196029954 edit: You can also check the maj/min numbers, but IMO that seems a bit more brittle or prone to weird errors. |
This is too risky for Go 1.7. I'm not convinced we should do this at all. Certainly not for Go 1.7. At the least I would want to see serious evidence that no Linux distribution anywhere has ever or will ever ship different device numbers. |
@rsc, what's your opinion on checking for char device (the crux of this
|
I also think that if the attacker is able to replace /dev/urandom,
then nothing prevents him from loading a kernel module to
defeat this kind of checks. It's basically protecting the wrong
thing.
|
@minux I agree that if an attacker has has enough access to swap out /dev/urandom then you're hosed anyway. But messing up /dev/urandom isn't just limited to attackers (esp. attackers with a root shell). IMO it's good security etiquette to inform the user that what should be a CSPRNG isn't. |
Demoting to Go1.8Maybe. I'm not very convinced by this either. Does OpenSSL or anybody else do this? |
Apparently libsodium and random_compat: On Sun, Sep 25, 2016 at 4:19 PM Brad Fitzpatrick notifications@github.com
|
The world is migrating to syscall based entropy gathering, and I think
this issue is much less important now. And I still don't think the check
is useful. If the attack has gained enough access to tamper /dev/urandom,
I imagine he would rather do others much more useful tricks than to
tamper with /dev/urandom.
Is there any realistic attack scenarios that the attacker would just
swap /dev/urandom? The only benefit of switching /dev/urandom is
perhaps generating deterministic random numbers, but if the attacker
has root, then it's easier to just steal the private key, which leaves
no trace and enables the attackers to do basically the same with
making CSPRNG deterministic.
If it's the user that replaces /dev/urandom, then we shouldn't bother
either because this is Unix, and the user with root is supposed to
know what they are doing.
I don't think OpenSSL does this check (it did do fstat on the fd, but
it's to avoid reading entropy multiple times from the same device.)
|
I agree with Minux that the scenarios seem contrived. However, it does seem Also: I think dropping the dev numbers part of this issue is a good idea.
|
But dropping the device number requirement means replacing
/dev/unrandom with /dev/zero goes undetected.
If we must do anything, I'd rather do some basic statistical tests
on the RNG output. But even that has debatable benefit.
|
That is true. But it seemed the consensus was checking dev nos was too The nice thing about checking char device is it's at most a handful of
|
CL https://golang.org/cl/23448 mentions this issue. |
I remain unconvinced that we should do this. I would like to see evidence that either (1) there exists a plausible attack this defends against, or (2) this is a widespread, standard best-practices check. I haven't seen evidence of either. And as I mentioned above, it seems more likely this will break incorrectly than it will defend against an actual attack. Can someone make the case for doing this? If not, let's close this. Thanks. |
I don't have anything else to add. I'll abandon the CL. |
Posting here per my e-mail conversation with rsc@
go version
)?1.6.2
go env
)?GOOS=linux
GOARCH=amd64
If possible, provide a recipe for reproducing the error.
A complete runnable program is good.
A link on play.golang.org is best.
An error because
/dev/urandom
isn't a character device.A normal read of the bad file.
Kernel versions < 3.17 read /dev/urandom instead of calling
getrandom(2). This allows an attacker to redirect modify /dev/urandom so
to a block device instead of a character device. A simple check (e.g.,
f.Mode()&ModeCharDevice == 0
) would mostly mitigate this.Additionally, the min:maj could be checked to see if it matches what
Linux says it's supposed to be (
man 4 random
says 1:9 for /dev/urandom)The text was updated successfully, but these errors were encountered: