From f1571512d2f1e730f360ca7f6a2cbc9ab3c3ebef Mon Sep 17 00:00:00 2001 From: Dennis Duda Date: Sun, 30 Oct 2022 15:06:55 -0700 Subject: [PATCH] fix `try_pod_read_unaligned`... never having worked correctly (#138) It seems like a copy-paste error has happened between `try_from_bytes`/`try_from_bytes_mut` and `try_pod_read_unaligned`, causing `internal::try_pod_read_unaligned` to try to read a &T::Bits instead of a T::Bits, usually failing with a `SizeMismatch` error. In the worst case, this allows UB in safe code by having a type allowing any bit pattern and being pointer-sized. --- derive/tests/basic.rs | 15 +++++++++++++++ src/checked.rs | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/derive/tests/basic.rs b/derive/tests/basic.rs index 5e05555..9d5667d 100644 --- a/derive/tests/basic.rs +++ b/derive/tests/basic.rs @@ -186,6 +186,21 @@ fn anybitpattern_implies_zeroable() { assert_eq!(test, AnyBitPatternTest { a: 0, b: 0 }); } +#[test] +fn checkedbitpattern_try_pod_read_unaligned() { + let pod = [0u8]; + let res = bytemuck::checked::try_pod_read_unaligned::< + CheckedBitPatternEnumWithValues, + >(&pod); + assert!(res.is_ok()); + + let pod = [5u8]; + let res = bytemuck::checked::try_pod_read_unaligned::< + CheckedBitPatternEnumWithValues, + >(&pod); + assert!(res.is_err()); +} + #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] #[repr(C, align(16))] struct Issue127 {} diff --git a/src/checked.rs b/src/checked.rs index 112abf0..2fea55d 100644 --- a/src/checked.rs +++ b/src/checked.rs @@ -249,7 +249,7 @@ pub fn try_pod_read_unaligned( ) -> Result { let pod = unsafe { internal::try_pod_read_unaligned(bytes) }?; - if ::is_valid_bit_pattern(pod) { + if ::is_valid_bit_pattern(&pod) { Ok(unsafe { transmute!(pod) }) } else { Err(CheckedCastError::InvalidBitPattern)