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 #1159

Closed
wants to merge 1 commit into from

Conversation

joshlf
Copy link
Contributor

@joshlf joshlf commented Aug 18, 2021

Previously, certain implementations of BlockRngCore could cause BlockRng64's implementation of RngCore::next_u32 to exhibit undefined behavior (UB). This removes that UB by adding a bounds check, and adds documentation to BlockRngCore::Results clarifying requirements for that type.

While we're here, run rustfmt on existing code.

Fixes #1158

Previously, certain implementations of `BlockRngCore` could cause
`BlockRng64`'s implementation of `RngCore::next_u32` to exhibit
undefined behavior (UB). This removes that UB by adding a bounds check,
and adds documentation to `BlockRngCore::Results` clarifying
requirements for that type.

While we're here, run `rustfmt` on existing code.

Fixes rust-random#1158
// return slices of the same length. Thus, it would be unsound to
// assume that this index is in-bounds and to elide the bounds
// check.
results[index]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Could we make all of the code safe at this point?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, we can by getting u64 from the cached block, shifting it to 32 bits if one half was already used, and casting it to u32.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think this is the best approach. Maybe let's just convert index to an index into the u64 slice and shift by 32 * self.half_used bits.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I opened #1160 for this.

@vks
Copy link
Collaborator

vks commented Aug 18, 2021

I think we should also look into the performance impact. If it is big, we could introduce a breaking change (later, in another PR) and replace AsRef with an equivalent trait that is unsafe to implement.

@newpavlov
Copy link
Member

newpavlov commented Aug 18, 2021

@vks
The unsoundness must be fixed, even if it noticeably degrades performance. The unsafe trait is a breaking change, so we should discuss it separately. Ideally we would simply use const generics, but AFAIK the currently stable version is not sufficient for our needs (associated constant can not be used in defining arrays).

@vks
Copy link
Collaborator

vks commented Aug 18, 2021

@newpavlov I agree. I should have been more clear about this.

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.

Yes, rand still doesn't use rustfmt, but no worries.

This looks okay, but as said could probably be better still.

///
/// Code which uses this type is allowed to assume that `Results` is a type
/// with at least one element. It may panic or exhibit incorrect behavior
/// if this is not the case. It may *not* exhibit undefined behavior.
Copy link
Member

Choose a reason for hiding this comment

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

This goes without saying, usually..

@dhardy
Copy link
Member

dhardy commented Aug 19, 2021

Can you also add a note to the changelog and bump the version number?

@vks looks like the only other PR worth mentioning for rand is #1142. If @joshlf adds that and the date, I think we should be good for 0.8.5?

@vks
Copy link
Collaborator

vks commented Sep 12, 2021

Fixed by #1160.

@vks vks closed this Sep 12, 2021
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
4 participants