Skip to content

Commit 8ed31d2

Browse files
authored
Rollup merge of #78602 - RalfJung:raw-ptr-aliasing-issues, r=m-ou-se
fix various aliasing issues in the standard library This fixes various cases where the standard library either used raw pointers after they were already invalidated by using the original reference again, or created raw pointers for one element of a slice and used it to access neighboring elements.
2 parents f281a76 + 9749eb7 commit 8ed31d2

File tree

5 files changed

+17
-9
lines changed

5 files changed

+17
-9
lines changed

library/alloc/src/collections/binary_heap.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1036,8 +1036,9 @@ impl<'a, T> Hole<'a, T> {
10361036
debug_assert!(index != self.pos);
10371037
debug_assert!(index < self.data.len());
10381038
unsafe {
1039-
let index_ptr: *const _ = self.data.get_unchecked(index);
1040-
let hole_ptr = self.data.get_unchecked_mut(self.pos);
1039+
let ptr = self.data.as_mut_ptr();
1040+
let index_ptr: *const _ = ptr.add(index);
1041+
let hole_ptr = ptr.add(self.pos);
10411042
ptr::copy_nonoverlapping(index_ptr, hole_ptr, 1);
10421043
}
10431044
self.pos = index;

library/core/src/fmt/num.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,6 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
595595
// 2^128 is about 3*10^38, so 39 gives an extra byte of space
596596
let mut buf = [MaybeUninit::<u8>::uninit(); 39];
597597
let mut curr = buf.len() as isize;
598-
let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
599598

600599
let (n, rem) = udiv_1e19(n);
601600
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
606605
// SAFETY: Guaranteed that we wrote at most 19 bytes, and there must be space
607606
// remaining since it has length 39
608607
unsafe {
609-
ptr::write_bytes(buf_ptr.offset(target), b'0', (curr - target) as usize);
608+
ptr::write_bytes(
609+
MaybeUninit::slice_as_mut_ptr(&mut buf).offset(target),
610+
b'0',
611+
(curr - target) as usize,
612+
);
610613
}
611614
curr = target;
612615

@@ -615,6 +618,9 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
615618
// Should this following branch be annotated with unlikely?
616619
if n != 0 {
617620
let target = (buf.len() - 38) as isize;
621+
// The raw `buf_ptr` pointer is only valid until `buf` is used the next time,
622+
// buf `buf` is not used in this scope so we are good.
623+
let buf_ptr = MaybeUninit::slice_as_mut_ptr(&mut buf);
618624
// SAFETY: At this point we wrote at most 38 bytes, pad up to that point,
619625
// There can only be at most 1 digit remaining.
620626
unsafe {
@@ -629,7 +635,7 @@ fn fmt_u128(n: u128, is_nonnegative: bool, f: &mut fmt::Formatter<'_>) -> fmt::R
629635
// UTF-8 since `DEC_DIGITS_LUT` is
630636
let buf_slice = unsafe {
631637
str::from_utf8_unchecked(slice::from_raw_parts(
632-
buf_ptr.offset(curr),
638+
MaybeUninit::slice_as_mut_ptr(&mut buf).offset(curr),
633639
buf.len() - curr as usize,
634640
))
635641
};

library/core/src/hash/sip.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ macro_rules! load_int_le {
111111
debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len());
112112
let mut data = 0 as $int_ty;
113113
ptr::copy_nonoverlapping(
114-
$buf.get_unchecked($i),
114+
$buf.as_ptr().add($i),
115115
&mut data as *mut _ as *mut u8,
116116
mem::size_of::<$int_ty>(),
117117
);

library/core/src/mem/maybe_uninit.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -842,13 +842,13 @@ impl<T> MaybeUninit<T> {
842842
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
843843
#[inline(always)]
844844
pub fn slice_as_ptr(this: &[MaybeUninit<T>]) -> *const T {
845-
this as *const [MaybeUninit<T>] as *const T
845+
this.as_ptr() as *const T
846846
}
847847

848848
/// Gets a mutable pointer to the first element of the array.
849849
#[unstable(feature = "maybe_uninit_slice", issue = "63569")]
850850
#[inline(always)]
851851
pub fn slice_as_mut_ptr(this: &mut [MaybeUninit<T>]) -> *mut T {
852-
this as *mut [MaybeUninit<T>] as *mut T
852+
this.as_mut_ptr() as *mut T
853853
}
854854
}

library/std/src/sys/unix/thread.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,8 @@ impl Thread {
178178
tv_nsec: nsecs,
179179
};
180180
secs -= ts.tv_sec as u64;
181-
if libc::nanosleep(&ts, &mut ts) == -1 {
181+
let ts_ptr = &mut ts as *mut _;
182+
if libc::nanosleep(ts_ptr, ts_ptr) == -1 {
182183
assert_eq!(os::errno(), libc::EINTR);
183184
secs += ts.tv_sec as u64;
184185
nsecs = ts.tv_nsec;

0 commit comments

Comments
 (0)