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 assertions inside read_{u32,u64}_into #1096

Merged
merged 2 commits into from
Feb 14, 2021
Merged

Conversation

tmandry
Copy link
Contributor

@tmandry tmandry commented Feb 11, 2021

Unless I'm mistaken the size multiplier was on the wrong side, making the assertions too permissive. This could have resulted in destination buffers not being fully populated.

Unless I'm mistaken the size multiplier was on the wrong side, making the assertions too permissive. This could have resulted in destination buffers not being fully populated.
@newpavlov
Copy link
Member

newpavlov commented Feb 11, 2021

No, the asserts are correct. &[u64] must be 8 times longer than &[u8], i.e. on each u64 we must have 8 bytes.

@tmandry
Copy link
Contributor Author

tmandry commented Feb 11, 2021

dst here is the &[u64], and the length of src (bytes) is what's being multiplied by 8.

  • If I have 16 bytes in src and 2 u64 in dst, this assert is checking that (16 * 8) >= 2. I'd expect equality here.
  • If I have 2 bytes in src and 1 u64 in dst, this assert is checking that (2 * 8) >= 1, which is also true despite not having enough bytes to fill the destination.

That doesn't make sense to me.

@tmandry
Copy link
Contributor Author

tmandry commented Feb 11, 2021

Also this code was changed from the macro:

macro_rules! read_slice {
    ($src:expr, $dst:expr, $size:expr, $which:ident) => {{
        assert_eq!($src.len(), $size * $dst.len());

        unsafe {
            ptr::copy_nonoverlapping(
                $src.as_ptr(),
                $dst.as_mut_ptr() as *mut u8,
                $src.len());
        }
        for v in $dst.iter_mut() {
            *v = v.$which();
        }
    }};
}

Note that $dst.len() is what gets multiplied by $size.

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.

Oops, I was looking at the right side instead of the left one. :) Yes. you are right.

@dhardy
Copy link
Member

dhardy commented Feb 11, 2021

Yikes, good catch! This potentially affects seeding of Xoshiro128++, 256++, PCG, and HC128 generators.

The HC128 generator is even declared as a crypto generator:

impl CryptoRng for Hc128Core {}

So, how do we handle this?

  • We should probably push this as a hotfix even though it could be a breaking change
  • We should yank other 0.6.x releases?
  • We should publish a security advisory since it can theoretically allow cryptographic RNGs to be initialised with insufficient entropy? Note though this is not security hole in itself, it merely makes it easier for other crypto libs to do something stupid, so perhaps not.

Can I ask you to add a changelog entry and bump rand_core to v0.6.2 in this PR?

@tmandry
Copy link
Contributor Author

tmandry commented Feb 13, 2021

Can I ask you to add a changelog entry and bump rand_core to v0.6.2 in this PR?

Sure, done.

@dhardy
Copy link
Member

dhardy commented Feb 14, 2021

Fixed version published; thanks @tmandry. I'll let the Rust advisory team decide how to deal with the rest.

lopopolo added a commit to artichoke/rand_mt that referenced this pull request Feb 16, 2021
```
error[A001]: Incorrect check on buffer length when seeding RNGs
   ┌─ /home/lopopolo/dev/artichoke/rand_mt/Cargo.lock:13:1
   │
13 │ rand_core 0.6.1 registry+https://github.com/rust-lang/crates.io-index
   │ --------------------------------------------------------------------- security vulnerability detected
   │
   = ID: RUSTSEC-2021-0023
   = Advisory: https://rustsec.org/advisories/RUSTSEC-2021-0023
   = Summary: rand_core::le::read_u32_into and read_u64_into have incorrect checks on the source buffer length, allowing the destination buffer to be under-filled.

     Implications: some downstream RNGs, including Hc128Rng (but not the more widely used ChaCha*Rng), allow seeding using the SeedableRng::from_seed trait-function with too short keys.
   = Announcement: rust-random/rand#1096
   = Solution: Upgrade to >=0.6.2
   = rand_core v0.6.1
     └── rand_mt v4.0.0
```
lopopolo added a commit to artichoke/artichoke that referenced this pull request Feb 16, 2021
https://rustsec.org/advisories/RUSTSEC-2021-0023

```
error[A001]: Incorrect check on buffer length when seeding RNGs
   ┌─ /home/lopopolo/dev/artichoke/rand_mt/Cargo.lock:13:1
   │
13 │ rand_core 0.6.1 registry+https://github.com/rust-lang/crates.io-index
   │ --------------------------------------------------------------------- security vulnerability detected
   │
   = ID: RUSTSEC-2021-0023
   = Advisory: https://rustsec.org/advisories/RUSTSEC-2021-0023
   = Summary: rand_core::le::read_u32_into and read_u64_into have incorrect checks on the source buffer length, allowing the destination buffer to be under-filled.

     Implications: some downstream RNGs, including Hc128Rng (but not the more widely used ChaCha*Rng), allow seeding using the SeedableRng::from_seed trait-function with too short keys.
   = Announcement: rust-random/rand#1096
   = Solution: Upgrade to >=0.6.2
   = rand_core v0.6.1
     └── rand_mt v4.0.0
```
@tmandry tmandry deleted the patch-1 branch February 16, 2021 23:35
@plugwash
Copy link

Hi.

This was recently filed as a release critical bug in Debian. Debian testing/unstable has version 0.5.1 of rand_core and Debian stable has version 0.3.0 of rand_core. Wolfgang Silbermayr has looked at the code for 0.5.1 and I have looked at the code for both 0.3.0 and 0.5.1 (which appears to be identical). We have concluded that this is a 0.6.x specific issue but would like confirmation from those familiar with the code base.

@dhardy
Copy link
Member

dhardy commented Mar 15, 2021

@plugwash that is correct (it is in the advisory notice).

@vks
Copy link
Collaborator

vks commented Mar 15, 2021

@dhardy Somehow this does not show on the rustsec.org website.

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.

5 participants