Make strict provenance compatible (#542)

This commit is contained in:
Alice Ryhl
2022-04-16 00:26:58 +02:00
committed by GitHub
parent 547a32033e
commit 8198f9e28e
2 changed files with 30 additions and 18 deletions
+2
View File
@@ -5,5 +5,7 @@ rustup toolchain install nightly --component miri
rustup override set nightly rustup override set nightly
cargo miri setup cargo miri setup
export MIRIFLAGS="-Zmiri-strict-provenance"
cargo miri test cargo miri test
cargo miri test --target mips64-unknown-linux-gnuabi64 cargo miri test --target mips64-unknown-linux-gnuabi64
+28 -18
View File
@@ -314,15 +314,15 @@ impl Bytes {
assert!( assert!(
sub_p >= bytes_p, sub_p >= bytes_p,
"subset pointer ({:p}) is smaller than self pointer ({:p})", "subset pointer ({:p}) is smaller than self pointer ({:p})",
sub_p as *const u8, subset.as_ptr(),
bytes_p as *const u8, self.as_ptr(),
); );
assert!( assert!(
sub_p + sub_len <= bytes_p + bytes_len, sub_p + sub_len <= bytes_p + bytes_len,
"subset is out of bounds: self = ({:p}, {}), subset = ({:p}, {})", "subset is out of bounds: self = ({:p}, {}), subset = ({:p}, {})",
bytes_p as *const u8, self.as_ptr(),
bytes_len, bytes_len,
sub_p as *const u8, subset.as_ptr(),
sub_len, sub_len,
); );
@@ -821,18 +821,18 @@ impl From<Box<[u8]>> for Bytes {
let ptr = Box::into_raw(slice) as *mut u8; let ptr = Box::into_raw(slice) as *mut u8;
if ptr as usize & 0x1 == 0 { if ptr as usize & 0x1 == 0 {
let data = ptr as usize | KIND_VEC; let data = ptr_map(ptr, |addr| addr | KIND_VEC);
Bytes { Bytes {
ptr, ptr,
len, len,
data: AtomicPtr::new(data as *mut _), data: AtomicPtr::new(data.cast()),
vtable: &PROMOTABLE_EVEN_VTABLE, vtable: &PROMOTABLE_EVEN_VTABLE,
} }
} else { } else {
Bytes { Bytes {
ptr, ptr,
len, len,
data: AtomicPtr::new(ptr as *mut _), data: AtomicPtr::new(ptr.cast()),
vtable: &PROMOTABLE_ODD_VTABLE, vtable: &PROMOTABLE_ODD_VTABLE,
} }
} }
@@ -889,10 +889,10 @@ unsafe fn promotable_even_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize
let kind = shared as usize & KIND_MASK; let kind = shared as usize & KIND_MASK;
if kind == KIND_ARC { if kind == KIND_ARC {
shallow_clone_arc(shared as _, ptr, len) shallow_clone_arc(shared.cast(), ptr, len)
} else { } else {
debug_assert_eq!(kind, KIND_VEC); debug_assert_eq!(kind, KIND_VEC);
let buf = (shared as usize & !KIND_MASK) as *mut u8; let buf = ptr_map(shared.cast(), |addr| addr & !KIND_MASK);
shallow_clone_vec(data, shared, buf, ptr, len) shallow_clone_vec(data, shared, buf, ptr, len)
} }
} }
@@ -903,11 +903,11 @@ unsafe fn promotable_even_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: us
let kind = shared as usize & KIND_MASK; let kind = shared as usize & KIND_MASK;
if kind == KIND_ARC { if kind == KIND_ARC {
release_shared(shared as *mut Shared); release_shared(shared.cast());
} else { } else {
debug_assert_eq!(kind, KIND_VEC); debug_assert_eq!(kind, KIND_VEC);
let buf = (shared as usize & !KIND_MASK) as *mut u8; let buf = ptr_map(shared.cast(), |addr| addr & !KIND_MASK);
drop(rebuild_boxed_slice(buf, ptr, len)); free_boxed_slice(buf, ptr, len);
} }
}); });
} }
@@ -920,7 +920,7 @@ unsafe fn promotable_odd_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize)
shallow_clone_arc(shared as _, ptr, len) shallow_clone_arc(shared as _, ptr, len)
} else { } else {
debug_assert_eq!(kind, KIND_VEC); debug_assert_eq!(kind, KIND_VEC);
shallow_clone_vec(data, shared, shared as *mut u8, ptr, len) shallow_clone_vec(data, shared, shared.cast(), ptr, len)
} }
} }
@@ -930,18 +930,18 @@ unsafe fn promotable_odd_drop(data: &mut AtomicPtr<()>, ptr: *const u8, len: usi
let kind = shared as usize & KIND_MASK; let kind = shared as usize & KIND_MASK;
if kind == KIND_ARC { if kind == KIND_ARC {
release_shared(shared as *mut Shared); release_shared(shared.cast());
} else { } else {
debug_assert_eq!(kind, KIND_VEC); debug_assert_eq!(kind, KIND_VEC);
drop(rebuild_boxed_slice(shared as *mut u8, ptr, len)); free_boxed_slice(shared.cast(), ptr, len);
} }
}); });
} }
unsafe fn rebuild_boxed_slice(buf: *mut u8, offset: *const u8, len: usize) -> Box<[u8]> { unsafe fn free_boxed_slice(buf: *mut u8, offset: *const u8, len: usize) {
let cap = (offset as usize - buf as usize) + len; let cap = (offset as usize - buf as usize) + len;
Box::from_raw(slice::from_raw_parts_mut(buf, cap)) dealloc(buf, Layout::from_size_align(cap, 1).unwrap())
} }
// ===== impl SharedVtable ===== // ===== impl SharedVtable =====
@@ -981,7 +981,7 @@ unsafe fn shared_clone(data: &AtomicPtr<()>, ptr: *const u8, len: usize) -> Byte
unsafe fn shared_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) { unsafe fn shared_drop(data: &mut AtomicPtr<()>, _ptr: *const u8, _len: usize) {
data.with_mut(|shared| { data.with_mut(|shared| {
release_shared(*shared as *mut Shared); release_shared(shared.cast());
}); });
} }
@@ -1104,6 +1104,16 @@ unsafe fn release_shared(ptr: *mut Shared) {
Box::from_raw(ptr); Box::from_raw(ptr);
} }
fn ptr_map<F>(ptr: *mut u8, f: F) -> *mut u8
where
F: FnOnce(usize) -> usize,
{
let old_addr = ptr as usize;
let new_addr = f(old_addr);
// this optimizes better than `ptr.wrapping_add(new_addr.wrapping_sub(old_addr))`
ptr.wrapping_sub(old_addr).wrapping_add(new_addr)
}
// compile-fails // compile-fails
/// ```compile_fail /// ```compile_fail