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

Use getrandom syscall for all Linux and Android targets. #45896

Merged
merged 2 commits into from
Nov 14, 2017

Conversation

malbarbo
Copy link
Contributor

@malbarbo malbarbo commented Nov 9, 2017

I suppose we can use it in all Linux and Android targets. In function is_getrandom_available is checked if the syscall is available (getrandom syscall was add in version 3.17 of Linux kernel), if the syscall is not available fill_bytes fallback to reading from /dev/urandom.

Update libc to include getrandom related constants.

unsafe {
libc::syscall(NR_GETRANDOM, buf.as_mut_ptr(), buf.len(), GRND_NONBLOCK)
libc::syscall(libc::SYS_getrandom, buf.as_mut_ptr(), buf.len(), libc::GRND_NONBLOCK)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why libc::GRND_NONBLOCK? Presumably users want this call to be blocking?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GRND_NONBLOCK causes getrandom to return an error immediately rather than blocking indefinitely if the kernel randomness source isn't yet initialized. It only matters for things running around init time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The right behavior is to block indefinitely until the kernel randomness source is initialized. See, e.g., this paper. The vast majority of applications that need cryptographic randomness need it to actually be secure. The tiny minority of applications that don't can call getrandom directly if they really want to. This is a secure-by-default vs insecure-by-default thing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API is not publicly exposed. It's only used by RandomState.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW, Python 3.5 had some controversy about this: https://lwn.net/Articles/693189/

But Python 3.6 does default to blocking now: https://docs.python.org/3.6/library/os.html#os.urandom

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This API is not publicly exposed. It's only used by RandomState.

Sure, but that implies that RandomState would then be insecure. To be concrete on the problem here: if getrandom with GRND_NONBLOCK returns immediately because the entropy system isn't yet initialized, and then you fall back on reading from /dev/urandom, it means that (barring the system getting initialized between the call to getrandom and the read from /dev/urandom), you'll be reading insecure entropy.

In fact, it won't just be that single read that will return insecure entropy, it could be all future reads. As section 3.1 of this paper (see the "Corollary" section under "Reality 1") describes, reading while the entropy system isn't yet initialized can actually allow an attacker to execute attacks that compromise the entropy system on an ongoing basis into the future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is quite a bit of discussion about this here: #32953.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, fair enough. The TLDR of that discussion seems to be that using RandomState for HashMaps right after boot is problematic on embedded devices because of the blocking problem.

In keeping with the general trend of default-secure, perhaps we could have blocking be the default, but add a constructor that produces a RandomState that doesn't block? Users that need it explicitly could call that constructor, but most users would get the secure option without having to do anything.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That doesn't solve the underlying problem, which is that you don't have control of the construction of every HashMap in your dependency graph.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, good point. I hadn't thought of that.

@kennytm kennytm added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Nov 10, 2017
@alexcrichton
Copy link
Member

@bors: r+

Thanks @malbarbo!

I think the discussion about nonblocking or not can happen in parallel with this PR, it's just refactoring.

@bors
Copy link
Contributor

bors commented Nov 12, 2017

📌 Commit 62fce3b has been approved by alexcrichton

@alexcrichton alexcrichton self-assigned this Nov 12, 2017
@kennytm kennytm added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Nov 12, 2017
@bors
Copy link
Contributor

bors commented Nov 13, 2017

⌛ Testing commit 62fce3b with merge e08637d6c1f60232536a0126699d9af4a7af6cf6...

@bors
Copy link
Contributor

bors commented Nov 13, 2017

💔 Test failed - status-travis

@kennytm
Copy link
Member

kennytm commented Nov 14, 2017

cross build failed when targeting sparc64-unknown-linux-gnu, waiting for libc update to include rust-lang/libc#846.

@kennytm kennytm added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Nov 14, 2017
@malbarbo
Copy link
Contributor Author

libc updated.

@kennytm
Copy link
Member

kennytm commented Nov 14, 2017

@bors r=alexcrichton

@bors
Copy link
Contributor

bors commented Nov 14, 2017

📌 Commit 8f2dfd1 has been approved by alexcrichton

@kennytm kennytm added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Nov 14, 2017
@bors
Copy link
Contributor

bors commented Nov 14, 2017

⌛ Testing commit 8f2dfd1 with merge 9cd994c...

bors added a commit that referenced this pull request Nov 14, 2017
Use getrandom syscall for all Linux and Android targets.

I suppose we can use it in all Linux and Android targets. In function `is_getrandom_available` is checked if the syscall is available (getrandom syscall was add in version 3.17 of Linux kernel), if the syscall is not available `fill_bytes` fallback to reading from `/dev/urandom`.

Update libc to include getrandom related constants.
@bors
Copy link
Contributor

bors commented Nov 14, 2017

☀️ Test successful - status-appveyor, status-travis
Approved by: alexcrichton
Pushing 9cd994c to master...

@bors bors merged commit 8f2dfd1 into rust-lang:master Nov 14, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants