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

Fix unsoundness in <BlockRng64 as RngCore>::next_u32, with less unsafe code #1160

Merged
merged 22 commits into from Sep 12, 2021

Conversation

vks
Copy link
Collaborator

@vks vks commented Aug 19, 2021

Many thanks to @joshlf for reporting this issue. This replaces #1159 and removes all unsafe code in the next_u32 implementation.

Fixes #1158.

Many thanks to @joshlf for reporting this issue.

Fixes rust-random#1158.
rand_core/src/block.rs Outdated Show resolved Hide resolved
@vks vks changed the title Fix unsoundness in <BlockRng64 as RngCore>::next_u32 Fix unsoundness in <BlockRng64 as RngCore>::next_u32, with less unsafe code Aug 19, 2021
Copy link
Member

@newpavlov newpavlov left a comment

Choose a reason for hiding this comment

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

@dhardy
I think we should prefer this PR over #1159.

Copy link
Member

@dhardy dhardy left a comment

Choose a reason for hiding this comment

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

Corrections needed, and I would like to see before/after benchmarks, though I expect perf is fine.

rand_core/src/block.rs Outdated Show resolved Hide resolved
rand_core/src/block.rs Outdated Show resolved Hide resolved
@vks vks requested a review from dhardy August 24, 2021 15:23
Copy link
Member

@dhardy dhardy left a comment

Choose a reason for hiding this comment

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

I think the code is fine, but the test is not.

It would still be nice to see before/after benches, though considering we only have one obscure RNG affecting by this, maybe nobody cares.

In fact, is there a good rationale for keeping this code?

rand_chacha/src/chacha.rs Outdated Show resolved Hide resolved
rand_core/src/block.rs Show resolved Hide resolved
@vks
Copy link
Collaborator Author

vks commented Aug 26, 2021

It would still be nice to see before/after benches, though considering we only have one obscure RNG affecting by this, maybe nobody cares.

In fact, is there a good rationale for keeping this code?

I only found the following uses outside of Rand: 1 2

@vks
Copy link
Collaborator Author

vks commented Aug 26, 2021

I did not measure a significant performance difference.

Before:

test gen_bytes_isaac64              ... bench:     310,060 ns/iter (+/- 7,379) = 3302 MB/s
test gen_u32_isaac64                ... bench:       1,973 ns/iter (+/- 154) = 2027 MB/s
test gen_u64_isaac64                ... bench:       2,768 ns/iter (+/- 397) = 2890 MB/s
test init_isaac64                   ... bench:         832 ns/iter (+/- 67)

After:

test gen_bytes_isaac64              ... bench:     313,418 ns/iter (+/- 6,781) = 3267 MB/s
test gen_u32_isaac64                ... bench:       1,976 ns/iter (+/- 55) = 2024 MB/s
test gen_u64_isaac64                ... bench:       2,732 ns/iter (+/- 62) = 2928 MB/s
test init_isaac64                   ... bench:         802 ns/iter (+/- 51)

@dhardy
Copy link
Member

dhardy commented Aug 26, 2021

I only found the following uses outside of Rand: 1 2

Both libraries look obscure and haven't been touched in a couple of years.

My issue is that BlockRng64 seems to be completely untested in this repository.

Anyone else care to comment (@newpavlov)? Perhaps we should move BlockRng64 to a new crate in the RNGs repo, though it would be a nuisance having yet another crate.

@newpavlov
Copy link
Member

I think we should simply create dummy 32 and 64 bit core RNGs (e.g. by simply incrementing an inner field) inside a module in the tests/ folder and test the wrapper impls using them.

@vks
Copy link
Collaborator Author

vks commented Sep 5, 2021

@newpavlov I migrated the new test from ChaChaRng to StepRng, and I'm now testing BlockRng and BlockRng64. This was worthwhile, because I found a bug in the BlockRng::next_u32 implementation that I fixed now.

@dhardy I believe all your concerns are addressed now?

@vks
Copy link
Collaborator Author

vks commented Sep 5, 2021

The nightly failures are unrelated (packed_simd_2 seems to be broken on the current nightly), but there is a failure of the new test on MIPS. Is there a problem with our endianness logic?

@newpavlov
Copy link
Member

@vks
I think it's better to keep StepRng and related tests inside tests folder instead of the the current test module. Also I think it may be worth to define separate StepRng32 and StepRng64 which would implement BlockRng without the common underlying StepRng. Currently you use only next_u32 and next_u64, so the rest of RngCore implementation is useless.

We no longer implement the non-block step RNG.
@vks
Copy link
Collaborator Author

vks commented Sep 7, 2021

@newpavlov We currently don't have a tests folder for rand_core. Why would you prefer to move the test there?

I agree that implementing RngCore is unnecessary. I got rid of the StepRng, implementing BlockRngCore for the dummy RNGs is trivial enough and simplifies the code.

@vks vks requested a review from dhardy September 7, 2021 20:04
@vks
Copy link
Collaborator Author

vks commented Sep 7, 2021

I fixed the MIPS test by removing the special big-endian logic. I'm not sure this is correct.

@dhardy Could you please have another look whether your concerns are addressed now? Thanks!

@newpavlov
Copy link
Member

@vks

We currently don't have a tests folder for rand_core. Why would you prefer to move the test there?

I generally prefer to keep integration tests in the tests/, especially if they require additional mocking code like we do with StepRngs. It's a somewhat stylistic choice, so I do not insist on it.

@dhardy dhardy mentioned this pull request Sep 11, 2021
rand_core/src/block.rs Outdated Show resolved Hide resolved
rand_core/src/block.rs Show resolved Hide resolved
Copy link
Member

@dhardy dhardy left a comment

Choose a reason for hiding this comment

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

Looks okay now! (For a real RNG the increment should be odd, otherwise the lowest bit is never flipped, but it really doesn't matter in this test.)

@vks vks merged commit e359b27 into rust-random:master Sep 12, 2021
@vks vks deleted the fix-unsafe-block branch September 12, 2021 14:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unsoundness in <BlockRng64 as RngCore>:: next_u32
3 participants