Skip to content
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

Closed
ericlagergren opened this issue May 26, 2016 · 16 comments
Closed

crypto/rand: does not verify /dev/urandom is a character device #15850

ericlagergren opened this issue May 26, 2016 · 16 comments
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Milestone

Comments

@ericlagergren
Copy link
Contributor

Posting here per my e-mail conversation with rsc@

  1. What version of Go are you using (go version)?

1.6.2

  1. What operating system and processor architecture are you using (go env)?

GOOS=linux
GOARCH=amd64

  1. What did you do?
    If possible, provide a recipe for reproducing the error.
    A complete runnable program is good.
    A link on play.golang.org is best.

glissue

  1. What did you expect to see?

An error because /dev/urandom isn't a character device.

  1. What did you see instead?

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)

@ianlancetaylor ianlancetaylor added this to the Go1.7Maybe milestone May 26, 2016
@ianlancetaylor
Copy link
Contributor

CC @agl

@randall77
Copy link
Contributor

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?

@ericlagergren
Copy link
Contributor Author

ericlagergren commented May 26, 2016

@randall77 it would be.

However, I'm under the impression it's common practice. Or, at least good practice.

See: https://github.com/jedisct1/libsodium/blob/c752eb55d9e9992bc38e7790128953427aa0a89f/src/libsodium/randombytes/sysrandom/randombytes_sysrandom.c#L164

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.

@rsc rsc modified the milestones: Go1.8, Go1.7Maybe May 27, 2016
@rsc
Copy link
Contributor

rsc commented May 27, 2016

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.

@ericlagergren
Copy link
Contributor Author

@rsc, what's your opinion on checking for char device (the crux of this
issue)?
On Thu, May 26, 2016 at 7:18 PM Russ Cox notifications@github.com wrote:

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.


You are receiving this because you authored the thread.

Reply to this email directly, view it on GitHub
#15850 (comment), or mute
the thread
https://github.com/notifications/unsubscribe/AFnwZ4FLU06HoRo5xkoHmWuyh5f7a4J1ks5qFlRtgaJpZM4Inxf2
.

@minux
Copy link
Member

minux commented May 28, 2016 via email

@ericlagergren
Copy link
Contributor Author

@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.

@bradfitz bradfitz modified the milestones: Go1.8Maybe, Go1.8 Sep 25, 2016
@bradfitz
Copy link
Contributor

Demoting to Go1.8Maybe.

I'm not very convinced by this either.

Does OpenSSL or anybody else do this?

@ericlagergren
Copy link
Contributor Author

Apparently libsodium and random_compat:
https://mobile.twitter.com/ELagergren/status/733904157514424321

On Sun, Sep 25, 2016 at 4:19 PM Brad Fitzpatrick notifications@github.com
wrote:

Demoting to Go1.8Maybe.

I'm not very convinced by this either.

Does OpenSSL or anybody else do this?


You are receiving this because you commented.

Reply to this email directly, view it on GitHub
#15850 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AFnwZ17AMEq1fYL6pJE8TvJVcJWN25Y7ks5qtwGLgaJpZM4Inxf2
.

@minux
Copy link
Member

minux commented Sep 26, 2016 via email

@ericlagergren
Copy link
Contributor Author

I agree with Minux that the scenarios seem contrived. However, it does seem
like common courtesy to say, "hey, your system is obviously borked"

Also: I think dropping the dev numbers part of this issue is a good idea.
But still maintain checking to see if it's a char device is a good idea.
On Sun, Sep 25, 2016 at 5:08 PM Minux Ma notifications@github.com wrote:

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.)


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#15850 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AFnwZ2m0oLEgieDnDw5xPDamJUoFI326ks5qtw0WgaJpZM4Inxf2
.

@minux
Copy link
Member

minux commented Sep 26, 2016 via email

@ericlagergren
Copy link
Contributor Author

That is true. But it seemed the consensus was checking dev nos was too
risky because a specific distribution might change it, so the choices are
either check and either bend over backwards to ensure compat or ignore it
and risk the situation you described.

The nice thing about checking char device is it's at most a handful of
instructions which doesn't have much startup overhead which I heard you
guys were trying to avoid.
On Sun, Sep 25, 2016 at 5:36 PM Minux Ma notifications@github.com wrote:

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.


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
#15850 (comment), or mute
the thread
https://github.com/notifications/unsubscribe-auth/AFnwZ5-2APOxNXHwd146aLJ5d-Z_lz6iks5qtxOWgaJpZM4Inxf2
.

@gopherbot
Copy link

CL https://golang.org/cl/23448 mentions this issue.

@quentinmit quentinmit added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label Oct 10, 2016
@rsc
Copy link
Contributor

rsc commented Oct 10, 2016

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.

@ericlagergren
Copy link
Contributor Author

I don't have anything else to add. I'll abandon the CL.

@golang golang locked and limited conversation to collaborators Oct 10, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Projects
None yet
Development

No branches or pull requests

8 participants