From ed96321e7e32d3c047f204445b849c75f3c63e28 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 31 Oct 2020 16:13:33 +0100 Subject: [PATCH 1/4] fix aliasing issues in u128 formatting code --- library/core/src/fmt/num.rs | 12 +++++++++--- library/core/src/mem/maybe_uninit.rs | 4 ++-- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/library/core/src/fmt/num.rs b/library/core/src/fmt/num.rs index 795cbf5fbbd44..7a98210995ec7 100644 --- a/library/core/src/fmt/num.rs +++ b/library/core/src/fmt/num.rs @@ -595,7 +595,6 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R // 2^128 is about 3*10^38, so 39 gives an extra byte of space let mut buf = [MaybeUninit::::uninit(); 39]; let mut curr = buf.len() as isize; - let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf); let (n, rem) = udiv_1e19(n); parse_u64_into(rem, &mut buf, &mut curr); @@ -606,7 +605,11 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R // SAFETY: Guaranteed that we wrote at most 19 bytes, and there must be space // remaining since it has length 39 unsafe { - ptr::write_bytes(buf_ptr.offset(target), b'0', (curr - target) as usize); + ptr::write_bytes( + MaybeUninit::slice_as_mut_ptr(&mut buf).offset(target), + b'0', + (curr - target) as usize, + ); } curr = target; @@ -615,6 +618,9 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R // Should this following branch be annotated with unlikely? if n != 0 { let target = (buf.len() - 38) as isize; + // The raw `buf_ptr` pointer is only valid until `buf` is used the next time, + // buf `buf` is not used in this scope so we are good. + let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf); // SAFETY: At this point we wrote at most 38 bytes, pad up to that point, // There can only be at most 1 digit remaining. unsafe { @@ -629,7 +635,7 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R // UTF-8 since `DEC_DIGITS_LUT` is let buf_slice = unsafe { str::from_utf8_unchecked(slice::from_raw_parts( - buf_ptr.offset(curr), + MaybeUninit::slice_as_mut_ptr(&mut buf).offset(curr), buf.len() - curr as usize, )) }; diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs index 862c452a43480..660b7db70be92 100644 --- a/library/core/src/mem/maybe_uninit.rs +++ b/library/core/src/mem/maybe_uninit.rs @@ -842,13 +842,13 @@ impl MaybeUninit { #[unstable(feature = "maybe_uninit_slice", issue = "63569")] #[inline(always)] pub fn slice_as_ptr(this: &[MaybeUninit]) -> *const T { - this as *const [MaybeUninit] as *const T + this.as_ptr() as *const T } /// Gets a mutable pointer to the first element of the array. #[unstable(feature = "maybe_uninit_slice", issue = "63569")] #[inline(always)] pub fn slice_as_mut_ptr(this: &mut [MaybeUninit]) -> *mut T { - this as *mut [MaybeUninit] as *mut T + this.as_mut_ptr() as *mut T } } From 9f630af93077b276f78701dcd2307d19dccf0e14 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 31 Oct 2020 16:16:54 +0100 Subject: [PATCH 2/4] fix aliasing issue in unix sleep function --- library/std/src/sys/unix/thread.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index fdf114d6df6fe..f1ab302d30e1e 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -178,7 +178,8 @@ impl Thread { tv_nsec: nsecs, }; secs -= ts.tv_sec as u64; - if libc::nanosleep(&ts, &mut ts) == -1 { + let ts_ptr = &mut ts as *mut _; + if libc::nanosleep(ts_ptr, ts_ptr) == -1 { assert_eq!(os::errno(), libc::EINTR); secs += ts.tv_sec as u64; nsecs = ts.tv_nsec; From 607076e20903bb5267d5d8f2bc7520ba1686cec8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 31 Oct 2020 16:22:24 +0100 Subject: [PATCH 3/4] fix aliasing issue in binary_heap --- library/alloc/src/collections/binary_heap.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs index f2852b1cc2b80..b67c72d7136a6 100644 --- a/library/alloc/src/collections/binary_heap.rs +++ b/library/alloc/src/collections/binary_heap.rs @@ -1036,8 +1036,9 @@ impl<'a, T> Hole<'a, T> { debug_assert!(index != self.pos); debug_assert!(index < self.data.len()); unsafe { - let index_ptr: *const _ = self.data.get_unchecked(index); - let hole_ptr = self.data.get_unchecked_mut(self.pos); + let ptr = self.data.as_mut_ptr(); + let index_ptr: *const _ = ptr.add(index); + let hole_ptr = ptr.add(self.pos); ptr::copy_nonoverlapping(index_ptr, hole_ptr, 1); } self.pos = index; From 9749eb72af8f817fd72c0a7cdad324a9baa8b635 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 28 Oct 2020 14:01:04 +0100 Subject: [PATCH 4/4] fix aliasing issues in SipHasher --- library/core/src/hash/sip.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs index a9882d54de4f1..6178b0af137e8 100644 --- a/library/core/src/hash/sip.rs +++ b/library/core/src/hash/sip.rs @@ -111,7 +111,7 @@ macro_rules! load_int_le { debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len()); let mut data = 0 as $int_ty; ptr::copy_nonoverlapping( - $buf.get_unchecked($i), + $buf.as_ptr().add($i), &mut data as *mut _ as *mut u8, mem::size_of::<$int_ty>(), );