diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs index 49bf941984af5..2cdf4ca003c49 100644 --- a/library/alloc/src/alloc.rs +++ b/library/alloc/src/alloc.rs @@ -116,6 +116,7 @@ pub struct Global; #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn alloc(layout: Layout) -> *mut u8 { + // SAFETY: Untriaged. unsafe { // Make sure we don't accidentally allow omitting the allocator shim in // stable code until it is actually stabilized. @@ -159,6 +160,7 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { + // SAFETY: Untriaged. unsafe { dealloc_nonnull(NonNull::new_unchecked(ptr), layout) } } @@ -166,6 +168,7 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces unsafe fn dealloc_nonnull(ptr: NonNull, layout: Layout) { + // SAFETY: Untriaged. unsafe { __rust_dealloc(ptr, layout.size(), layout.alignment()) } } @@ -212,6 +215,7 @@ unsafe fn dealloc_nonnull(ptr: NonNull, layout: Layout) { #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + // SAFETY: Untriaged. unsafe { realloc_nonnull(NonNull::new_unchecked(ptr), layout, new_size) } } @@ -219,6 +223,7 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces unsafe fn realloc_nonnull(ptr: NonNull, layout: Layout, new_size: usize) -> *mut u8 { + // SAFETY: Untriaged. unsafe { __rust_realloc(ptr, layout.size(), layout.alignment(), new_size) } } @@ -276,6 +281,7 @@ unsafe fn realloc_nonnull(ptr: NonNull, layout: Layout, new_size: usize) -> #[inline] #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { + // SAFETY: Untriaged. unsafe { // Make sure we don't accidentally allow omitting the allocator shim in // stable code until it is actually stabilized. @@ -519,6 +525,7 @@ impl Global { cmp::min(old_layout.size(), new_layout.size()), ); } + // SAFETY: Untriaged. unsafe { self.deallocate_impl(ptr, old_layout); } @@ -633,6 +640,7 @@ pub const fn handle_alloc_error(layout: Layout) -> ! { #[inline] fn rt_error(layout: Layout) -> ! { + // SAFETY: Untriaged. unsafe { __rust_alloc_error_handler(layout.size(), layout.align()); } diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs index cd2508a76a10e..bb4537cb64888 100644 --- a/library/alloc/src/boxed.rs +++ b/library/alloc/src/boxed.rs @@ -266,6 +266,7 @@ const fn box_new_uninit(layout: Layout) -> *mut u8 { pub const fn box_assume_init_into_vec_unsafe( b: Box>, ) -> crate::vec::Vec { + // SAFETY: Untriaged. unsafe { (b.assume_init() as Box<[T]>).into_vec() } } @@ -450,6 +451,7 @@ impl Box { if size_of::() == size_of::() && align_of::() == align_of::() { let (value, allocation) = Box::take(this); Box::write( + // SAFETY: Untriaged. unsafe { mem::transmute::>, Box>>(allocation) }, f(value), ) @@ -490,6 +492,7 @@ impl Box { let (value, allocation) = Box::take(this); try { Box::write( + // SAFETY: Untriaged. unsafe { mem::transmute::>, Box>>( allocation, @@ -528,6 +531,7 @@ impl Box { { let mut boxed = Self::new_uninit_in(alloc); boxed.write(x); + // SAFETY: Untriaged. unsafe { boxed.assume_init() } } @@ -554,6 +558,7 @@ impl Box { { let mut boxed = Self::try_new_uninit_in(alloc)?; boxed.write(x); + // SAFETY: Untriaged. unsafe { Ok(boxed.assume_init()) } } @@ -618,6 +623,7 @@ impl Box { let layout = Layout::new::>(); alloc.allocate(layout)?.cast() }; + // SAFETY: Untriaged. unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } } @@ -690,6 +696,7 @@ impl Box { let layout = Layout::new::>(); alloc.allocate_zeroed(layout)?.cast() }; + // SAFETY: Untriaged. unsafe { Ok(Box::from_raw_in(ptr.as_ptr(), alloc)) } } @@ -726,6 +733,7 @@ impl Box { #[unstable(feature = "box_into_boxed_slice", issue = "71582")] pub fn into_boxed_slice(boxed: Self) -> Box<[T], A> { let (raw, alloc) = Box::into_raw_with_allocator(boxed); + // SAFETY: Untriaged. unsafe { Box::from_raw_in(raw as *mut [T; 1], alloc) } } @@ -769,6 +777,7 @@ impl Box { /// ``` #[unstable(feature = "box_take", issue = "147212")] pub fn take(boxed: Self) -> (T, Box, A>) { + // SAFETY: Untriaged. unsafe { let (raw, alloc) = Box::into_non_null_with_allocator(boxed); let value = raw.read(); @@ -873,6 +882,7 @@ impl Box { fn drop(&mut self) { let &mut DeallocDropGuard(layout, alloc, ptr) = self; // Safety: `ptr` was allocated by `*alloc` with layout `layout` + // SAFETY: Untriaged. unsafe { alloc.deallocate(ptr, layout); } @@ -890,12 +900,14 @@ impl Box { // Safety: `*ptr` is newly allocated, correctly aligned to `align_of_val(src)`, // and is valid for writes for `size_of_val(src)`. // If this panics, then `guard` will deallocate for us (if allocation occuured) + // SAFETY: Untriaged. unsafe { ::clone_to_uninit(src, ptr); } // Defuse the deallocate guard core::mem::forget(guard); // Safety: We just initialized `*ptr` as a clone of `src` + // SAFETY: Untriaged. Ok(unsafe { Box::from_raw_in(ptr.with_metadata_of(src), alloc) }) } } @@ -919,6 +931,7 @@ impl Box<[T]> { #[stable(feature = "new_uninit", since = "1.82.0")] #[must_use] pub fn new_uninit_slice(len: usize) -> Box<[mem::MaybeUninit]> { + // SAFETY: Untriaged. unsafe { RawVec::with_capacity(len).into_box(len) } } @@ -942,6 +955,7 @@ impl Box<[T]> { #[stable(feature = "new_zeroed_alloc", since = "1.92.0")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Box<[mem::MaybeUninit]> { + // SAFETY: Untriaged. unsafe { RawVec::with_capacity_zeroed(len).into_box(len) } } @@ -975,6 +989,7 @@ impl Box<[T]> { }; Global.allocate(layout)?.cast() }; + // SAFETY: Untriaged. unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } } @@ -1009,6 +1024,7 @@ impl Box<[T]> { }; Global.allocate_zeroed(layout)?.cast() }; + // SAFETY: Untriaged. unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, Global).into_box(len)) } } } @@ -1036,6 +1052,7 @@ impl Box<[T], A> { #[unstable(feature = "allocator_api", issue = "32838")] #[must_use] pub fn new_uninit_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit], A> { + // SAFETY: Untriaged. unsafe { RawVec::with_capacity_in(len, alloc).into_box(len) } } @@ -1063,6 +1080,7 @@ impl Box<[T], A> { #[unstable(feature = "allocator_api", issue = "32838")] #[must_use] pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Box<[mem::MaybeUninit], A> { + // SAFETY: Untriaged. unsafe { RawVec::with_capacity_zeroed_in(len, alloc).into_box(len) } } @@ -1101,6 +1119,7 @@ impl Box<[T], A> { }; alloc.allocate(layout)?.cast() }; + // SAFETY: Untriaged. unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) } } @@ -1140,6 +1159,7 @@ impl Box<[T], A> { }; alloc.allocate_zeroed(layout)?.cast() }; + // SAFETY: Untriaged. unsafe { Ok(RawVec::from_raw_parts_in(ptr.as_ptr(), len, alloc).into_box(len)) } } @@ -1237,6 +1257,7 @@ impl Box, A> { #[stable(feature = "box_uninit_write", since = "1.87.0")] #[inline] pub fn write(mut boxed: Self, value: T) -> Box { + // SAFETY: Untriaged. unsafe { (*boxed).write(value); boxed.assume_init() @@ -1273,6 +1294,7 @@ impl Box<[mem::MaybeUninit], A> { #[inline] pub unsafe fn assume_init(self) -> Box<[T], A> { let (raw, alloc) = Box::into_raw_with_allocator(self); + // SAFETY: Untriaged. unsafe { Box::from_raw_in(raw as *mut [T], alloc) } } } @@ -1326,6 +1348,7 @@ impl Box { #[inline] #[must_use = "call `drop(Box::from_raw(ptr))` if you intend to drop the `Box`"] pub unsafe fn from_raw(raw: *mut T) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_raw_in(raw, Global) } } @@ -1378,6 +1401,7 @@ impl Box { #[inline] #[must_use = "call `drop(Box::from_non_null(ptr))` if you intend to drop the `Box`"] pub unsafe fn from_non_null(ptr: NonNull) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_raw(ptr.as_ptr()) } } @@ -1557,6 +1581,7 @@ impl Box { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub unsafe fn from_raw_in(raw: *mut T, alloc: A) -> Self { + // SAFETY: Untriaged. Box(unsafe { Unique::new_unchecked(raw) }, alloc) } @@ -1675,6 +1700,7 @@ impl Box { // In case `A` *is* `Global`, this does not quite have the right behavior; `into_raw` // works around that. let ptr = &raw mut **b; + // SAFETY: Untriaged. let alloc = unsafe { ptr::read(&b.1) }; (ptr, alloc) } @@ -1742,6 +1768,7 @@ impl Box { #[doc(hidden)] pub fn into_unique(b: Self) -> (Unique, A) { let (ptr, alloc) = Box::into_raw_with_allocator(b); + // SAFETY: Untriaged. unsafe { (Unique::from(&mut *ptr), alloc) } } @@ -1940,6 +1967,7 @@ impl Box { { let (ptr, alloc) = Box::into_raw_with_allocator(b); mem::forget(alloc); + // SAFETY: Untriaged. unsafe { &mut *ptr } } @@ -1981,6 +2009,7 @@ impl Box { // It's not possible to move or replace the insides of a `Pin>` // when `T: !Unpin`, so it's safe to pin it directly without any // additional requirements. + // SAFETY: Untriaged. unsafe { Pin::new_unchecked(boxed) } } } @@ -1993,6 +2022,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Box { let ptr = self.0; + // SAFETY: Untriaged. unsafe { let layout = Layout::for_value_raw(ptr.as_ptr()); if layout.size() != 0 { @@ -2009,6 +2039,7 @@ impl Default for Box { #[inline] fn default() -> Self { let mut x: Box> = Box::new_uninit(); + // SAFETY: Untriaged. unsafe { // SAFETY: `x` is valid for writing and has the same layout as `T`. // If `T::default()` panics, dropping `x` will just deallocate the Box as `MaybeUninit` @@ -2084,6 +2115,7 @@ impl Clone for Box { fn clone(&self) -> Self { // Pre-allocate memory to allow writing the cloned value directly. let mut boxed = Self::new_uninit_in(self.1.clone()); + // SAFETY: Untriaged. unsafe { (**self).clone_to_uninit(boxed.as_mut_ptr().cast()); boxed.assume_init() @@ -2154,6 +2186,7 @@ impl Clone for Box { fn clone(&self) -> Self { // this makes a copy of the data let buf: Box<[u8]> = self.as_bytes().into(); + // SAFETY: Untriaged. unsafe { from_boxed_utf8_unchecked(buf) } } } diff --git a/library/alloc/src/boxed/convert.rs b/library/alloc/src/boxed/convert.rs index d6a8e78991b84..4ab9a796297c6 100644 --- a/library/alloc/src/boxed/convert.rs +++ b/library/alloc/src/boxed/convert.rs @@ -217,6 +217,7 @@ impl From> for Box<[u8], A> { #[inline] fn from(s: Box) -> Self { let (raw, alloc) = Box::into_raw_with_allocator(s); + // SAFETY: Untriaged. unsafe { Box::from_raw_in(raw as *mut [u8], alloc) } } } @@ -270,6 +271,7 @@ impl TryFrom> for Box<[T; N]> { /// `boxed_slice.len()` does not equal `N`. fn try_from(boxed_slice: Box<[T]>) -> Result { if boxed_slice.len() == N { + // SAFETY: Untriaged. Ok(unsafe { boxed_slice_as_array_unchecked(boxed_slice) }) } else { Err(boxed_slice) @@ -303,6 +305,7 @@ impl TryFrom> for Box<[T; N]> { fn try_from(vec: Vec) -> Result { if vec.len() == N { let boxed_slice = vec.into_boxed_slice(); + // SAFETY: Untriaged. Ok(unsafe { boxed_slice_as_array_unchecked(boxed_slice) }) } else { Err(vec) @@ -331,6 +334,7 @@ impl Box { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn downcast(self) -> Result, Self> { + // SAFETY: Untriaged. if self.is::() { unsafe { Ok(self.downcast_unchecked::()) } } else { Err(self) } } @@ -362,6 +366,7 @@ impl Box { #[unstable(feature = "downcast_unchecked", issue = "90850")] pub unsafe fn downcast_unchecked(self) -> Box { debug_assert!(self.is::()); + // SAFETY: Untriaged. unsafe { let (raw, alloc): (*mut dyn Any, _) = Box::into_raw_with_allocator(self); Box::from_raw_in(raw as *mut T, alloc) @@ -390,6 +395,7 @@ impl Box { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn downcast(self) -> Result, Self> { + // SAFETY: Untriaged. if self.is::() { unsafe { Ok(self.downcast_unchecked::()) } } else { Err(self) } } @@ -421,6 +427,7 @@ impl Box { #[unstable(feature = "downcast_unchecked", issue = "90850")] pub unsafe fn downcast_unchecked(self) -> Box { debug_assert!(self.is::()); + // SAFETY: Untriaged. unsafe { let (raw, alloc): (*mut (dyn Any + Send), _) = Box::into_raw_with_allocator(self); Box::from_raw_in(raw as *mut T, alloc) @@ -449,6 +456,7 @@ impl Box { #[inline] #[stable(feature = "box_send_sync_any_downcast", since = "1.51.0")] pub fn downcast(self) -> Result, Self> { + // SAFETY: Untriaged. if self.is::() { unsafe { Ok(self.downcast_unchecked::()) } } else { Err(self) } } @@ -480,6 +488,7 @@ impl Box { #[unstable(feature = "downcast_unchecked", issue = "90850")] pub unsafe fn downcast_unchecked(self) -> Box { debug_assert!(self.is::()); + // SAFETY: Untriaged. unsafe { let (raw, alloc): (*mut (dyn Any + Send + Sync), _) = Box::into_raw_with_allocator(self); @@ -709,6 +718,7 @@ impl dyn Error { #[rustc_allow_incoherent_impl] pub fn downcast(self: Box) -> Result, Box> { if self.is::() { + // SAFETY: Untriaged. unsafe { let raw: *mut dyn Error = Box::into_raw(self); Ok(Box::from_raw(raw as *mut T)) @@ -726,6 +736,7 @@ impl dyn Error + Send { #[rustc_allow_incoherent_impl] pub fn downcast(self: Box) -> Result, Box> { let err: Box = self; + // SAFETY: Untriaged. ::downcast(err).map_err(|s| unsafe { // Reapply the `Send` marker. mem::transmute::, Box>(s) @@ -740,6 +751,7 @@ impl dyn Error + Send + Sync { #[rustc_allow_incoherent_impl] pub fn downcast(self: Box) -> Result, Box> { let err: Box = self; + // SAFETY: Untriaged. ::downcast(err).map_err(|s| unsafe { // Reapply the `Send + Sync` markers. mem::transmute::, Box>(s) diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index 22c3d89e3ccdb..44d3eeee89d78 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -146,6 +146,7 @@ impl Deref for ThinBox { let value = self.data(); let metadata = self.meta(); let pointer = ptr::from_raw_parts(value as *const (), metadata); + // SAFETY: Untriaged. unsafe { &*pointer } } } @@ -156,6 +157,7 @@ impl DerefMut for ThinBox { let value = self.data(); let metadata = self.meta(); let pointer = ptr::from_raw_parts_mut::(value as *mut (), metadata); + // SAFETY: Untriaged. unsafe { &mut *pointer } } } @@ -163,6 +165,7 @@ impl DerefMut for ThinBox { #[unstable(feature = "thin_box", issue = "92791")] impl Drop for ThinBox { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { let value = self.deref_mut(); let value = value as *mut T; @@ -176,6 +179,7 @@ impl ThinBox { fn meta(&self) -> ::Metadata { // Safety: // - NonNull and valid. + // SAFETY: Untriaged. unsafe { *self.with_header().header() } } @@ -238,6 +242,7 @@ impl WithHeader { alloc::handle_alloc_error(Layout::new::<()>()); }; + // SAFETY: Untriaged. unsafe { // Note: It's UB to pass a layout with a zero size to `alloc::alloc`, so // we use `layout.dangling()` for this case, which should have a valid @@ -275,6 +280,7 @@ impl WithHeader { return Err(core::alloc::AllocError); }; + // SAFETY: Untriaged. unsafe { // Note: It's UB to pass a layout with a zero size to `alloc::alloc`, so // we use `layout.dangling()` for this case, which should have a valid @@ -330,6 +336,7 @@ impl WithHeader { let alloc_size = max(align_of::(), size_of::<::Metadata>()); + // SAFETY: Untriaged. unsafe { // SAFETY: align is power of two because it is the maximum of two alignments. let alloc: *mut u8 = const_allocate(alloc_size, alloc_align); @@ -350,6 +357,7 @@ impl WithHeader { // SAFETY: `alloc` points to `::Metadata`, so addition stays in-bounds. let value_ptr = +// SAFETY: Untriaged. unsafe { (alloc as *const ::Metadata).add(1) }.cast::().cast_mut(); debug_assert!(value_ptr.is_aligned()); mem::forget(value); @@ -373,6 +381,7 @@ impl WithHeader { return; } + // SAFETY: Untriaged. unsafe { // SAFETY: Layout must have been computable if we're in drop let (layout, value_offset) = @@ -385,6 +394,7 @@ impl WithHeader { } } + // SAFETY: Untriaged. unsafe { // `_guard` will deallocate the memory when dropped, even if `drop_in_place` unwinds. let _guard = DropGuard { @@ -407,6 +417,7 @@ impl WithHeader { // needed to align the header. Subtracting the header size from the aligned data pointer // will always result in an aligned header pointer, it just may not point to the // beginning of the allocation. + // SAFETY: Untriaged. let hp = unsafe { self.0.as_ptr().sub(Self::header_size()) as *mut H }; debug_assert!(hp.is_aligned()); hp diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs index 98192e1fb5b01..8f6435299bdb3 100644 --- a/library/alloc/src/collections/binary_heap/mod.rs +++ b/library/alloc/src/collections/binary_heap/mod.rs @@ -327,6 +327,7 @@ impl Deref for PeekMut<'_, T, A> { fn deref(&self) -> &T { debug_assert!(!self.heap.is_empty()); // SAFE: PeekMut is only instantiated for non-empty heaps + // SAFETY: Untriaged. unsafe { self.heap.data.get_unchecked(0) } } } @@ -346,6 +347,7 @@ impl DerefMut for PeekMut<'_, T, A> { // // This is technique is described throughout several other places in // the standard library as "leak amplification". + // SAFETY: Untriaged. unsafe { // SAFETY: len > 1 so len != 0. self.original_len = Some(NonZero::new_unchecked(len)); @@ -356,6 +358,7 @@ impl DerefMut for PeekMut<'_, T, A> { } // SAFE: PeekMut is only instantiated for non-empty heaps + // SAFETY: Untriaged. unsafe { self.heap.data.get_unchecked_mut(0) } } } @@ -1537,6 +1540,7 @@ impl<'a, T> Hole<'a, T> { unsafe fn new(data: &'a mut [T], pos: usize) -> Self { debug_assert!(pos < data.len()); // SAFE: pos should be inside the slice + // SAFETY: Untriaged. let elt = unsafe { ptr::read(data.get_unchecked(pos)) }; Hole { data, elt: ManuallyDrop::new(elt), pos } } @@ -1559,6 +1563,7 @@ impl<'a, T> Hole<'a, T> { unsafe fn get(&self, index: usize) -> &T { debug_assert!(index != self.pos); debug_assert!(index < self.data.len()); + // SAFETY: Untriaged. unsafe { self.data.get_unchecked(index) } } @@ -1569,6 +1574,7 @@ impl<'a, T> Hole<'a, T> { unsafe fn move_to(&mut self, index: usize) { debug_assert!(index != self.pos); debug_assert!(index < self.data.len()); + // SAFETY: Untriaged. unsafe { let ptr = self.data.as_mut_ptr(); let index_ptr: *const _ = ptr.add(index); @@ -1583,6 +1589,7 @@ impl Drop for Hole<'_, T> { #[inline] fn drop(&mut self) { // fill the hole again + // SAFETY: Untriaged. unsafe { let pos = self.pos; ptr::copy_nonoverlapping(&*self.elt, self.data.get_unchecked_mut(pos), 1); diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 0a1f7738632c1..291b3dd42170a 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -205,6 +205,7 @@ pub struct BTreeMap< #[stable(feature = "btree_drop", since = "1.7.0")] unsafe impl<#[may_dangle] K, #[may_dangle] V, A: Allocator + Clone> Drop for BTreeMap { fn drop(&mut self) { + // SAFETY: Untriaged. drop(unsafe { ptr::read(self) }.into_iter()) } } @@ -279,6 +280,7 @@ impl Clone for BTreeMap { // We can't destructure subtree directly // because BTreeMap implements Drop + // SAFETY: Untriaged. let (subroot, sublength) = unsafe { let subtree = ManuallyDrop::new(subtree); let root = ptr::read(&subtree.root); @@ -1324,6 +1326,7 @@ impl BTreeMap { // apply 'f' to get a new (K, V), and insert it back // into the next entry that the cursor is pointing at let v = conflict(&k, v, first_other_val); + // SAFETY: Untriaged. unsafe { self_cursor.insert_after_unchecked(k, v) }; } } @@ -1360,6 +1363,7 @@ impl BTreeMap { // apply 'f' to get a new (K, V), and insert it back // into the next entry that the cursor is pointing at let v = conflict(&k, v, other_val); + // SAFETY: Untriaged. unsafe { self_cursor.insert_after_unchecked(k, v) }; } break; @@ -1737,6 +1741,7 @@ impl<'a, K: 'a, V: 'a> Iterator for Iter<'a, K, V> { None } else { self.length -= 1; + // SAFETY: Untriaged. Some(unsafe { self.range.next_unchecked() }) } } @@ -1774,6 +1779,7 @@ impl<'a, K: 'a, V: 'a> DoubleEndedIterator for Iter<'a, K, V> { None } else { self.length -= 1; + // SAFETY: Untriaged. Some(unsafe { self.range.next_back_unchecked() }) } } @@ -1815,6 +1821,7 @@ impl<'a, K, V> Iterator for IterMut<'a, K, V> { None } else { self.length -= 1; + // SAFETY: Untriaged. Some(unsafe { self.range.next_unchecked() }) } } @@ -1849,6 +1856,7 @@ impl<'a, K, V> DoubleEndedIterator for IterMut<'a, K, V> { None } else { self.length -= 1; + // SAFETY: Untriaged. Some(unsafe { self.range.next_back_unchecked() }) } } @@ -1889,12 +1897,14 @@ impl IntoIterator for BTreeMap { IntoIter { range: full_range, length: me.length, + // SAFETY: Untriaged. alloc: unsafe { ManuallyDrop::take(&mut me.alloc) }, } } else { IntoIter { range: LazyLeafRange::none(), length: 0, + // SAFETY: Untriaged. alloc: unsafe { ManuallyDrop::take(&mut me.alloc) }, } } @@ -1937,6 +1947,7 @@ impl IntoIter { None } else { self.length -= 1; + // SAFETY: Untriaged. Some(unsafe { self.range.deallocating_next_unchecked(self.alloc.clone()) }) } } @@ -1951,6 +1962,7 @@ impl IntoIter { None } else { self.length -= 1; + // SAFETY: Untriaged. Some(unsafe { self.range.deallocating_next_back_unchecked(self.alloc.clone()) }) } } @@ -3347,6 +3359,7 @@ impl<'a, K, V, A> CursorMutKey<'a, K, V, A> { let (k, v) = unsafe { kv.reborrow_mut().into_kv_mut() }; let (k, v) = (k as *mut _, v as *mut _); self.current = Some(kv.next_leaf_edge()); + // SAFETY: Untriaged. Some(unsafe { (&mut *k, &mut *v) }) } Err(root) => { @@ -3372,6 +3385,7 @@ impl<'a, K, V, A> CursorMutKey<'a, K, V, A> { let (k, v) = unsafe { kv.reborrow_mut().into_kv_mut() }; let (k, v) = (k as *mut _, v as *mut _); self.current = Some(kv.next_back_leaf_edge()); + // SAFETY: Untriaged. Some(unsafe { (&mut *k, &mut *v) }) } Err(root) => { @@ -3534,6 +3548,7 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> { return Err(UnorderedKeyError {}); } } + // SAFETY: Untriaged. unsafe { self.insert_after_unchecked(key, value); } @@ -3562,6 +3577,7 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> { return Err(UnorderedKeyError {}); } } + // SAFETY: Untriaged. unsafe { self.insert_before_unchecked(key, value); } @@ -3643,6 +3659,7 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMut<'a, K, V, A> { /// * All keys in the tree must remain in sorted order. #[unstable(feature = "btree_cursors", issue = "107540")] pub unsafe fn insert_after_unchecked(&mut self, key: K, value: V) { + // SAFETY: Untriaged. unsafe { self.inner.insert_after_unchecked(key, value) } } @@ -3661,6 +3678,7 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMut<'a, K, V, A> { /// * All keys in the tree must remain in sorted order. #[unstable(feature = "btree_cursors", issue = "107540")] pub unsafe fn insert_before_unchecked(&mut self, key: K, value: V) { + // SAFETY: Untriaged. unsafe { self.inner.insert_before_unchecked(key, value) } } diff --git a/library/alloc/src/collections/btree/mem.rs b/library/alloc/src/collections/btree/mem.rs index 4643c4133d55d..674083ac6ae09 100644 --- a/library/alloc/src/collections/btree/mem.rs +++ b/library/alloc/src/collections/btree/mem.rs @@ -23,8 +23,10 @@ pub(super) fn replace(v: &mut T, change: impl FnOnce(T) -> (T, R)) -> R { } } let guard = PanicGuard; + // SAFETY: Untriaged. let value = unsafe { ptr::read(v) }; let (new_value, ret) = change(value); + // SAFETY: Untriaged. unsafe { ptr::write(v, new_value); } diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs index b2a7de74875d9..880507928d72a 100644 --- a/library/alloc/src/collections/btree/navigate.rs +++ b/library/alloc/src/collections/btree/navigate.rs @@ -57,11 +57,13 @@ impl<'a, K, V> LeafRange, K, V> { impl<'a, K, V> LeafRange, K, V> { #[inline] pub(super) fn next_checked(&mut self) -> Option<(&'a K, &'a mut V)> { + // SAFETY: Untriaged. self.perform_next_checked(|kv| unsafe { ptr::read(kv) }.into_kv_valmut()) } #[inline] pub(super) fn next_back_checked(&mut self) -> Option<(&'a K, &'a mut V)> { + // SAFETY: Untriaged. self.perform_next_back_checked(|kv| unsafe { ptr::read(kv) }.into_kv_valmut()) } } @@ -158,11 +160,13 @@ impl LazyLeafRange { impl<'a, K, V> LazyLeafRange, K, V> { #[inline] pub(super) unsafe fn next_unchecked(&mut self) -> (&'a K, &'a V) { + // SAFETY: Untriaged. unsafe { self.init_front().unwrap().next_unchecked() } } #[inline] pub(super) unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a V) { + // SAFETY: Untriaged. unsafe { self.init_back().unwrap().next_back_unchecked() } } } @@ -170,11 +174,13 @@ impl<'a, K, V> LazyLeafRange, K, V> { impl<'a, K, V> LazyLeafRange, K, V> { #[inline] pub(super) unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) { + // SAFETY: Untriaged. unsafe { self.init_front().unwrap().next_unchecked() } } #[inline] pub(super) unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) { + // SAFETY: Untriaged. unsafe { self.init_back().unwrap().next_back_unchecked() } } } @@ -196,6 +202,7 @@ impl LazyLeafRange { ) -> Handle, marker::KV> { debug_assert!(self.front.is_some()); let front = self.init_front().unwrap(); + // SAFETY: Untriaged. unsafe { front.deallocating_next_unchecked(alloc) } } @@ -206,6 +213,7 @@ impl LazyLeafRange { ) -> Handle, marker::KV> { debug_assert!(self.back.is_some()); let back = self.init_back().unwrap(); + // SAFETY: Untriaged. unsafe { back.deallocating_next_back_unchecked(alloc) } } @@ -222,6 +230,7 @@ impl LazyLeafRange { &mut self, ) -> Option<&mut Handle, marker::Edge>> { if let Some(LazyLeafHandle::Root(root)) = &self.front { + // SAFETY: Untriaged. self.front = Some(LazyLeafHandle::Edge(unsafe { ptr::read(root) }.first_leaf_edge())); } match &mut self.front { @@ -236,6 +245,7 @@ impl LazyLeafRange { &mut self, ) -> Option<&mut Handle, marker::Edge>> { if let Some(LazyLeafHandle::Root(root)) = &self.back { + // SAFETY: Untriaged. self.back = Some(LazyLeafHandle::Edge(unsafe { ptr::read(root) }.last_leaf_edge())); } match &mut self.back { @@ -279,7 +289,9 @@ impl NodeRef { + // SAFETY: Untriaged. let mut lower_edge = unsafe { Handle::new_edge(ptr::read(&node), lower_edge_idx) }; + // SAFETY: Untriaged. let mut upper_edge = unsafe { Handle::new_edge(node, upper_edge_idx) }; loop { match (lower_edge.force(), upper_edge.force()) { @@ -345,6 +357,7 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> K: Borrow, R: RangeBounds, { + // SAFETY: Untriaged. unsafe { self.find_leaf_edges_spanning_range(range) } } @@ -354,6 +367,7 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> pub(super) fn full_range(self) -> LazyLeafRange, K, V> { // We duplicate the root NodeRef here -- we will never visit the same KV // twice, and never end up with overlapping value references. + // SAFETY: Untriaged. let self2 = unsafe { ptr::read(&self) }; full_range(self, self2) } @@ -366,6 +380,7 @@ impl NodeRef { pub(super) fn full_range(self) -> LazyLeafRange { // We duplicate the root NodeRef here -- we will never access it in a way // that overlaps references obtained from the root. + // SAFETY: Untriaged. let self2 = unsafe { ptr::read(&self) }; full_range(self, self2) } @@ -464,8 +479,10 @@ impl Handle, marker::Edge> { let mut edge = self.forget_node_type(); loop { edge = match edge.right_kv() { + // SAFETY: Untriaged. Ok(kv) => return Some((unsafe { ptr::read(&kv) }.next_leaf_edge(), kv)), Err(last_edge) => { + // SAFETY: Untriaged. match unsafe { last_edge.into_node().deallocate_and_ascend(alloc.clone()) } { Some(parent_edge) => parent_edge.forget_node_type(), None => return None, @@ -496,8 +513,10 @@ impl Handle, marker::Edge> { let mut edge = self.forget_node_type(); loop { edge = match edge.left_kv() { + // SAFETY: Untriaged. Ok(kv) => return Some((unsafe { ptr::read(&kv) }.next_back_leaf_edge(), kv)), Err(last_edge) => { + // SAFETY: Untriaged. match unsafe { last_edge.into_node().deallocate_and_ascend(alloc.clone()) } { Some(parent_edge) => parent_edge.forget_node_type(), None => return None, @@ -516,6 +535,7 @@ impl Handle, marker::Edge> { fn deallocating_end(self, alloc: A) { let mut edge = self.forget_node_type(); while let Some(parent_edge) = + // SAFETY: Untriaged. unsafe { edge.into_node().deallocate_and_ascend(alloc.clone()) } { edge = parent_edge.forget_node_type(); @@ -558,6 +578,7 @@ impl<'a, K, V> Handle, K, V, marker::Leaf>, marker::E unsafe fn next_unchecked(&mut self) -> (&'a K, &'a mut V) { let kv = super::mem::replace(self, |leaf_edge| { let kv = leaf_edge.next_kv().ok().unwrap(); + // SAFETY: Untriaged. (unsafe { ptr::read(&kv) }.next_leaf_edge(), kv) }); // Doing this last is faster, according to benchmarks. @@ -572,6 +593,7 @@ impl<'a, K, V> Handle, K, V, marker::Leaf>, marker::E unsafe fn next_back_unchecked(&mut self) -> (&'a K, &'a mut V) { let kv = super::mem::replace(self, |leaf_edge| { let kv = leaf_edge.next_back_kv().ok().unwrap(); + // SAFETY: Untriaged. (unsafe { ptr::read(&kv) }.next_back_leaf_edge(), kv) }); // Doing this last is faster, according to benchmarks. @@ -596,6 +618,7 @@ impl Handle, marker::Edge> { &mut self, alloc: A, ) -> Handle, marker::KV> { + // SAFETY: Untriaged. super::mem::replace(self, |leaf_edge| unsafe { leaf_edge.deallocating_next(alloc).unwrap() }) @@ -617,6 +640,7 @@ impl Handle, marker::Edge> { &mut self, alloc: A, ) -> Handle, marker::KV> { + // SAFETY: Untriaged. super::mem::replace(self, |leaf_edge| unsafe { leaf_edge.deallocating_next_back(alloc).unwrap() }) diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index 84dd4b7e49def..6ba7042b389ad 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -75,6 +75,7 @@ impl LeafNode { unsafe fn init(this: *mut Self) { // As a general policy, we leave fields uninitialized if they can be, as this should // be both slightly faster and easier to track in Valgrind. + // SAFETY: Untriaged. unsafe { // parent_idx, keys, and vals are all MaybeUninit (&raw mut (*this).parent).write(None); @@ -85,6 +86,7 @@ impl LeafNode { /// Creates a new boxed `LeafNode`. fn new(alloc: A) -> Box { let mut leaf = Box::new_uninit_in(alloc); + // SAFETY: Untriaged. unsafe { // SAFETY: `leaf` points to a `LeafNode` LeafNode::init(leaf.as_mut_ptr()); @@ -119,6 +121,7 @@ impl InternalNode { /// such an edge. unsafe fn new(alloc: A) -> Box { let mut node = Box::::new_uninit_in(alloc); + // SAFETY: Untriaged. unsafe { // SAFETY: argument points to the `node.data` `LeafNode` LeafNode::init(&raw mut (*node.as_mut_ptr()).data); @@ -235,6 +238,7 @@ impl NodeRef { impl NodeRef { /// Creates a new internal (height > 0) `NodeRef` fn new_internal(child: Root, alloc: A) -> Self { + // SAFETY: Untriaged. let mut new_node = unsafe { InternalNode::new(alloc) }; new_node.edges[0].write(child.node); NodeRef::from_new_internal(new_node, NonZero::new(child.height + 1).unwrap()) @@ -275,6 +279,7 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { /// Borrows exclusive access to the data of an internal node. fn as_internal_mut(&mut self) -> &mut InternalNode { let ptr = Self::as_internal_ptr(self); + // SAFETY: Untriaged. unsafe { &mut *ptr } } } @@ -287,6 +292,7 @@ impl NodeRef { pub(super) fn len(&self) -> usize { // Crucially, we only access the `len` field here. If BorrowType is marker::ValMut, // there might be outstanding mutable references to values that we must not invalidate. + // SAFETY: Untriaged. unsafe { usize::from((*Self::as_leaf_ptr(self)).len) } } @@ -335,10 +341,12 @@ impl NodeRef // We need to use raw pointers to nodes because, if BorrowType is marker::ValMut, // there might be outstanding mutable references to values that we must not invalidate. let leaf_ptr: *const _ = Self::as_leaf_ptr(&self); + // SAFETY: Untriaged. unsafe { (*leaf_ptr).parent } .as_ref() .map(|parent| Handle { node: NodeRef::from_internal(*parent, self.height + 1), + // SAFETY: Untriaged. idx: unsafe { usize::from((*leaf_ptr).parent_idx.assume_init()) }, _marker: PhantomData, }) @@ -346,11 +354,13 @@ impl NodeRef } pub(super) fn first_edge(self) -> Handle { + // SAFETY: Untriaged. unsafe { Handle::new_edge(self, 0) } } pub(super) fn last_edge(self) -> Handle { let len = self.len(); + // SAFETY: Untriaged. unsafe { Handle::new_edge(self, len) } } @@ -358,6 +368,7 @@ impl NodeRef pub(super) fn first_kv(self) -> Handle { let len = self.len(); assert!(len > 0); + // SAFETY: Untriaged. unsafe { Handle::new_kv(self, 0) } } @@ -365,6 +376,7 @@ impl NodeRef pub(super) fn last_kv(self) -> Handle { let len = self.len(); assert!(len > 0); + // SAFETY: Untriaged. unsafe { Handle::new_kv(self, len - 1) } } } @@ -393,6 +405,7 @@ impl<'a, K: 'a, V: 'a, Type> NodeRef, K, V, Type> { /// Borrows a view into the keys stored in the node. pub(super) fn keys(&self) -> &[K] { let leaf = self.into_leaf(); + // SAFETY: Untriaged. unsafe { leaf.keys.get_unchecked(..usize::from(leaf.len)).assume_init_ref() } } } @@ -408,6 +421,7 @@ impl NodeRef { let height = self.height; let node = self.node; let ret = self.ascend().ok(); + // SAFETY: Untriaged. unsafe { alloc.deallocate( node.cast(), @@ -533,12 +547,16 @@ impl<'a, K, V, Type> NodeRef, K, V, Type> { // to avoid aliasing with outstanding references to other elements, // in particular, those returned to the caller in earlier iterations. let leaf = Self::as_leaf_ptr(&mut self); + // SAFETY: Untriaged. let keys = unsafe { &raw const (*leaf).keys }; + // SAFETY: Untriaged. let vals = unsafe { &raw mut (*leaf).vals }; // We must coerce to unsized array pointers because of Rust issue #74679. let keys: *const [_] = keys; let vals: *mut [_] = vals; + // SAFETY: Untriaged. let key = unsafe { (&*keys.get_unchecked(idx)).assume_init_ref() }; + // SAFETY: Untriaged. let val = unsafe { (&mut *vals.get_unchecked_mut(idx)).assume_init_mut() }; (key, val) } @@ -557,12 +575,14 @@ impl<'a, K, V> NodeRef, K, V, marker::Internal> { unsafe fn correct_childrens_parent_links>(&mut self, range: R) { for i in range { debug_assert!(i <= self.len()); + // SAFETY: Untriaged. unsafe { Handle::new_edge(self.reborrow_mut(), i) }.correct_parent_link(); } } fn correct_all_childrens_parent_links(&mut self) { let len = self.len(); + // SAFETY: Untriaged. unsafe { self.correct_childrens_parent_links(0..=len) }; } } @@ -572,7 +592,9 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::LeafOrInternal> { /// without invalidating other references to the node. fn set_parent_link(&mut self, parent: NonNull>, parent_idx: usize) { let leaf = Self::as_leaf_ptr(self); + // SAFETY: Untriaged. unsafe { (*leaf).parent = Some(parent) }; + // SAFETY: Untriaged. unsafe { (*leaf).parent_idx.write(parent_idx as u16) }; } } @@ -627,6 +649,7 @@ impl NodeRef { self.height -= 1; self.clear_parent_link(); + // SAFETY: Untriaged. unsafe { alloc.deallocate(top.cast(), Layout::new::>()); } @@ -669,6 +692,7 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Leaf> { let idx = usize::from(*len); assert!(idx < CAPACITY); *len += 1; + // SAFETY: Untriaged. unsafe { self.key_area_mut(idx).write(key); self.val_area_mut(idx).write(val); @@ -697,6 +721,7 @@ impl<'a, K: 'a, V: 'a> NodeRef, K, V, marker::Internal> { let idx = usize::from(*len); assert!(idx < CAPACITY); *len += 1; + // SAFETY: Untriaged. unsafe { self.key_area_mut(idx).write(key); self.val_area_mut(idx).write(val); @@ -805,10 +830,12 @@ impl Handle, mar } pub(super) fn left_edge(self) -> Handle, marker::Edge> { + // SAFETY: Untriaged. unsafe { Handle::new_edge(self.node, self.idx) } } pub(super) fn right_edge(self) -> Handle, marker::Edge> { + // SAFETY: Untriaged. unsafe { Handle::new_edge(self.node, self.idx + 1) } } } @@ -844,6 +871,7 @@ impl<'a, K, V, NodeType, HandleType> Handle, K, V, NodeT &mut self, ) -> Handle, K, V, NodeType>, HandleType> { // We can't use Handle::new_kv or Handle::new_edge because we don't know our type + // SAFETY: Untriaged. Handle { node: unsafe { self.node.reborrow_mut() }, idx: self.idx, _marker: PhantomData } } @@ -867,6 +895,7 @@ impl Handle( self, ) -> Handle, K, V, NodeType>, HandleType> { + // SAFETY: Untriaged. Handle { node: unsafe { self.node.awaken() }, idx: self.idx, _marker: PhantomData } } } @@ -884,6 +913,7 @@ impl Handle, mar self, ) -> Result, marker::KV>, Self> { if self.idx > 0 { + // SAFETY: Untriaged. Ok(unsafe { Handle::new_kv(self.node, self.idx - 1) }) } else { Err(self) @@ -894,6 +924,7 @@ impl Handle, mar self, ) -> Result, marker::KV>, Self> { if self.idx < self.node.len() { + // SAFETY: Untriaged. Ok(unsafe { Handle::new_kv(self.node, self.idx) }) } else { Err(self) @@ -934,6 +965,7 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, mark debug_assert!(self.node.len() < CAPACITY); let new_len = self.node.len() + 1; + // SAFETY: Untriaged. unsafe { slice_insert(self.node.key_area_mut(..new_len), self.idx, key); slice_insert(self.node.val_area_mut(..new_len), self.idx, val); @@ -965,12 +997,15 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, mark (None, handle.dormant()) } else { let (middle_kv_idx, insertion) = splitpoint(self.idx); + // SAFETY: Untriaged. let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) }; let mut result = middle.split(alloc); let insertion_edge = match insertion { + // SAFETY: Untriaged. LeftOrRight::Left(insert_idx) => unsafe { Handle::new_edge(result.left.reborrow_mut(), insert_idx) }, + // SAFETY: Untriaged. LeftOrRight::Right(insert_idx) => unsafe { Handle::new_edge(result.right.borrow_mut(), insert_idx) }, @@ -988,6 +1023,7 @@ impl<'a, K, V> Handle, K, V, marker::Internal>, marker:: /// links to. This is useful when the ordering of edges has been changed, fn correct_parent_link(self) { // Create backpointer without invalidating other references to the node. + // SAFETY: Untriaged. let ptr = unsafe { NonNull::new_unchecked(NodeRef::as_internal_ptr(&self.node)) }; let idx = self.idx; let mut child = self.descend(); @@ -1004,6 +1040,7 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Internal>, debug_assert!(edge.height == self.node.height - 1); let new_len = self.node.len() + 1; + // SAFETY: Untriaged. unsafe { slice_insert(self.node.key_area_mut(..new_len), self.idx, key); slice_insert(self.node.val_area_mut(..new_len), self.idx, val); @@ -1031,12 +1068,15 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Internal>, None } else { let (middle_kv_idx, insertion) = splitpoint(self.idx); + // SAFETY: Untriaged. let middle = unsafe { Handle::new_kv(self.node, middle_kv_idx) }; let mut result = middle.split(alloc); let mut insertion_edge = match insertion { + // SAFETY: Untriaged. LeftOrRight::Left(insert_idx) => unsafe { Handle::new_edge(result.left.reborrow_mut(), insert_idx) }, + // SAFETY: Untriaged. LeftOrRight::Right(insert_idx) => unsafe { Handle::new_edge(result.right.borrow_mut(), insert_idx) }, @@ -1112,6 +1152,7 @@ impl // reference (Rust issue #73987) and invalidate any other references // to or inside the array, should any be around. let parent_ptr = NodeRef::as_internal_ptr(&self.node); + // SAFETY: Untriaged. let node = unsafe { (*parent_ptr).edges.get_unchecked(self.idx).assume_init_read() }; NodeRef { node, height: self.node.height - 1, _marker: PhantomData } } @@ -1121,7 +1162,9 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeTyp pub(super) fn into_kv(self) -> (&'a K, &'a V) { debug_assert!(self.idx < self.node.len()); let leaf = self.node.into_leaf(); + // SAFETY: Untriaged. let k = unsafe { leaf.keys.get_unchecked(self.idx).assume_init_ref() }; + // SAFETY: Untriaged. let v = unsafe { leaf.vals.get_unchecked(self.idx).assume_init_ref() }; (k, v) } @@ -1129,19 +1172,23 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeTyp impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeType>, marker::KV> { pub(super) fn key_mut(&mut self) -> &mut K { + // SAFETY: Untriaged. unsafe { self.node.key_area_mut(self.idx).assume_init_mut() } } pub(super) fn into_val_mut(self) -> &'a mut V { debug_assert!(self.idx < self.node.len()); let leaf = self.node.into_leaf_mut(); + // SAFETY: Untriaged. unsafe { leaf.vals.get_unchecked_mut(self.idx).assume_init_mut() } } pub(super) fn into_kv_mut(self) -> (&'a mut K, &'a mut V) { debug_assert!(self.idx < self.node.len()); let leaf = self.node.into_leaf_mut(); + // SAFETY: Untriaged. let k = unsafe { leaf.keys.get_unchecked_mut(self.idx).assume_init_mut() }; + // SAFETY: Untriaged. let v = unsafe { leaf.vals.get_unchecked_mut(self.idx).assume_init_mut() }; (k, v) } @@ -1149,6 +1196,7 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeType> impl<'a, K, V, NodeType> Handle, K, V, NodeType>, marker::KV> { pub(super) fn into_kv_valmut(self) -> (&'a K, &'a mut V) { + // SAFETY: Untriaged. unsafe { self.node.into_key_val_mut_at(self.idx) } } } @@ -1158,6 +1206,7 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeType> debug_assert!(self.idx < self.node.len()); // We cannot call separate key and value methods, because calling the second one // invalidates the reference returned by the first. + // SAFETY: Untriaged. unsafe { let leaf = self.node.as_leaf_mut(); let key = leaf.keys.get_unchecked_mut(self.idx).assume_init_mut(); @@ -1180,6 +1229,7 @@ impl Handle, marker::KV> pub(super) unsafe fn into_key_val(mut self) -> (K, V) { debug_assert!(self.idx < self.node.len()); let leaf = self.node.as_leaf_dying(); + // SAFETY: Untriaged. unsafe { let key = leaf.keys.get_unchecked_mut(self.idx).assume_init_read(); let val = leaf.vals.get_unchecked_mut(self.idx).assume_init_read(); @@ -1197,6 +1247,7 @@ impl Handle, marker::KV> impl Drop for Dropper<'_, T> { #[inline] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { self.0.assume_init_drop(); } @@ -1205,6 +1256,7 @@ impl Handle, marker::KV> debug_assert!(self.idx < self.node.len()); let leaf = self.node.as_leaf_dying(); + // SAFETY: Untriaged. unsafe { let key = leaf.keys.get_unchecked_mut(self.idx); let val = leaf.vals.get_unchecked_mut(self.idx); @@ -1223,6 +1275,7 @@ impl<'a, K: 'a, V: 'a, NodeType> Handle, K, V, NodeType> let old_len = self.node.len(); let new_len = old_len - self.idx - 1; new_node.len = new_len as u16; + // SAFETY: Untriaged. unsafe { let k = self.node.key_area_mut(self.idx).assume_init_read(); let v = self.node.val_area_mut(self.idx).assume_init_read(); @@ -1268,6 +1321,7 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, mark mut self, ) -> ((K, V), Handle, K, V, marker::Leaf>, marker::Edge>) { let old_len = self.node.len(); + // SAFETY: Untriaged. unsafe { let k = slice_remove(self.node.key_area_mut(..old_len), self.idx); let v = slice_remove(self.node.val_area_mut(..old_len), self.idx); @@ -1290,6 +1344,7 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Internal>, alloc: A, ) -> SplitResult<'a, K, V, marker::Internal> { let old_len = self.node.len(); + // SAFETY: Untriaged. unsafe { let mut new_node = InternalNode::new(alloc); let kv = self.split_leaf_data(&mut new_node.data); @@ -1318,7 +1373,9 @@ pub(super) struct BalancingContext<'a, K, V> { impl<'a, K, V> Handle, K, V, marker::Internal>, marker::KV> { pub(super) fn consider_for_balancing(self) -> BalancingContext<'a, K, V> { + // SAFETY: Untriaged. let self1 = unsafe { ptr::read(&self) }; + // SAFETY: Untriaged. let self2 = unsafe { ptr::read(&self) }; BalancingContext { parent: self, @@ -1344,15 +1401,18 @@ impl<'a, K, V> NodeRef, K, V, marker::LeafOrInternal> { /// the right, instead of shifting at least N of the sibling's elements to /// the left. pub(super) fn choose_parent_kv(self) -> Result>, Self> { + // SAFETY: Untriaged. match unsafe { ptr::read(&self) }.ascend() { Ok(parent_edge) => match parent_edge.left_kv() { Ok(left_parent_kv) => Ok(LeftOrRight::Left(BalancingContext { + // SAFETY: Untriaged. parent: unsafe { ptr::read(&left_parent_kv) }, left_child: left_parent_kv.left_edge().descend(), right_child: self, })), Err(parent_edge) => match parent_edge.right_kv() { Ok(right_parent_kv) => Ok(LeftOrRight::Right(BalancingContext { + // SAFETY: Untriaged. parent: unsafe { ptr::read(&right_parent_kv) }, left_child: self, right_child: right_parent_kv.right_edge().descend(), @@ -1413,6 +1473,7 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { assert!(new_left_len <= CAPACITY); + // SAFETY: Untriaged. unsafe { *left_node.len_mut() = new_left_len as u16; @@ -1497,6 +1558,7 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { LeftOrRight::Left(idx) => idx, LeftOrRight::Right(idx) => old_left_len + 1 + idx, }; + // SAFETY: Untriaged. unsafe { Handle::new_edge(child, new_idx) } } @@ -1509,6 +1571,7 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { track_right_edge_idx: usize, ) -> Handle, K, V, marker::LeafOrInternal>, marker::Edge> { self.bulk_steal_left(1); + // SAFETY: Untriaged. unsafe { Handle::new_edge(self.right_child, 1 + track_right_edge_idx) } } @@ -1521,12 +1584,14 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { track_left_edge_idx: usize, ) -> Handle, K, V, marker::LeafOrInternal>, marker::Edge> { self.bulk_steal_right(1); + // SAFETY: Untriaged. unsafe { Handle::new_edge(self.left_child, track_left_edge_idx) } } /// This does stealing similar to `steal_left` but steals multiple elements at once. pub(super) fn bulk_steal_left(&mut self, count: usize) { assert!(count > 0); + // SAFETY: Untriaged. unsafe { let left_node = &mut self.left_child; let old_left_len = left_node.len(); @@ -1590,6 +1655,7 @@ impl<'a, K: 'a, V: 'a> BalancingContext<'a, K, V> { /// The symmetric clone of `bulk_steal_left`. pub(super) fn bulk_steal_right(&mut self, count: usize) { assert!(count > 0); + // SAFETY: Untriaged. unsafe { let left_node = &mut self.left_child; let old_left_len = left_node.len(); @@ -1656,6 +1722,7 @@ impl Handle, marker::E pub(super) fn forget_node_type( self, ) -> Handle, marker::Edge> { + // SAFETY: Untriaged. unsafe { Handle::new_edge(self.node.forget_type(), self.idx) } } } @@ -1664,6 +1731,7 @@ impl Handle, marke pub(super) fn forget_node_type( self, ) -> Handle, marker::Edge> { + // SAFETY: Untriaged. unsafe { Handle::new_edge(self.node.forget_type(), self.idx) } } } @@ -1672,6 +1740,7 @@ impl Handle, marker::K pub(super) fn forget_node_type( self, ) -> Handle, marker::KV> { + // SAFETY: Untriaged. unsafe { Handle::new_kv(self.node.forget_type(), self.idx) } } } @@ -1700,6 +1769,7 @@ impl<'a, K, V, Type> Handle, K, V, marker::LeafOrInterna pub(super) unsafe fn cast_to_leaf_unchecked( self, ) -> Handle, K, V, marker::Leaf>, Type> { + // SAFETY: Untriaged. let node = unsafe { self.node.cast_to_leaf_unchecked() }; Handle { node, idx: self.idx, _marker: PhantomData } } @@ -1712,6 +1782,7 @@ impl<'a, K, V> Handle, K, V, marker::LeafOrInternal>, ma &mut self, right: &mut NodeRef, K, V, marker::LeafOrInternal>, ) { + // SAFETY: Untriaged. unsafe { let new_left_len = self.idx; let mut left_node = self.reborrow_mut().into_node(); @@ -1820,6 +1891,7 @@ pub(super) mod marker { /// # Safety /// The slice has more than `idx` elements. unsafe fn slice_insert(slice: &mut [MaybeUninit], idx: usize, val: T) { + // SAFETY: Untriaged. unsafe { let len = slice.len(); debug_assert!(len > idx); @@ -1837,6 +1909,7 @@ unsafe fn slice_insert(slice: &mut [MaybeUninit], idx: usize, val: T) { /// # Safety /// The slice has more than `idx` elements. unsafe fn slice_remove(slice: &mut [MaybeUninit], idx: usize) -> T { + // SAFETY: Untriaged. unsafe { let len = slice.len(); debug_assert!(idx < len); @@ -1852,6 +1925,7 @@ unsafe fn slice_remove(slice: &mut [MaybeUninit], idx: usize) -> T { /// # Safety /// The slice has at least `distance` elements. unsafe fn slice_shl(slice: &mut [MaybeUninit], distance: usize) { + // SAFETY: Untriaged. unsafe { let slice_ptr = slice.as_mut_ptr(); ptr::copy(slice_ptr.add(distance), slice_ptr, slice.len() - distance); @@ -1863,6 +1937,7 @@ unsafe fn slice_shl(slice: &mut [MaybeUninit], distance: usize) { /// # Safety /// The slice has at least `distance` elements. unsafe fn slice_shr(slice: &mut [MaybeUninit], distance: usize) { + // SAFETY: Untriaged. unsafe { let slice_ptr = slice.as_mut_ptr(); ptr::copy(slice_ptr, slice_ptr.add(distance), slice.len() - distance); @@ -1874,6 +1949,7 @@ unsafe fn slice_shr(slice: &mut [MaybeUninit], distance: usize) { /// Works like `dst.copy_from_slice(src)` but does not require `T` to be `Copy`. fn move_to_slice(src: &mut [MaybeUninit], dst: &mut [MaybeUninit]) { assert!(src.len() == dst.len()); + // SAFETY: Untriaged. unsafe { ptr::copy_nonoverlapping(src.as_ptr(), dst.as_mut_ptr(), src.len()); } diff --git a/library/alloc/src/collections/btree/remove.rs b/library/alloc/src/collections/btree/remove.rs index 9d870b86f34a0..81344631d007f 100644 --- a/library/alloc/src/collections/btree/remove.rs +++ b/library/alloc/src/collections/btree/remove.rs @@ -53,6 +53,7 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Leaf>, mark right_parent_kv.steal_right(idx) } } + // SAFETY: Untriaged. Err(pos) => unsafe { Handle::new_edge(pos, idx) }, }; // SAFETY: `new_pos` is the leaf we started from or a sibling. @@ -85,11 +86,13 @@ impl<'a, K: 'a, V: 'a> Handle, K, V, marker::Internal>, // the element we were asked to remove. Prefer the left adjacent KV, // for the reasons listed in `choose_parent_kv`. let left_leaf_kv = self.left_edge().descend().last_leaf_edge().left_kv(); + // SAFETY: Untriaged. let left_leaf_kv = unsafe { left_leaf_kv.ok().unwrap_unchecked() }; let (left_kv, left_hole) = left_leaf_kv.remove_leaf_kv(handle_emptied_internal_root, alloc); // The internal node may have been stolen from or merged. Go back right // to find where the original KV ended up. + // SAFETY: Untriaged. let mut internal = unsafe { left_hole.next_kv().ok().unwrap_unchecked() }; let old_kv = internal.replace_kv(left_kv.0, left_kv.1); let pos = internal.next_leaf_edge(); diff --git a/library/alloc/src/collections/btree/search.rs b/library/alloc/src/collections/btree/search.rs index 96e5bf108024b..ebc61a2dc0b18 100644 --- a/library/alloc/src/collections/btree/search.rs +++ b/library/alloc/src/collections/btree/search.rs @@ -128,6 +128,7 @@ impl NodeRef NodeRef return Err(common_edge), @@ -165,6 +167,7 @@ impl NodeRef, { let (edge_idx, bound) = self.find_lower_bound_index(bound); + // SAFETY: Untriaged. let edge = unsafe { Handle::new_edge(self, edge_idx) }; (edge, bound) } @@ -178,7 +181,9 @@ impl NodeRef, { + // SAFETY: Untriaged. let (edge_idx, bound) = unsafe { self.find_upper_bound_index(bound, 0) }; + // SAFETY: Untriaged. let edge = unsafe { Handle::new_edge(self, edge_idx) }; (edge, bound) } @@ -200,8 +205,11 @@ impl NodeRef { Q: Ord, K: Borrow, { + // SAFETY: Untriaged. match unsafe { self.find_key_index(key, 0) } { + // SAFETY: Untriaged. IndexResult::KV(idx) => Found(unsafe { Handle::new_kv(self, idx) }), + // SAFETY: Untriaged. IndexResult::Edge(idx) => GoDown(unsafe { Handle::new_edge(self, idx) }), } } @@ -222,6 +230,7 @@ impl NodeRef { let node = self.reborrow(); let keys = node.keys(); debug_assert!(start_index <= keys.len()); + // SAFETY: Untriaged. for (offset, k) in unsafe { keys.get_unchecked(start_index..) }.iter().enumerate() { match key.cmp(k.borrow()) { Ordering::Greater => {} @@ -246,10 +255,12 @@ impl NodeRef { K: Borrow, { match bound { + // SAFETY: Untriaged. Included(key) => match unsafe { self.find_key_index(key, 0) } { IndexResult::KV(idx) => (idx, AllExcluded), IndexResult::Edge(idx) => (idx, bound), }, + // SAFETY: Untriaged. Excluded(key) => match unsafe { self.find_key_index(key, 0) } { IndexResult::KV(idx) => (idx + 1, AllIncluded), IndexResult::Edge(idx) => (idx, bound), @@ -274,10 +285,12 @@ impl NodeRef { K: Borrow, { match bound { + // SAFETY: Untriaged. Included(key) => match unsafe { self.find_key_index(key, start_index) } { IndexResult::KV(idx) => (idx + 1, AllExcluded), IndexResult::Edge(idx) => (idx, bound), }, + // SAFETY: Untriaged. Excluded(key) => match unsafe { self.find_key_index(key, start_index) } { IndexResult::KV(idx) => (idx, AllIncluded), IndexResult::Edge(idx) => (idx, bound), diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs index 2a483b3d3982e..717661ead0356 100644 --- a/library/alloc/src/collections/btree/set.rs +++ b/library/alloc/src/collections/btree/set.rs @@ -2303,6 +2303,7 @@ impl<'a, T, A> CursorMut<'a, T, A> { /// * All elements in the tree must remain in sorted order. #[unstable(feature = "btree_cursors", issue = "107540")] pub unsafe fn with_mutable_key(self) -> CursorMutKey<'a, T, A> { + // SAFETY: Untriaged. CursorMutKey { inner: unsafe { self.inner.with_mutable_key() } } } } @@ -2372,6 +2373,7 @@ impl<'a, T: Ord, A: Allocator + Clone> CursorMut<'a, T, A> { /// * All elements in the tree must remain in sorted order. #[unstable(feature = "btree_cursors", issue = "107540")] pub unsafe fn insert_after_unchecked(&mut self, value: T) { + // SAFETY: Untriaged. unsafe { self.inner.insert_after_unchecked(value, SetValZST) } } @@ -2390,6 +2392,7 @@ impl<'a, T: Ord, A: Allocator + Clone> CursorMut<'a, T, A> { /// * All elements in the tree must remain in sorted order. #[unstable(feature = "btree_cursors", issue = "107540")] pub unsafe fn insert_before_unchecked(&mut self, value: T) { + // SAFETY: Untriaged. unsafe { self.inner.insert_before_unchecked(value, SetValZST) } } @@ -2458,6 +2461,7 @@ impl<'a, T: Ord, A: Allocator + Clone> CursorMutKey<'a, T, A> { /// * All elements in the tree must remain in sorted order. #[unstable(feature = "btree_cursors", issue = "107540")] pub unsafe fn insert_after_unchecked(&mut self, value: T) { + // SAFETY: Untriaged. unsafe { self.inner.insert_after_unchecked(value, SetValZST) } } @@ -2476,6 +2480,7 @@ impl<'a, T: Ord, A: Allocator + Clone> CursorMutKey<'a, T, A> { /// * All elements in the tree must remain in sorted order. #[unstable(feature = "btree_cursors", issue = "107540")] pub unsafe fn insert_before_unchecked(&mut self, value: T) { + // SAFETY: Untriaged. unsafe { self.inner.insert_before_unchecked(value, SetValZST) } } diff --git a/library/alloc/src/collections/linked_list.rs b/library/alloc/src/collections/linked_list.rs index ca3b2eab30402..6547ed6332ea2 100644 --- a/library/alloc/src/collections/linked_list.rs +++ b/library/alloc/src/collections/linked_list.rs @@ -173,6 +173,7 @@ impl LinkedList { unsafe fn push_front_node(&mut self, node: NonNull>) { // This method takes care not to create mutable references to whole nodes, // to maintain validity of aliasing pointers into `element`. + // SAFETY: Untriaged. unsafe { (*node.as_ptr()).next = self.head; (*node.as_ptr()).prev = None; @@ -194,6 +195,7 @@ impl LinkedList { fn pop_front_node(&mut self) -> Option, &A>> { // This method takes care not to create mutable references to whole nodes, // to maintain validity of aliasing pointers into `element`. + // SAFETY: Untriaged. self.head.map(|node| unsafe { let node = Box::from_raw_in(node.as_ptr(), &self.alloc); self.head = node.next; @@ -218,6 +220,7 @@ impl LinkedList { unsafe fn push_back_node(&mut self, node: NonNull>) { // This method takes care not to create mutable references to whole nodes, // to maintain validity of aliasing pointers into `element`. + // SAFETY: Untriaged. unsafe { (*node.as_ptr()).next = None; (*node.as_ptr()).prev = self.tail; @@ -239,6 +242,7 @@ impl LinkedList { fn pop_back_node(&mut self) -> Option, &A>> { // This method takes care not to create mutable references to whole nodes, // to maintain validity of aliasing pointers into `element`. + // SAFETY: Untriaged. self.tail.map(|node| unsafe { let node = Box::from_raw_in(node.as_ptr(), &self.alloc); self.tail = node.prev; @@ -262,16 +266,19 @@ impl LinkedList { /// maintain validity of aliasing pointers. #[inline] unsafe fn unlink_node(&mut self, mut node: NonNull>) { + // SAFETY: Untriaged. let node = unsafe { node.as_mut() }; // this one is ours now, we can create an &mut. // Not creating new mutable (unique!) references overlapping `element`. match node.prev { + // SAFETY: Untriaged. Some(prev) => unsafe { (*prev.as_ptr()).next = node.next }, // this node is the head node None => self.head = node.next, }; match node.next { + // SAFETY: Untriaged. Some(next) => unsafe { (*next.as_ptr()).prev = node.prev }, // this node is the tail node None => self.tail = node.prev, @@ -295,6 +302,7 @@ impl LinkedList { // This method takes care not to create multiple mutable references to whole nodes at the same time, // to maintain validity of aliasing pointers into `element`. if let Some(mut existing_prev) = existing_prev { + // SAFETY: Untriaged. unsafe { existing_prev.as_mut().next = Some(splice_start); } @@ -302,12 +310,14 @@ impl LinkedList { self.head = Some(splice_start); } if let Some(mut existing_next) = existing_next { + // SAFETY: Untriaged. unsafe { existing_next.as_mut().prev = Some(splice_end); } } else { self.tail = Some(splice_end); } + // SAFETY: Untriaged. unsafe { splice_start.as_mut().prev = existing_prev; splice_end.as_mut().next = existing_next; @@ -346,10 +356,12 @@ impl LinkedList { if let Some(mut split_node) = split_node { let first_part_head; let first_part_tail; + // SAFETY: Untriaged. unsafe { first_part_tail = split_node.as_mut().prev.take(); } if let Some(mut tail) = first_part_tail { + // SAFETY: Untriaged. unsafe { tail.as_mut().next = None; } @@ -390,10 +402,12 @@ impl LinkedList { if let Some(mut split_node) = split_node { let second_part_head; let second_part_tail; + // SAFETY: Untriaged. unsafe { second_part_head = split_node.as_mut().next.take(); } if let Some(mut head) = second_part_head { + // SAFETY: Untriaged. unsafe { head.as_mut().prev = None; } @@ -485,6 +499,7 @@ impl LinkedList { // `as_mut` is okay here because we have exclusive access to the entirety // of both lists. if let Some(mut other_head) = other.head.take() { + // SAFETY: Untriaged. unsafe { tail.as_mut().next = Some(other_head); other_head.as_mut().prev = Some(tail); @@ -742,6 +757,7 @@ impl LinkedList { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_confusables("first")] pub fn front(&self) -> Option<&T> { + // SAFETY: Untriaged. unsafe { self.head.as_ref().map(|node| &node.as_ref().element) } } @@ -771,6 +787,7 @@ impl LinkedList { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] pub fn front_mut(&mut self) -> Option<&mut T> { + // SAFETY: Untriaged. unsafe { self.head.as_mut().map(|node| &mut node.as_mut().element) } } @@ -794,6 +811,7 @@ impl LinkedList { #[must_use] #[stable(feature = "rust1", since = "1.0.0")] pub fn back(&self) -> Option<&T> { + // SAFETY: Untriaged. unsafe { self.tail.as_ref().map(|node| &node.as_ref().element) } } @@ -822,6 +840,7 @@ impl LinkedList { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub fn back_mut(&mut self) -> Option<&mut T> { + // SAFETY: Untriaged. unsafe { self.tail.as_mut().map(|node| &mut node.as_mut().element) } } @@ -1023,6 +1042,7 @@ impl LinkedList { } iter.tail }; + // SAFETY: Untriaged. unsafe { self.split_off_after_node(split_node, at) } } @@ -1202,6 +1222,7 @@ impl<'a, T> Iterator for Iter<'a, T> { if self.len == 0 { None } else { + // SAFETY: Untriaged. self.head.map(|node| unsafe { // Need an unbound lifetime to get 'a let node = &*node.as_ptr(); @@ -1230,6 +1251,7 @@ impl<'a, T> DoubleEndedIterator for Iter<'a, T> { if self.len == 0 { None } else { + // SAFETY: Untriaged. self.tail.map(|node| unsafe { // Need an unbound lifetime to get 'a let node = &*node.as_ptr(); @@ -1270,6 +1292,7 @@ impl<'a, T> Iterator for IterMut<'a, T> { if self.len == 0 { None } else { + // SAFETY: Untriaged. self.head.map(|node| unsafe { // Need an unbound lifetime to get 'a let node = &mut *node.as_ptr(); @@ -1298,6 +1321,7 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> { if self.len == 0 { None } else { + // SAFETY: Untriaged. self.tail.map(|node| unsafe { // Need an unbound lifetime to get 'a let node = &mut *node.as_ptr(); @@ -1412,6 +1436,7 @@ impl<'a, T, A: Allocator> Cursor<'a, T, A> { self.index = 0; } // We had a previous element, so let's go to its next + // SAFETY: Untriaged. Some(current) => unsafe { self.current = current.as_ref().next; self.index += 1; @@ -1433,6 +1458,7 @@ impl<'a, T, A: Allocator> Cursor<'a, T, A> { self.index = self.list.len().saturating_sub(1); } // Have a prev. Yield it and go to the previous element. + // SAFETY: Untriaged. Some(current) => unsafe { self.current = current.as_ref().prev; self.index = self.index.checked_sub(1).unwrap_or_else(|| self.list.len()); @@ -1448,6 +1474,7 @@ impl<'a, T, A: Allocator> Cursor<'a, T, A> { #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn current(&self) -> Option<&'a T> { + // SAFETY: Untriaged. unsafe { self.current.map(|current| &(*current.as_ptr()).element) } } @@ -1459,6 +1486,7 @@ impl<'a, T, A: Allocator> Cursor<'a, T, A> { #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn peek_next(&self) -> Option<&'a T> { + // SAFETY: Untriaged. unsafe { let next = match self.current { None => self.list.head, @@ -1476,6 +1504,7 @@ impl<'a, T, A: Allocator> Cursor<'a, T, A> { #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn peek_prev(&self) -> Option<&'a T> { + // SAFETY: Untriaged. unsafe { let prev = match self.current { None => self.list.tail, @@ -1539,6 +1568,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { self.index = 0; } // We had a previous element, so let's go to its next + // SAFETY: Untriaged. Some(current) => unsafe { self.current = current.as_ref().next; self.index += 1; @@ -1560,6 +1590,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { self.index = self.list.len().saturating_sub(1); } // Have a prev. Yield it and go to the previous element. + // SAFETY: Untriaged. Some(current) => unsafe { self.current = current.as_ref().prev; self.index = self.index.checked_sub(1).unwrap_or_else(|| self.list.len()); @@ -1575,6 +1606,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { #[must_use] #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn current(&mut self) -> Option<&mut T> { + // SAFETY: Untriaged. unsafe { self.current.map(|current| &mut (*current.as_ptr()).element) } } @@ -1585,6 +1617,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { /// element of the `LinkedList` then this returns `None`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn peek_next(&mut self) -> Option<&mut T> { + // SAFETY: Untriaged. unsafe { let next = match self.current { None => self.list.head, @@ -1601,6 +1634,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { /// element of the `LinkedList` then this returns `None`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn peek_prev(&mut self) -> Option<&mut T> { + // SAFETY: Untriaged. unsafe { let prev = match self.current { None => self.list.tail, @@ -1643,6 +1677,7 @@ impl<'a, T> CursorMut<'a, T> { /// inserted at the start of the `LinkedList`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn splice_after(&mut self, list: LinkedList) { + // SAFETY: Untriaged. unsafe { let Some((splice_head, splice_tail, splice_len)) = list.detach_all_nodes() else { return; @@ -1665,6 +1700,7 @@ impl<'a, T> CursorMut<'a, T> { /// inserted at the end of the `LinkedList`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn splice_before(&mut self, list: LinkedList) { + // SAFETY: Untriaged. unsafe { let (splice_head, splice_tail, splice_len) = match list.detach_all_nodes() { Some(parts) => parts, @@ -1687,6 +1723,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { /// inserted at the front of the `LinkedList`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn insert_after(&mut self, item: T) { + // SAFETY: Untriaged. unsafe { let spliced_node = Box::into_non_null_with_allocator(Box::new_in(Node::new(item), &self.list.alloc)).0; @@ -1708,6 +1745,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { /// inserted at the end of the `LinkedList`. #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn insert_before(&mut self, item: T) { + // SAFETY: Untriaged. unsafe { let spliced_node = Box::into_non_null_with_allocator(Box::new_in(Node::new(item), &self.list.alloc)).0; @@ -1730,6 +1768,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { #[unstable(feature = "linked_list_cursors", issue = "58533")] pub fn remove_current(&mut self) -> Option { let unlinked_node = self.current?; + // SAFETY: Untriaged. unsafe { self.current = unlinked_node.as_ref().next; self.list.unlink_node(unlinked_node); @@ -1751,6 +1790,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { A: Clone, { let mut unlinked_node = self.current?; + // SAFETY: Untriaged. unsafe { self.current = unlinked_node.as_ref().next; self.list.unlink_node(unlinked_node); @@ -1783,6 +1823,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { // The "ghost" non-element's index has changed to 0. self.index = 0; } + // SAFETY: Untriaged. unsafe { self.list.split_off_after_node(self.current, split_off_idx) } } @@ -1799,6 +1840,7 @@ impl<'a, T, A: Allocator> CursorMut<'a, T, A> { { let split_off_idx = self.index; self.index = 0; + // SAFETY: Untriaged. unsafe { self.list.split_off_before_node(self.current, split_off_idx) } } @@ -1970,6 +2012,7 @@ where fn next(&mut self) -> Option { while let Some(mut node) = self.it { + // SAFETY: Untriaged. unsafe { self.it = node.as_ref().next; self.idx += 1; @@ -1997,6 +2040,7 @@ where A: Allocator, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // SAFETY: Untriaged. let peek = self.it.map(|node| unsafe { &node.as_ref().element }); f.debug_struct("ExtractIf").field("peek", &peek).finish_non_exhaustive() } diff --git a/library/alloc/src/collections/vec_deque/drain.rs b/library/alloc/src/collections/vec_deque/drain.rs index da4b803c64d56..92950ebcc3dac 100644 --- a/library/alloc/src/collections/vec_deque/drain.rs +++ b/library/alloc/src/collections/vec_deque/drain.rs @@ -55,6 +55,7 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> { // Only returns pointers to the slices, as that's all we need // to drop them. May only be called if `self.remaining != 0`. pub(super) unsafe fn as_slices(&self) -> (*mut [T], *mut [T]) { + // SAFETY: Untriaged. unsafe { let deque = self.deque.as_ref(); @@ -98,6 +99,7 @@ impl Drop for Drain<'_, T, A> { let guard = DropGuard(self); if mem::needs_drop::() && guard.0.remaining != 0 { + // SAFETY: Untriaged. unsafe { // SAFETY: We just checked that `self.remaining != 0`. let (front, back) = guard.0.as_slices(); @@ -115,6 +117,7 @@ impl Drop for Drain<'_, T, A> { #[inline] fn drop(&mut self) { if mem::needs_drop::() && self.0.remaining != 0 { + // SAFETY: Untriaged. unsafe { // SAFETY: We just checked that `self.remaining != 0`. let (front, back) = self.0.as_slices(); @@ -123,6 +126,7 @@ impl Drop for Drain<'_, T, A> { } } + // SAFETY: Untriaged. let source_deque = unsafe { self.0.deque.as_mut() }; let drain_len = self.0.drain_len; @@ -212,6 +216,7 @@ impl Drop for Drain<'_, T, A> { len = tail_len; }; + // SAFETY: Untriaged. unsafe { source_deque.wrap_copy(src, dst, len); } @@ -241,9 +246,11 @@ impl Iterator for Drain<'_, T, A> { if self.remaining == 0 { return None; } + // SAFETY: Untriaged. let wrapped_idx = unsafe { self.deque.as_ref().to_wrapped_index(self.idx) }; self.idx += 1; self.remaining -= 1; + // SAFETY: Untriaged. Some(unsafe { self.deque.as_mut().buffer_read(wrapped_idx) }) } @@ -263,7 +270,9 @@ impl DoubleEndedIterator for Drain<'_, T, A> { } self.remaining -= 1; let wrapped_idx = +// SAFETY: Untriaged. unsafe { self.deque.as_ref().to_wrapped_index(self.idx + self.remaining) }; + // SAFETY: Untriaged. Some(unsafe { self.deque.as_mut().buffer_read(wrapped_idx) }) } } diff --git a/library/alloc/src/collections/vec_deque/extract_if.rs b/library/alloc/src/collections/vec_deque/extract_if.rs index 19439dfb4f05d..3d178d07e1055 100644 --- a/library/alloc/src/collections/vec_deque/extract_if.rs +++ b/library/alloc/src/collections/vec_deque/extract_if.rs @@ -84,6 +84,7 @@ where // Note: we can't use `vec.get_mut(i).unwrap()` here since the precondition for that // function is that i < vec.len, but we've set vec's length to zero. let idx = self.vec.to_wrapped_index(i); + // SAFETY: Untriaged. let cur = unsafe { &mut *self.vec.ptr().add(idx.as_index()) }; let drained = (self.pred)(cur); // Update the index *after* the predicate is called. If the index diff --git a/library/alloc/src/collections/vec_deque/iter.rs b/library/alloc/src/collections/vec_deque/iter.rs index d3dbd10c863fb..14ab2393ea1b5 100644 --- a/library/alloc/src/collections/vec_deque/iter.rs +++ b/library/alloc/src/collections/vec_deque/iter.rs @@ -147,6 +147,7 @@ impl<'a, T> Iterator for Iter<'a, T> { unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item { // Safety: The TrustedRandomAccess contract requires that callers only pass an index // that is in bounds. + // SAFETY: Untriaged. unsafe { let i1_len = self.i1.len(); if idx < i1_len { diff --git a/library/alloc/src/collections/vec_deque/iter_mut.rs b/library/alloc/src/collections/vec_deque/iter_mut.rs index 0c5f06e752b7b..cf29810ecb7b3 100644 --- a/library/alloc/src/collections/vec_deque/iter_mut.rs +++ b/library/alloc/src/collections/vec_deque/iter_mut.rs @@ -211,6 +211,7 @@ impl<'a, T> Iterator for IterMut<'a, T> { unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item { // Safety: The TrustedRandomAccess contract requires that callers only pass an index // that is in bounds. + // SAFETY: Untriaged. unsafe { let i1_len = self.i1.len(); if idx < i1_len { diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs index 940fce7377938..80127ca36e1dc 100644 --- a/library/alloc/src/collections/vec_deque/mod.rs +++ b/library/alloc/src/collections/vec_deque/mod.rs @@ -139,6 +139,7 @@ struct Dropper<'a, T>(&'a mut [T]); impl Drop for Dropper<'_, T> { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { ptr::drop_in_place(self.0); } @@ -149,6 +150,7 @@ impl Drop for Dropper<'_, T> { unsafe impl<#[may_dangle] T, A: Allocator> Drop for VecDeque { fn drop(&mut self) { let (front, back) = self.as_mut_slices(); + // SAFETY: Untriaged. unsafe { let _back_dropper = Dropper(back); // use drop for [T] @@ -206,6 +208,7 @@ impl VecDeque { /// Moves an element out of the buffer #[inline] unsafe fn buffer_read(&mut self, off: WrappedIndex) -> T { + // SAFETY: Untriaged. unsafe { ptr::read(self.ptr().add(off.as_index())) } } @@ -215,6 +218,7 @@ impl VecDeque { /// May only be called if `off < self.capacity()`. #[inline] unsafe fn buffer_write(&mut self, off: WrappedIndex, value: T) -> &mut T { + // SAFETY: Untriaged. unsafe { let ptr = self.ptr().add(off.as_index()); ptr::write(ptr, value); @@ -226,6 +230,7 @@ impl VecDeque { /// `range` must lie inside `0..self.capacity()`. #[inline] unsafe fn buffer_range(&self, range: Range) -> *mut [T] { + // SAFETY: Untriaged. unsafe { self.ptr().add(range.start).cast_slice(range.end - range.start) } } @@ -304,6 +309,7 @@ impl VecDeque { self.capacity(), ); + // SAFETY: Untriaged. unsafe { let ptr = self.ptr(); let src_ptr = ptr.add(wrapped_src.as_index()); @@ -348,6 +354,7 @@ impl VecDeque { len, self.capacity() ); + // SAFETY: Untriaged. unsafe { ptr::copy(self.ptr().add(src.as_index()), self.ptr().add(dst.as_index()), len); } @@ -372,6 +379,7 @@ impl VecDeque { len, self.capacity() ); + // SAFETY: Untriaged. unsafe { ptr::copy_nonoverlapping( self.ptr().add(src.as_index()), @@ -416,6 +424,7 @@ impl VecDeque { // 2 [_ _ A A A A B B _] // D . . . // + // SAFETY: Untriaged. unsafe { self.copy(src, dst, len); } @@ -429,6 +438,7 @@ impl VecDeque { // 3 [B B B B _ _ _ A A] // . . D . // + // SAFETY: Untriaged. unsafe { self.copy(src, dst, dst_pre_wrap_len); self.copy( @@ -447,6 +457,7 @@ impl VecDeque { // 3 [B B _ _ _ A A A A] // . . D . // + // SAFETY: Untriaged. unsafe { self.copy( src.add(dst_pre_wrap_len), @@ -465,6 +476,7 @@ impl VecDeque { // 3 [C C _ _ _ B B C C] // D . . . // + // SAFETY: Untriaged. unsafe { self.copy(src, dst, src_pre_wrap_len); self.copy( @@ -483,6 +495,7 @@ impl VecDeque { // 3 [C C A A _ _ _ C C] // D . . . // + // SAFETY: Untriaged. unsafe { self.copy( WrappedIndex::zero(), @@ -504,6 +517,7 @@ impl VecDeque { // debug_assert!(dst_pre_wrap_len > src_pre_wrap_len); let delta = dst_pre_wrap_len - src_pre_wrap_len; + // SAFETY: Untriaged. unsafe { self.copy(src, dst, src_pre_wrap_len); self.copy(WrappedIndex::zero(), dst.add(src_pre_wrap_len), delta); @@ -526,6 +540,7 @@ impl VecDeque { // debug_assert!(src_pre_wrap_len > dst_pre_wrap_len); let delta = src_pre_wrap_len - dst_pre_wrap_len; + // SAFETY: Untriaged. unsafe { self.copy( WrappedIndex::zero(), @@ -550,11 +565,13 @@ impl VecDeque { debug_assert!(src.len() <= self.capacity()); let head_room = self.capacity() - dst.as_index(); if src.len() <= head_room { + // SAFETY: Untriaged. unsafe { ptr::copy_nonoverlapping(src.as_ptr(), self.ptr().add(dst.as_index()), src.len()); } } else { let (left, right) = src.split_at(head_room); + // SAFETY: Untriaged. unsafe { ptr::copy_nonoverlapping(left.as_ptr(), self.ptr().add(dst.as_index()), left.len()); ptr::copy_nonoverlapping(right.as_ptr(), self.ptr(), right.len()); @@ -572,6 +589,7 @@ impl VecDeque { /// See [`ptr::copy_nonoverlapping`]. unsafe fn copy_nonoverlapping_reversed(src: *const T, dst: *mut T, count: usize) { for i in 0..count { + // SAFETY: Untriaged. unsafe { ptr::copy_nonoverlapping(src.add(count - 1 - i), dst.add(i), 1) }; } } @@ -579,6 +597,7 @@ impl VecDeque { debug_assert!(src.len() <= self.capacity()); let head_room = self.capacity() - dst.as_index(); if src.len() <= head_room { + // SAFETY: Untriaged. unsafe { copy_nonoverlapping_reversed( src.as_ptr(), @@ -588,6 +607,7 @@ impl VecDeque { } } else { let (left, right) = src.split_at(src.len() - head_room); + // SAFETY: Untriaged. unsafe { copy_nonoverlapping_reversed( right.as_ptr(), @@ -612,6 +632,7 @@ impl VecDeque { iter: impl Iterator, written: &mut usize, ) { + // SAFETY: Untriaged. iter.enumerate().for_each(|(i, element)| unsafe { self.buffer_write(dst.add(i), element); *written += 1; @@ -648,8 +669,10 @@ impl VecDeque { let mut guard = Guard { deque: self, written: 0 }; if head_room >= len { + // SAFETY: Untriaged. unsafe { guard.deque.write_iter(dst, iter, &mut guard.written) }; } else { + // SAFETY: Untriaged. unsafe { guard.deque.write_iter( dst, @@ -697,6 +720,7 @@ impl VecDeque { let tail_len = self.len - head_len; if head_len > tail_len && new_capacity - old_capacity >= tail_len { // B + // SAFETY: Untriaged. unsafe { self.copy_nonoverlapping( WrappedIndex::zero(), @@ -707,6 +731,7 @@ impl VecDeque { } else { // C let new_head = WrappedIndex::from_arbitrary_number(new_capacity - head_len); + // SAFETY: Untriaged. unsafe { // can't use copy_nonoverlapping here, because if e.g. head_len = 2 // and new_capacity = old_capacity + 1, then the heads overlap. @@ -966,6 +991,7 @@ impl VecDeque { pub fn get(&self, index: usize) -> Option<&T> { if index < self.len { let idx = self.to_wrapped_index(index); + // SAFETY: Untriaged. unsafe { Some(&*self.ptr().add(idx.as_index())) } } else { None @@ -996,6 +1022,7 @@ impl VecDeque { pub fn get_mut(&mut self, index: usize) -> Option<&mut T> { if index < self.len { let idx = self.to_wrapped_index(index); + // SAFETY: Untriaged. unsafe { Some(&mut *self.ptr().add(idx.as_index())) } } else { None @@ -1031,6 +1058,7 @@ impl VecDeque { assert!(j < self.len()); let ri = self.to_wrapped_index(i); let rj = self.to_wrapped_index(j); + // SAFETY: Untriaged. unsafe { ptr::swap(self.ptr().add(ri.as_index()), self.ptr().add(rj.as_index())) } } @@ -1080,6 +1108,7 @@ impl VecDeque { if new_cap > old_cap { self.buf.reserve_exact(self.len, additional); + // SAFETY: Untriaged. unsafe { self.handle_capacity_increase(old_cap); } @@ -1112,6 +1141,7 @@ impl VecDeque { // we don't need to reserve_exact(), as the size doesn't have // to be a power of 2. self.buf.reserve(self.len, additional); + // SAFETY: Untriaged. unsafe { self.handle_capacity_increase(old_cap); } @@ -1163,6 +1193,7 @@ impl VecDeque { if new_cap > old_cap { self.buf.try_reserve_exact(self.len, additional)?; + // SAFETY: Untriaged. unsafe { self.handle_capacity_increase(old_cap); } @@ -1211,6 +1242,7 @@ impl VecDeque { if new_cap > old_cap { self.buf.try_reserve(self.len, additional)?; + // SAFETY: Untriaged. unsafe { self.handle_capacity_increase(old_cap); } @@ -1292,6 +1324,7 @@ impl VecDeque { // [. . . . . . . . o o o o o o o . ] // H L // [o o o o o o o . ] + // SAFETY: Untriaged. unsafe { // nonoverlapping because `self.head >= target_cap >= self.len`. self.copy_nonoverlapping(self.head, WrappedIndex::zero(), self.len); @@ -1310,6 +1343,7 @@ impl VecDeque { // [o o . o o o o o ] let len = self.head + self.len - target_cap; // Safety: head is < target_cap, so the index is wrapped + // SAFETY: Untriaged. unsafe { self.copy_nonoverlapping( WrappedIndex::from_arbitrary_number(target_cap), @@ -1332,6 +1366,7 @@ impl VecDeque { // head_len is at least one, so new_head will be < target_cap let new_head = WrappedIndex::from_arbitrary_number(target_cap - head_len); + // SAFETY: Untriaged. unsafe { // can't use `copy_nonoverlapping()` here because the new and old // regions for the head might overlap. @@ -1349,6 +1384,7 @@ impl VecDeque { impl Drop for Guard<'_, T, A> { #[cold] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { // SAFETY: This is only called if `buf.shrink_to_fit` unwinds, // which is the only time it's safe to call `abort_shrink`. @@ -1391,6 +1427,7 @@ impl VecDeque { // There's enough spare capacity to copy the tail to the back (because `tail_len < self.capacity() - target_cap`), // and copying the tail should be cheaper than copying the head (because `tail_len <= head_len`). + // SAFETY: Untriaged. unsafe { // The old tail and the new tail can't overlap because the head slice lies between them. The // head slice ends at `target_cap`, so that's where we copy to. @@ -1403,6 +1440,7 @@ impl VecDeque { } else { // Either there's not enough spare capacity to make the deque contiguous, or the head is shorter than the tail // (and therefore hopefully cheaper to copy). + // SAFETY: Untriaged. unsafe { // The old and the new head slice can overlap, so we can't use `copy_nonoverlapping` here. self.copy(self.head, old_head, head_len); @@ -1440,6 +1478,7 @@ impl VecDeque { // `begin <= back.len()` in the first case // * The head of the VecDeque is moved before calling `drop_in_place`, // so no value is dropped twice if `drop_in_place` panics + // SAFETY: Untriaged. unsafe { if len >= self.len { return; @@ -1487,6 +1526,7 @@ impl VecDeque { #[doc(alias = "truncate_front")] #[stable(feature = "vec_deque_truncate_front", since = "CURRENT_RUSTC_VERSION")] pub fn retain_back(&mut self, len: usize) { + // SAFETY: Untriaged. unsafe { if len >= self.len { // No action is taken @@ -1565,6 +1605,7 @@ impl VecDeque { let fptr = front.as_mut_ptr(); let bptr = back.as_mut_ptr(); + // SAFETY: Untriaged. unsafe { let (drop_a, drop_b, drop_c) = if end <= flen { // Kept range lies in `front`. The dropped suffix is the rest of `front` @@ -1859,6 +1900,7 @@ impl VecDeque { // it's ok to pass them to `buffer_range` and // dereference the result. let a = unsafe { &*self.buffer_range(a_range) }; + // SAFETY: Untriaged. let b = unsafe { &*self.buffer_range(b_range) }; Iter::new(a.iter(), b.iter()) } @@ -1899,6 +1941,7 @@ impl VecDeque { // it's ok to pass them to `buffer_range` and // dereference the result. let a = unsafe { &mut *self.buffer_range(a_range) }; + // SAFETY: Untriaged. let b = unsafe { &mut *self.buffer_range(b_range) }; IterMut::new(a.iter_mut(), b.iter_mut()) } @@ -1975,6 +2018,7 @@ impl VecDeque { // "forget" about the values after the start of the drain until after // the drain is complete and the Drain destructor is run. + // SAFETY: Untriaged. unsafe { Drain::new(self, drain_start, drain_len) } } @@ -2201,6 +2245,7 @@ impl VecDeque { let old_head = self.head; self.head = self.to_wrapped_index(1); self.len -= 1; + // SAFETY: Untriaged. unsafe { core::hint::assert_unchecked(self.len < self.capacity()); Some(self.buffer_read(old_head)) @@ -2228,6 +2273,7 @@ impl VecDeque { None } else { self.len -= 1; + // SAFETY: Untriaged. unsafe { core::hint::assert_unchecked(self.len < self.capacity()); Some(self.buffer_read(self.to_wrapped_index(self.len))) @@ -2360,6 +2406,7 @@ impl VecDeque { let len = self.len; self.len += 1; + // SAFETY: Untriaged. unsafe { self.buffer_write(self.to_wrapped_index(len), value) } } @@ -2572,6 +2619,7 @@ impl VecDeque { // `index + 1` can't overflow, because if index was usize::MAX, then either the // assert would've failed, or the deque would've tried to grow past usize::MAX // and panicked. + // SAFETY: Untriaged. unsafe { // see `remove()` for explanation why this wrap_copy() call is safe. self.wrap_copy(self.to_wrapped_index(index), self.to_wrapped_index(index + 1), k); @@ -2581,6 +2629,7 @@ impl VecDeque { } else { let old_head = self.head; self.head = self.wrap_sub(self.head, 1); + // SAFETY: Untriaged. unsafe { self.wrap_copy(old_head, self.head, index); self.len += 1; @@ -2619,6 +2668,7 @@ impl VecDeque { let wrapped_idx = self.to_wrapped_index(index); + // SAFETY: Untriaged. let elem = unsafe { Some(self.buffer_read(wrapped_idx)) }; let k = self.len - index - 1; @@ -2626,11 +2676,13 @@ impl VecDeque { // its length argument will be at most `self.len / 2`, so there can't be more than // one overlapping area. if k < index { + // SAFETY: Untriaged. unsafe { self.wrap_copy(self.wrap_add(wrapped_idx, 1), wrapped_idx, k) }; self.len -= 1; } else { let old_head = self.head; self.head = self.to_wrapped_index(1); + // SAFETY: Untriaged. unsafe { self.wrap_copy(old_head, self.head, index) }; self.len -= 1; } @@ -2678,6 +2730,7 @@ impl VecDeque { let first_len = first_half.len(); let second_len = second_half.len(); + // SAFETY: Untriaged. unsafe { if at < first_len { // `at` lies in the first half. @@ -2739,6 +2792,7 @@ impl VecDeque { } self.reserve(other.len); + // SAFETY: Untriaged. unsafe { let (left, right) = other.as_slices(); self.copy_slice(self.to_wrapped_index(self.len), left); @@ -2858,6 +2912,7 @@ impl VecDeque { debug_assert!(self.is_full()); let old_cap = self.capacity(); self.buf.grow_one(); + // SAFETY: Untriaged. unsafe { self.handle_capacity_increase(old_cap); } @@ -2962,6 +3017,7 @@ impl VecDeque { } if self.is_contiguous() { + // SAFETY: Untriaged. unsafe { return slice::from_raw_parts_mut(self.ptr().add(self.head.as_index()), self.len); } @@ -2987,6 +3043,7 @@ impl VecDeque { // // from: DEFGH....ABC // to: ABCDEFGH.... + // SAFETY: Untriaged. unsafe { self.copy( WrappedIndex::zero(), @@ -3006,6 +3063,7 @@ impl VecDeque { // // from: FGH....ABCDE // to: ...ABCDEFGH. + // SAFETY: Untriaged. unsafe { self.copy(head, tail, head_len); // FGHABCDE.... @@ -3038,6 +3096,7 @@ impl VecDeque { // 2. rotate used part of the buffer // 3. update head to point to the new beginning (which is just `free`) + // SAFETY: Untriaged. unsafe { // if there is no free space in the buffer, then the slices are already // right next to each other and we don't need to move any memory. @@ -3070,6 +3129,7 @@ impl VecDeque { // 2. rotate used part of the buffer // 3. update head to point to the new beginning (which is the beginning of the buffer) + // SAFETY: Untriaged. unsafe { // if there is no free space in the buffer, then the slices are already // right next to each other and we don't need to move any memory. @@ -3097,6 +3157,7 @@ impl VecDeque { } } + // SAFETY: Untriaged. unsafe { slice::from_raw_parts_mut(ptr.add(self.head.as_index()), self.len) } } @@ -3137,8 +3198,10 @@ impl VecDeque { assert!(n <= self.len()); let k = self.len - n; if n <= k { + // SAFETY: Untriaged. unsafe { self.rotate_left_inner(n) } } else { + // SAFETY: Untriaged. unsafe { self.rotate_right_inner(k) } } } @@ -3180,8 +3243,10 @@ impl VecDeque { assert!(n <= self.len()); let k = self.len - n; if n <= k { + // SAFETY: Untriaged. unsafe { self.rotate_right_inner(n) } } else { + // SAFETY: Untriaged. unsafe { self.rotate_left_inner(k) } } } @@ -3196,6 +3261,7 @@ impl VecDeque { unsafe fn rotate_left_inner(&mut self, mid: usize) { debug_assert!(mid * 2 <= self.len()); + // SAFETY: Untriaged. unsafe { self.wrap_copy(self.head, self.to_wrapped_index(self.len), mid); } @@ -3205,6 +3271,7 @@ impl VecDeque { unsafe fn rotate_right_inner(&mut self, k: usize) { debug_assert!(k * 2 <= self.len()); self.head = self.wrap_sub(self.head, k); + // SAFETY: Untriaged. unsafe { self.wrap_copy(self.to_wrapped_index(self.len), self.head, k); } @@ -3566,6 +3633,7 @@ impl SpecExtendFromWithin for VecDeque { let count = src.end - src.start; let src = src.start; + // SAFETY: Untriaged. unsafe { // SAFETY: // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values. @@ -3592,6 +3660,7 @@ impl SpecExtendFromWithin for VecDeque { let new_head = self.wrap_sub(self.head, count); let cap = self.capacity(); + // SAFETY: Untriaged. unsafe { // SAFETY: // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values. @@ -3643,6 +3712,7 @@ impl SpecExtendFromWithin for VecDeque { let count = src.end - src.start; let src = src.start; + // SAFETY: Untriaged. unsafe { // SAFETY: // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values. @@ -3665,6 +3735,7 @@ impl SpecExtendFromWithin for VecDeque { let new_head = self.wrap_sub(self.head, count); + // SAFETY: Untriaged. unsafe { // SAFETY: // - Ranges do not overlap: src entirely spans initialized values, dst entirely spans uninitialized values. @@ -3995,6 +4066,7 @@ impl From> for VecDeque { Self { head: WrappedIndex::zero(), len, + // SAFETY: Untriaged. buf: unsafe { RawVec::from_raw_parts_in(ptr, cap, alloc) }, } } @@ -4034,6 +4106,7 @@ impl From> for Vec { fn from(mut other: VecDeque) -> Self { other.make_contiguous(); + // SAFETY: Untriaged. unsafe { let other = ManuallyDrop::new(other); let buf = other.buf.ptr(); diff --git a/library/alloc/src/collections/vec_deque/spec_extend.rs b/library/alloc/src/collections/vec_deque/spec_extend.rs index 0699d403d9de5..31997f187dec2 100644 --- a/library/alloc/src/collections/vec_deque/spec_extend.rs +++ b/library/alloc/src/collections/vec_deque/spec_extend.rs @@ -57,6 +57,7 @@ where ); self.reserve(additional); + // SAFETY: Untriaged. let written = unsafe { self.write_iter_wrapping(self.to_wrapped_index(self.len), iter, additional) }; @@ -82,6 +83,7 @@ impl SpecExtend> for Ve let slice = iterator.as_slice(); self.reserve(slice.len()); + // SAFETY: Untriaged. unsafe { self.copy_slice(self.to_wrapped_index(self.len), slice); self.len += slice.len(); @@ -108,6 +110,7 @@ where let slice = iterator.as_slice(); self.reserve(slice.len()); + // SAFETY: Untriaged. unsafe { self.copy_slice(self.to_wrapped_index(self.len), slice); self.len += slice.len(); @@ -213,6 +216,7 @@ impl<'a, T, A1: Allocator, A2: Allocator> SpecExtendFront> f } self.reserve(iter.remaining); + // SAFETY: Untriaged. unsafe { // SAFETY: iter.remaining != 0. let (left, right) = iter.as_slices(); @@ -240,6 +244,7 @@ impl<'a, T, A1: Allocator, A2: Allocator> SpecExtendFront SpecExtendFront(deque: &mut VecDeque, slice: &[T]) { + // SAFETY: Untriaged. unsafe { deque.head = deque.wrap_sub(deque.head, slice.len()); deque.copy_slice(deque.head, slice); @@ -276,6 +282,7 @@ unsafe fn prepend(deque: &mut VecDeque, slice: &[T]) { /// - `deque` must have space for `slice.len()` new elements. /// - Elements of `slice` will be copied into the deque, make sure to forget the elements if `T` is not `Copy`. unsafe fn prepend_reversed(deque: &mut VecDeque, slice: &[T]) { + // SAFETY: Untriaged. unsafe { deque.head = deque.wrap_sub(deque.head, slice.len()); deque.copy_slice_reversed(deque.head, slice); diff --git a/library/alloc/src/collections/vec_deque/splice.rs b/library/alloc/src/collections/vec_deque/splice.rs index a29e9c3742564..bdbb61afafe94 100644 --- a/library/alloc/src/collections/vec_deque/splice.rs +++ b/library/alloc/src/collections/vec_deque/splice.rs @@ -64,6 +64,7 @@ impl Drop for Splice<'_, I, A> { // At this point draining is done and the only remaining tasks are splicing // and moving things into the final place. + // SAFETY: Untriaged. unsafe { let tail_len = self.drain.tail_len; // #elements behind the drain @@ -114,6 +115,7 @@ impl Drain<'_, T, A> { /// self.deque must be valid. self.deque.len and self.deque.len + self.drain_len must be less /// than twice the deque's capacity. unsafe fn fill>(&mut self, replace_with: &mut I) -> bool { + // SAFETY: Untriaged. let deque = unsafe { self.deque.as_mut() }; let range_start = deque.len; let range_end = range_start + self.drain_len; @@ -121,6 +123,7 @@ impl Drain<'_, T, A> { for idx in range_start..range_end { if let Some(new_item) = replace_with.next() { let index = deque.to_wrapped_index(idx); + // SAFETY: Untriaged. unsafe { deque.buffer_write(index, new_item) }; deque.len += 1; self.drain_len -= 1; @@ -137,6 +140,7 @@ impl Drain<'_, T, A> { /// /// self.deque must be valid. unsafe fn move_tail(&mut self, additional: usize) { + // SAFETY: Untriaged. let deque = unsafe { self.deque.as_mut() }; // `Drain::new` modifies the deque's len (so does `Drain::fill` here) @@ -182,6 +186,7 @@ impl Drain<'_, T, A> { } let new_tail_start = tail_start + additional; + // SAFETY: Untriaged. unsafe { deque.wrap_copy( deque.to_wrapped_index(tail_start), diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs index b340cf9566f2e..53e89235f2f5a 100644 --- a/library/alloc/src/ffi/c_str.rs +++ b/library/alloc/src/ffi/c_str.rs @@ -264,6 +264,7 @@ impl CString { let bytes: Vec = self.into(); match memchr::memchr(0, &bytes) { Some(i) => Err(NulError(i, bytes)), + // SAFETY: Untriaged. None => Ok(unsafe { CString::_from_vec_unchecked(bytes) }), } } @@ -287,6 +288,7 @@ impl CString { // This allows better optimizations if lto enabled. match memchr::memchr(0, bytes) { Some(i) => Err(NulError(i, buffer)), + // SAFETY: Untriaged. None => Ok(unsafe { CString::_from_vec_unchecked(buffer) }), } } @@ -339,6 +341,7 @@ impl CString { #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_vec_unchecked(v: Vec) -> Self { debug_assert!(memchr::memchr(0, &v).is_none()); + // SAFETY: Untriaged. unsafe { Self::_from_vec_unchecked(v) } } @@ -478,6 +481,7 @@ impl CString { pub fn into_string(self) -> Result { String::from_utf8(self.into_bytes()).map_err(|e| IntoStringError { error: e.utf8_error(), + // SAFETY: Untriaged. inner: unsafe { Self::_from_vec_unchecked(e.into_bytes()) }, }) } @@ -584,6 +588,7 @@ impl CString { #[stable(feature = "as_c_str", since = "1.20.0")] #[rustc_diagnostic_item = "cstring_as_c_str"] pub fn as_c_str(&self) -> &CStr { + // SAFETY: Untriaged. unsafe { CStr::from_bytes_with_nul_unchecked(self.as_bytes_with_nul()) } } @@ -599,6 +604,7 @@ impl CString { #[must_use = "`self` will be dropped if the result is not used"] #[stable(feature = "into_boxed_c_str", since = "1.20.0")] pub fn into_boxed_c_str(self) -> Box { + // SAFETY: Untriaged. unsafe { Box::from_raw(Box::into_raw(self.into_inner()) as *mut CStr) } } @@ -610,6 +616,7 @@ impl CString { // Then we can return the box directly without invalidating it. // See https://github.com/rust-lang/rust/issues/62553. let this = mem::ManuallyDrop::new(self); + // SAFETY: Untriaged. unsafe { ptr::read(&this.inner) } } @@ -634,6 +641,7 @@ impl CString { #[stable(feature = "cstring_from_vec_with_nul", since = "1.58.0")] pub unsafe fn from_vec_with_nul_unchecked(v: Vec) -> Self { debug_assert!(memchr::memchr(0, &v).unwrap() + 1 == v.len()); + // SAFETY: Untriaged. unsafe { Self::_from_vec_with_nul_unchecked(v) } } @@ -702,6 +710,7 @@ impl CString { impl Drop for CString { #[inline] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { *self.inner.get_unchecked_mut(0) = 0; } @@ -802,6 +811,7 @@ impl From> for CString { #[inline] fn from(s: Box) -> CString { let raw = Box::into_raw(s) as *mut [u8]; + // SAFETY: Untriaged. CString { inner: unsafe { Box::from_raw(raw) } } } } @@ -812,6 +822,7 @@ impl From>> for CString { /// copying nor checking for inner nul bytes. #[inline] fn from(v: Vec>) -> CString { + // SAFETY: Untriaged. unsafe { // Transmute `Vec>` to `Vec`. let v: Vec = { @@ -906,6 +917,7 @@ impl From for Arc { #[inline] fn from(s: CString) -> Arc { let arc: Arc<[u8]> = Arc::from(s.into_inner()); + // SAFETY: Untriaged. unsafe { Arc::from_raw(Arc::into_raw(arc) as *const CStr) } } } @@ -918,6 +930,7 @@ impl From<&CStr> for Arc { #[inline] fn from(s: &CStr) -> Arc { let arc: Arc<[u8]> = Arc::from(s.to_bytes_with_nul()); + // SAFETY: Untriaged. unsafe { Arc::from_raw(Arc::into_raw(arc) as *const CStr) } } } @@ -940,6 +953,7 @@ impl From for Rc { #[inline] fn from(s: CString) -> Rc { let rc: Rc<[u8]> = Rc::from(s.into_inner()); + // SAFETY: Untriaged. unsafe { Rc::from_raw(Rc::into_raw(rc) as *const CStr) } } } @@ -951,6 +965,7 @@ impl From<&CStr> for Rc { #[inline] fn from(s: &CStr) -> Rc { let rc: Rc<[u8]> = Rc::from(s.to_bytes_with_nul()); + // SAFETY: Untriaged. unsafe { Rc::from_raw(Rc::into_raw(rc) as *const CStr) } } } diff --git a/library/alloc/src/io/buf_read.rs b/library/alloc/src/io/buf_read.rs index bba1c2b8c8a45..d496c8c614fbf 100644 --- a/library/alloc/src/io/buf_read.rs +++ b/library/alloc/src/io/buf_read.rs @@ -343,6 +343,7 @@ pub trait BufRead: Read { // Note that we are not calling the `.read_until` method here, but // rather our hardcoded implementation. For more details as to why, see // the comments in `default_read_to_string`. + // SAFETY: Untriaged. unsafe { append_to_string(buf, |b| default_read_until(self, b'\n', b)) } } diff --git a/library/alloc/src/io/buffered/bufreader.rs b/library/alloc/src/io/buffered/bufreader.rs index e8b3302e29b98..ef3fe29330d87 100644 --- a/library/alloc/src/io/buffered/bufreader.rs +++ b/library/alloc/src/io/buffered/bufreader.rs @@ -456,6 +456,7 @@ impl Read for BufReader { // bytes but also modify existing bytes and render them invalid. On the other hand, // if `buf` is empty then by definition any writes must be appends and // `append_to_string` will validate all of the new bytes. + // SAFETY: Untriaged. unsafe { crate::io::append_to_string(buf, |b| self.read_to_end(b)) } } else { // We cannot append our byte buffer directly onto the `buf` String as there could diff --git a/library/alloc/src/io/buffered/bufwriter.rs b/library/alloc/src/io/buffered/bufwriter.rs index 806e71c2772ae..6a7d8c762dac7 100644 --- a/library/alloc/src/io/buffered/bufwriter.rs +++ b/library/alloc/src/io/buffered/bufwriter.rs @@ -470,6 +470,7 @@ impl BufWriter { let old_len = self.buf.len(); let buf_len = buf.len(); let src = buf.as_ptr(); + // SAFETY: Untriaged. unsafe { let dst = self.buf.as_mut_ptr().add(old_len); ptr::copy_nonoverlapping(src, dst, buf_len); diff --git a/library/alloc/src/io/cursor.rs b/library/alloc/src/io/cursor.rs index 4bd5a59e54fad..df01104b1f733 100644 --- a/library/alloc/src/io/cursor.rs +++ b/library/alloc/src/io/cursor.rs @@ -157,6 +157,7 @@ fn reserve_and_pad( debug_assert!(spare.len() >= diff); // Safety: we have allocated enough capacity for this. // And we are only writing, not reading + // SAFETY: Untriaged. unsafe { spare.get_unchecked_mut(..diff).fill(core::mem::MaybeUninit::new(0)); vec.set_len(pos); @@ -176,6 +177,7 @@ where A: Allocator, { debug_assert!(vec.capacity() >= pos + buf.len()); + // SAFETY: Untriaged. unsafe { vec.as_mut_ptr().add(pos).copy_from(buf.as_ptr(), buf.len()) }; pos + buf.len() } @@ -201,6 +203,7 @@ where // Write the buf then progress the vec forward if necessary // Safety: we have ensured that the capacity is available // and that all bytes get written up to pos + // SAFETY: Untriaged. unsafe { pos = vec_write_all_unchecked(pos, vec, buf); if pos > vec.len() { @@ -240,6 +243,7 @@ where // Write the buf then progress the vec forward if necessary // Safety: we have ensured that the capacity is available // and that all bytes get written up to the last pos + // SAFETY: Untriaged. unsafe { for buf in bufs { pos = vec_write_all_unchecked(pos, vec, buf); diff --git a/library/alloc/src/io/error.rs b/library/alloc/src/io/error.rs index 055d743dee6a1..7813b26bc460b 100644 --- a/library/alloc/src/io/error.rs +++ b/library/alloc/src/io/error.rs @@ -216,6 +216,7 @@ impl Error { Ok(*err) } else { // Safety: We have just checked that the condition is true + // SAFETY: Untriaged. unsafe { core::hint::unreachable_unchecked() } } } else { @@ -256,6 +257,7 @@ fn custom_owner_from_box( unsafe fn drop_box_raw(ptr: *mut T) { // SAFETY // Caller ensures `ptr` is valid to pass into `Box::from_raw`. + // SAFETY: Untriaged. drop(unsafe { Box::from_raw(ptr) }) } diff --git a/library/alloc/src/io/read.rs b/library/alloc/src/io/read.rs index 58d3e7005f288..4a34740ea1c12 100644 --- a/library/alloc/src/io/read.rs +++ b/library/alloc/src/io/read.rs @@ -633,6 +633,7 @@ pub trait Read { self.read_buf_exact(borrowed_buf.unfilled())?; // Guard against incorrect `read_buf_exact` implementations. assert_eq!(borrowed_buf.len(), N); + // SAFETY: Untriaged. Ok(unsafe { MaybeUninit::array_assume_init(buf) }) } @@ -807,6 +808,7 @@ where let len_original = buf.len(); // SAFETY: invalid UTF-8 discarded before return or unwind let buf_vec = unsafe { buf.as_mut_vec() }; + // SAFETY: Untriaged. let mut g = DropGuard::new((len_original, buf_vec), |(len, buf)| unsafe { buf.set_len(len); }); @@ -978,6 +980,7 @@ pub fn default_read_to_string( // To prevent extraneously checking the UTF-8-ness of the entire buffer // we pass it to our hardcoded `default_read_to_end` implementation which // we know is guaranteed to only read data into the end of the buffer. + // SAFETY: Untriaged. unsafe { append_to_string(buf, |b| default_read_to_end(r, b, size_hint)) } } diff --git a/library/alloc/src/io/util.rs b/library/alloc/src/io/util.rs index 9bf5a56dd7157..0fd55a7eaab87 100644 --- a/library/alloc/src/io/util.rs +++ b/library/alloc/src/io/util.rs @@ -287,6 +287,7 @@ impl Read for Take { unsafe { buf.set_init() }; } + // SAFETY: Untriaged. unsafe { // SAFETY: filled bytes have been filled buf.advance(filled); diff --git a/library/alloc/src/raw_vec/mod.rs b/library/alloc/src/raw_vec/mod.rs index 5d4ad3ac4bf98..d0fa74f7f9ee0 100644 --- a/library/alloc/src/raw_vec/mod.rs +++ b/library/alloc/src/raw_vec/mod.rs @@ -38,12 +38,14 @@ enum AllocInit { type Cap = core::num::niche_types::UsizeNoHighBit; +// SAFETY: Untriaged. const ZERO_CAP: Cap = unsafe { Cap::new_unchecked(0) }; /// `Cap(cap)`, except if `T` is a ZST then `Cap::ZERO`. /// /// # Safety: cap must be <= `isize::MAX`. const unsafe fn new_cap(cap: usize) -> Cap { + // SAFETY: Untriaged. if T::IS_ZST { ZERO_CAP } else { unsafe { Cap::new_unchecked(cap) } } } @@ -243,6 +245,7 @@ impl RawVec { ); let me = ManuallyDrop::new(self); + // SAFETY: Untriaged. unsafe { let slice = me.ptr().cast::>().cast_slice(len); Box::from_raw_in(slice, ptr::read(&me.inner.alloc)) @@ -413,6 +416,7 @@ impl RawVec { /// Panics if the given amount is *larger* than the current capacity. #[inline] pub(crate) fn try_shrink_to_fit(&mut self, cap: usize) -> Result<(), TryReserveError> { + // SAFETY: Untriaged. unsafe { self.inner.try_shrink_to_fit(cap, T::LAYOUT) } } } @@ -434,6 +438,7 @@ const impl RawVecInner { fn with_capacity_in(capacity: usize, alloc: A, elem_layout: Layout) -> Self { match Self::try_allocate_in(capacity, AllocInit::Uninitialized, alloc, elem_layout) { Ok(this) => { +// SAFETY: Untriaged. unsafe { // Make it more obvious that a subsequent Vec::reserve(capacity) will not allocate. hint::assert_unchecked(!this.needs_to_grow(0, capacity, elem_layout)); @@ -477,6 +482,7 @@ const impl RawVecInner { // here should change to `ptr.len() / size_of::()`. Ok(Self { ptr: Unique::from(ptr.cast()), +// SAFETY: Untriaged. cap: unsafe { Cap::new_unchecked(capacity) }, alloc, }) @@ -548,9 +554,11 @@ const impl RawVecInner { ) -> Result, TryReserveError> { let new_layout = layout_array(cap, elem_layout)?; +// SAFETY: Untriaged. let memory = if let Some((ptr, old_layout)) = unsafe { self.current_memory(elem_layout) } { // FIXME(const-hack): switch to `debug_assert_eq` debug_assert!(old_layout.align() == new_layout.align()); +// SAFETY: Untriaged. unsafe { // The allocator checks for alignment equality hint::assert_unchecked(old_layout.align() == new_layout.align()); @@ -592,6 +600,7 @@ impl RawVecInner { #[inline] const unsafe fn from_raw_parts_in(ptr: *mut u8, cap: Cap, alloc: A) -> Self { + // SAFETY: Untriaged. Self { ptr: unsafe { Unique::new_unchecked(ptr) }, cap, alloc } } @@ -635,6 +644,7 @@ impl RawVecInner { // and could hypothetically handle differences between stride and size, but this memory // has already been allocated so we know it can't overflow and currently Rust does not // support such types. So we can do better by skipping some checks and avoid an unwrap. + // SAFETY: Untriaged. unsafe { let alloc_size = elem_layout.size().unchecked_mul(self.cap.as_inner()); let layout = Layout::from_size_align_unchecked(alloc_size, elem_layout.align()); @@ -668,6 +678,7 @@ impl RawVecInner { } if self.needs_to_grow(len, additional, elem_layout) { + // SAFETY: Untriaged. unsafe { do_reserve_and_handle(self, len, additional, elem_layout); } @@ -690,6 +701,7 @@ impl RawVecInner { self.grow_amortized(len, additional, elem_layout)?; } } + // SAFETY: Untriaged. unsafe { // Inform the optimizer that the reservation has succeeded or wasn't needed hint::assert_unchecked(!self.needs_to_grow(len, additional, elem_layout)); @@ -725,6 +737,7 @@ impl RawVecInner { self.grow_exact(len, additional, elem_layout)?; } } + // SAFETY: Untriaged. unsafe { // Inform the optimizer that the reservation has succeeded or wasn't needed hint::assert_unchecked(!self.needs_to_grow(len, additional, elem_layout)); @@ -740,6 +753,7 @@ impl RawVecInner { #[cfg(not(no_global_oom_handling))] #[inline] unsafe fn shrink_to_fit(&mut self, cap: usize, elem_layout: Layout) { + // SAFETY: Untriaged. if let Err(err) = unsafe { self.shrink(cap, elem_layout) } { handle_error(err); } @@ -756,6 +770,7 @@ impl RawVecInner { cap: usize, elem_layout: Layout, ) -> Result<(), TryReserveError> { + // SAFETY: Untriaged. unsafe { self.shrink(cap, elem_layout) } } @@ -771,6 +786,7 @@ impl RawVecInner { // the size requested. If that ever changes, the capacity here should // change to `ptr.len() / size_of::()`. self.ptr = Unique::from(ptr.cast()); + // SAFETY: Untriaged. self.cap = unsafe { Cap::new_unchecked(cap) }; } @@ -837,11 +853,14 @@ impl RawVecInner { // for the T::IS_ZST case since current_memory() will have returned // None. if cap == 0 { + // SAFETY: Untriaged. unsafe { self.alloc.deallocate(ptr, layout) }; self.ptr = +// SAFETY: Untriaged. unsafe { Unique::new_unchecked(ptr::without_provenance_mut(elem_layout.align())) }; self.cap = ZERO_CAP; } else { + // SAFETY: Untriaged. let ptr = unsafe { // Layout cannot overflow here because it would have // overflowed earlier when capacity was larger. @@ -872,6 +891,7 @@ const impl RawVecInner { unsafe fn deallocate(&mut self, elem_layout: Layout) { // SAFETY: Precondition passed to caller if let Some((ptr, layout)) = unsafe { self.current_memory(elem_layout) } { + // SAFETY: Untriaged. unsafe { self.alloc.deallocate(ptr, layout); } diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 4629a0b500107..a89b34188bba1 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -359,11 +359,13 @@ unsafe impl CloneFromCell for Rc {} impl Rc { #[inline] unsafe fn from_inner(ptr: NonNull>) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_inner_in(ptr, Global) } } #[inline] unsafe fn from_ptr(ptr: *mut RcInner) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_inner(NonNull::new_unchecked(ptr)) } } } @@ -373,12 +375,14 @@ impl Rc { fn inner(&self) -> &RcInner { // This unsafety is ok because while this Rc is alive we're guaranteed // that the inner pointer is valid. + // SAFETY: Untriaged. unsafe { self.ptr.as_ref() } } #[inline] fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { let this = mem::ManuallyDrop::new(this); + // SAFETY: Untriaged. (this.ptr, unsafe { ptr::read(&this.alloc) }) } @@ -389,6 +393,7 @@ impl Rc { #[inline] unsafe fn from_ptr_in(ptr: *mut RcInner, alloc: A) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_inner_in(NonNull::new_unchecked(ptr), alloc) } } @@ -402,6 +407,7 @@ impl Rc { // Destroy the contained object. // We cannot use `get_mut_unchecked` here, because `self.alloc` is borrowed. + // SAFETY: Untriaged. unsafe { ptr::drop_in_place(&mut (*self.ptr.as_ptr()).value); } @@ -425,6 +431,7 @@ impl Rc { // pointers, which ensures that the weak destructor never frees // the allocation while the strong destructor is running, even // if the weak pointer is stored inside the strong one. + // SAFETY: Untriaged. unsafe { Self::from_inner( Box::leak(Box::new(RcInner { strong: Cell::new(1), weak: Cell::new(1), value })) @@ -513,6 +520,7 @@ impl Rc { #[stable(feature = "new_uninit", since = "1.82.0")] #[must_use] pub fn new_uninit() -> Rc> { + // SAFETY: Untriaged. unsafe { Rc::from_ptr(Rc::allocate_for_layout( Layout::new::(), @@ -544,6 +552,7 @@ impl Rc { #[stable(feature = "new_zeroed_alloc", since = "1.92.0")] #[must_use] pub fn new_zeroed() -> Rc> { + // SAFETY: Untriaged. unsafe { Rc::from_ptr(Rc::allocate_for_layout( Layout::new::(), @@ -570,6 +579,7 @@ impl Rc { // pointers, which ensures that the weak destructor never frees // the allocation while the strong destructor is running, even // if the weak pointer is stored inside the strong one. + // SAFETY: Untriaged. unsafe { Ok(Self::from_inner( Box::leak(Box::try_new(RcInner { @@ -603,6 +613,7 @@ impl Rc { /// ``` #[unstable(feature = "allocator_api", issue = "32838")] pub fn try_new_uninit() -> Result>, AllocError> { + // SAFETY: Untriaged. unsafe { Ok(Rc::from_ptr(Rc::try_allocate_for_layout( Layout::new::(), @@ -635,6 +646,7 @@ impl Rc { /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] pub fn try_new_zeroed() -> Result>, AllocError> { + // SAFETY: Untriaged. unsafe { Ok(Rc::from_ptr(Rc::try_allocate_for_layout( Layout::new::(), @@ -649,6 +661,7 @@ impl Rc { #[stable(feature = "pin", since = "1.33.0")] #[must_use] pub fn pin(value: T) -> Pin> { + // SAFETY: Untriaged. unsafe { Pin::new_unchecked(Rc::new(value)) } } @@ -679,6 +692,7 @@ impl Rc { && align_of::() == align_of::() && Rc::is_unique(&this) { + // SAFETY: Untriaged. unsafe { let ptr = Rc::into_raw(this); let value = ptr.read(); @@ -726,6 +740,7 @@ impl Rc { && align_of::() == align_of::() && Rc::is_unique(&this) { + // SAFETY: Untriaged. unsafe { let ptr = Rc::into_raw(this); let value = ptr.read(); @@ -791,6 +806,7 @@ impl Rc { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn new_uninit_in(alloc: A) -> Rc, A> { + // SAFETY: Untriaged. unsafe { Rc::from_ptr_in( Rc::allocate_for_layout( @@ -828,6 +844,7 @@ impl Rc { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn new_zeroed_in(alloc: A) -> Rc, A> { + // SAFETY: Untriaged. unsafe { Rc::from_ptr_in( Rc::allocate_for_layout( @@ -885,6 +902,7 @@ impl Rc { }, alloc, )); + // SAFETY: Untriaged. let uninit_ptr: NonNull<_> = (unsafe { &mut *uninit_raw_ptr }).into(); let init_ptr: NonNull> = uninit_ptr.cast(); @@ -898,6 +916,7 @@ impl Rc { // otherwise. let data = data_fn(&weak); + // SAFETY: Untriaged. let strong = unsafe { let inner = init_ptr.as_ptr(); ptr::write(&raw mut (*inner).value, data); @@ -942,6 +961,7 @@ impl Rc { RcInner { strong: Cell::new(1), weak: Cell::new(1), value }, alloc, )?); + // SAFETY: Untriaged. Ok(unsafe { Self::from_inner_in(ptr.into(), alloc) }) } @@ -972,6 +992,7 @@ impl Rc { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> { + // SAFETY: Untriaged. unsafe { Ok(Rc::from_ptr_in( Rc::try_allocate_for_layout( @@ -1010,6 +1031,7 @@ impl Rc { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> { + // SAFETY: Untriaged. unsafe { Ok(Rc::from_ptr_in( Rc::try_allocate_for_layout( @@ -1031,6 +1053,7 @@ impl Rc { where A: 'static, { + // SAFETY: Untriaged. unsafe { Pin::new_unchecked(Rc::new_in(value, alloc)) } } @@ -1059,7 +1082,9 @@ impl Rc { if Rc::strong_count(&this) == 1 { let this = ManuallyDrop::new(this); + // SAFETY: Untriaged. let val: T = unsafe { ptr::read(&**this) }; // copy the contained object + // SAFETY: Untriaged. let alloc: A = unsafe { ptr::read(&this.alloc) }; // copy the allocator // Indicate to Weaks that they can't be promoted by decrementing @@ -1135,6 +1160,7 @@ impl Rc<[T]> { #[stable(feature = "new_uninit", since = "1.82.0")] #[must_use] pub fn new_uninit_slice(len: usize) -> Rc<[mem::MaybeUninit]> { + // SAFETY: Untriaged. unsafe { Rc::from_ptr(Rc::allocate_for_slice(len)) } } @@ -1160,6 +1186,7 @@ impl Rc<[T]> { #[stable(feature = "new_zeroed_alloc", since = "1.92.0")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Rc<[mem::MaybeUninit]> { + // SAFETY: Untriaged. unsafe { Rc::from_ptr(Rc::allocate_for_layout( Layout::array::(len).unwrap(), @@ -1199,6 +1226,7 @@ impl Rc<[T], A> { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn new_uninit_slice_in(len: usize, alloc: A) -> Rc<[mem::MaybeUninit], A> { + // SAFETY: Untriaged. unsafe { Rc::from_ptr_in(Rc::allocate_for_slice_in(len, &alloc), alloc) } } @@ -1227,6 +1255,7 @@ impl Rc<[T], A> { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Rc<[mem::MaybeUninit], A> { + // SAFETY: Untriaged. unsafe { Rc::from_ptr_in( Rc::allocate_for_layout( @@ -1305,6 +1334,7 @@ impl Rc, A> { #[inline] pub unsafe fn assume_init(self) -> Rc { let (ptr, alloc) = Rc::into_inner_with_allocator(self); + // SAFETY: Untriaged. unsafe { Rc::from_inner_in(ptr.cast(), alloc) } } } @@ -1366,6 +1396,7 @@ impl Rc { let mut in_progress: UniqueRcUninit = UniqueRcUninit::new(value, alloc); // Initialize with clone of value. + // SAFETY: Untriaged. let initialized_clone = unsafe { // Clone. If the clone panics, `in_progress` will be dropped and clean up. value.clone_to_uninit(in_progress.data_ptr().cast()); @@ -1396,6 +1427,7 @@ impl Rc { let mut in_progress: UniqueRcUninit = UniqueRcUninit::try_new(value, alloc)?; // Initialize with clone of value. + // SAFETY: Untriaged. let initialized_clone = unsafe { // Clone. If the clone panics, `in_progress` will be dropped and clean up. value.clone_to_uninit(in_progress.data_ptr().cast()); @@ -1441,6 +1473,7 @@ impl Rc<[mem::MaybeUninit], A> { #[inline] pub unsafe fn assume_init(self) -> Rc<[T], A> { let (ptr, alloc) = Rc::into_inner_with_allocator(self); + // SAFETY: Untriaged. unsafe { Rc::from_ptr_in(ptr.as_ptr() as _, alloc) } } } @@ -1513,6 +1546,7 @@ impl Rc { #[inline] #[stable(feature = "rc_raw", since = "1.17.0")] pub unsafe fn from_raw(ptr: *const T) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_raw_in(ptr, Global) } } @@ -1571,6 +1605,7 @@ impl Rc { #[inline] #[stable(feature = "rc_mutate_strong_count", since = "1.53.0")] pub unsafe fn increment_strong_count(ptr: *const T) { + // SAFETY: Untriaged. unsafe { Self::increment_strong_count_in(ptr, Global) } } @@ -1608,6 +1643,7 @@ impl Rc { #[inline] #[stable(feature = "rc_mutate_strong_count", since = "1.53.0")] pub unsafe fn decrement_strong_count(ptr: *const T) { + // SAFETY: Untriaged. unsafe { Self::decrement_strong_count_in(ptr, Global) } } } @@ -1648,6 +1684,7 @@ impl Rc { let this = mem::ManuallyDrop::new(this); let ptr = Self::as_ptr(&this); // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped + // SAFETY: Untriaged. let alloc = unsafe { ptr::read(&this.alloc) }; (ptr, alloc) } @@ -1751,11 +1788,14 @@ impl Rc { /// ``` #[unstable(feature = "allocator_api", issue = "32838")] pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self { + // SAFETY: Untriaged. let offset = unsafe { data_offset(ptr) }; // Reverse the offset to find the original RcInner. + // SAFETY: Untriaged. let rc_ptr = unsafe { ptr.byte_sub(offset) as *mut RcInner }; + // SAFETY: Untriaged. unsafe { Self::from_ptr_in(rc_ptr, alloc) } } @@ -1859,6 +1899,7 @@ impl Rc { A: Clone, { // Retain Rc, but don't touch refcount by wrapping in ManuallyDrop + // SAFETY: Untriaged. let rc = unsafe { mem::ManuallyDrop::new(Rc::::from_raw_in(ptr, alloc)) }; // Now increase refcount, but don't drop new refcount either let _rc_clone: mem::ManuallyDrop<_> = rc.clone(); @@ -1901,6 +1942,7 @@ impl Rc { #[inline] #[unstable(feature = "allocator_api", issue = "32838")] pub unsafe fn decrement_strong_count_in(ptr: *const T, alloc: A) { + // SAFETY: Untriaged. unsafe { drop(Rc::from_raw_in(ptr, alloc)) }; } @@ -1938,6 +1980,7 @@ impl Rc { #[inline] #[stable(feature = "rc_unique", since = "1.4.0")] pub fn get_mut(this: &mut Self) -> Option<&mut T> { + // SAFETY: Untriaged. if Rc::is_unique(this) { unsafe { Some(Rc::get_mut_unchecked(this)) } } else { None } } @@ -2006,6 +2049,7 @@ impl Rc { pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T { // We are careful to *not* create a reference covering the "count" fields, as // this would conflict with accesses to the reference counts (e.g. by `Weak`). + // SAFETY: Untriaged. unsafe { &mut (*this.ptr.as_ptr()).value } } @@ -2096,6 +2140,7 @@ impl Rc { let mut in_progress: UniqueRcUninit = UniqueRcUninit::new(&**this, this.alloc.clone()); + // SAFETY: Untriaged. unsafe { // Initialize `in_progress` with move of **this. // We have to express this in terms of bytes because `T: ?Sized`; there is no @@ -2127,6 +2172,7 @@ impl Rc { // reference count is guaranteed to be 1 at this point, and we required // the `Rc` itself to be `mut`, so we're returning the only possible // reference to the allocation. + // SAFETY: Untriaged. unsafe { &mut this.ptr.as_mut().value } } } @@ -2190,6 +2236,7 @@ impl Rc { #[stable(feature = "rc_downcast", since = "1.29.0")] pub fn downcast(self) -> Result, Self> { if (*self).is::() { + // SAFETY: Untriaged. unsafe { let (ptr, alloc) = Rc::into_inner_with_allocator(self); Ok(Rc::from_inner_in(ptr.cast(), alloc)) @@ -2228,6 +2275,7 @@ impl Rc { #[inline] #[unstable(feature = "downcast_unchecked", issue = "90850")] pub unsafe fn downcast_unchecked(self) -> Rc { + // SAFETY: Untriaged. unsafe { let (ptr, alloc) = Rc::into_inner_with_allocator(self); Rc::from_inner_in(ptr.cast(), alloc) @@ -2248,6 +2296,7 @@ impl Rc { mem_to_rc_inner: impl FnOnce(*mut u8) -> *mut RcInner, ) -> *mut RcInner { let layout = rc_inner_layout_for_value_layout(value_layout); + // SAFETY: Untriaged. unsafe { Rc::try_allocate_for_layout(value_layout, allocate, mem_to_rc_inner) .unwrap_or_else(|_| handle_alloc_error(layout)) @@ -2273,6 +2322,7 @@ impl Rc { // Initialize the RcInner let inner = mem_to_rc_inner(ptr.as_non_null_ptr().as_ptr()); + // SAFETY: Untriaged. unsafe { debug_assert_eq!(Layout::for_value_raw(inner), layout); @@ -2289,6 +2339,7 @@ impl Rc { #[cfg(not(no_global_oom_handling))] unsafe fn allocate_for_ptr_in(ptr: *const T, alloc: &A) -> *mut RcInner { // Allocate for the `RcInner` using the given value. + // SAFETY: Untriaged. unsafe { Rc::::allocate_for_layout( Layout::for_value_raw(ptr), @@ -2300,6 +2351,7 @@ impl Rc { #[cfg(not(no_global_oom_handling))] fn from_box_in(src: Box) -> Rc { + // SAFETY: Untriaged. unsafe { let value_size = size_of_val(&*src); let ptr = Self::allocate_for_ptr_in(&*src, Box::allocator(&src)); @@ -2325,6 +2377,7 @@ impl Rc<[T]> { /// Allocates an `RcInner<[T]>` with the given length. #[cfg(not(no_global_oom_handling))] unsafe fn allocate_for_slice(len: usize) -> *mut RcInner<[T]> { + // SAFETY: Untriaged. unsafe { Self::allocate_for_layout( Layout::array::(len).unwrap(), @@ -2340,6 +2393,7 @@ impl Rc<[T]> { /// bind `T: TrivialClone`. #[cfg(not(no_global_oom_handling))] unsafe fn copy_from_slice(v: &[T]) -> Rc<[T]> { + // SAFETY: Untriaged. unsafe { let ptr = Self::allocate_for_slice(v.len()); ptr::copy_nonoverlapping(v.as_ptr(), (&raw mut (*ptr).value) as *mut T, v.len()); @@ -2364,6 +2418,7 @@ impl Rc<[T]> { impl Drop for Guard { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { let slice = from_raw_parts_mut(self.elems, self.n_elems); ptr::drop_in_place(slice); @@ -2373,6 +2428,7 @@ impl Rc<[T]> { } } + // SAFETY: Untriaged. unsafe { let ptr = Self::allocate_for_slice(len); @@ -2402,6 +2458,7 @@ impl Rc<[T], A> { #[inline] #[cfg(not(no_global_oom_handling))] unsafe fn allocate_for_slice_in(len: usize, alloc: &A) -> *mut RcInner<[T]> { + // SAFETY: Untriaged. unsafe { Rc::<[T]>::allocate_for_layout( Layout::array::(len).unwrap(), @@ -2422,6 +2479,7 @@ trait RcFromSlice { impl RcFromSlice for Rc<[T]> { #[inline] default fn from_slice(v: &[T]) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_iter_exact(v.iter().cloned(), v.len()) } } } @@ -2499,6 +2557,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Rc { /// ``` #[inline] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { self.inner().dec_strong(); if self.inner().strong() == 0 { @@ -2526,6 +2585,7 @@ impl Clone for Rc { /// ``` #[inline] fn clone(&self) -> Self { + // SAFETY: Untriaged. unsafe { self.inner().inc_strong(); Self::from_inner_in(self.ptr, self.alloc.clone()) @@ -2554,6 +2614,7 @@ impl Default for Rc { /// ``` #[inline] fn default() -> Self { + // SAFETY: Untriaged. unsafe { Self::from_inner( Box::leak(Box::write( @@ -2576,6 +2637,7 @@ impl Default for Rc { fn default() -> Self { let rc = Rc::<[u8]>::default(); // `[u8]` has the same layout as `str`. + // SAFETY: Untriaged. unsafe { Rc::from_raw(Rc::into_raw(rc) as *const str) } } } @@ -2602,6 +2664,7 @@ where { #[inline] fn default() -> Self { + // SAFETY: Untriaged. unsafe { Pin::new_unchecked(Rc::::default()) } } } @@ -2942,6 +3005,7 @@ impl From<&str> for Rc { #[inline] fn from(v: &str) -> Rc { let rc = Rc::<[u8]>::from(v.as_bytes()); + // SAFETY: Untriaged. unsafe { Rc::from_raw(Rc::into_raw(rc) as *const str) } } } @@ -3019,6 +3083,7 @@ impl From> for Rc<[T], A> { /// ``` #[inline] fn from(v: Vec) -> Rc<[T], A> { + // SAFETY: Untriaged. unsafe { let (vec_ptr, len, cap, alloc) = v.into_raw_parts_with_alloc(); @@ -3087,6 +3152,7 @@ impl TryFrom> for Rc<[T; N], A> { fn try_from(boxed_slice: Rc<[T], A>) -> Result { if boxed_slice.len() == N { let (ptr, alloc) = Rc::into_inner_with_allocator(boxed_slice); + // SAFETY: Untriaged. Ok(unsafe { Rc::from_inner_in(ptr.cast(), alloc) }) } else { Err(boxed_slice) @@ -3166,6 +3232,7 @@ impl> ToRcSlice for I { (low, high) ); + // SAFETY: Untriaged. unsafe { // SAFETY: We need to ensure that the iterator has an exact length and we have. Rc::from_iter_exact(self, low) @@ -3334,6 +3401,7 @@ impl Weak { #[inline] #[stable(feature = "weak_into_raw", since = "1.45.0")] pub unsafe fn from_raw(ptr: *const T) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_raw_in(ptr, Global) } } @@ -3457,6 +3525,7 @@ impl Weak { let this = mem::ManuallyDrop::new(self); let result = this.as_ptr(); // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped + // SAFETY: Untriaged. let alloc = unsafe { ptr::read(&this.alloc) }; (result, alloc) } @@ -3565,6 +3634,7 @@ impl Weak { if inner.strong() == 0 { None } else { + // SAFETY: Untriaged. unsafe { inner.inc_strong(); Some(Rc::from_inner_in(self.ptr, self.alloc.clone())) @@ -3608,6 +3678,7 @@ impl Weak { // We are careful to *not* create a reference covering the "data" field, as // the field may be mutated concurrently (for example, if the last `Rc` // is dropped, the data field will be dropped in-place). + // SAFETY: Untriaged. Some(unsafe { let ptr = self.ptr.as_ptr(); WeakInner { strong: &(*ptr).strong, weak: &(*ptr).weak } @@ -3695,6 +3766,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Weak { // the weak count starts at 1, and will only go to zero if all // the strong pointers have disappeared. if inner.weak() == 0 { + // SAFETY: Untriaged. unsafe { self.alloc.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr())); } @@ -4246,6 +4318,7 @@ impl UniqueRc { && align_of::() == align_of::() && UniqueRc::weak_count(&this) == 0 { + // SAFETY: Untriaged. unsafe { let ptr = UniqueRc::into_raw(this); let value = ptr.read(); @@ -4294,6 +4367,7 @@ impl UniqueRc { && align_of::() == align_of::() && UniqueRc::weak_count(&this) == 0 { + // SAFETY: Untriaged. unsafe { let ptr = UniqueRc::into_raw(this); let value = ptr.read(); @@ -4310,6 +4384,7 @@ impl UniqueRc { #[cfg(not(no_global_oom_handling))] fn unwrap(this: Self) -> T { let this = ManuallyDrop::new(this); + // SAFETY: Untriaged. let val: T = unsafe { ptr::read(&**this) }; let _weak = Weak { ptr: this.ptr, alloc: Global }; @@ -4321,12 +4396,15 @@ impl UniqueRc { impl UniqueRc { #[cfg(not(no_global_oom_handling))] unsafe fn from_raw(ptr: *const T) -> Self { + // SAFETY: Untriaged. let offset = unsafe { data_offset(ptr) }; // Reverse the offset to find the original RcInner. + // SAFETY: Untriaged. let rc_ptr = unsafe { ptr.byte_sub(offset) as *mut RcInner }; Self { + // SAFETY: Untriaged. ptr: unsafe { NonNull::new_unchecked(rc_ptr) }, _marker: PhantomData, _marker2: PhantomData, @@ -4415,6 +4493,7 @@ impl UniqueRc { #[cfg(not(no_global_oom_handling))] fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { let this = mem::ManuallyDrop::new(this); + // SAFETY: Untriaged. (this.ptr, unsafe { ptr::read(&this.alloc) }) } @@ -4445,6 +4524,7 @@ impl UniqueRc { impl UniqueRc, A> { unsafe fn assume_init(self) -> UniqueRc { let (ptr, alloc) = UniqueRc::into_inner_with_allocator(self); + // SAFETY: Untriaged. unsafe { UniqueRc::from_inner_in(ptr.cast(), alloc) } } } @@ -4472,6 +4552,7 @@ impl DerefMut for UniqueRc { #[unstable(feature = "unique_rc_arc", issue = "112566")] unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueRc { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { // destroy the contained object drop_in_place(DerefMut::deref_mut(self)); @@ -4503,6 +4584,7 @@ impl UniqueRcUninit { #[cfg(not(no_global_oom_handling))] fn new(for_value: &T, alloc: A) -> UniqueRcUninit { let layout = Layout::for_value(for_value); + // SAFETY: Untriaged. let ptr = unsafe { Rc::allocate_for_layout( layout, @@ -4517,6 +4599,7 @@ impl UniqueRcUninit { /// returning an error if allocation fails. fn try_new(for_value: &T, alloc: A) -> Result, AllocError> { let layout = Layout::for_value(for_value); + // SAFETY: Untriaged. let ptr = unsafe { Rc::try_allocate_for_layout( layout, @@ -4530,6 +4613,7 @@ impl UniqueRcUninit { /// Returns the pointer to be written into to initialize the [`Rc`]. fn data_ptr(&mut self) -> *mut T { let offset = data_offset_alignment(self.layout_for_value.alignment()); + // SAFETY: Untriaged. unsafe { self.ptr.as_ptr().byte_add(offset) as *mut T } } diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs index e6b540f093ba5..d729eb7e92199 100644 --- a/library/alloc/src/slice.rs +++ b/library/alloc/src/slice.rs @@ -450,6 +450,7 @@ impl [T] { // allocated above with the capacity of `s`, and initialize to `s.len()` in // ptr::copy_to_non_overlapping below. if len > 0 { + // SAFETY: Untriaged. unsafe { s.as_ptr().copy_to_nonoverlapping(v.as_mut_ptr(), len); v.set_len(len); @@ -479,6 +480,7 @@ impl [T] { #[rustc_const_unstable(feature = "const_heap", issue = "79597")] #[inline] pub const fn into_vec(self: Box) -> Vec { + // SAFETY: Untriaged. unsafe { let len = self.len(); let (b, alloc) = Box::into_raw_with_allocator(self); @@ -531,6 +533,7 @@ impl [T] { // If `m > 0`, there are remaining bits up to the leftmost '1'. while m > 0 { // `buf.extend(buf)`: + // SAFETY: Untriaged. unsafe { ptr::copy_nonoverlapping::( buf.as_ptr(), @@ -551,6 +554,7 @@ impl [T] { let rem_len = capacity - buf.len(); // `self.len() * rem` if rem_len > 0 { // `buf.extend(buf[0 .. rem_len])`: + // SAFETY: Untriaged. unsafe { // This is non-overlapping since `2^expn > rem`. ptr::copy_nonoverlapping::( diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs index ee9e82368899f..c4d6e23b11061 100644 --- a/library/alloc/src/str.rs +++ b/library/alloc/src/str.rs @@ -73,6 +73,7 @@ impl> Join<&str> for [S] { type Output = String; fn join(slice: &Self, sep: &str) -> String { + // SAFETY: Untriaged. unsafe { String::from_utf8_unchecked(join_generic_copy(slice, sep.as_bytes())) } } } @@ -180,6 +181,7 @@ where result.extend_from_slice(first); + // SAFETY: Untriaged. unsafe { let pos = result.len(); debug_assert!(reserved_len >= pos); @@ -248,6 +250,7 @@ impl ToOwned for str { #[inline] fn to_owned(&self) -> String { + // SAFETY: Untriaged. unsafe { String::from_utf8_unchecked(self.as_bytes().to_owned()) } } @@ -316,6 +319,7 @@ impl str { _ => None, } { if let [to_byte] = to.as_bytes() { + // SAFETY: Untriaged. return unsafe { replace_ascii(self.as_bytes(), from_byte, *to_byte) }; } } @@ -328,10 +332,12 @@ impl str { let mut result = String::with_capacity(default_capacity); let mut last_end = 0; for (start, part) in self.match_indices(from) { + // SAFETY: Untriaged. result.push_str(unsafe { self.get_unchecked(last_end..start) }); result.push_str(to); last_end = start + part.len(); } + // SAFETY: Untriaged. result.push_str(unsafe { self.get_unchecked(last_end..self.len()) }); result } @@ -368,10 +374,12 @@ impl str { let mut result = String::with_capacity(32); let mut last_end = 0; for (start, part) in self.match_indices(pat).take(count) { + // SAFETY: Untriaged. result.push_str(unsafe { self.get_unchecked(last_end..start) }); result.push_str(to); last_end = start + part.len(); } + // SAFETY: Untriaged. result.push_str(unsafe { self.get_unchecked(last_end..self.len()) }); result } @@ -785,6 +793,7 @@ impl str { #[inline] pub fn into_string(self: Box) -> String { let slice = Box::<[u8]>::from(self); + // SAFETY: Untriaged. unsafe { String::from_utf8_unchecked(slice.into_vec()) } } @@ -814,6 +823,7 @@ impl str { #[stable(feature = "repeat_str", since = "1.16.0")] #[inline] pub fn repeat(&self, n: usize) -> String { + // SAFETY: Untriaged. unsafe { String::from_utf8_unchecked(self.as_bytes().repeat(n)) } } @@ -903,6 +913,7 @@ impl str { #[must_use] #[inline] pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box { + // SAFETY: Untriaged. unsafe { Box::from_raw(Box::into_raw(v) as *mut str) } } @@ -960,7 +971,9 @@ pub unsafe fn convert_while_ascii(s: &str, convert: fn(&u8) -> u8) -> (String, & } ascii_prefix_len += N; + // SAFETY: Untriaged. slice = unsafe { slice.get_unchecked(N..) }; + // SAFETY: Untriaged. out_slice = unsafe { out_slice.get_unchecked_mut(N..) }; } @@ -975,10 +988,13 @@ pub unsafe fn convert_while_ascii(s: &str, convert: fn(&u8) -> u8) -> (String, & *out_slice.get_unchecked_mut(0) = MaybeUninit::new(convert(&byte)); } ascii_prefix_len += 1; + // SAFETY: Untriaged. slice = unsafe { slice.get_unchecked(1..) }; + // SAFETY: Untriaged. out_slice = unsafe { out_slice.get_unchecked_mut(1..) }; } + // SAFETY: Untriaged. unsafe { // SAFETY: ascii_prefix_len bytes have been initialized above out.set_len(ascii_prefix_len); diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index cc321660e6ea4..19f06cbedac34 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -790,6 +790,7 @@ impl String { let (chunks, []) = v.as_chunks::<2>() else { return Err(FromUtf16Error { kind: FromUtf16ErrorKind::OddBytes }); }; + // SAFETY: Untriaged. match (cfg!(target_endian = "little"), unsafe { v.align_to::() }) { (true, ([], v, [])) => Self::from_utf16(v), _ => char::decode_utf16(chunks.iter().copied().map(u16::from_le_bytes)) @@ -825,6 +826,7 @@ impl String { #[cfg(not(no_global_oom_handling))] #[stable(feature = "str_from_utf16_endian", since = "1.98.0")] pub fn from_utf16le_lossy(v: &[u8]) -> String { + // SAFETY: Untriaged. match (cfg!(target_endian = "little"), unsafe { v.align_to::() }) { (true, ([], v, [])) => Self::from_utf16_lossy(v), (true, ([], v, [_remainder])) => Self::from_utf16_lossy(v) + "\u{FFFD}", @@ -863,6 +865,7 @@ impl String { let (chunks, []) = v.as_chunks::<2>() else { return Err(FromUtf16Error { kind: FromUtf16ErrorKind::OddBytes }); }; + // SAFETY: Untriaged. match (cfg!(target_endian = "big"), unsafe { v.align_to::() }) { (true, ([], v, [])) => Self::from_utf16(v), _ => char::decode_utf16(chunks.iter().copied().map(u16::from_be_bytes)) @@ -898,6 +901,7 @@ impl String { #[cfg(not(no_global_oom_handling))] #[stable(feature = "str_from_utf16_endian", since = "1.98.0")] pub fn from_utf16be_lossy(v: &[u8]) -> String { + // SAFETY: Untriaged. match (cfg!(target_endian = "big"), unsafe { v.align_to::() }) { (true, ([], v, [])) => Self::from_utf16_lossy(v), (true, ([], v, [_remainder])) => Self::from_utf16_lossy(v) + "\u{FFFD}", @@ -981,6 +985,7 @@ impl String { #[inline] #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_raw_parts(buf: *mut u8, length: usize, capacity: usize) -> String { + // SAFETY: Untriaged. unsafe { String { vec: Vec::from_raw_parts(buf, length, capacity) } } } @@ -1125,6 +1130,7 @@ impl String { let additional: Saturating = slice.iter().map(|x| Saturating(x.len())).sum(); self.reserve(additional.0); let (ptr, len, cap) = core::mem::take(self).into_raw_parts(); + // SAFETY: Untriaged. unsafe { let mut dst = ptr.add(len); for new in slice { @@ -1513,6 +1519,7 @@ impl String { pub fn pop(&mut self) -> Option { let ch = self.chars().rev().next()?; let newlen = self.len() - ch.len_utf8(); + // SAFETY: Untriaged. unsafe { self.vec.set_len(newlen); } @@ -1551,6 +1558,7 @@ impl String { let next = idx + ch.len_utf8(); let len = self.len(); + // SAFETY: Untriaged. unsafe { ptr::copy(self.vec.as_ptr().add(next), self.vec.as_mut_ptr().add(idx), len - next); self.vec.set_len(len - (next - idx)); @@ -1624,6 +1632,7 @@ impl String { len += count; } + // SAFETY: Untriaged. unsafe { self.vec.set_len(len); } @@ -1671,6 +1680,7 @@ impl String { fn drop(&mut self) { let new_len = self.idx - self.del_bytes; debug_assert!(new_len <= self.s.len()); + // SAFETY: Untriaged. unsafe { self.s.vec.set_len(new_len) }; } } @@ -1928,6 +1938,7 @@ impl String { pub fn split_off(&mut self, at: usize) -> String { assert!(self.is_char_boundary(at)); let other = self.vec.split_off(at); + // SAFETY: Untriaged. unsafe { String::from_utf8_unchecked(other) } } @@ -2104,6 +2115,7 @@ impl String { "end of range should be a character boundary" ); + // SAFETY: Untriaged. unsafe { self.as_mut_vec() }.splice(checked_range, replace_with.bytes()); } @@ -2189,6 +2201,7 @@ impl String { #[inline] pub fn into_boxed_str(self) -> Box { let slice = self.vec.into_boxed_slice(); + // SAFETY: Untriaged. unsafe { from_boxed_utf8_unchecked(slice) } } @@ -2220,6 +2233,7 @@ impl String { #[inline] pub fn leak<'a>(self) -> &'a mut str { let slice = self.vec.leak(); + // SAFETY: Untriaged. unsafe { from_utf8_unchecked_mut(slice) } } } @@ -3455,6 +3469,7 @@ impl IntoChars { #[inline] pub fn into_string(self) -> String { // Safety: `bytes` are kept in UTF-8 form, only removing whole `char`s at a time. + // SAFETY: Untriaged. unsafe { String::from_utf8_unchecked(self.bytes.collect()) } } @@ -3551,6 +3566,7 @@ unsafe impl Send for Drain<'_> {} #[stable(feature = "drain", since = "1.6.0")] impl Drop for Drain<'_> { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { // Use Vec::drain. "Reaffirm" the bounds checks to avoid // panic code being inserted again. diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 18fc19cba27d1..58f07afba212f 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -295,10 +295,12 @@ unsafe impl CloneFromCell for Arc {} impl Arc { unsafe fn from_inner(ptr: NonNull>) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_inner_in(ptr, Global) } } unsafe fn from_ptr(ptr: *mut ArcInner) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_ptr_in(ptr, Global) } } } @@ -307,6 +309,7 @@ impl Arc { #[inline] fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { let this = mem::ManuallyDrop::new(this); + // SAFETY: Untriaged. (this.ptr, unsafe { ptr::read(&this.alloc) }) } @@ -317,6 +320,7 @@ impl Arc { #[inline] unsafe fn from_ptr_in(ptr: *mut ArcInner, alloc: A) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_inner_in(NonNull::new_unchecked(ptr), alloc) } } } @@ -437,6 +441,7 @@ impl Arc { weak: atomic::AtomicUsize::new(1), data, }); + // SAFETY: Untriaged. unsafe { Self::from_inner(Box::leak(x).into()) } } @@ -522,6 +527,7 @@ impl Arc { #[stable(feature = "new_uninit", since = "1.82.0")] #[must_use] pub fn new_uninit() -> Arc> { + // SAFETY: Untriaged. unsafe { Arc::from_ptr(Arc::allocate_for_layout( Layout::new::(), @@ -554,6 +560,7 @@ impl Arc { #[stable(feature = "new_zeroed_alloc", since = "1.92.0")] #[must_use] pub fn new_zeroed() -> Arc> { + // SAFETY: Untriaged. unsafe { Arc::from_ptr(Arc::allocate_for_layout( Layout::new::(), @@ -569,6 +576,7 @@ impl Arc { #[stable(feature = "pin", since = "1.33.0")] #[must_use] pub fn pin(data: T) -> Pin> { + // SAFETY: Untriaged. unsafe { Pin::new_unchecked(Arc::new(data)) } } @@ -576,6 +584,7 @@ impl Arc { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn try_pin(data: T) -> Result>, AllocError> { + // SAFETY: Untriaged. unsafe { Ok(Pin::new_unchecked(Arc::try_new(data)?)) } } @@ -600,6 +609,7 @@ impl Arc { weak: atomic::AtomicUsize::new(1), data, })?; + // SAFETY: Untriaged. unsafe { Ok(Self::from_inner(Box::leak(x).into())) } } @@ -625,6 +635,7 @@ impl Arc { /// ``` #[unstable(feature = "allocator_api", issue = "32838")] pub fn try_new_uninit() -> Result>, AllocError> { + // SAFETY: Untriaged. unsafe { Ok(Arc::from_ptr(Arc::try_allocate_for_layout( Layout::new::(), @@ -657,6 +668,7 @@ impl Arc { /// [zeroed]: mem::MaybeUninit::zeroed #[unstable(feature = "allocator_api", issue = "32838")] pub fn try_new_zeroed() -> Result>, AllocError> { + // SAFETY: Untriaged. unsafe { Ok(Arc::from_ptr(Arc::try_allocate_for_layout( Layout::new::(), @@ -693,6 +705,7 @@ impl Arc { && align_of::() == align_of::() && Arc::is_unique(&this) { + // SAFETY: Untriaged. unsafe { let ptr = Arc::into_raw(this); let value = ptr.read(); @@ -740,6 +753,7 @@ impl Arc { && align_of::() == align_of::() && Arc::is_unique(&this) { + // SAFETY: Untriaged. unsafe { let ptr = Arc::into_raw(this); let value = ptr.read(); @@ -782,6 +796,7 @@ impl Arc { alloc, ); let (ptr, alloc) = Box::into_unique(x); + // SAFETY: Untriaged. unsafe { Self::from_inner_in(ptr.into(), alloc) } } @@ -811,6 +826,7 @@ impl Arc { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn new_uninit_in(alloc: A) -> Arc, A> { + // SAFETY: Untriaged. unsafe { Arc::from_ptr_in( Arc::allocate_for_layout( @@ -848,6 +864,7 @@ impl Arc { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn new_zeroed_in(alloc: A) -> Arc, A> { + // SAFETY: Untriaged. unsafe { Arc::from_ptr_in( Arc::allocate_for_layout( @@ -906,6 +923,7 @@ impl Arc { }, alloc, )); + // SAFETY: Untriaged. let uninit_ptr: NonNull<_> = (unsafe { &mut *uninit_raw_ptr }).into(); let init_ptr: NonNull> = uninit_ptr.cast(); @@ -921,6 +939,7 @@ impl Arc { // Now we can properly initialize the inner value and turn our weak // reference into a strong reference. + // SAFETY: Untriaged. let strong = unsafe { let inner = init_ptr.as_ptr(); ptr::write(&raw mut (*inner).data, data); @@ -961,6 +980,7 @@ impl Arc { where A: 'static, { + // SAFETY: Untriaged. unsafe { Pin::new_unchecked(Arc::new_in(data, alloc)) } } @@ -972,6 +992,7 @@ impl Arc { where A: 'static, { + // SAFETY: Untriaged. unsafe { Ok(Pin::new_unchecked(Arc::try_new_in(data, alloc)?)) } } @@ -1002,6 +1023,7 @@ impl Arc { alloc, )?; let (ptr, alloc) = Box::into_unique(x); + // SAFETY: Untriaged. Ok(unsafe { Self::from_inner_in(ptr.into(), alloc) }) } @@ -1032,6 +1054,7 @@ impl Arc { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn try_new_uninit_in(alloc: A) -> Result, A>, AllocError> { + // SAFETY: Untriaged. unsafe { Ok(Arc::from_ptr_in( Arc::try_allocate_for_layout( @@ -1070,6 +1093,7 @@ impl Arc { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn try_new_zeroed_in(alloc: A) -> Result, A>, AllocError> { + // SAFETY: Untriaged. unsafe { Ok(Arc::from_ptr_in( Arc::try_allocate_for_layout( @@ -1124,7 +1148,9 @@ impl Arc { acquire!(this.inner().strong); let this = ManuallyDrop::new(this); + // SAFETY: Untriaged. let elem: T = unsafe { ptr::read(&this.ptr.as_ref().data) }; + // SAFETY: Untriaged. let alloc: A = unsafe { ptr::read(&this.alloc) }; // copy the allocator // Make a weak pointer to clean up the implicit strong-weak reference @@ -1251,6 +1277,7 @@ impl Arc { // safety conditions as `ptr::drop_in_place`. let inner = unsafe { ptr::read(Self::get_mut_unchecked(&mut this)) }; + // SAFETY: Untriaged. let alloc = unsafe { ptr::read(&this.alloc) }; drop(Weak { ptr: this.ptr, alloc }); @@ -1284,6 +1311,7 @@ impl Arc<[T]> { #[stable(feature = "new_uninit", since = "1.82.0")] #[must_use] pub fn new_uninit_slice(len: usize) -> Arc<[mem::MaybeUninit]> { + // SAFETY: Untriaged. unsafe { Arc::from_ptr(Arc::allocate_for_slice(len)) } } @@ -1310,6 +1338,7 @@ impl Arc<[T]> { #[stable(feature = "new_zeroed_alloc", since = "1.92.0")] #[must_use] pub fn new_zeroed_slice(len: usize) -> Arc<[mem::MaybeUninit]> { + // SAFETY: Untriaged. unsafe { Arc::from_ptr(Arc::allocate_for_layout( Layout::array::(len).unwrap(), @@ -1350,6 +1379,7 @@ impl Arc<[T], A> { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn new_uninit_slice_in(len: usize, alloc: A) -> Arc<[mem::MaybeUninit], A> { + // SAFETY: Untriaged. unsafe { Arc::from_ptr_in(Arc::allocate_for_slice_in(len, &alloc), alloc) } } @@ -1378,6 +1408,7 @@ impl Arc<[T], A> { #[unstable(feature = "allocator_api", issue = "32838")] #[inline] pub fn new_zeroed_slice_in(len: usize, alloc: A) -> Arc<[mem::MaybeUninit], A> { + // SAFETY: Untriaged. unsafe { Arc::from_ptr_in( Arc::allocate_for_layout( @@ -1457,6 +1488,7 @@ impl Arc, A> { #[inline] pub unsafe fn assume_init(self) -> Arc { let (ptr, alloc) = Arc::into_inner_with_allocator(self); + // SAFETY: Untriaged. unsafe { Arc::from_inner_in(ptr.cast(), alloc) } } } @@ -1518,6 +1550,7 @@ impl Arc { let mut in_progress: UniqueArcUninit = UniqueArcUninit::new(value, alloc); // Initialize with clone of value. + // SAFETY: Untriaged. let initialized_clone = unsafe { // Clone. If the clone panics, `in_progress` will be dropped and clean up. value.clone_to_uninit(in_progress.data_ptr().cast()); @@ -1548,6 +1581,7 @@ impl Arc { let mut in_progress: UniqueArcUninit = UniqueArcUninit::try_new(value, alloc)?; // Initialize with clone of value. + // SAFETY: Untriaged. let initialized_clone = unsafe { // Clone. If the clone panics, `in_progress` will be dropped and clean up. value.clone_to_uninit(in_progress.data_ptr().cast()); @@ -1594,6 +1628,7 @@ impl Arc<[mem::MaybeUninit], A> { #[inline] pub unsafe fn assume_init(self) -> Arc<[T], A> { let (ptr, alloc) = Arc::into_inner_with_allocator(self); + // SAFETY: Untriaged. unsafe { Arc::from_ptr_in(ptr.as_ptr() as _, alloc) } } } @@ -1666,6 +1701,7 @@ impl Arc { #[inline] #[stable(feature = "rc_raw", since = "1.17.0")] pub unsafe fn from_raw(ptr: *const T) -> Self { + // SAFETY: Untriaged. unsafe { Arc::from_raw_in(ptr, Global) } } @@ -1728,6 +1764,7 @@ impl Arc { #[inline] #[stable(feature = "arc_mutate_strong_count", since = "1.51.0")] pub unsafe fn increment_strong_count(ptr: *const T) { + // SAFETY: Untriaged. unsafe { Arc::increment_strong_count_in(ptr, Global) } } @@ -1768,6 +1805,7 @@ impl Arc { #[inline] #[stable(feature = "arc_mutate_strong_count", since = "1.51.0")] pub unsafe fn decrement_strong_count(ptr: *const T) { + // SAFETY: Untriaged. unsafe { Arc::decrement_strong_count_in(ptr, Global) } } } @@ -1808,6 +1846,7 @@ impl Arc { let this = mem::ManuallyDrop::new(this); let ptr = Self::as_ptr(&this); // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped + // SAFETY: Untriaged. let alloc = unsafe { ptr::read(&this.alloc) }; (ptr, alloc) } @@ -1913,6 +1952,7 @@ impl Arc { #[inline] #[unstable(feature = "allocator_api", issue = "32838")] pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self { + // SAFETY: Untriaged. unsafe { let offset = data_offset(ptr); @@ -2073,6 +2113,7 @@ impl Arc { A: Clone, { // Retain Arc, but don't touch refcount by wrapping in ManuallyDrop + // SAFETY: Untriaged. let arc = unsafe { mem::ManuallyDrop::new(Arc::from_raw_in(ptr, alloc)) }; // Now increase refcount, but don't drop new refcount either let _arc_clone: mem::ManuallyDrop<_> = arc.clone(); @@ -2118,6 +2159,7 @@ impl Arc { #[inline] #[unstable(feature = "allocator_api", issue = "32838")] pub unsafe fn decrement_strong_count_in(ptr: *const T, alloc: A) { + // SAFETY: Untriaged. unsafe { drop(Arc::from_raw_in(ptr, alloc)) }; } @@ -2128,6 +2170,7 @@ impl Arc { // `ArcInner` structure itself is `Sync` because the inner data is // `Sync` as well, so we're ok loaning out an immutable pointer to these // contents. + // SAFETY: Untriaged. unsafe { self.ptr.as_ref() } } @@ -2144,6 +2187,7 @@ impl Arc { // Destroy the data at this time, even though we must not free the box // allocation itself (there might still be weak pointers lying around). // We cannot use `get_mut_unchecked` here, because `self.alloc` is borrowed. + // SAFETY: Untriaged. unsafe { ptr::drop_in_place(&mut (*self.ptr.as_ptr()).data) }; } @@ -2188,6 +2232,7 @@ impl Arc { let ptr = allocate(layout).unwrap_or_else(|_| handle_alloc_error(layout)); + // SAFETY: Untriaged. unsafe { Self::initialize_arcinner(ptr, layout, mem_to_arcinner) } } @@ -2206,6 +2251,7 @@ impl Arc { let ptr = allocate(layout)?; + // SAFETY: Untriaged. let inner = unsafe { Self::initialize_arcinner(ptr, layout, mem_to_arcinner) }; Ok(inner) @@ -2217,8 +2263,10 @@ impl Arc { mem_to_arcinner: impl FnOnce(*mut u8) -> *mut ArcInner, ) -> *mut ArcInner { let inner = mem_to_arcinner(ptr.as_non_null_ptr().as_ptr()); + // SAFETY: Untriaged. debug_assert_eq!(unsafe { Layout::for_value_raw(inner) }, layout); + // SAFETY: Untriaged. unsafe { (&raw mut (*inner).strong).write(atomic::AtomicUsize::new(1)); (&raw mut (*inner).weak).write(atomic::AtomicUsize::new(1)); @@ -2234,6 +2282,7 @@ impl Arc { #[cfg(not(no_global_oom_handling))] unsafe fn allocate_for_ptr_in(ptr: *const T, alloc: &A) -> *mut ArcInner { // Allocate for the `ArcInner` using the given value. + // SAFETY: Untriaged. unsafe { Arc::allocate_for_layout( Layout::for_value_raw(ptr), @@ -2245,6 +2294,7 @@ impl Arc { #[cfg(not(no_global_oom_handling))] fn from_box_in(src: Box) -> Arc { + // SAFETY: Untriaged. unsafe { let value_size = size_of_val(&*src); let ptr = Self::allocate_for_ptr_in(&*src, Box::allocator(&src)); @@ -2270,6 +2320,7 @@ impl Arc<[T]> { /// Allocates an `ArcInner<[T]>` with the given length. #[cfg(not(no_global_oom_handling))] unsafe fn allocate_for_slice(len: usize) -> *mut ArcInner<[T]> { + // SAFETY: Untriaged. unsafe { Self::allocate_for_layout( Layout::array::(len).unwrap(), @@ -2285,6 +2336,7 @@ impl Arc<[T]> { /// bind `T: TrivialClone`. #[cfg(not(no_global_oom_handling))] unsafe fn copy_from_slice(v: &[T]) -> Arc<[T]> { + // SAFETY: Untriaged. unsafe { let ptr = Self::allocate_for_slice(v.len()); @@ -2311,6 +2363,7 @@ impl Arc<[T]> { impl Drop for Guard { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { let slice = from_raw_parts_mut(self.elems, self.n_elems); ptr::drop_in_place(slice); @@ -2320,6 +2373,7 @@ impl Arc<[T]> { } } + // SAFETY: Untriaged. unsafe { let ptr = Self::allocate_for_slice(len); @@ -2349,6 +2403,7 @@ impl Arc<[T], A> { #[inline] #[cfg(not(no_global_oom_handling))] unsafe fn allocate_for_slice_in(len: usize, alloc: &A) -> *mut ArcInner<[T]> { + // SAFETY: Untriaged. unsafe { Arc::allocate_for_layout( Layout::array::(len).unwrap(), @@ -2369,6 +2424,7 @@ trait ArcFromSlice { impl ArcFromSlice for Arc<[T]> { #[inline] default fn from_slice(v: &[T]) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_iter_exact(v.iter().cloned(), v.len()) } } } @@ -2433,6 +2489,7 @@ impl Clone for Arc { abort(); } + // SAFETY: Untriaged. unsafe { Self::from_inner_in(self.ptr, self.alloc.clone()) } } } @@ -2572,6 +2629,7 @@ impl Arc { let mut in_progress: UniqueArcUninit = UniqueArcUninit::new(&**this, this.alloc.clone()); + // SAFETY: Untriaged. unsafe { // Initialize `in_progress` with move of **this. // We have to express this in terms of bytes because `T: ?Sized`; there is no @@ -2601,6 +2659,7 @@ impl Arc { // As with `get_mut()`, the unsafety is ok because our reference was // either unique to begin with, or became one upon cloning the contents. + // SAFETY: Untriaged. unsafe { Self::get_mut_unchecked(this) } } } @@ -2675,6 +2734,7 @@ impl Arc { // reference count is guaranteed to be 1 at this point, and we required // the Arc itself to be `mut`, so we're returning the only possible // reference to the inner data. + // SAFETY: Untriaged. unsafe { Some(Arc::get_mut_unchecked(this)) } } else { None @@ -2746,6 +2806,7 @@ impl Arc { pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T { // We are careful to *not* create a reference covering the "count" fields, as // this would alias with concurrent access to the reference counts (e.g. by `Weak`). + // SAFETY: Untriaged. unsafe { &mut (*this.ptr.as_ptr()).data } } @@ -2905,6 +2966,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Arc { Likely decrement_strong_count or from_raw were called too many times.", ); + // SAFETY: Untriaged. unsafe { self.drop_slow(); } @@ -2937,6 +2999,7 @@ impl Arc { T: Any + Send + Sync, { if (*self).is::() { + // SAFETY: Untriaged. unsafe { let (ptr, alloc) = Arc::into_inner_with_allocator(self); Ok(Arc::from_inner_in(ptr.cast(), alloc)) @@ -2978,6 +3041,7 @@ impl Arc { where T: Any + Send + Sync, { + // SAFETY: Untriaged. unsafe { let (ptr, alloc) = Arc::into_inner_with_allocator(self); Arc::from_inner_in(ptr.cast(), alloc) @@ -3085,6 +3149,7 @@ impl Weak { #[inline] #[stable(feature = "weak_into_raw", since = "1.45.0")] pub unsafe fn from_raw(ptr: *const T) -> Self { + // SAFETY: Untriaged. unsafe { Weak::from_raw_in(ptr, Global) } } @@ -3207,6 +3272,7 @@ impl Weak { let this = mem::ManuallyDrop::new(self); let result = this.as_ptr(); // Safety: `this` is ManuallyDrop so the allocator will not be double-dropped + // SAFETY: Untriaged. let alloc = unsafe { ptr::read(&this.alloc) }; (result, alloc) } @@ -3391,6 +3457,7 @@ impl Weak { // We are careful to *not* create a reference covering the "data" field, as // the field may be mutated concurrently (for example, if the last `Arc` // is dropped, the data field will be dropped in-place). + // SAFETY: Untriaged. Some(unsafe { WeakInner { strong: &(*ptr).strong, weak: &(*ptr).weak } }) } } @@ -3548,6 +3615,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for Weak { Likely decrement_strong_count or from_raw were called too many times.", ); + // SAFETY: Untriaged. unsafe { self.alloc.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr())) } @@ -3785,6 +3853,7 @@ impl Default for Arc { /// assert_eq!(*x, 0); /// ``` fn default() -> Arc { + // SAFETY: Untriaged. unsafe { Self::from_inner( Box::leak(Box::write( @@ -3834,6 +3903,7 @@ impl Default for Arc { let arc: Arc<[u8]> = Default::default(); debug_assert!(core::str::from_utf8(&*arc).is_ok()); let (ptr, alloc) = Arc::into_inner_with_allocator(arc); + // SAFETY: Untriaged. unsafe { Arc::from_ptr_in(ptr.as_ptr() as *mut ArcInner, alloc) } } } @@ -3852,6 +3922,7 @@ impl Default for Arc { NonNull::new(inner.as_ptr() as *mut ArcInner).unwrap(); // `this` semantically is the Arc "owned" by the static, so make sure not to drop it. let this: mem::ManuallyDrop> = +// SAFETY: Untriaged. unsafe { mem::ManuallyDrop::new(Arc::from_inner(inner)) }; (*this).clone() } @@ -3874,6 +3945,7 @@ impl Default for Arc<[T]> { let inner: NonNull> = inner.cast(); // `this` semantically is the Arc "owned" by the static, so make sure not to drop it. let this: mem::ManuallyDrop> = +// SAFETY: Untriaged. unsafe { mem::ManuallyDrop::new(Arc::from_inner(inner)) }; return (*this).clone(); } @@ -3893,6 +3965,7 @@ where { #[inline] fn default() -> Self { + // SAFETY: Untriaged. unsafe { Pin::new_unchecked(Arc::::default()) } } } @@ -4001,6 +4074,7 @@ impl From<&str> for Arc { #[inline] fn from(v: &str) -> Arc { let arc = Arc::<[u8]>::from(v.as_bytes()); + // SAFETY: Untriaged. unsafe { Arc::from_raw(Arc::into_raw(arc) as *const str) } } } @@ -4078,6 +4152,7 @@ impl From> for Arc<[T], A> { /// ``` #[inline] fn from(v: Vec) -> Arc<[T], A> { + // SAFETY: Untriaged. unsafe { let (vec_ptr, len, cap, alloc) = v.into_raw_parts_with_alloc(); @@ -4146,6 +4221,7 @@ impl TryFrom> for Arc<[T; N], A> { fn try_from(boxed_slice: Arc<[T], A>) -> Result { if boxed_slice.len() == N { let (ptr, alloc) = Arc::into_inner_with_allocator(boxed_slice); + // SAFETY: Untriaged. Ok(unsafe { Arc::from_inner_in(ptr.cast(), alloc) }) } else { Err(boxed_slice) @@ -4225,6 +4301,7 @@ impl> ToArcSlice for I { (low, high) ); + // SAFETY: Untriaged. unsafe { // SAFETY: We need to ensure that the iterator has an exact length and we have. Arc::from_iter_exact(self, low) @@ -4293,6 +4370,7 @@ impl UniqueArcUninit { #[cfg(not(no_global_oom_handling))] fn new(for_value: &T, alloc: A) -> UniqueArcUninit { let layout = Layout::for_value(for_value); + // SAFETY: Untriaged. let ptr = unsafe { Arc::allocate_for_layout( layout, @@ -4307,6 +4385,7 @@ impl UniqueArcUninit { /// returning an error if allocation fails. fn try_new(for_value: &T, alloc: A) -> Result, AllocError> { let layout = Layout::for_value(for_value); + // SAFETY: Untriaged. let ptr = unsafe { Arc::try_allocate_for_layout( layout, @@ -4320,6 +4399,7 @@ impl UniqueArcUninit { /// Returns the pointer to be written into to initialize the [`Arc`]. fn data_ptr(&mut self) -> *mut T { let offset = data_offset_alignment(self.layout_for_value.alignment()); + // SAFETY: Untriaged. unsafe { self.ptr.as_ptr().byte_add(offset) as *mut T } } @@ -4692,6 +4772,7 @@ impl UniqueArc { && align_of::() == align_of::() && UniqueArc::weak_count(&this) == 0 { + // SAFETY: Untriaged. unsafe { let ptr = UniqueArc::into_raw(this); let value = ptr.read(); @@ -4740,6 +4821,7 @@ impl UniqueArc { && align_of::() == align_of::() && UniqueArc::weak_count(&this) == 0 { + // SAFETY: Untriaged. unsafe { let ptr = UniqueArc::into_raw(this); let value = ptr.read(); @@ -4756,6 +4838,7 @@ impl UniqueArc { #[cfg(not(no_global_oom_handling))] fn unwrap(this: Self) -> T { let this = ManuallyDrop::new(this); + // SAFETY: Untriaged. let val: T = unsafe { ptr::read(&**this) }; let _weak = Weak { ptr: this.ptr, alloc: Global }; @@ -4767,12 +4850,15 @@ impl UniqueArc { impl UniqueArc { #[cfg(not(no_global_oom_handling))] unsafe fn from_raw(ptr: *const T) -> Self { + // SAFETY: Untriaged. let offset = unsafe { data_offset(ptr) }; // Reverse the offset to find the original ArcInner. + // SAFETY: Untriaged. let rc_ptr = unsafe { ptr.byte_sub(offset) as *mut ArcInner }; Self { + // SAFETY: Untriaged. ptr: unsafe { NonNull::new_unchecked(rc_ptr) }, _marker: PhantomData, _marker2: PhantomData, @@ -4864,6 +4950,7 @@ impl UniqueArc { #[cfg(not(no_global_oom_handling))] fn into_inner_with_allocator(this: Self) -> (NonNull>, A) { let this = mem::ManuallyDrop::new(this); + // SAFETY: Untriaged. (this.ptr, unsafe { ptr::read(&this.alloc) }) } @@ -4906,6 +4993,7 @@ impl UniqueArc { impl UniqueArc, A> { unsafe fn assume_init(self) -> UniqueArc { let (ptr, alloc) = UniqueArc::into_inner_with_allocator(self); + // SAFETY: Untriaged. unsafe { UniqueArc::from_inner_in(ptr.cast(), alloc) } } } @@ -4948,6 +5036,7 @@ unsafe impl<#[may_dangle] T: ?Sized, A: Allocator> Drop for UniqueArc { // SAFETY: This pointer was allocated at creation time so we know it is valid. let _weak = Weak { ptr: self.ptr, alloc: &self.alloc }; + // SAFETY: Untriaged. unsafe { ptr::drop_in_place(&mut (*self.ptr.as_ptr()).data) }; } } diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index 0e36c91f466fd..43e3ce8d6701e 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -189,6 +189,7 @@ fn raw_waker(waker: Arc) -> RawWaker { // within the vtables. #[inline(always)] unsafe fn clone_waker(waker: *const ()) -> RawWaker { + // SAFETY: Untriaged. unsafe { Arc::increment_strong_count(waker as *const W) }; RawWaker::new( waker, @@ -198,18 +199,21 @@ fn raw_waker(waker: Arc) -> RawWaker { // Wake by value, moving the Arc into the Wake::wake function unsafe fn wake(waker: *const ()) { + // SAFETY: Untriaged. let waker = unsafe { Arc::from_raw(waker as *const W) }; ::wake(waker); } // Wake by reference, wrap the waker in ManuallyDrop to avoid dropping it unsafe fn wake_by_ref(waker: *const ()) { + // SAFETY: Untriaged. let waker = unsafe { ManuallyDrop::new(Arc::from_raw(waker as *const W)) }; ::wake_by_ref(&waker); } // Decrement the reference count of the Arc on drop unsafe fn drop_waker(waker: *const ()) { + // SAFETY: Untriaged. unsafe { Arc::decrement_strong_count(waker as *const W) }; } @@ -401,6 +405,7 @@ fn local_raw_waker(waker: Rc) -> RawWaker { // always inline. #[inline(always)] unsafe fn clone_waker(waker: *const ()) -> RawWaker { + // SAFETY: Untriaged. unsafe { Rc::increment_strong_count(waker as *const W) }; RawWaker::new( waker, @@ -410,18 +415,21 @@ fn local_raw_waker(waker: Rc) -> RawWaker { // Wake by value, moving the Rc into the LocalWake::wake function unsafe fn wake(waker: *const ()) { + // SAFETY: Untriaged. let waker = unsafe { Rc::from_raw(waker as *const W) }; ::wake(waker); } // Wake by reference, wrap the waker in ManuallyDrop to avoid dropping it unsafe fn wake_by_ref(waker: *const ()) { + // SAFETY: Untriaged. let waker = unsafe { ManuallyDrop::new(Rc::from_raw(waker as *const W)) }; ::wake_by_ref(&waker); } // Decrement the reference count of the Rc on drop unsafe fn drop_waker(waker: *const ()) { + // SAFETY: Untriaged. unsafe { Rc::decrement_strong_count(waker as *const W) }; } diff --git a/library/alloc/src/vec/drain.rs b/library/alloc/src/vec/drain.rs index d12dea20b33cb..bef7c86cc102d 100644 --- a/library/alloc/src/vec/drain.rs +++ b/library/alloc/src/vec/drain.rs @@ -62,6 +62,7 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> { #[must_use] #[inline] pub fn allocator(&self) -> &A { + // SAFETY: Untriaged. unsafe { self.vec.as_ref().allocator() } } @@ -101,6 +102,7 @@ impl<'a, T, A: Allocator> Drain<'a, T, A> { // 4. Do *not* drop self, as everything is put in a consistent state already, there is nothing to do let mut this = ManuallyDrop::new(self); + // SAFETY: Untriaged. unsafe { let source_vec = this.vec.as_mut(); @@ -153,6 +155,7 @@ impl Iterator for Drain<'_, T, A> { #[inline] fn next(&mut self) -> Option { + // SAFETY: Untriaged. self.iter.next().map(|elt| unsafe { ptr::read(elt as *const _) }) } @@ -165,6 +168,7 @@ impl Iterator for Drain<'_, T, A> { impl DoubleEndedIterator for Drain<'_, T, A> { #[inline] fn next_back(&mut self) -> Option { + // SAFETY: Untriaged. self.iter.next_back().map(|elt| unsafe { ptr::read(elt as *const _) }) } } @@ -178,6 +182,7 @@ impl Drop for Drain<'_, T, A> { impl<'r, 'a, T, A: Allocator> Drop for DropGuard<'r, 'a, T, A> { fn drop(&mut self) { if self.0.tail_len > 0 { + // SAFETY: Untriaged. unsafe { let source_vec = self.0.vec.as_mut(); // memmove back untouched tail, update to new length @@ -202,6 +207,7 @@ impl Drop for Drain<'_, T, A> { if T::IS_ZST { // ZSTs have no identity, so we don't need to move them around, we only need to drop the correct amount. // this can be achieved by manipulating the Vec length instead of moving values out from `iter`. + // SAFETY: Untriaged. unsafe { let vec = vec.as_mut(); let old_len = vec.len(); @@ -225,6 +231,7 @@ impl Drop for Drain<'_, T, A> { // lead to invalid pointer arithmetic below. let drop_ptr = iter.as_slice().as_ptr(); + // SAFETY: Untriaged. unsafe { // drop_ptr comes from a slice::Iter which only gives us a &[T] but for drop_in_place // a pointer with mutable provenance is necessary. Therefore we must reconstruct diff --git a/library/alloc/src/vec/extract_if.rs b/library/alloc/src/vec/extract_if.rs index a4c4c19682195..a457bf7c4ffcc 100644 --- a/library/alloc/src/vec/extract_if.rs +++ b/library/alloc/src/vec/extract_if.rs @@ -43,6 +43,7 @@ impl<'a, T, F, A: Allocator> ExtractIf<'a, T, F, A> { let Range { start, end } = slice::range(range, ..old_len); // Guard against the vec getting leaked (leak amplification) + // SAFETY: Untriaged. unsafe { vec.set_len(0); } @@ -139,10 +140,12 @@ where // SAFETY: we have not yet touched elements starting at `self.idx`. let valid_tail = +// SAFETY: Untriaged. unsafe { slice::from_raw_parts(start.add(self.idx), self.old_len - self.idx) }; // SAFETY: `end - idx <= old_len - idx`, because `end <= old_len`. Also `idx <= end` by invariant. let (remainder, skipped_tail) = +// SAFETY: Untriaged. unsafe { valid_tail.split_at_unchecked(self.end - self.idx) }; f.debug_struct("ExtractIf") diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs index 8a7c0b92eccf6..460b437a52969 100644 --- a/library/alloc/src/vec/in_place_collect.rs +++ b/library/alloc/src/vec/in_place_collect.rs @@ -251,6 +251,7 @@ where I: Iterator + InPlaceCollect, ::Source: AsVecIntoIter, { + // SAFETY: Untriaged. let (src_buf, src_ptr, src_cap, mut dst_buf, dst_end, dst_cap) = unsafe { let inner = iterator.as_inner().as_into_iter(); ( @@ -269,6 +270,7 @@ where SpecInPlaceCollect::collect_in_place(&mut iterator, dst_buf.as_ptr() as *mut T, dst_end) }; + // SAFETY: Untriaged. let src = unsafe { iterator.as_inner().as_into_iter() }; // check if SourceIter contract was upheld // caveat: if they weren't we might not even make it to this point @@ -278,6 +280,7 @@ where // then the source pointer will stay in its initial position and we can't use it as reference if src.ptr != src_ptr { debug_assert!( + // SAFETY: Untriaged. unsafe { dst_buf.add(len).cast() } <= src.ptr, "InPlaceIterable contract violation, write pointer advanced beyond read pointer" ); @@ -306,6 +309,7 @@ where let alloc = Global; debug_assert_ne!(src_cap, 0); debug_assert_ne!(dst_cap, 0); + // SAFETY: Untriaged. unsafe { // The old allocation exists, therefore it must have a valid layout. let src_align = align_of::(); @@ -328,6 +332,7 @@ where mem::forget(dst_guard); + // SAFETY: Untriaged. let vec = unsafe { Vec::from_parts(dst_buf, len, dst_cap) }; vec @@ -337,6 +342,7 @@ fn write_in_place_with_drop( src_end: *const T, ) -> impl FnMut(InPlaceDrop, T) -> Result, !> { move |mut sink, item| { + // SAFETY: Untriaged. unsafe { // the InPlaceIterable contract cannot be verified precisely here since // try_fold has an exclusive reference to the source pointer @@ -377,6 +383,7 @@ where let sink = self.try_fold::<_, _, Result<_, !>>(sink, write_in_place_with_drop(end)).into_ok(); // iteration succeeded, don't drop head + // SAFETY: Untriaged. unsafe { ManuallyDrop::new(sink).dst.offset_from_unsigned(dst_buf) } } } @@ -393,6 +400,7 @@ where // Safety: InplaceIterable contract guarantees that for every element we read // one slot in the underlying storage will have been freed up and we can immediately // write back the result. + // SAFETY: Untriaged. unsafe { let dst = dst_buf.add(i); debug_assert!(dst as *const _ <= end, "InPlaceIterable contract violation"); diff --git a/library/alloc/src/vec/in_place_drop.rs b/library/alloc/src/vec/in_place_drop.rs index 5c3d598cdef0c..50d3b4d7ab004 100644 --- a/library/alloc/src/vec/in_place_drop.rs +++ b/library/alloc/src/vec/in_place_drop.rs @@ -13,6 +13,7 @@ pub(super) struct InPlaceDrop { impl InPlaceDrop { fn len(&self) -> usize { + // SAFETY: Untriaged. unsafe { self.dst.offset_from_unsigned(self.inner) } } } @@ -20,6 +21,7 @@ impl InPlaceDrop { impl Drop for InPlaceDrop { #[inline] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { self.inner.cast_slice(self.len()).drop_in_place() } } } @@ -37,6 +39,7 @@ pub(super) struct InPlaceDstDataSrcBufDrop { impl Drop for InPlaceDstDataSrcBufDrop { #[inline] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { let _drop_allocation = RawVec::::from_nonnull_in(self.ptr.cast::(), self.src_cap, Global); diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 4b25634326e16..bf4e32285d164 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -21,10 +21,12 @@ use crate::raw_vec::RawVec; macro non_null { (mut $place:expr, $t:ident) => {{ #![allow(unused_unsafe)] // we're sometimes used within an unsafe block +// SAFETY: Untriaged. unsafe { &mut *((&raw mut $place) as *mut NonNull<$t>) } }}, ($place:expr, $t:ident) => {{ #![allow(unused_unsafe)] // we're sometimes used within an unsafe block +// SAFETY: Untriaged. unsafe { *((&raw const $place) as *const NonNull<$t>) } }}, } @@ -86,6 +88,7 @@ impl IntoIter { /// ``` #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")] pub fn as_slice(&self) -> &[T] { + // SAFETY: Untriaged. unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len()) } } @@ -104,6 +107,7 @@ impl IntoIter { /// ``` #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")] pub fn as_mut_slice(&mut self) -> &mut [T] { + // SAFETY: Untriaged. unsafe { &mut *self.as_raw_mut_slice() } } @@ -153,6 +157,7 @@ impl IntoIter { // Dropping the remaining elements can panic, so this needs to be // done only after updating the other fields. + // SAFETY: Untriaged. unsafe { ptr::drop_in_place(remaining); } @@ -196,6 +201,7 @@ impl IntoIter { /// memory if there are any remaining elements. #[inline] unsafe fn dealloc_only(&mut self) { + // SAFETY: Untriaged. unsafe { // SAFETY: our caller promises not to touch `*self` again let alloc = ManuallyDrop::take(&mut self.alloc); @@ -263,9 +269,11 @@ impl Iterator for IntoIter { return None; } let old = self.ptr; + // SAFETY: Untriaged. self.ptr = unsafe { old.add(1) }; old }; + // SAFETY: Untriaged. Some(unsafe { ptr.read() }) } @@ -274,6 +282,7 @@ impl Iterator for IntoIter { let exact = if T::IS_ZST { self.end.addr().wrapping_sub(self.ptr.as_ptr().addr()) } else { + // SAFETY: Untriaged. unsafe { non_null!(self.end, T).offset_from_unsigned(self.ptr) } }; (exact, Some(exact)) @@ -317,17 +326,20 @@ impl Iterator for IntoIter { if len < N { self.forget_remaining_elements(); // Safety: ZSTs can be conjured ex nihilo, only the amount has to be correct + // SAFETY: Untriaged. return Err(unsafe { array::IntoIter::new_unchecked(raw_ary, 0..len) }); } self.end = self.end.wrapping_byte_sub(N); // Safety: ditto + // SAFETY: Untriaged. return Ok(unsafe { raw_ary.transpose().assume_init() }); } if len < N { // Safety: `len` indicates that this many elements are available and we just checked that // it fits into the array. + // SAFETY: Untriaged. unsafe { ptr::copy_nonoverlapping(self.ptr.as_ptr(), raw_ary.as_mut_ptr() as *mut T, len); self.forget_remaining_elements(); @@ -337,6 +349,7 @@ impl Iterator for IntoIter { // Safety: `len` is larger than the array size. Copy a fixed amount here to fully initialize // the array. + // SAFETY: Untriaged. unsafe { ptr::copy_nonoverlapping(self.ptr.as_ptr(), raw_ary.as_mut_ptr() as *mut T, N); self.ptr = self.ptr.add(N); @@ -433,11 +446,13 @@ impl DoubleEndedIterator for IntoIter { // Note that even though this is next_back() we're reading from `self.ptr`, not // `self.end`. We track our length using the byte offset from `self.ptr` to `self.end`, // so the end pointer may not be suitably aligned for T. + // SAFETY: Untriaged. Some(unsafe { ptr::read(self.ptr.as_ptr()) }) } else { if self.ptr == non_null!(self.end, T) { return None; } + // SAFETY: Untriaged. unsafe { self.end = self.end.sub(1); Some(ptr::read(self.end)) @@ -455,17 +470,20 @@ impl DoubleEndedIterator for IntoIter { if len < N { self.forget_remaining_elements(); // Safety: ZSTs can be conjured ex nihilo, only the amount has to be correct + // SAFETY: Untriaged. return Err(unsafe { array::IntoIter::new_unchecked(raw_ary, N - len..N) }); } self.end = self.end.wrapping_byte_sub(N); // Safety: ditto + // SAFETY: Untriaged. return Ok(unsafe { MaybeUninit::array_assume_init(raw_ary) }); } if len < N { // Safety: `len` indicates that this many elements are available and we just checked that // it fits into the array. + // SAFETY: Untriaged. unsafe { ptr::copy_nonoverlapping(self.ptr.as_ptr(), raw_ary.as_mut_ptr() as *mut T, len); self.forget_remaining_elements(); @@ -475,6 +493,7 @@ impl DoubleEndedIterator for IntoIter { // Safety: `len` is larger than the array size. Copy a fixed amount here to fully initialize // the array. + // SAFETY: Untriaged. unsafe { ptr::copy_nonoverlapping( self.ptr.add(len - N).as_ptr(), @@ -585,6 +604,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter { impl Drop for DropGuard<'_, T, A> { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { self.0.dealloc_only(); } @@ -593,6 +613,7 @@ unsafe impl<#[may_dangle] T, A: Allocator> Drop for IntoIter { let guard = DropGuard(self); // destroy the remaining elements + // SAFETY: Untriaged. unsafe { ptr::drop_in_place(guard.0.as_raw_mut_slice()); } diff --git a/library/alloc/src/vec/is_zero.rs b/library/alloc/src/vec/is_zero.rs index 04b50e5762986..a9167b726e88c 100644 --- a/library/alloc/src/vec/is_zero.rs +++ b/library/alloc/src/vec/is_zero.rs @@ -153,6 +153,7 @@ macro_rules! impl_is_zero_option_of_int { #[inline] fn is_zero(&self) -> bool { const { +// SAFETY: Untriaged. let none: Self = unsafe { core::mem::MaybeUninit::zeroed().assume_init() }; assert!(none.is_none()); } diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index a619aa6e5427b..78c70b0942fb2 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -640,6 +640,7 @@ impl Vec { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] pub const unsafe fn from_raw_parts(ptr: *mut T, length: usize, capacity: usize) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_raw_parts_in(ptr, length, capacity, Global) } } @@ -739,6 +740,7 @@ impl Vec { #[stable(feature = "box_vec_non_null", since = "CURRENT_RUSTC_VERSION")] #[rustc_const_unstable(feature = "const_heap", issue = "79597")] pub const unsafe fn from_parts(ptr: NonNull, length: usize, capacity: usize) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_parts_in(ptr, length, capacity, Global) } } @@ -895,10 +897,13 @@ impl Vec { // which is why we instead return a new slice in this case. if self.capacity() == 0 || T::IS_ZST { let me = ManuallyDrop::new(self); + // SAFETY: Untriaged. unsafe { slice::from_raw_parts(NonNull::::dangling().as_ptr(), me.len) } } else { + // SAFETY: Untriaged. unsafe { core::intrinsics::const_make_global(self.as_mut_ptr().cast()) }; let me = ManuallyDrop::new(self); + // SAFETY: Untriaged. unsafe { slice::from_raw_parts(me.as_ptr(), me.len) } } } @@ -1032,6 +1037,7 @@ const impl Vec { if len == self.buf.capacity() { self.buf.grow_one(); } +// SAFETY: Untriaged. unsafe { let end = self.as_mut_ptr().add(len); ptr::write(end, value); @@ -1193,6 +1199,7 @@ impl Vec { "Vec::from_raw_parts_in requires that length <= capacity", (length: usize = length, capacity: usize = capacity) => length <= capacity ); + // SAFETY: Untriaged. unsafe { Vec { buf: RawVec::from_raw_parts_in(ptr, capacity, alloc), len: length } } } @@ -1308,6 +1315,7 @@ impl Vec { "Vec::from_parts_in requires that length <= capacity", (length: usize = length, capacity: usize = capacity) => length <= capacity ); + // SAFETY: Untriaged. unsafe { Vec { buf: RawVec::from_nonnull_in(ptr, capacity, alloc), len: length } } } @@ -1356,6 +1364,7 @@ impl Vec { let len = me.len(); let capacity = me.capacity(); let ptr = me.as_mut_ptr(); + // SAFETY: Untriaged. let alloc = unsafe { ptr::read(me.allocator()) }; (ptr, len, capacity, alloc) } @@ -1721,6 +1730,7 @@ impl Vec { #[cfg(not(no_global_oom_handling))] #[stable(feature = "rust1", since = "1.0.0")] pub fn into_boxed_slice(mut self) -> Box<[T], A> { + // SAFETY: Untriaged. unsafe { self.shrink_to_fit(); let me = ManuallyDrop::new(self); @@ -2262,6 +2272,7 @@ impl Vec { if index >= len { assert_failed(index, len); } + // SAFETY: Untriaged. unsafe { // We replace self[index] with the last element. Note that if the // bounds check above succeeds there must be a last element (which @@ -2349,6 +2360,7 @@ impl Vec { self.buf.grow_one(); } + // SAFETY: Untriaged. unsafe { // infallible // The spot to put the new value @@ -2435,6 +2447,7 @@ impl Vec { if index >= len { return None; } + // SAFETY: Untriaged. unsafe { // infallible let ret; @@ -2682,6 +2695,7 @@ impl Vec { let mut first_duplicate_idx: usize = 1; let start = self.as_mut_ptr(); while first_duplicate_idx != len { + // SAFETY: Untriaged. let found_duplicate = unsafe { // SAFETY: first_duplicate always in range [1..len) // Note that we start iteration from 1 so we never overflow. @@ -2721,6 +2735,7 @@ impl Vec { /* SAFETY: invariant guarantees that `read - write` * and `len - read` never overflow and that the copy is always * in-bounds. */ + // SAFETY: Untriaged. unsafe { let ptr = self.vec.as_mut_ptr(); let len = self.vec.len(); @@ -2753,6 +2768,7 @@ impl Vec { // Construct gap first and then drop item to avoid memory corruption if `T::drop` panics. let mut gap = FillGapOnDrop { read: first_duplicate_idx + 1, write: first_duplicate_idx, vec: self }; + // SAFETY: Untriaged. unsafe { // SAFETY: we checked that first_duplicate_idx in bounds before. // If drop panics, `gap` would remove this item without drop. @@ -2761,6 +2777,7 @@ impl Vec { /* SAFETY: Because of the invariant, read_ptr, prev_ptr and write_ptr * are always in-bounds and read_ptr never aliases prev_ptr */ + // SAFETY: Untriaged. unsafe { while gap.read < len { let read_ptr = start.add(gap.read); @@ -2837,6 +2854,7 @@ impl Vec { return Err(value); } + // SAFETY: Untriaged. unsafe { let end = self.as_mut_ptr().add(self.len); ptr::write(end, value); @@ -2873,6 +2891,7 @@ impl Vec { if self.len == 0 { None } else { + // SAFETY: Untriaged. unsafe { self.len -= 1; core::hint::assert_unchecked(self.len < self.capacity()); @@ -2947,6 +2966,7 @@ impl Vec { #[inline] #[stable(feature = "append", since = "1.4.0")] pub fn append(&mut self, other: &mut Self) { + // SAFETY: Untriaged. unsafe { self.append_elements(other.as_slice() as _); other.set_len(0); @@ -2958,6 +2978,7 @@ impl Vec { #[inline] unsafe fn append_elements(&mut self, other: *const [T]) { self.reserve(other.len()); + // SAFETY: Untriaged. unsafe { self.append_elements_unreserved(other); } @@ -2967,6 +2988,7 @@ impl Vec { #[inline] unsafe fn try_append_elements(&mut self, other: *const [T]) -> Result<(), TryReserveError> { self.try_reserve(other.len())?; + // SAFETY: Untriaged. unsafe { self.append_elements_unreserved(other); } @@ -2979,6 +3001,7 @@ impl Vec { let count = other.len(); let len = self.len(); if count > 0 { + // SAFETY: Untriaged. unsafe { ptr::copy_nonoverlapping(other as *const T, self.as_mut_ptr().add(len), count) }; @@ -3036,6 +3059,7 @@ impl Vec { let len = self.len(); let Range { start, end } = slice::range(range, ..len); + // SAFETY: Untriaged. unsafe { // set self.vec length's to start, to be safe in case Drain is leaked self.set_len(start); @@ -3175,6 +3199,7 @@ impl Vec { let mut other = Vec::with_capacity_in(other_len, self.allocator().clone()); // Unsafely `set_len` and copy items to `other`. + // SAFETY: Untriaged. unsafe { self.set_len(at); other.set_len(other_len); @@ -3263,6 +3288,7 @@ impl Vec { A: 'a, { let mut me = ManuallyDrop::new(self); + // SAFETY: Untriaged. unsafe { slice::from_raw_parts_mut(me.as_mut_ptr(), me.len) } } @@ -3301,6 +3327,7 @@ impl Vec { // Note: // This method is not implemented in terms of `split_at_spare_mut`, // to prevent invalidation of pointers to the buffer. + // SAFETY: Untriaged. unsafe { slice::from_raw_parts_mut( self.as_mut_ptr().add(self.len) as *mut MaybeUninit, @@ -3660,6 +3687,7 @@ impl Vec { &mut self, other: &[u8], ) -> Result<(), TryReserveError> { + // SAFETY: Untriaged. unsafe { self.try_append_elements(other) } } } @@ -3713,6 +3741,7 @@ impl Vec { fn extend_with(&mut self, n: usize, value: T) { self.reserve(n); + // SAFETY: Untriaged. unsafe { let mut ptr = self.as_mut_ptr().add(self.len()); // Use SetLenOnDrop to work around bug where compiler @@ -4020,6 +4049,7 @@ impl IntoIterator for Vec { /// ``` #[inline] fn into_iter(self) -> Self::IntoIter { + // SAFETY: Untriaged. unsafe { let me = ManuallyDrop::new(self); let alloc = ManuallyDrop::new(ptr::read(me.allocator())); @@ -4103,6 +4133,7 @@ impl Vec { let (lower, _) = iterator.size_hint(); self.reserve(lower.saturating_add(1)); } + // SAFETY: Untriaged. unsafe { ptr::write(self.as_mut_ptr().add(len), element); // Since next() executes user code which can panic we have to bump the length @@ -4126,6 +4157,7 @@ impl Vec { (low, high) ); self.reserve(additional); + // SAFETY: Untriaged. unsafe { let ptr = self.as_mut_ptr(); let mut local_len = SetLenOnDrop::new(&mut self.len); @@ -4351,6 +4383,7 @@ const unsafe impl<#[may_dangle] T: [const] Destruct, A: [const] Allocator + [con for Vec { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { // use drop for [T] // use a raw slice to refer to the elements of the vector as weakest necessary type; diff --git a/library/alloc/src/vec/spec_extend.rs b/library/alloc/src/vec/spec_extend.rs index b3fee7d094e20..320342b2fc898 100644 --- a/library/alloc/src/vec/spec_extend.rs +++ b/library/alloc/src/vec/spec_extend.rs @@ -30,6 +30,7 @@ where impl SpecExtend> for Vec { fn spec_extend(&mut self, iterator: IntoIter) { + // SAFETY: Untriaged. unsafe { self.append_elements(iterator.as_slice() as _); } @@ -53,6 +54,7 @@ where { fn spec_extend(&mut self, iterator: slice::Iter<'a, T>) { let slice = iterator.as_slice(); + // SAFETY: Untriaged. unsafe { self.append_elements(slice) }; } } diff --git a/library/alloc/src/vec/spec_from_elem.rs b/library/alloc/src/vec/spec_from_elem.rs index 96d701e15d487..68558cc380832 100644 --- a/library/alloc/src/vec/spec_from_elem.rs +++ b/library/alloc/src/vec/spec_from_elem.rs @@ -36,6 +36,7 @@ impl SpecFromElem for i8 { return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n }; } let mut v = Vec::with_capacity_in(n, alloc); + // SAFETY: Untriaged. unsafe { ptr::write_bytes(v.as_mut_ptr(), elem as u8, n); v.set_len(n); @@ -51,6 +52,7 @@ impl SpecFromElem for u8 { return Vec { buf: RawVec::with_capacity_zeroed_in(n, alloc), len: n }; } let mut v = Vec::with_capacity_in(n, alloc); + // SAFETY: Untriaged. unsafe { ptr::write_bytes(v.as_mut_ptr(), elem, n); v.set_len(n); diff --git a/library/alloc/src/vec/spec_from_iter.rs b/library/alloc/src/vec/spec_from_iter.rs index ccbc2936fb4e8..c8cda1de9169c 100644 --- a/library/alloc/src/vec/spec_from_iter.rs +++ b/library/alloc/src/vec/spec_from_iter.rs @@ -46,6 +46,7 @@ impl SpecFromIter> for Vec { // But it is a conservative choice. let has_advanced = iterator.buf != iterator.ptr; if !has_advanced || iterator.len() >= iterator.cap / 2 { + // SAFETY: Untriaged. unsafe { let it = ManuallyDrop::new(iterator); if has_advanced { diff --git a/library/alloc/src/vec/spec_from_iter_nested.rs b/library/alloc/src/vec/spec_from_iter_nested.rs index 77f7761d22f95..5a078f36aeb8c 100644 --- a/library/alloc/src/vec/spec_from_iter_nested.rs +++ b/library/alloc/src/vec/spec_from_iter_nested.rs @@ -28,6 +28,7 @@ where let initial_capacity = cmp::max(RawVec::::MIN_NON_ZERO_CAP, lower.saturating_add(1)); let mut vector = Vec::with_capacity(initial_capacity); + // SAFETY: Untriaged. unsafe { // SAFETY: We requested capacity at least 1 ptr::write(vector.as_mut_ptr(), element); diff --git a/library/alloc/src/vec/splice.rs b/library/alloc/src/vec/splice.rs index 99ebcb4ada296..33b08be9423be 100644 --- a/library/alloc/src/vec/splice.rs +++ b/library/alloc/src/vec/splice.rs @@ -61,6 +61,7 @@ impl Drop for Splice<'_, I, A> { // the ptr.offset_from_unsigned contract. self.drain.iter = (&[]).iter(); + // SAFETY: Untriaged. unsafe { if self.drain.tail_len == 0 { self.drain.vec.as_mut().extend(self.replace_with.by_ref()); @@ -104,6 +105,7 @@ impl Drain<'_, T, A> { /// Fill that range as much as possible with new elements from the `replace_with` iterator. /// Returns `true` if we filled the entire range. (`replace_with.next()` didn’t return `None`.) unsafe fn fill>(&mut self, replace_with: &mut I) -> bool { + // SAFETY: Untriaged. let vec = unsafe { self.vec.as_mut() }; let range_start = vec.len; let range_end = self.tail_start; @@ -113,6 +115,7 @@ impl Drain<'_, T, A> { let Some(new_item) = replace_with.next() else { return false; }; + // SAFETY: Untriaged. unsafe { vec.as_mut_ptr().add(idx).write(new_item) }; vec.len += 1; } @@ -121,11 +124,13 @@ impl Drain<'_, T, A> { /// Makes room for inserting more elements before the tail. unsafe fn move_tail(&mut self, additional: usize) { + // SAFETY: Untriaged. let vec = unsafe { self.vec.as_mut() }; let len = self.tail_start + self.tail_len; vec.buf.reserve(len, additional); let new_tail_start = self.tail_start + additional; + // SAFETY: Untriaged. unsafe { let src = vec.as_ptr().add(self.tail_start); let dst = vec.as_mut_ptr().add(new_tail_start); diff --git a/library/alloc/src/wtf8/mod.rs b/library/alloc/src/wtf8/mod.rs index 394c41bf36727..481d648435127 100644 --- a/library/alloc/src/wtf8/mod.rs +++ b/library/alloc/src/wtf8/mod.rs @@ -148,11 +148,13 @@ impl Wtf8Buf { Err(surrogate) => { let surrogate = surrogate.unpaired_surrogate(); // Surrogates are known to be in the code point range. + // SAFETY: Untriaged. let code_point = unsafe { CodePoint::from_u32_unchecked(surrogate as u32) }; // The string will now contain an unpaired surrogate. string.is_known_utf8 = false; // Skip the WTF-8 concatenation check, // surrogate pairs are already decoded by decode_utf16 + // SAFETY: Untriaged. unsafe { string.push_code_point_unchecked(code_point); } @@ -173,6 +175,7 @@ impl Wtf8Buf { #[inline] pub fn as_slice(&self) -> &Wtf8 { + // SAFETY: Untriaged. unsafe { Wtf8::from_bytes_unchecked(&self.bytes) } } @@ -181,6 +184,7 @@ impl Wtf8Buf { // Safety: `Wtf8` doesn't expose any way to mutate the bytes that would // cause them to change from well-formed UTF-8 to ill-formed UTF-8, // which would break the assumptions of the `is_known_utf8` field. + // SAFETY: Untriaged. unsafe { Wtf8::from_mut_bytes_unchecked(&mut self.bytes) } } @@ -262,6 +266,7 @@ impl Wtf8Buf { #[inline] pub fn leak<'a>(self) -> &'a mut Wtf8 { + // SAFETY: Untriaged. unsafe { Wtf8::from_mut_bytes_unchecked(self.bytes.leak()) } } @@ -337,6 +342,7 @@ impl Wtf8Buf { } // No newly paired surrogates at the boundary. + // SAFETY: Untriaged. unsafe { self.push_code_point_unchecked(code_point) } } @@ -371,6 +377,7 @@ impl Wtf8Buf { /// the original WTF-8 string is returned instead. pub fn into_string(self) -> Result { if self.is_known_utf8 || self.next_surrogate(0).is_none() { + // SAFETY: Untriaged. Ok(unsafe { String::from_utf8_unchecked(self.bytes) }) } else { Err(self) @@ -392,6 +399,7 @@ impl Wtf8Buf { self.bytes[surrogate_pos..pos].copy_from_slice("\u{FFFD}".as_bytes()); } } + // SAFETY: Untriaged. unsafe { String::from_utf8_unchecked(self.bytes) } } @@ -404,6 +412,7 @@ impl Wtf8Buf { /// Converts a `Box` into a `Wtf8Buf`. pub fn from_box(boxed: Box) -> Wtf8Buf { + // SAFETY: Untriaged. let bytes: Box<[u8]> = unsafe { mem::transmute(boxed) }; Wtf8Buf { bytes: bytes.into_vec(), is_known_utf8: false } } @@ -468,6 +477,7 @@ pub(super) fn to_owned(slice: &Wtf8) -> Wtf8Buf { /// This only copies the data if necessary (if it contains any surrogate). pub(super) fn to_string_lossy(slice: &Wtf8) -> Cow<'_, str> { let Some((surrogate_pos, _)) = slice.next_surrogate(0) else { + // SAFETY: Untriaged. return Cow::Borrowed(unsafe { str::from_utf8_unchecked(slice.as_bytes()) }); }; let wtf8_bytes = slice.as_bytes(); @@ -484,6 +494,7 @@ pub(super) fn to_string_lossy(slice: &Wtf8) -> Cow<'_, str> { } None => { utf8_bytes.extend_from_slice(&wtf8_bytes[pos..]); + // SAFETY: Untriaged. return Cow::Owned(unsafe { String::from_utf8_unchecked(utf8_bytes) }); } } @@ -516,12 +527,14 @@ impl Wtf8 { #[rustc_allow_incoherent_impl] pub fn into_box(&self) -> Box { let boxed: Box<[u8]> = self.as_bytes().into(); + // SAFETY: Untriaged. unsafe { mem::transmute(boxed) } } #[rustc_allow_incoherent_impl] pub fn empty_box() -> Box { let boxed: Box<[u8]> = Default::default(); + // SAFETY: Untriaged. unsafe { mem::transmute(boxed) } } @@ -529,12 +542,14 @@ impl Wtf8 { #[rustc_allow_incoherent_impl] pub fn into_arc(&self) -> Arc { let arc: Arc<[u8]> = Arc::from(self.as_bytes()); + // SAFETY: Untriaged. unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Wtf8) } } #[rustc_allow_incoherent_impl] pub fn into_rc(&self) -> Rc { let rc: Rc<[u8]> = Rc::from(self.as_bytes()); + // SAFETY: Untriaged. unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Wtf8) } } @@ -554,6 +569,7 @@ impl Wtf8 { #[inline] fn decode_surrogate_pair(lead: u16, trail: u16) -> char { let code_point = 0x10000 + ((((lead - 0xD800) as u32) << 10) | (trail - 0xDC00) as u32); + // SAFETY: Untriaged. unsafe { char::from_u32_unchecked(code_point) } } diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index 9d39fbf770e91..413a3afcd365f 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -354,6 +354,7 @@ pub fn set_alloc_error_hook(hook: fn(Layout)) { #[unstable(feature = "alloc_error_hook", issue = "51245")] pub fn take_alloc_error_hook() -> fn(Layout) { let hook = HOOK.swap(ptr::null_mut(), Ordering::Acquire); + // SAFETY: Untriaged. if hook.is_null() { default_alloc_error_hook } else { unsafe { mem::transmute(hook) } } } @@ -430,6 +431,7 @@ pub fn rust_oom(layout: Layout) -> ! { crate::sys::backtrace::__rust_end_short_backtrace(|| { let hook = HOOK.load(Ordering::Acquire); let hook: fn(Layout) = +// SAFETY: Untriaged. if hook.is_null() { default_alloc_error_hook } else { unsafe { mem::transmute(hook) } }; hook(layout); crate::process::abort() diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs index 99724e29e02b2..e2e638644aeec 100644 --- a/library/std/src/backtrace.rs +++ b/library/std/src/backtrace.rs @@ -327,6 +327,7 @@ impl Backtrace { let mut frames = Vec::new(); let mut actual_start = None; set_image_base(); + // SAFETY: Untriaged. unsafe { backtrace_rs::trace_unsynchronized(|frame| { frames.push(BacktraceFrame { @@ -446,6 +447,7 @@ mod helper { #[cfg(test)] RawFrame::Fake => unimplemented!(), }; + // SAFETY: Untriaged. unsafe { backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| { symbols.push(BacktraceSymbol { diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs index af03ae9a35b1c..188adc7d36553 100644 --- a/library/std/src/collections/hash/map.rs +++ b/library/std/src/collections/hash/map.rs @@ -1244,6 +1244,7 @@ where K: Borrow, Q: Hash + Eq, { + // SAFETY: Untriaged. unsafe { self.base.get_disjoint_unchecked_mut(ks) } } diff --git a/library/std/src/env.rs b/library/std/src/env.rs index f5c60f7562d4a..8e760d281b800 100644 --- a/library/std/src/env.rs +++ b/library/std/src/env.rs @@ -358,6 +358,7 @@ impl Error for VarError {} #[stable(feature = "env", since = "1.0.0")] pub unsafe fn set_var, V: AsRef>(key: K, value: V) { let (key, value) = (key.as_ref(), value.as_ref()); + // SAFETY: Untriaged. unsafe { env_imp::setenv(key, value) }.unwrap_or_else(|e| { panic!("failed to set environment variable `{key:?}` to `{value:?}`: {e}") }) @@ -429,6 +430,7 @@ pub unsafe fn set_var, V: AsRef>(key: K, value: V) { #[stable(feature = "env", since = "1.0.0")] pub unsafe fn remove_var>(key: K) { let key = key.as_ref(); + // SAFETY: Untriaged. unsafe { env_imp::unsetenv(key) } .unwrap_or_else(|e| panic!("failed to remove environment variable `{key:?}`: {e}")) } diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs index 73fb3f54097fa..1e7a25d19a502 100644 --- a/library/std/src/ffi/os_str.rs +++ b/library/std/src/ffi/os_str.rs @@ -174,6 +174,7 @@ impl OsString { #[inline] #[stable(feature = "os_str_bytes", since = "1.74.0")] pub unsafe fn from_encoded_bytes_unchecked(bytes: Vec) -> Self { + // SAFETY: Untriaged. OsString { inner: unsafe { Buf::from_encoded_bytes_unchecked(bytes) } } } @@ -544,6 +545,7 @@ impl OsString { #[stable(feature = "into_boxed_os_str", since = "1.20.0")] pub fn into_boxed_os_str(self) -> Box { let rw = Box::into_raw(self.inner.into_box()) as *mut OsStr; + // SAFETY: Untriaged. unsafe { Box::from_raw(rw) } } @@ -871,6 +873,7 @@ impl OsStr { #[inline] #[stable(feature = "os_str_bytes", since = "1.74.0")] pub unsafe fn from_encoded_bytes_unchecked(bytes: &[u8]) -> &Self { + // SAFETY: Untriaged. Self::from_inner(unsafe { Slice::from_encoded_bytes_unchecked(bytes) }) } @@ -1043,6 +1046,7 @@ impl OsStr { #[stable(feature = "into_boxed_os_str", since = "1.20.0")] #[must_use = "`self` will be dropped if the result is not used"] pub fn into_os_string(self: Box) -> OsString { + // SAFETY: Untriaged. let boxed = unsafe { Box::from_raw(Box::into_raw(self) as *mut Slice) }; OsString { inner: Buf::from_box(boxed) } } @@ -1419,6 +1423,7 @@ impl From for Arc { #[inline] fn from(s: OsString) -> Arc { let arc = s.inner.into_arc(); + // SAFETY: Untriaged. unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) } } } @@ -1429,6 +1434,7 @@ impl From<&OsStr> for Arc { #[inline] fn from(s: &OsStr) -> Arc { let arc = s.inner.into_arc(); + // SAFETY: Untriaged. unsafe { Arc::from_raw(Arc::into_raw(arc) as *const OsStr) } } } @@ -1449,6 +1455,7 @@ impl From for Rc { #[inline] fn from(s: OsString) -> Rc { let rc = s.inner.into_rc(); + // SAFETY: Untriaged. unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) } } } @@ -1459,6 +1466,7 @@ impl From<&OsStr> for Rc { #[inline] fn from(s: &OsStr) -> Rc { let rc = s.inner.into_rc(); + // SAFETY: Untriaged. unsafe { Rc::from_raw(Rc::into_raw(rc) as *const OsStr) } } } @@ -1532,6 +1540,7 @@ impl Default for Box { #[inline] fn default() -> Box { let rw = Box::into_raw(Slice::empty_box()) as *mut OsStr; + // SAFETY: Untriaged. unsafe { Box::from_raw(rw) } } } diff --git a/library/std/src/os/android/fs.rs b/library/std/src/os/android/fs.rs index d67c5582fd915..17244230eb794 100644 --- a/library/std/src/os/android/fs.rs +++ b/library/std/src/os/android/fs.rs @@ -63,6 +63,7 @@ pub trait MetadataExt { impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } } fn st_dev(&self) -> u64 { diff --git a/library/std/src/os/darwin/fs.rs b/library/std/src/os/darwin/fs.rs index fc2869d6b13f6..49731db57be12 100644 --- a/library/std/src/os/darwin/fs.rs +++ b/library/std/src/os/darwin/fs.rs @@ -82,6 +82,7 @@ impl MetadataExt for Metadata { #[allow(deprecated)] #[cfg(any(doc, target_os = "macos", target_os = "ios"))] fn as_raw_stat(&self) -> &super::raw::stat { + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const super::raw::stat) } } fn st_dev(&self) -> u64 { diff --git a/library/std/src/os/dragonfly/fs.rs b/library/std/src/os/dragonfly/fs.rs index b47b5108c70e6..b8e7850a648bb 100644 --- a/library/std/src/os/dragonfly/fs.rs +++ b/library/std/src/os/dragonfly/fs.rs @@ -69,6 +69,7 @@ pub trait MetadataExt { impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } } fn st_dev(&self) -> u64 { diff --git a/library/std/src/os/emscripten/fs.rs b/library/std/src/os/emscripten/fs.rs index a5778812ad947..10be411779147 100644 --- a/library/std/src/os/emscripten/fs.rs +++ b/library/std/src/os/emscripten/fs.rs @@ -63,6 +63,7 @@ pub trait MetadataExt { impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } } fn st_dev(&self) -> u64 { diff --git a/library/std/src/os/espidf/fs.rs b/library/std/src/os/espidf/fs.rs index cd09efca2db5f..cd6ced4f23d1e 100644 --- a/library/std/src/os/espidf/fs.rs +++ b/library/std/src/os/espidf/fs.rs @@ -59,6 +59,7 @@ pub trait MetadataExt { impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } } fn st_dev(&self) -> u64 { diff --git a/library/std/src/os/fd/net.rs b/library/std/src/os/fd/net.rs index 98faf0709153b..fc8a5f3a920f7 100644 --- a/library/std/src/os/fd/net.rs +++ b/library/std/src/os/fd/net.rs @@ -22,6 +22,7 @@ macro_rules! impl_from_raw_fd { impl FromRawFd for net::$t { #[inline] unsafe fn from_raw_fd(fd: RawFd) -> net::$t { +// SAFETY: Untriaged. unsafe { let socket = sys::net::Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd))); net::$t::from_inner(sys::net::$t::from_inner(socket)) diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index 4ed5c43616a29..3ae3ca9a0e69c 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -125,7 +125,9 @@ impl BorrowedFd<'_> { let cmd = libc::F_DUPFD; // Avoid using file descriptors below 3 as they are used for stdio + // SAFETY: Untriaged. let fd = cvt(unsafe { libc::fcntl(self.as_raw_fd(), cmd, 3) })?; + // SAFETY: Untriaged. Ok(unsafe { OwnedFd::from_raw_fd(fd) }) } @@ -147,6 +149,7 @@ impl BorrowedFd<'_> { #[stable(feature = "io_safety", since = "1.63.0")] pub fn try_clone_to_owned(&self) -> io::Result { let fd = moto_rt::fs::duplicate(self.as_raw_fd()).map_err(crate::sys::map_motor_error)?; + // SAFETY: Untriaged. Ok(unsafe { OwnedFd::from_raw_fd(fd) }) } } @@ -200,6 +203,7 @@ impl FromRawFd for OwnedFd { impl Drop for OwnedFd { #[inline] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { // Note that errors are ignored when closing a file descriptor. According to POSIX 2024, // we can and indeed should retry `close` on `EINTR` @@ -310,6 +314,7 @@ impl AsFd for OwnedFd { // Safety: `OwnedFd` and `BorrowedFd` have the same validity // invariants, and the `BorrowedFd` is bounded by the lifetime // of `&self`. + // SAFETY: Untriaged. unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) } } } @@ -485,6 +490,7 @@ impl AsFd for Box { impl AsFd for io::Stdin { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { + // SAFETY: Untriaged. unsafe { BorrowedFd::borrow_raw(0) } } } @@ -502,6 +508,7 @@ impl<'a> AsFd for io::StdinLock<'a> { impl AsFd for io::Stdout { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { + // SAFETY: Untriaged. unsafe { BorrowedFd::borrow_raw(1) } } } @@ -519,6 +526,7 @@ impl<'a> AsFd for io::StdoutLock<'a> { impl AsFd for io::Stderr { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { + // SAFETY: Untriaged. unsafe { BorrowedFd::borrow_raw(2) } } } diff --git a/library/std/src/os/fd/raw.rs b/library/std/src/os/fd/raw.rs index a0c96e2836fc5..606b765f83dbd 100644 --- a/library/std/src/os/fd/raw.rs +++ b/library/std/src/os/fd/raw.rs @@ -180,6 +180,7 @@ impl AsRawFd for fs::File { impl FromRawFd for fs::File { #[inline] unsafe fn from_raw_fd(fd: RawFd) -> fs::File { + // SAFETY: Untriaged. unsafe { fs::File::from(OwnedFd::from_raw_fd(fd)) } } } @@ -301,6 +302,7 @@ impl AsRawFd for io::PipeReader { #[cfg(not(target_os = "trusty"))] impl FromRawFd for io::PipeReader { unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + // SAFETY: Untriaged. Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) }) } } @@ -325,6 +327,7 @@ impl AsRawFd for io::PipeWriter { #[cfg(not(target_os = "trusty"))] impl FromRawFd for io::PipeWriter { unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + // SAFETY: Untriaged. Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) }) } } diff --git a/library/std/src/os/fd/stdio.rs b/library/std/src/os/fd/stdio.rs index c50cbd39849b7..d740fa45ee7a1 100644 --- a/library/std/src/os/fd/stdio.rs +++ b/library/std/src/os/fd/stdio.rs @@ -5,6 +5,7 @@ use super::BorrowedFd; /// See [`io::stdin()`][`crate::io::stdin`] for the higher level handle, which should be preferred /// whenever possible. See [`STDERR`] for why the file descriptor might be required and caveats. #[unstable(feature = "stdio_fd_consts", issue = "150836")] +// SAFETY: Untriaged. pub const STDIN: BorrowedFd<'static> = unsafe { BorrowedFd::borrow_raw(0) }; /// The file descriptor for the standard output stream of the current process. @@ -14,6 +15,7 @@ pub const STDIN: BorrowedFd<'static> = unsafe { BorrowedFd::borrow_raw(0) }; /// addition to the issues discussed there, note that [`Stdout`][`crate::io::Stdout`] is buffered by /// default, and writing to the file descriptor will bypass this buffer. #[unstable(feature = "stdio_fd_consts", issue = "150836")] +// SAFETY: Untriaged. pub const STDOUT: BorrowedFd<'static> = unsafe { BorrowedFd::borrow_raw(1) }; /// The file descriptor for the standard error stream of the current process. @@ -50,4 +52,5 @@ pub const STDOUT: BorrowedFd<'static> = unsafe { BorrowedFd::borrow_raw(1) }; /// [io-safety]: ../../../std/io/index.html#io-safety /// [global-alloc-reentrancy]: ../../../std/alloc/trait.GlobalAlloc.html#re-entrance #[unstable(feature = "stdio_fd_consts", issue = "150836")] +// SAFETY: Untriaged. pub const STDERR: BorrowedFd<'static> = unsafe { BorrowedFd::borrow_raw(2) }; diff --git a/library/std/src/os/fortanix_sgx/arch.rs b/library/std/src/os/fortanix_sgx/arch.rs index 4c8048e7152e2..e7c0b723d2e22 100644 --- a/library/std/src/os/fortanix_sgx/arch.rs +++ b/library/std/src/os/fortanix_sgx/arch.rs @@ -29,6 +29,7 @@ const ENCLU_EGETKEY: u32 = 1; /// Call the `EGETKEY` instruction to obtain a 128-bit secret key. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn egetkey(request: &Align512<[u8; 512]>) -> Result, u32> { + // SAFETY: Untriaged. unsafe { let mut out = MaybeUninit::uninit(); let error; @@ -61,6 +62,7 @@ pub fn ereport( targetinfo: &Align512<[u8; 512]>, reportdata: &Align128<[u8; 64]>, ) -> Align512<[u8; 432]> { + // SAFETY: Untriaged. unsafe { let mut report = MaybeUninit::uninit(); diff --git a/library/std/src/os/haiku/fs.rs b/library/std/src/os/haiku/fs.rs index 86624edcaef95..f9036be35893b 100644 --- a/library/std/src/os/haiku/fs.rs +++ b/library/std/src/os/haiku/fs.rs @@ -67,6 +67,7 @@ pub trait MetadataExt { impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } } fn st_dev(&self) -> u64 { diff --git a/library/std/src/os/hermit/io/net.rs b/library/std/src/os/hermit/io/net.rs index d5baeafec6497..60ac9f9181a5f 100644 --- a/library/std/src/os/hermit/io/net.rs +++ b/library/std/src/os/hermit/io/net.rs @@ -21,6 +21,7 @@ macro_rules! impl_from_raw_fd { impl FromRawFd for net::$t { #[inline] unsafe fn from_raw_fd(fd: RawFd) -> net::$t { +// SAFETY: Untriaged. unsafe { let socket = sys::net::Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd))); net::$t::from_inner(sys::net::$t::from_inner(socket)) diff --git a/library/std/src/os/illumos/fs.rs b/library/std/src/os/illumos/fs.rs index 76a5871638a1e..bb95fc4c12451 100644 --- a/library/std/src/os/illumos/fs.rs +++ b/library/std/src/os/illumos/fs.rs @@ -62,6 +62,7 @@ pub trait MetadataExt { impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } } fn st_dev(&self) -> u64 { diff --git a/library/std/src/os/l4re/fs.rs b/library/std/src/os/l4re/fs.rs index 2dc899bcb5a6e..44cb147829c71 100644 --- a/library/std/src/os/l4re/fs.rs +++ b/library/std/src/os/l4re/fs.rs @@ -345,6 +345,7 @@ pub trait MetadataExt { impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const _ as *const raw::stat) } } fn st_dev(&self) -> u64 { diff --git a/library/std/src/os/linux/fs.rs b/library/std/src/os/linux/fs.rs index 0e8fa0a15da09..c39369932db68 100644 --- a/library/std/src/os/linux/fs.rs +++ b/library/std/src/os/linux/fs.rs @@ -346,10 +346,12 @@ impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { #[cfg(target_env = "musl")] + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } #[cfg(not(target_env = "musl"))] + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const libc::stat64 as *const raw::stat) } diff --git a/library/std/src/os/netbsd/fs.rs b/library/std/src/os/netbsd/fs.rs index e61afd895debb..5295e160c089f 100644 --- a/library/std/src/os/netbsd/fs.rs +++ b/library/std/src/os/netbsd/fs.rs @@ -71,6 +71,7 @@ pub trait MetadataExt { impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } } fn st_dev(&self) -> u64 { diff --git a/library/std/src/os/openbsd/fs.rs b/library/std/src/os/openbsd/fs.rs index d3ca2426507a5..66fe938bfd1e4 100644 --- a/library/std/src/os/openbsd/fs.rs +++ b/library/std/src/os/openbsd/fs.rs @@ -71,6 +71,7 @@ pub trait MetadataExt { impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } } fn st_dev(&self) -> u64 { diff --git a/library/std/src/os/redox/fs.rs b/library/std/src/os/redox/fs.rs index ed6c8cb08677d..ddc3ad2f54e24 100644 --- a/library/std/src/os/redox/fs.rs +++ b/library/std/src/os/redox/fs.rs @@ -345,6 +345,7 @@ pub trait MetadataExt { impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } } fn st_dev(&self) -> u64 { diff --git a/library/std/src/os/solaris/fs.rs b/library/std/src/os/solaris/fs.rs index d32f575228603..e2aa4245b8e2c 100644 --- a/library/std/src/os/solaris/fs.rs +++ b/library/std/src/os/solaris/fs.rs @@ -63,6 +63,7 @@ pub trait MetadataExt { impl MetadataExt for Metadata { #[allow(deprecated)] fn as_raw_stat(&self) -> &raw::stat { + // SAFETY: Untriaged. unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) } } fn st_dev(&self) -> u64 { diff --git a/library/std/src/os/solid/io.rs b/library/std/src/os/solid/io.rs index d4defb5f47fb0..bca8eedd3a049 100644 --- a/library/std/src/os/solid/io.rs +++ b/library/std/src/os/solid/io.rs @@ -119,7 +119,9 @@ impl BorrowedFd<'_> { /// Creates a new `OwnedFd` instance that shares the same underlying file /// description as the existing `BorrowedFd` instance. pub fn try_clone_to_owned(&self) -> io::Result { + // SAFETY: Untriaged. let fd = sys::net::cvt(unsafe { crate::sys::abi::sockets::dup(self.as_raw_fd()) })?; + // SAFETY: Untriaged. Ok(unsafe { OwnedFd::from_raw_fd(fd) }) } } @@ -162,6 +164,7 @@ impl FromRawFd for OwnedFd { impl Drop for OwnedFd { #[inline] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { crate::sys::abi::sockets::close(self.fd.as_inner()) }; } } @@ -226,6 +229,7 @@ impl AsFd for OwnedFd { // Safety: `OwnedFd` and `BorrowedFd` have the same validity // invariants, and the `BorrowedFd` is bounded by the lifetime // of `&self`. + // SAFETY: Untriaged. unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) } } } @@ -378,6 +382,7 @@ macro_rules! impl_from_raw_fd { impl FromRawFd for net::$t { #[inline] unsafe fn from_raw_fd(fd: RawFd) -> net::$t { +// SAFETY: Untriaged. let socket = unsafe { sys::net::Socket::from_raw_fd(fd) }; net::$t::from_inner(sys::net::$t::from_inner(socket)) } diff --git a/library/std/src/os/uefi/env.rs b/library/std/src/os/uefi/env.rs index 82e3fc9775cba..4738e52579d23 100644 --- a/library/std/src/os/uefi/env.rs +++ b/library/std/src/os/uefi/env.rs @@ -83,6 +83,7 @@ pub fn image_handle() -> NonNull { pub fn boot_services() -> Option> { if BOOT_SERVICES_FLAG.load(Ordering::Acquire) { let system_table: NonNull = try_system_table()?.cast(); + // SAFETY: Untriaged. let boot_services = unsafe { (*system_table.as_ptr()).boot_services }; NonNull::new(boot_services).map(|x| x.cast()) } else { diff --git a/library/std/src/os/unix/ffi/os_str.rs b/library/std/src/os/unix/ffi/os_str.rs index 5beabd5618084..bf747bfa3a381 100644 --- a/library/std/src/os/unix/ffi/os_str.rs +++ b/library/std/src/os/unix/ffi/os_str.rs @@ -54,6 +54,7 @@ pub impl(self) trait OsStrExt { impl OsStrExt for OsStr { #[inline] fn from_bytes(slice: &[u8]) -> &OsStr { + // SAFETY: Untriaged. unsafe { mem::transmute(slice) } } #[inline] diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs index 618e0dca7659b..bfc4e6f429335 100644 --- a/library/std/src/os/unix/io/mod.rs +++ b/library/std/src/os/unix/io/mod.rs @@ -211,20 +211,22 @@ fn null_fd() -> io::Result { /// Does not set CLOEXEC. fn replace_stdio_fd(this: BorrowedFd<'_>, other: OwnedFd) -> io::Result<()> { cfg_select! { - all(target_os = "wasi", target_env = "p1") => { - cvt(unsafe { libc::__wasilibc_fd_renumber(other.as_raw_fd(), this.as_raw_fd()) }).map(|_| ()) + all(target_os = "wasi", target_env = "p1") => { + // SAFETY: Untriaged. + cvt(unsafe { libc::__wasilibc_fd_renumber(other.as_raw_fd(), this.as_raw_fd()) }).map(|_| ()) + } + not(any( + all(target_arch = "wasm32", not(target_os = "emscripten")), + target_os = "hermit", + target_os = "trusty", + target_os = "motor" + )) => { + // SAFETY: Untriaged. + cvt(unsafe {libc::dup2(other.as_raw_fd(), this.as_raw_fd())}).map(|_| ()) + } + _ => { + let _ = (this, other); + Err(io::Error::UNSUPPORTED_PLATFORM) + } } - not(any( - all(target_arch = "wasm32", not(target_os = "emscripten")), - target_os = "hermit", - target_os = "trusty", - target_os = "motor" - )) => { - cvt(unsafe {libc::dup2(other.as_raw_fd(), this.as_raw_fd())}).map(|_| ()) - } - _ => { - let _ = (this, other); - Err(io::Error::UNSUPPORTED_PLATFORM) - } - } } diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 08cd6138591e4..313bb28460e0d 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -101,6 +101,7 @@ impl SocketAddr { where F: FnOnce(*mut libc::sockaddr, *mut libc::socklen_t) -> libc::c_int, { + // SAFETY: Untriaged. unsafe { let mut addr: libc::sockaddr_un = mem::zeroed(); let mut len = size_of::() as libc::socklen_t; @@ -118,6 +119,7 @@ impl SocketAddr { // and not the len of the content. Figure out the length for ourselves. // https://marc.info/?l=openbsd-bugs&m=170105481926736&w=2 let sun_path: &[u8] = +// SAFETY: Untriaged. unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&addr.sun_path) }; len = core::slice::memchr::memchr(0, sun_path) .map_or(len, |new_len| (new_len + SUN_PATH_OFFSET) as libc::socklen_t); @@ -251,6 +253,7 @@ impl SocketAddr { fn address(&self) -> AddressKind<'_> { let len = self.len as usize - SUN_PATH_OFFSET; + // SAFETY: Untriaged. let path = unsafe { mem::transmute::<&[libc::c_char], &[u8]>(&self.addr.sun_path) }; // macOS seems to return a len of 16 and a zeroed sun_path for unnamed addresses @@ -286,6 +289,7 @@ impl linux_ext::addr::SocketAddrExt for SocketAddr { N: AsRef<[u8]>, { let name = name.as_ref(); + // SAFETY: Untriaged. unsafe { let mut addr: libc::sockaddr_un = mem::zeroed(); addr.sun_family = libc::AF_UNIX as libc::sa_family_t; diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs index a9029f7fa0bfb..1fec6be3a906c 100644 --- a/library/std/src/os/unix/net/ancillary.rs +++ b/library/std/src/os/unix/net/ancillary.rs @@ -35,6 +35,7 @@ pub(super) fn recv_vectored_with_ancillary_from( bufs: &mut [IoSliceMut<'_>], ancillary: &mut SocketAncillary<'_>, ) -> io::Result<(usize, bool, io::Result)> { + // SAFETY: Untriaged. unsafe { let mut msg_name: libc::sockaddr_un = zeroed(); let mut msg: libc::msghdr = zeroed(); @@ -66,6 +67,7 @@ pub(super) fn send_vectored_with_ancillary_to( bufs: &[IoSlice<'_>], ancillary: &mut SocketAncillary<'_>, ) -> io::Result { + // SAFETY: Untriaged. unsafe { let (mut msg_name, msg_namelen) = if let Some(path) = path { sockaddr_un(path)? } else { (zeroed(), 0) }; @@ -97,6 +99,7 @@ fn add_to_ancillary_data( #[cfg(not(target_os = "freebsd"))] let cmsg_size = source.len().checked_mul(size_of::()); #[cfg(target_os = "freebsd")] + // SAFETY: Untriaged. let cmsg_size = Some(unsafe { libc::SOCKCRED2SIZE(1) }); let source_len = if let Some(source_len) = cmsg_size { @@ -109,6 +112,7 @@ fn add_to_ancillary_data( return false; }; + // SAFETY: Untriaged. unsafe { let additional_space = libc::CMSG_SPACE(source_len) as usize; @@ -180,6 +184,7 @@ impl<'a, T> Iterator for AncillaryDataIter<'a, T> { fn next(&mut self) -> Option { if size_of::() <= self.data.len() { + // SAFETY: Untriaged. unsafe { let unit = read_unaligned(self.data.as_ptr().cast()); self.data = &self.data[size_of::()..]; @@ -504,6 +509,7 @@ impl<'a> AncillaryData<'a> { } fn try_from_cmsghdr(cmsg: &'a libc::cmsghdr) -> Result { + // SAFETY: Untriaged. unsafe { let cmsg_len_zero = libc::CMSG_LEN(0) as usize; let data_len = (*cmsg).cmsg_len as usize - cmsg_len_zero; @@ -544,6 +550,7 @@ impl<'a> Iterator for Messages<'a> { type Item = Result, AncillaryError>; fn next(&mut self) -> Option { + // SAFETY: Untriaged. unsafe { let mut msg: libc::msghdr = zeroed(); msg.msg_control = self.buffer.as_ptr() as *mut _; diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs index e03ecd7eed9ea..c8d53b3aeabef 100644 --- a/library/std/src/os/unix/net/datagram.rs +++ b/library/std/src/os/unix/net/datagram.rs @@ -96,6 +96,7 @@ impl UnixDatagram { /// ``` #[stable(feature = "unix_socket", since = "1.10.0")] pub fn bind>(path: P) -> io::Result { + // SAFETY: Untriaged. unsafe { let socket = UnixDatagram::unbound()?; let (addr, len) = sockaddr_un(path.as_ref())?; @@ -130,6 +131,7 @@ impl UnixDatagram { /// ``` #[stable(feature = "unix_socket_abstract", since = "1.70.0")] pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result { + // SAFETY: Untriaged. unsafe { let socket = UnixDatagram::unbound()?; cvt(libc::bind( @@ -216,6 +218,7 @@ impl UnixDatagram { /// ``` #[stable(feature = "unix_socket", since = "1.10.0")] pub fn connect>(&self, path: P) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { let (addr, len) = sockaddr_un(path.as_ref())?; @@ -249,6 +252,7 @@ impl UnixDatagram { /// ``` #[stable(feature = "unix_socket_abstract", since = "1.70.0")] pub fn connect_addr(&self, socket_addr: &SocketAddr) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { cvt(libc::connect( self.as_raw_fd(), @@ -298,6 +302,7 @@ impl UnixDatagram { /// ``` #[stable(feature = "unix_socket", since = "1.10.0")] pub fn local_addr(&self) -> io::Result { + // SAFETY: Untriaged. SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.as_raw_fd(), addr, len) }) } @@ -323,6 +328,7 @@ impl UnixDatagram { /// ``` #[stable(feature = "unix_socket", since = "1.10.0")] pub fn peer_addr(&self) -> io::Result { + // SAFETY: Untriaged. SocketAddr::new(|addr, len| unsafe { libc::getpeername(self.as_raw_fd(), addr, len) }) } @@ -332,6 +338,7 @@ impl UnixDatagram { flags: core::ffi::c_int, ) -> io::Result<(usize, SocketAddr)> { let mut count = 0; + // SAFETY: Untriaged. let addr = SocketAddr::new(|addr, len| unsafe { count = libc::recvfrom( self.as_raw_fd(), @@ -529,6 +536,7 @@ impl UnixDatagram { /// ``` #[stable(feature = "unix_socket", since = "1.10.0")] pub fn send_to>(&self, buf: &[u8], path: P) -> io::Result { + // SAFETY: Untriaged. unsafe { let (addr, len) = sockaddr_un(path.as_ref())?; @@ -567,6 +575,7 @@ impl UnixDatagram { /// ``` #[stable(feature = "unix_socket_abstract", since = "1.70.0")] pub fn send_to_addr(&self, buf: &[u8], socket_addr: &SocketAddr) -> io::Result { + // SAFETY: Untriaged. unsafe { let count = cvt(libc::sendto( self.as_raw_fd(), @@ -1021,6 +1030,7 @@ impl From for OwnedFd { /// Takes ownership of a [`UnixDatagram`]'s socket file descriptor. #[inline] fn from(unix_datagram: UnixDatagram) -> OwnedFd { + // SAFETY: Untriaged. unsafe { OwnedFd::from_raw_fd(unix_datagram.into_raw_fd()) } } } @@ -1029,6 +1039,7 @@ impl From for OwnedFd { impl From for UnixDatagram { #[inline] fn from(owned: OwnedFd) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_raw_fd(owned.into_raw_fd()) } } } diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs index b7f8d25a85ae5..dae3a929d5c7a 100644 --- a/library/std/src/os/unix/net/listener.rs +++ b/library/std/src/os/unix/net/listener.rs @@ -71,6 +71,7 @@ impl UnixListener { /// ``` #[stable(feature = "unix_socket", since = "1.10.0")] pub fn bind>(path: P) -> io::Result { + // SAFETY: Untriaged. unsafe { let inner = Socket::new(libc::AF_UNIX, libc::SOCK_STREAM)?; let (addr, len) = sockaddr_un(path.as_ref())?; @@ -137,6 +138,7 @@ impl UnixListener { /// ``` #[stable(feature = "unix_socket_abstract", since = "1.70.0")] pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result { + // SAFETY: Untriaged. unsafe { let inner = Socket::new(libc::AF_UNIX, libc::SOCK_STREAM)?; #[cfg(target_os = "linux")] @@ -179,6 +181,7 @@ impl UnixListener { /// ``` #[stable(feature = "unix_socket", since = "1.10.0")] pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> { + // SAFETY: Untriaged. let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() }; let mut len = size_of_val(&storage) as libc::socklen_t; let sock = self.0.accept((&raw mut storage) as *mut _, &mut len)?; @@ -225,6 +228,7 @@ impl UnixListener { /// ``` #[stable(feature = "unix_socket", since = "1.10.0")] pub fn local_addr(&self) -> io::Result { + // SAFETY: Untriaged. SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.as_raw_fd(), addr, len) }) } diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs index 8567e2fbb783d..7fc11bd06ceef 100644 --- a/library/std/src/os/unix/net/stream.rs +++ b/library/std/src/os/unix/net/stream.rs @@ -108,6 +108,7 @@ impl UnixStream { /// ``` #[stable(feature = "unix_socket", since = "1.10.0")] pub fn connect>(path: P) -> io::Result { + // SAFETY: Untriaged. unsafe { let inner = Socket::new(libc::AF_UNIX, libc::SOCK_STREAM)?; let (addr, len) = sockaddr_un(path.as_ref())?; @@ -143,6 +144,7 @@ impl UnixStream { /// ``` #[stable(feature = "unix_socket_abstract", since = "1.70.0")] pub fn connect_addr(socket_addr: &SocketAddr) -> io::Result { + // SAFETY: Untriaged. unsafe { let inner = Socket::new(libc::AF_UNIX, libc::SOCK_STREAM)?; cvt(libc::connect( @@ -218,6 +220,7 @@ impl UnixStream { /// ``` #[stable(feature = "unix_socket", since = "1.10.0")] pub fn local_addr(&self) -> io::Result { + // SAFETY: Untriaged. SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.as_raw_fd(), addr, len) }) } @@ -237,6 +240,7 @@ impl UnixStream { /// ``` #[stable(feature = "unix_socket", since = "1.10.0")] pub fn peer_addr(&self) -> io::Result { + // SAFETY: Untriaged. SocketAddr::new(|addr, len| unsafe { libc::getpeername(self.as_raw_fd(), addr, len) }) } @@ -744,6 +748,7 @@ impl From for OwnedFd { /// Takes ownership of a [`UnixStream`]'s socket file descriptor. #[inline] fn from(unix_stream: UnixStream) -> OwnedFd { + // SAFETY: Untriaged. unsafe { OwnedFd::from_raw_fd(unix_stream.into_raw_fd()) } } } @@ -752,6 +757,7 @@ impl From for OwnedFd { impl From for UnixStream { #[inline] fn from(owned: OwnedFd) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_raw_fd(owned.into_raw_fd()) } } } diff --git a/library/std/src/os/unix/net/ucred.rs b/library/std/src/os/unix/net/ucred.rs index 36b67cb1163d8..a0d4c6efc5790 100644 --- a/library/std/src/os/unix/net/ucred.rs +++ b/library/std/src/os/unix/net/ucred.rs @@ -56,6 +56,7 @@ mod impl_linux { let mut ucred_size = ucred_size as socklen_t; let mut ucred: ucred = ucred { pid: 1, uid: 1, gid: 1 }; + // SAFETY: Untriaged. unsafe { let ret = getsockopt( socket.as_raw_fd(), @@ -90,6 +91,7 @@ mod impl_bsd { pub fn peer_cred(socket: &UnixStream) -> io::Result { let mut cred = UCred { uid: 1, gid: 1, pid: None }; + // SAFETY: Untriaged. unsafe { let ret = libc::getpeereid(socket.as_raw_fd(), &mut cred.uid, &mut cred.gid); @@ -109,6 +111,7 @@ mod impl_apple { pub fn peer_cred(socket: &UnixStream) -> io::Result { let mut cred = UCred { uid: 1, gid: 1, pid: None }; + // SAFETY: Untriaged. unsafe { let ret = getpeereid(socket.as_raw_fd(), &mut cred.uid, &mut cred.gid); diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs index 9fa731de82691..738b1236355bb 100644 --- a/library/std/src/os/unix/process.rs +++ b/library/std/src/os/unix/process.rs @@ -128,6 +128,7 @@ pub impl(self) trait CommandExt { where F: FnMut() -> io::Result<()> + Send + Sync + 'static, { + // SAFETY: Untriaged. unsafe { self.pre_exec(f) } } diff --git a/library/std/src/os/wasi/fs.rs b/library/std/src/os/wasi/fs.rs index fc9e6c925f0bd..e58ffebb0ea53 100644 --- a/library/std/src/os/wasi/fs.rs +++ b/library/std/src/os/wasi/fs.rs @@ -246,6 +246,7 @@ impl FileExt for File { #[cfg(target_env = "p1")] fn fdstat_set_flags(&self, flags: u16) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { wasip1::fd_fdstat_set_flags(self.as_raw_fd() as wasip1::Fd, flags).map_err(err2io) } @@ -253,6 +254,7 @@ impl FileExt for File { #[cfg(target_env = "p1")] fn fdstat_set_rights(&self, rights: u64, inheriting: u64) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { wasip1::fd_fdstat_set_rights(self.as_raw_fd() as wasip1::Fd, rights, inheriting) .map_err(err2io) @@ -276,6 +278,7 @@ impl FileExt for File { } }; + // SAFETY: Untriaged. unsafe { wasip1::fd_advise(self.as_raw_fd() as wasip1::Fd, offset, len, advice).map_err(err2io) } @@ -283,12 +286,14 @@ impl FileExt for File { #[cfg(target_env = "p1")] fn allocate(&self, offset: u64, len: u64) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { wasip1::fd_allocate(self.as_raw_fd() as wasip1::Fd, offset, len).map_err(err2io) } } #[cfg(target_env = "p1")] fn create_directory>(&self, dir: P) -> io::Result<()> { let path = osstr2str(dir.as_ref().as_ref())?; + // SAFETY: Untriaged. unsafe { wasip1::path_create_directory(self.as_raw_fd() as wasip1::Fd, path).map_err(err2io) } @@ -297,12 +302,14 @@ impl FileExt for File { #[cfg(target_env = "p1")] fn remove_file>(&self, path: P) -> io::Result<()> { let path = osstr2str(path.as_ref().as_ref())?; + // SAFETY: Untriaged. unsafe { wasip1::path_unlink_file(self.as_raw_fd() as wasip1::Fd, path).map_err(err2io) } } #[cfg(target_env = "p1")] fn remove_directory>(&self, path: P) -> io::Result<()> { let path = osstr2str(path.as_ref().as_ref())?; + // SAFETY: Untriaged. unsafe { wasip1::path_remove_directory(self.as_raw_fd() as wasip1::Fd, path).map_err(err2io) } @@ -393,6 +400,7 @@ pub fn link, U: AsRef>( new_fd: &File, new_path: U, ) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { wasip1::path_link( old_fd.as_raw_fd() as wasip1::Fd, @@ -416,6 +424,7 @@ pub fn rename, U: AsRef>( new_fd: &File, new_path: U, ) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { wasip1::path_rename( old_fd.as_raw_fd() as wasip1::Fd, @@ -437,6 +446,7 @@ pub fn symlink, U: AsRef>( fd: &File, new_path: U, ) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { wasip1::path_symlink( osstr2str(old_path.as_ref().as_ref())?, diff --git a/library/std/src/os/wasi/net/mod.rs b/library/std/src/os/wasi/net/mod.rs index fd5889bf9b7b5..7d09ac0ab36b8 100644 --- a/library/std/src/os/wasi/net/mod.rs +++ b/library/std/src/os/wasi/net/mod.rs @@ -18,6 +18,7 @@ pub trait TcpListenerExt { impl TcpListenerExt for net::TcpListener { fn sock_accept(&self, flags: u16) -> io::Result { + // SAFETY: Untriaged. unsafe { wasip1::sock_accept(self.as_raw_fd() as wasip1::Fd, flags).map_err(err2io) } } } diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs index 29697bbb5f8fc..c8221e75d8049 100644 --- a/library/std/src/os/windows/io/handle.rs +++ b/library/std/src/os/windows/io/handle.rs @@ -173,6 +173,7 @@ impl Drop for HandleOrNull { #[inline] fn drop(&mut self) { if self.is_valid() { + // SAFETY: Untriaged. unsafe { let _ = sys::c::CloseHandle(self.0); } @@ -210,10 +211,12 @@ impl BorrowedHandle<'_> { // if we passed it a null handle, but we can treat null as a valid // handle which doesn't do any I/O, and allow it to be duplicated. if handle.is_null() { + // SAFETY: Untriaged. return unsafe { Ok(OwnedHandle::from_raw_handle(handle)) }; } let mut ret = ptr::null_mut(); + // SAFETY: Untriaged. cvt(unsafe { let cur_proc = sys::c::GetCurrentProcess(); sys::c::DuplicateHandle( @@ -226,6 +229,7 @@ impl BorrowedHandle<'_> { options, ) })?; + // SAFETY: Untriaged. unsafe { Ok(OwnedHandle::from_raw_handle(ret)) } } } @@ -251,6 +255,7 @@ impl Drop for HandleOrInvalid { #[inline] fn drop(&mut self) { if self.is_valid() { + // SAFETY: Untriaged. unsafe { let _ = sys::c::CloseHandle(self.0); } @@ -383,6 +388,7 @@ impl HandleOrInvalid { impl Drop for OwnedHandle { #[inline] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { let _ = sys::c::CloseHandle(self.handle); } @@ -513,6 +519,7 @@ impl AsHandle for OwnedHandle { // Safety: `OwnedHandle` and `BorrowedHandle` have the same validity // invariants, and the `BorrowedHandle` is bounded by the lifetime // of `&self`. + // SAFETY: Untriaged. unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } } } @@ -547,6 +554,7 @@ impl From for fs::File { impl AsHandle for io::Stdin { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { + // SAFETY: Untriaged. unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } } } @@ -555,6 +563,7 @@ impl AsHandle for io::Stdin { impl<'a> AsHandle for io::StdinLock<'a> { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { + // SAFETY: Untriaged. unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } } } @@ -563,6 +572,7 @@ impl<'a> AsHandle for io::StdinLock<'a> { impl AsHandle for io::Stdout { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { + // SAFETY: Untriaged. unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } } } @@ -571,6 +581,7 @@ impl AsHandle for io::Stdout { impl<'a> AsHandle for io::StdoutLock<'a> { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { + // SAFETY: Untriaged. unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } } } @@ -579,6 +590,7 @@ impl<'a> AsHandle for io::StdoutLock<'a> { impl AsHandle for io::Stderr { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { + // SAFETY: Untriaged. unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } } } @@ -587,6 +599,7 @@ impl AsHandle for io::Stderr { impl<'a> AsHandle for io::StderrLock<'a> { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { + // SAFETY: Untriaged. unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } } } @@ -595,6 +608,7 @@ impl<'a> AsHandle for io::StderrLock<'a> { impl AsHandle for crate::process::ChildStdin { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { + // SAFETY: Untriaged. unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } } } @@ -604,6 +618,7 @@ impl From for OwnedHandle { /// Takes ownership of a [`ChildStdin`](crate::process::ChildStdin)'s file handle. #[inline] fn from(child_stdin: crate::process::ChildStdin) -> OwnedHandle { + // SAFETY: Untriaged. unsafe { OwnedHandle::from_raw_handle(child_stdin.into_raw_handle()) } } } @@ -612,6 +627,7 @@ impl From for OwnedHandle { impl AsHandle for crate::process::ChildStdout { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { + // SAFETY: Untriaged. unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } } } @@ -621,6 +637,7 @@ impl From for OwnedHandle { /// Takes ownership of a [`ChildStdout`](crate::process::ChildStdout)'s file handle. #[inline] fn from(child_stdout: crate::process::ChildStdout) -> OwnedHandle { + // SAFETY: Untriaged. unsafe { OwnedHandle::from_raw_handle(child_stdout.into_raw_handle()) } } } @@ -629,6 +646,7 @@ impl From for OwnedHandle { impl AsHandle for crate::process::ChildStderr { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { + // SAFETY: Untriaged. unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } } } @@ -638,6 +656,7 @@ impl From for OwnedHandle { /// Takes ownership of a [`ChildStderr`](crate::process::ChildStderr)'s file handle. #[inline] fn from(child_stderr: crate::process::ChildStderr) -> OwnedHandle { + // SAFETY: Untriaged. unsafe { OwnedHandle::from_raw_handle(child_stderr.into_raw_handle()) } } } @@ -646,6 +665,7 @@ impl From for OwnedHandle { impl AsHandle for crate::thread::JoinHandle { #[inline] fn as_handle(&self) -> BorrowedHandle<'_> { + // SAFETY: Untriaged. unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } } } diff --git a/library/std/src/os/windows/io/mod.rs b/library/std/src/os/windows/io/mod.rs index bf0605aa08a95..f8f771f1a3487 100644 --- a/library/std/src/os/windows/io/mod.rs +++ b/library/std/src/os/windows/io/mod.rs @@ -149,6 +149,7 @@ macro io_ext_impl($stdio_ty:ty, $stdio_lock_ty:ty, $handle:path, $writer:literal #[cfg($writer)] self.flush()?; let raw = handle.map(|h| h.into().into_raw_handle()).unwrap_or(ptr::null_mut()); + // SAFETY: Untriaged. unsafe { c::SetStdHandle($handle, raw) }; Ok(()) } @@ -157,6 +158,7 @@ macro io_ext_impl($stdio_ty:ty, $stdio_lock_ty:ty, $handle:path, $writer:literal &mut self, replace_with: T, ) -> io::Result>> { + // SAFETY: Untriaged. let old = unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }; self.set_handle(Some(replace_with))?; let handle = if old.as_raw_handle().is_null() { None } else { Some(old) }; @@ -164,9 +166,11 @@ macro io_ext_impl($stdio_ty:ty, $stdio_lock_ty:ty, $handle:path, $writer:literal } fn take_handle(&mut self) -> io::Result>> { + // SAFETY: Untriaged. let old = unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }; #[cfg($writer)] self.flush()?; + // SAFETY: Untriaged. unsafe { c::SetStdHandle($handle, ptr::null_mut()) }; let handle = if old.as_raw_handle().is_null() { None } else { Some(old) }; Ok(handle) diff --git a/library/std/src/os/windows/io/raw.rs b/library/std/src/os/windows/io/raw.rs index d050c28832517..4917e906500b1 100644 --- a/library/std/src/os/windows/io/raw.rs +++ b/library/std/src/os/windows/io/raw.rs @@ -101,6 +101,7 @@ impl AsRawHandle for fs::File { #[stable(feature = "asraw_stdio", since = "1.21.0")] impl AsRawHandle for io::Stdin { fn as_raw_handle(&self) -> RawHandle { + // SAFETY: Untriaged. stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_INPUT_HANDLE) as RawHandle }) } } @@ -108,6 +109,7 @@ impl AsRawHandle for io::Stdin { #[stable(feature = "asraw_stdio", since = "1.21.0")] impl AsRawHandle for io::Stdout { fn as_raw_handle(&self) -> RawHandle { + // SAFETY: Untriaged. stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_OUTPUT_HANDLE) as RawHandle }) } } @@ -115,6 +117,7 @@ impl AsRawHandle for io::Stdout { #[stable(feature = "asraw_stdio", since = "1.21.0")] impl AsRawHandle for io::Stderr { fn as_raw_handle(&self) -> RawHandle { + // SAFETY: Untriaged. stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_ERROR_HANDLE) as RawHandle }) } } @@ -122,6 +125,7 @@ impl AsRawHandle for io::Stderr { #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] impl<'a> AsRawHandle for io::StdinLock<'a> { fn as_raw_handle(&self) -> RawHandle { + // SAFETY: Untriaged. stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_INPUT_HANDLE) as RawHandle }) } } @@ -129,6 +133,7 @@ impl<'a> AsRawHandle for io::StdinLock<'a> { #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] impl<'a> AsRawHandle for io::StdoutLock<'a> { fn as_raw_handle(&self) -> RawHandle { + // SAFETY: Untriaged. stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_OUTPUT_HANDLE) as RawHandle }) } } @@ -136,6 +141,7 @@ impl<'a> AsRawHandle for io::StdoutLock<'a> { #[stable(feature = "asraw_stdio_locks", since = "1.35.0")] impl<'a> AsRawHandle for io::StderrLock<'a> { fn as_raw_handle(&self) -> RawHandle { + // SAFETY: Untriaged. stdio_handle(unsafe { sys::c::GetStdHandle(sys::c::STD_ERROR_HANDLE) as RawHandle }) } } @@ -156,6 +162,7 @@ pub(super) fn stdio_handle(raw: RawHandle) -> RawHandle { impl FromRawHandle for fs::File { #[inline] unsafe fn from_raw_handle(handle: RawHandle) -> fs::File { + // SAFETY: Untriaged. unsafe { let handle = handle as sys::c::HANDLE; fs::File::from_inner(sys::fs::File::from_inner(FromInner::from_inner( @@ -260,6 +267,7 @@ impl AsRawSocket for net::UdpSocket { impl FromRawSocket for net::TcpStream { #[inline] unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpStream { + // SAFETY: Untriaged. unsafe { let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock)); net::TcpStream::from_inner(sys::net::TcpStream::from_inner(sock)) @@ -270,6 +278,7 @@ impl FromRawSocket for net::TcpStream { impl FromRawSocket for net::TcpListener { #[inline] unsafe fn from_raw_socket(sock: RawSocket) -> net::TcpListener { + // SAFETY: Untriaged. unsafe { let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock)); net::TcpListener::from_inner(sys::net::TcpListener::from_inner(sock)) @@ -280,6 +289,7 @@ impl FromRawSocket for net::TcpListener { impl FromRawSocket for net::UdpSocket { #[inline] unsafe fn from_raw_socket(sock: RawSocket) -> net::UdpSocket { + // SAFETY: Untriaged. unsafe { let sock = sys::net::Socket::from_inner(OwnedSocket::from_raw_socket(sock)); net::UdpSocket::from_inner(sys::net::UdpSocket::from_inner(sock)) @@ -321,6 +331,7 @@ impl AsRawHandle for io::PipeReader { #[stable(feature = "anonymous_pipe", since = "1.87.0")] impl FromRawHandle for io::PipeReader { unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_inner(FromRawHandle::from_raw_handle(raw_handle)) } } } @@ -342,6 +353,7 @@ impl AsRawHandle for io::PipeWriter { #[stable(feature = "anonymous_pipe", since = "1.87.0")] impl FromRawHandle for io::PipeWriter { unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_inner(FromRawHandle::from_raw_handle(raw_handle)) } } } diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs index ae1b7eaee8d12..7ffdae6aa6364 100644 --- a/library/std/src/os/windows/io/socket.rs +++ b/library/std/src/os/windows/io/socket.rs @@ -78,6 +78,7 @@ impl OwnedSocket { #[allow(implicit_provenance_casts)] #[cfg(not(target_vendor = "uwp"))] pub(crate) fn set_no_inherit(&self) -> io::Result<()> { + // SAFETY: Untriaged. cvt(unsafe { sys::c::SetHandleInformation( self.as_raw_socket() as sys::c::HANDLE, @@ -99,7 +100,9 @@ impl BorrowedSocket<'_> { /// object as the existing `BorrowedSocket` instance. #[stable(feature = "io_safety", since = "1.63.0")] pub fn try_clone_to_owned(&self) -> io::Result { + // SAFETY: Untriaged. let mut info = unsafe { mem::zeroed::() }; + // SAFETY: Untriaged. let result = unsafe { sys::c::WSADuplicateSocketW( self.as_raw_socket() as sys::c::SOCKET, @@ -108,6 +111,7 @@ impl BorrowedSocket<'_> { ) }; sys::net::cvt(result)?; + // SAFETY: Untriaged. let socket = unsafe { sys::c::WSASocketW( info.iAddressFamily, @@ -120,14 +124,17 @@ impl BorrowedSocket<'_> { }; if socket != sys::c::INVALID_SOCKET { + // SAFETY: Untriaged. unsafe { Ok(OwnedSocket::from_raw_socket(socket as RawSocket)) } } else { + // SAFETY: Untriaged. let error = unsafe { sys::c::WSAGetLastError() }; if error != sys::c::WSAEPROTOTYPE && error != sys::c::WSAEINVAL { return Err(io::Error::from_raw_os_error(error)); } + // SAFETY: Untriaged. let socket = unsafe { sys::c::WSASocketW( info.iAddressFamily, @@ -143,6 +150,7 @@ impl BorrowedSocket<'_> { return Err(last_error()); } + // SAFETY: Untriaged. unsafe { let socket = OwnedSocket::from_raw_socket(socket as RawSocket); socket.set_no_inherit()?; @@ -154,6 +162,7 @@ impl BorrowedSocket<'_> { /// Returns the last error from the Windows socket interface. fn last_error() -> io::Error { + // SAFETY: Untriaged. io::Error::from_raw_os_error(unsafe { sys::c::WSAGetLastError() }) } @@ -194,6 +203,7 @@ impl FromRawSocket for OwnedSocket { impl Drop for OwnedSocket { #[inline] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { let _ = sys::c::closesocket(self.socket.as_inner() as sys::c::SOCKET); } @@ -297,6 +307,7 @@ impl AsSocket for OwnedSocket { // Safety: `OwnedSocket` and `BorrowedSocket` have the same validity // invariants, and the `BorrowedSocket` is bounded by the lifetime // of `&self`. + // SAFETY: Untriaged. unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) } } } @@ -305,6 +316,7 @@ impl AsSocket for OwnedSocket { impl AsSocket for crate::net::TcpStream { #[inline] fn as_socket(&self) -> BorrowedSocket<'_> { + // SAFETY: Untriaged. unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) } } } @@ -314,6 +326,7 @@ impl From for OwnedSocket { /// Takes ownership of a [`TcpStream`](crate::net::TcpStream)'s socket. #[inline] fn from(tcp_stream: crate::net::TcpStream) -> OwnedSocket { + // SAFETY: Untriaged. unsafe { OwnedSocket::from_raw_socket(tcp_stream.into_raw_socket()) } } } @@ -322,6 +335,7 @@ impl From for OwnedSocket { impl From for crate::net::TcpStream { #[inline] fn from(owned: OwnedSocket) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_raw_socket(owned.into_raw_socket()) } } } @@ -330,6 +344,7 @@ impl From for crate::net::TcpStream { impl AsSocket for crate::net::TcpListener { #[inline] fn as_socket(&self) -> BorrowedSocket<'_> { + // SAFETY: Untriaged. unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) } } } @@ -339,6 +354,7 @@ impl From for OwnedSocket { /// Takes ownership of a [`TcpListener`](crate::net::TcpListener)'s socket. #[inline] fn from(tcp_listener: crate::net::TcpListener) -> OwnedSocket { + // SAFETY: Untriaged. unsafe { OwnedSocket::from_raw_socket(tcp_listener.into_raw_socket()) } } } @@ -347,6 +363,7 @@ impl From for OwnedSocket { impl From for crate::net::TcpListener { #[inline] fn from(owned: OwnedSocket) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_raw_socket(owned.into_raw_socket()) } } } @@ -355,6 +372,7 @@ impl From for crate::net::TcpListener { impl AsSocket for crate::net::UdpSocket { #[inline] fn as_socket(&self) -> BorrowedSocket<'_> { + // SAFETY: Untriaged. unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) } } } @@ -364,6 +382,7 @@ impl From for OwnedSocket { /// Takes ownership of a [`UdpSocket`](crate::net::UdpSocket)'s underlying socket. #[inline] fn from(udp_socket: crate::net::UdpSocket) -> OwnedSocket { + // SAFETY: Untriaged. unsafe { OwnedSocket::from_raw_socket(udp_socket.into_raw_socket()) } } } @@ -372,6 +391,7 @@ impl From for OwnedSocket { impl From for crate::net::UdpSocket { #[inline] fn from(owned: OwnedSocket) -> Self { + // SAFETY: Untriaged. unsafe { Self::from_raw_socket(owned.into_raw_socket()) } } } diff --git a/library/std/src/os/windows/net/addr.rs b/library/std/src/os/windows/net/addr.rs index c330432039a8f..3252c5d47a2f7 100644 --- a/library/std/src/os/windows/net/addr.rs +++ b/library/std/src/os/windows/net/addr.rs @@ -55,6 +55,7 @@ impl SocketAddr { where F: FnOnce(*mut SOCKADDR, *mut i32) -> i32, { + // SAFETY: Untriaged. unsafe { let mut addr: SOCKADDR_UN = mem::zeroed(); let mut len = mem::size_of::() as i32; @@ -135,6 +136,7 @@ impl SocketAddr { } fn address(&self) -> AddressKind<'_> { let len = self.len as usize - SUN_PATH_OFFSET; + // SAFETY: Untriaged. let path = unsafe { mem::transmute::<&[i8], &[u8]>(&self.addr.sun_path) }; if len == 0 { @@ -142,6 +144,7 @@ impl SocketAddr { } else if self.addr.sun_path[0] == 0 { AddressKind::Abstract(ByteStr::from_bytes(&path[1..len])) } else { + // SAFETY: Untriaged. AddressKind::Pathname(unsafe { OsStr::from_encoded_bytes_unchecked(&path[..len - 1]).as_ref() }) diff --git a/library/std/src/os/windows/net/listener.rs b/library/std/src/os/windows/net/listener.rs index 19f5254e08bf9..e27ff24382a0f 100644 --- a/library/std/src/os/windows/net/listener.rs +++ b/library/std/src/os/windows/net/listener.rs @@ -108,6 +108,7 @@ impl UnixListener { pub fn bind_addr(socket_addr: &SocketAddr) -> io::Result { startup(); let inner = Socket::new(AF_UNIX as _, SOCK_STREAM)?; + // SAFETY: Untriaged. unsafe { cvt_nz(bind(inner.as_raw(), &raw const socket_addr.addr as _, socket_addr.len as _))?; cvt_nz(listen(inner.as_raw(), 128))?; @@ -164,6 +165,7 @@ impl UnixListener { /// } /// ``` pub fn local_addr(&self) -> io::Result { + // SAFETY: Untriaged. SocketAddr::new(|addr, len| unsafe { getsockname(self.0.as_raw(), addr, len) }) } @@ -333,6 +335,7 @@ impl AsRawSocket for UnixListener { impl FromRawSocket for UnixListener { #[inline] unsafe fn from_raw_socket(sock: RawSocket) -> Self { + // SAFETY: Untriaged. UnixListener(unsafe { Socket::from_raw_socket(sock) }) } } diff --git a/library/std/src/os/windows/net/stream.rs b/library/std/src/os/windows/net/stream.rs index c0f32e75411e9..dbc4f5c5b6262 100644 --- a/library/std/src/os/windows/net/stream.rs +++ b/library/std/src/os/windows/net/stream.rs @@ -101,6 +101,7 @@ impl UnixStream { pub fn connect_addr(socket_addr: &SocketAddr) -> io::Result { startup(); let inner = Socket::new(AF_UNIX as _, SOCK_STREAM)?; + // SAFETY: Untriaged. unsafe { cvt_nz(connect( inner.as_raw(), @@ -127,6 +128,7 @@ impl UnixStream { /// } /// ``` pub fn local_addr(&self) -> io::Result { + // SAFETY: Untriaged. SocketAddr::new(|addr, len| unsafe { getsockname(self.0.as_raw(), addr, len) }) } @@ -146,6 +148,7 @@ impl UnixStream { /// } /// ``` pub fn peer_addr(&self) -> io::Result { + // SAFETY: Untriaged. SocketAddr::new(|addr, len| unsafe { getpeername(self.0.as_raw(), addr, len) }) } @@ -427,6 +430,7 @@ impl AsRawSocket for UnixStream { impl FromRawSocket for UnixStream { #[inline] unsafe fn from_raw_socket(sock: RawSocket) -> Self { + // SAFETY: Untriaged. unsafe { UnixStream(Socket::from_raw_socket(sock)) } } } diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs index 41dcb70c59c9f..37c29aac08684 100644 --- a/library/std/src/os/windows/process.rs +++ b/library/std/src/os/windows/process.rs @@ -15,6 +15,7 @@ use crate::{io, marker, process, ptr, sys}; #[stable(feature = "process_extensions", since = "1.2.0")] impl FromRawHandle for process::Stdio { unsafe fn from_raw_handle(handle: RawHandle) -> process::Stdio { + // SAFETY: Untriaged. let handle = unsafe { sys::handle::Handle::from_raw_handle(handle as *mut _) }; let io = sys::process::Stdio::Handle(handle); process::Stdio::from_inner(io) @@ -505,6 +506,7 @@ impl<'a> Drop for ProcThreadAttributeList<'a> { /// [1]: fn drop(&mut self) { let lp_attribute_list = self.attribute_list.as_mut_ptr().cast::(); + // SAFETY: Untriaged. unsafe { sys::c::DeleteProcThreadAttributeList(lp_attribute_list) } } } @@ -546,6 +548,7 @@ impl<'a> ProcThreadAttributeListBuilder<'a> { /// /// [1]: pub fn attribute(self, attribute: usize, value: &'a T) -> Self { + // SAFETY: Untriaged. unsafe { self.raw_attribute(attribute, ptr::addr_of!(*value).cast::(), size_of::()) } @@ -660,6 +663,7 @@ impl<'a> ProcThreadAttributeListBuilder<'a> { "maximum number of ProcThreadAttributes exceeded", )); }; + // SAFETY: Untriaged. unsafe { sys::c::InitializeProcThreadAttributeList( ptr::null_mut(), @@ -673,6 +677,7 @@ impl<'a> ProcThreadAttributeListBuilder<'a> { // Once we've allocated the necessary memory, it's safe to invoke // `InitializeProcThreadAttributeList` to properly initialize the list. + // SAFETY: Untriaged. sys::cvt(unsafe { sys::c::InitializeProcThreadAttributeList( attribute_list.as_mut_ptr().cast::(), @@ -687,6 +692,7 @@ impl<'a> ProcThreadAttributeListBuilder<'a> { // value. Therefore, we ensure that we don't add more attributes than // the buffer was initialized for. for (&attribute, value) in self.attributes.iter().take(attribute_count as usize) { + // SAFETY: Untriaged. sys::cvt(unsafe { sys::c::UpdateProcThreadAttribute( attribute_list.as_mut_ptr().cast::(), diff --git a/library/std/src/os/xous/ffi.rs b/library/std/src/os/xous/ffi.rs index 8a499446e98d0..2ebf825d06aa7 100644 --- a/library/std/src/os/xous/ffi.rs +++ b/library/std/src/os/xous/ffi.rs @@ -29,6 +29,7 @@ fn lend_mut_impl( let a6 = arg1; let a7 = arg2; + // SAFETY: Untriaged. unsafe { core::arch::asm!( "ecall", @@ -93,6 +94,7 @@ fn lend_impl( let mut ret1; let mut ret2; + // SAFETY: Untriaged. unsafe { core::arch::asm!( "ecall", @@ -148,6 +150,7 @@ fn scalar_impl(connection: Connection, args: [usize; 5], blocking: bool) -> Resu let a6 = args[3]; let a7 = args[4]; + // SAFETY: Untriaged. unsafe { core::arch::asm!( "ecall", @@ -195,6 +198,7 @@ fn blocking_scalar_impl( let a6 = args[3]; let a7 = args[4]; + // SAFETY: Untriaged. unsafe { core::arch::asm!( "ecall", @@ -252,6 +256,7 @@ fn connect_impl(address: ServerAddress, blocking: bool) -> Result ! { let a6 = 0; let a7 = 0; + // SAFETY: Untriaged. unsafe { core::arch::asm!( "ecall", @@ -333,6 +339,7 @@ pub(crate) fn do_yield() { let a6 = 0; let a7 = 0; + // SAFETY: Untriaged. unsafe { core::arch::asm!( "ecall", @@ -378,6 +385,7 @@ pub(crate) unsafe fn map_memory( let a6 = 0; let a7 = 0; + // SAFETY: Untriaged. unsafe { core::arch::asm!( "ecall", @@ -397,7 +405,9 @@ pub(crate) unsafe fn map_memory( if result == SyscallResult::MemoryRange as usize { let start = a1_out; let len = a2_out / size_of::(); + // SAFETY: Untriaged. let end = unsafe { start.add(len) }; + // SAFETY: Untriaged. Ok(unsafe { core::slice::from_raw_parts_mut(start, len) }) } else if result == SyscallResult::Error as usize { Err(a1_out.addr().into()) @@ -420,6 +430,7 @@ pub(crate) unsafe fn unmap_memory(range: *mut [T]) -> Result<(), Error> { let a6 = 0; let a7 = 0; + // SAFETY: Untriaged. unsafe { core::arch::asm!( "ecall", @@ -467,6 +478,7 @@ pub(crate) unsafe fn update_memory_flags( let a6 = 0; let a7 = 0; + // SAFETY: Untriaged. unsafe { core::arch::asm!( "ecall", @@ -511,6 +523,7 @@ pub(crate) unsafe fn create_thread( let a6 = arg2; let a7 = arg3; + // SAFETY: Untriaged. unsafe { core::arch::asm!( "ecall", @@ -547,6 +560,7 @@ pub(crate) fn join_thread(thread_id: ThreadId) -> Result { let a6 = 0; let a7 = 0; + // SAFETY: Untriaged. unsafe { core::arch::asm!( "ecall", @@ -587,6 +601,7 @@ pub(crate) fn thread_id() -> Result { let a6 = 0; let a7 = 0; + // SAFETY: Untriaged. unsafe { core::arch::asm!( "ecall", @@ -630,6 +645,7 @@ pub(crate) fn adjust_limit(knob: Limits, current: usize, new: usize) -> Result R + UnwindSafe, R>(f: F) -> Result { + // SAFETY: Untriaged. unsafe { panicking::catch_unwind(f) } } diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 7db6e93e8bd02..6533fdeaa596e 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -884,6 +884,7 @@ pub fn resume_unwind(payload: Box) -> ! { #[cfg_attr(not(test), rustc_std_internal_symbol)] #[cfg(not(panic = "immediate-abort"))] fn rust_panic(msg: &mut dyn PanicPayload) -> ! { + // SAFETY: Untriaged. let code = unsafe { __rust_start_panic(msg) }; rtabort!("failed to initiate panic, error {code}") } diff --git a/library/std/src/path.rs b/library/std/src/path.rs index be216d87f3241..d865c1988447e 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -345,6 +345,7 @@ fn rsplit_file_at_dot(file: &OsStr) -> (Option<&OsStr>, Option<&OsStr>) { if before == Some(b"") { (Some(file), None) } else { + // SAFETY: Untriaged. unsafe { ( before.map(|s| OsStr::from_encoded_bytes_unchecked(s)), @@ -370,6 +371,7 @@ fn split_file_at_dot(file: &OsStr) -> (&OsStr, Option<&OsStr>) { }; let before = &slice[..i]; let after = &slice[i + 1..]; + // SAFETY: Untriaged. unsafe { ( OsStr::from_encoded_bytes_unchecked(before), @@ -733,6 +735,7 @@ impl<'a> Components<'a> { if comps.back == State::Body { comps.trim_right(); } + // SAFETY: Untriaged. unsafe { Path::from_u8_slice(comps.path) } } @@ -772,6 +775,7 @@ impl<'a> Components<'a> { // separately via `include_cur_dir` b".." => Some(Component::ParentDir), b"" => None, + // SAFETY: Untriaged. _ => Some(Component::Normal(unsafe { OsStr::from_encoded_bytes_unchecked(comp) })), } } @@ -960,6 +964,7 @@ impl<'a> Iterator for Components<'a> { let raw = &self.path[..self.prefix_len()]; self.path = &self.path[self.prefix_len()..]; return Some(Component::Prefix(PrefixComponent { + // SAFETY: Untriaged. raw: unsafe { OsStr::from_encoded_bytes_unchecked(raw) }, parsed: self.prefix.unwrap(), })); @@ -1004,6 +1009,7 @@ impl<'a> DoubleEndedIterator for Components<'a> { State::Prefix if self.prefix_len() > 0 => { self.back = State::Done; return Some(Component::Prefix(PrefixComponent { + // SAFETY: Untriaged. raw: unsafe { OsStr::from_encoded_bytes_unchecked(self.path) }, parsed: self.prefix.unwrap(), })); @@ -1820,6 +1826,7 @@ impl PathBuf { #[inline] pub fn into_boxed_path(self) -> Box { let rw = Box::into_raw(self.inner.into_boxed_os_str()) as *mut Path; + // SAFETY: Untriaged. unsafe { Box::from_raw(rw) } } @@ -2175,6 +2182,7 @@ impl From for Arc { #[inline] fn from(s: PathBuf) -> Arc { let arc: Arc = Arc::from(s.into_os_string()); + // SAFETY: Untriaged. unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Path) } } } @@ -2185,6 +2193,7 @@ impl From<&Path> for Arc { #[inline] fn from(s: &Path) -> Arc { let arc: Arc = Arc::from(s.as_os_str()); + // SAFETY: Untriaged. unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Path) } } } @@ -2205,6 +2214,7 @@ impl From for Rc { #[inline] fn from(s: PathBuf) -> Rc { let rc: Rc = Rc::from(s.into_os_string()); + // SAFETY: Untriaged. unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Path) } } } @@ -2215,6 +2225,7 @@ impl From<&Path> for Rc { #[inline] fn from(s: &Path) -> Rc { let rc: Rc = Rc::from(s.as_os_str()); + // SAFETY: Untriaged. unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Path) } } } @@ -2378,6 +2389,7 @@ impl Path { // The following (private!) function allows construction of a path from a u8 // slice, which is only safe when it is known to follow the OsStr encoding. unsafe fn from_u8_slice(s: &[u8]) -> &Path { + // SAFETY: Untriaged. unsafe { Path::new(OsStr::from_encoded_bytes_unchecked(s)) } } // The following (private!) function reveals the byte encoding used for OsStr. @@ -2410,6 +2422,7 @@ impl Path { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_const_unstable(feature = "const_convert", issue = "143773")] pub const fn new + ?Sized>(s: &S) -> &Path { + // SAFETY: Untriaged. unsafe { &*(s.as_ref() as *const OsStr as *const Path) } } @@ -3680,6 +3693,7 @@ impl Path { #[must_use = "`self` will be dropped if the result is not used"] pub fn into_path_buf(self: Box) -> PathBuf { let rw = Box::into_raw(self) as *mut OsStr; + // SAFETY: Untriaged. let inner = unsafe { Box::from_raw(rw) }; PathBuf { inner: OsString::from(inner) } } diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs index 35d17d56ddd49..e71faaa1b6917 100644 --- a/library/std/src/rt.rs +++ b/library/std/src/rt.rs @@ -114,6 +114,7 @@ unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) { unsafe { main_thread::set(thread::current_id()) }; #[cfg_attr(target_os = "teeos", allow(unused_unsafe))] + // SAFETY: Untriaged. unsafe { sys::init(argc, argv, sigpipe) }; @@ -138,6 +139,7 @@ pub(crate) fn thread_cleanup() { // NOTE: this is not guaranteed to run, for example when the program aborts. pub(crate) fn cleanup() { static CLEANUP: Once = Once::new(); + // SAFETY: Untriaged. CLEANUP.call_once(|| unsafe { // Flush stdout and disable buffering. crate::io::cleanup(); diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs index 9bb25287275b2..8417c292300ce 100644 --- a/library/std/src/sync/lazy_lock.rs +++ b/library/std/src/sync/lazy_lock.rs @@ -134,12 +134,15 @@ impl T> LazyLock { OnceExclusiveState::Poisoned => panic_poisoned(), state => { let this = ManuallyDrop::new(this); + // SAFETY: Untriaged. let data = unsafe { ptr::read(&this.data) }.into_inner(); match state { OnceExclusiveState::Incomplete => { + // SAFETY: Untriaged. Err(ManuallyDrop::into_inner(unsafe { data.f })) } OnceExclusiveState::Complete => { + // SAFETY: Untriaged. Ok(ManuallyDrop::into_inner(unsafe { data.value })) } OnceExclusiveState::Poisoned => unreachable!(), @@ -246,6 +249,7 @@ impl T> LazyLock { // SAFETY: `call_once` only runs this closure once, ever. let data = unsafe { &mut *this.data.get() }; + // SAFETY: Untriaged. let f = unsafe { ManuallyDrop::take(&mut data.f) }; let value = f(); data.value = ManuallyDrop::new(value); @@ -324,9 +328,11 @@ impl LazyLock { impl Drop for LazyLock { fn drop(&mut self) { match self.once.state() { + // SAFETY: Untriaged. OnceExclusiveState::Incomplete => unsafe { ManuallyDrop::drop(&mut self.data.get_mut().f) }, + // SAFETY: Untriaged. OnceExclusiveState::Complete => unsafe { ManuallyDrop::drop(&mut self.data.get_mut().value) }, diff --git a/library/std/src/sync/mpmc/array.rs b/library/std/src/sync/mpmc/array.rs index 880d8b5f57cf4..dde6f57ec6bac 100644 --- a/library/std/src/sync/mpmc/array.rs +++ b/library/std/src/sync/mpmc/array.rs @@ -139,6 +139,7 @@ impl Channel { // Inspect the corresponding slot. debug_assert!(index < self.buffer.len()); + // SAFETY: Untriaged. let slot = unsafe { self.buffer.get_unchecked(index) }; let stamp = slot.stamp.load(Ordering::Acquire); @@ -200,6 +201,7 @@ impl Channel { } // Write the message into the slot and update the stamp. + // SAFETY: Untriaged. unsafe { let slot: &Slot = &*(token.array.slot as *const Slot); slot.msg.get().write(MaybeUninit::new(msg)); @@ -223,6 +225,7 @@ impl Channel { // Inspect the corresponding slot. debug_assert!(index < self.buffer.len()); + // SAFETY: Untriaged. let slot = unsafe { self.buffer.get_unchecked(index) }; let stamp = slot.stamp.load(Ordering::Acquire); @@ -292,6 +295,7 @@ impl Channel { } // Read the message from the slot and update the stamp. + // SAFETY: Untriaged. let msg = unsafe { let slot: &Slot = &*(token.array.slot as *const Slot); @@ -309,6 +313,7 @@ impl Channel { pub(crate) fn try_send(&self, msg: T) -> Result<(), TrySendError> { let token = &mut Token::default(); if self.start_send(token) { + // SAFETY: Untriaged. unsafe { self.write(token, msg).map_err(TrySendError::Disconnected) } } else { Err(TrySendError::Full(msg)) @@ -325,6 +330,7 @@ impl Channel { loop { // Try sending a message. if self.start_send(token) { + // SAFETY: Untriaged. let res = unsafe { self.write(token, msg) }; return res.map_err(SendTimeoutError::Disconnected); } @@ -365,6 +371,7 @@ impl Channel { let token = &mut Token::default(); if self.start_recv(token) { + // SAFETY: Untriaged. unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } } else { Err(TryRecvError::Empty) @@ -377,6 +384,7 @@ impl Channel { loop { // Try receiving a message. if self.start_recv(token) { + // SAFETY: Untriaged. let res = unsafe { self.read(token) }; return res.map_err(|_| RecvTimeoutError::Disconnected); } @@ -476,6 +484,7 @@ impl Channel { false }; + // SAFETY: Untriaged. unsafe { self.discard_all_messages(tail) }; disconnected } @@ -509,6 +518,7 @@ impl Channel { // Inspect the corresponding slot. debug_assert!(index < self.buffer.len()); + // SAFETY: Untriaged. let slot = unsafe { self.buffer.get_unchecked(index) }; let stamp = slot.stamp.load(Ordering::Acquire); @@ -524,6 +534,7 @@ impl Channel { lap.wrapping_add(self.one_lap) }; + // SAFETY: Untriaged. unsafe { (*slot.msg.get()).assume_init_drop(); } diff --git a/library/std/src/sync/mpmc/counter.rs b/library/std/src/sync/mpmc/counter.rs index efa6af1148334..a67c280f4990d 100644 --- a/library/std/src/sync/mpmc/counter.rs +++ b/library/std/src/sync/mpmc/counter.rs @@ -37,6 +37,7 @@ pub(crate) struct Sender { impl Sender { /// Returns the internal `Counter`. fn counter(&self) -> &Counter { + // SAFETY: Untriaged. unsafe { &*self.counter } } @@ -62,6 +63,7 @@ impl Sender { disconnect(&self.counter().chan); if self.counter().destroy.swap(true, Ordering::AcqRel) { + // SAFETY: Untriaged. drop(unsafe { Box::from_raw(self.counter) }); } } @@ -90,6 +92,7 @@ pub(crate) struct Receiver { impl Receiver { /// Returns the internal `Counter`. fn counter(&self) -> &Counter { + // SAFETY: Untriaged. unsafe { &*self.counter } } @@ -115,6 +118,7 @@ impl Receiver { disconnect(&self.counter().chan); if self.counter().destroy.swap(true, Ordering::AcqRel) { + // SAFETY: Untriaged. drop(unsafe { Box::from_raw(self.counter) }); } } diff --git a/library/std/src/sync/mpmc/list.rs b/library/std/src/sync/mpmc/list.rs index 050f26b097a0e..561fde45ac836 100644 --- a/library/std/src/sync/mpmc/list.rs +++ b/library/std/src/sync/mpmc/list.rs @@ -90,6 +90,7 @@ impl Block { // It is not necessary to set the `DESTROY` bit in the last slot because that slot has // begun destruction of the block. for i in start..BLOCK_CAP - 1 { + // SAFETY: Untriaged. let slot = unsafe { (*this).slots.get_unchecked(i) }; // Mark the `DESTROY` bit if a thread is still using the slot. @@ -102,6 +103,7 @@ impl Block { } // No thread is using the block, now it is safe to destroy it. + // SAFETY: Untriaged. drop(unsafe { Box::from_raw(this) }); } } @@ -221,6 +223,7 @@ impl Channel { self.head.block.store(new, Ordering::Release); block = new; } else { + // SAFETY: Untriaged. next_block = unsafe { Some(Box::from_raw(new)) }; tail = self.tail.index.load(Ordering::Acquire); block = self.tail.block.load(Ordering::Acquire); @@ -237,6 +240,7 @@ impl Channel { Ordering::SeqCst, Ordering::Acquire, ) { + // SAFETY: Untriaged. Ok(_) => unsafe { // If we've reached the end of the block, install the next one. if offset + 1 == BLOCK_CAP { @@ -269,6 +273,7 @@ impl Channel { // Write the message into the slot. let block = token.list.block as *mut Block; let offset = token.list.offset; + // SAFETY: Untriaged. unsafe { let slot = (*block).slots.get_unchecked(offset); slot.msg.get().write(MaybeUninit::new(msg)); @@ -339,6 +344,7 @@ impl Channel { Ordering::SeqCst, Ordering::Acquire, ) { + // SAFETY: Untriaged. Ok(_) => unsafe { // If we've reached the end of the block, move to the next one. if offset + 1 == BLOCK_CAP { @@ -375,6 +381,7 @@ impl Channel { // Read the message. let block = token.list.block as *mut Block; let offset = token.list.offset; + // SAFETY: Untriaged. unsafe { let slot = (*block).slots.get_unchecked(offset); slot.wait_write(); @@ -408,6 +415,7 @@ impl Channel { ) -> Result<(), SendTimeoutError> { let token = &mut Token::default(); assert!(self.start_send(token)); + // SAFETY: Untriaged. unsafe { self.write(token, msg).map_err(SendTimeoutError::Disconnected) } } @@ -416,6 +424,7 @@ impl Channel { let token = &mut Token::default(); if self.start_recv(token) { + // SAFETY: Untriaged. unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } } else { Err(TryRecvError::Empty) @@ -427,6 +436,7 @@ impl Channel { let token = &mut Token::default(); loop { if self.start_recv(token) { + // SAFETY: Untriaged. unsafe { return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); } @@ -579,6 +589,7 @@ impl Channel { // NULL. Failing to do so will lead to the Drop code attempting a double free. For this // reason both reads above do an atomic swap instead of a simple atomic load. + // SAFETY: Untriaged. unsafe { // Drop all messages between head and tail and deallocate the heap-allocated blocks. while head >> SHIFT != tail >> SHIFT { @@ -639,6 +650,7 @@ impl Drop for Channel { head &= !((1 << SHIFT) - 1); tail &= !((1 << SHIFT) - 1); + // SAFETY: Untriaged. unsafe { // Drop all messages between head and tail and deallocate the heap-allocated blocks. while head != tail { diff --git a/library/std/src/sync/mpmc/mod.rs b/library/std/src/sync/mpmc/mod.rs index a34eabbccb1fc..8edcb1093374e 100644 --- a/library/std/src/sync/mpmc/mod.rs +++ b/library/std/src/sync/mpmc/mod.rs @@ -663,6 +663,7 @@ impl Sender { #[unstable(feature = "mpmc_channel", issue = "126840")] impl Drop for Sender { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { match &self.flavor { SenderFlavor::Array(chan) => chan.release(|c| c.disconnect_senders()), @@ -1421,6 +1422,7 @@ impl Receiver { #[unstable(feature = "mpmc_channel", issue = "126840")] impl Drop for Receiver { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { match &self.flavor { ReceiverFlavor::Array(chan) => chan.release(|c| c.disconnect_receivers()), diff --git a/library/std/src/sync/mpmc/zero.rs b/library/std/src/sync/mpmc/zero.rs index 4f645e16fbb6f..50267c580e6fc 100644 --- a/library/std/src/sync/mpmc/zero.rs +++ b/library/std/src/sync/mpmc/zero.rs @@ -102,6 +102,7 @@ impl Channel { return Err(msg); } + // SAFETY: Untriaged. unsafe { let packet = &*(token.zero.0 as *const Packet); packet.msg.get().write(Some(msg)); @@ -117,12 +118,14 @@ impl Channel { return Err(()); } + // SAFETY: Untriaged. let packet = unsafe { &*(token.zero.0 as *const Packet) }; if packet.on_stack { // The message has been in the packet from the beginning, so there is no need to wait // for it. However, after reading the message, we need to set `ready` to `true` in // order to signal that the packet can be destroyed. + // SAFETY: Untriaged. let msg = unsafe { packet.msg.get().replace(None) }.unwrap(); packet.ready.store(true, Ordering::Release); Ok(msg) @@ -130,6 +133,7 @@ impl Channel { // Wait until the message becomes available, then read it and destroy the // heap-allocated packet. packet.wait_ready(); + // SAFETY: Untriaged. unsafe { let msg = packet.msg.get().replace(None).unwrap(); drop(Box::from_raw(token.zero.0 as *mut Packet)); @@ -147,6 +151,7 @@ impl Channel { if let Some(operation) = inner.receivers.try_select() { token.zero.0 = operation.packet; drop(inner); + // SAFETY: Untriaged. unsafe { self.write(token, msg).ok().unwrap(); } @@ -171,6 +176,7 @@ impl Channel { if let Some(operation) = inner.receivers.try_select() { token.zero.0 = operation.packet; drop(inner); + // SAFETY: Untriaged. unsafe { self.write(token, msg).ok().unwrap(); } @@ -197,11 +203,13 @@ impl Channel { Selected::Waiting => unreachable!(), Selected::Aborted => { self.inner.lock().unwrap().senders.unregister(oper).unwrap(); + // SAFETY: Untriaged. let msg = unsafe { packet.msg.get().replace(None).unwrap() }; Err(SendTimeoutError::Timeout(msg)) } Selected::Disconnected => { self.inner.lock().unwrap().senders.unregister(oper).unwrap(); + // SAFETY: Untriaged. let msg = unsafe { packet.msg.get().replace(None).unwrap() }; Err(SendTimeoutError::Disconnected(msg)) } @@ -223,6 +231,7 @@ impl Channel { if let Some(operation) = inner.senders.try_select() { token.zero.0 = operation.packet; drop(inner); + // SAFETY: Untriaged. unsafe { self.read(token).map_err(|_| TryRecvError::Disconnected) } } else if inner.is_disconnected { Err(TryRecvError::Disconnected) @@ -240,6 +249,7 @@ impl Channel { if let Some(operation) = inner.senders.try_select() { token.zero.0 = operation.packet; drop(inner); + // SAFETY: Untriaged. unsafe { return self.read(token).map_err(|_| RecvTimeoutError::Disconnected); } @@ -274,6 +284,7 @@ impl Channel { Selected::Operation(_) => { // Wait until the message is provided, then read it. packet.wait_ready(); + // SAFETY: Untriaged. unsafe { Ok(packet.msg.get().replace(None).unwrap()) } } } diff --git a/library/std/src/sync/nonpoison/condvar.rs b/library/std/src/sync/nonpoison/condvar.rs index d2b251d7c44c1..e9d66af223b7a 100644 --- a/library/std/src/sync/nonpoison/condvar.rs +++ b/library/std/src/sync/nonpoison/condvar.rs @@ -121,6 +121,7 @@ impl Condvar { /// ``` #[unstable(feature = "nonpoison_condvar", issue = "134645")] pub fn wait(&self, guard: &mut MutexGuard<'_, T>) { + // SAFETY: Untriaged. unsafe { let lock = mutex::guard_lock(guard); self.inner.wait(lock); @@ -249,6 +250,7 @@ impl Condvar { guard: &mut MutexGuard<'_, T>, dur: Duration, ) -> WaitTimeoutResult { + // SAFETY: Untriaged. let success = unsafe { let lock = mutex::guard_lock(guard); self.inner.wait_timeout(lock, dur) diff --git a/library/std/src/sync/nonpoison/mutex.rs b/library/std/src/sync/nonpoison/mutex.rs index 307bf8eaf512e..ac7d40fed4575 100644 --- a/library/std/src/sync/nonpoison/mutex.rs +++ b/library/std/src/sync/nonpoison/mutex.rs @@ -282,6 +282,7 @@ impl Mutex { /// ``` #[unstable(feature = "nonpoison_mutex", issue = "134645")] pub fn lock(&self) -> MutexGuard<'_, T> { + // SAFETY: Untriaged. unsafe { self.inner.lock(); MutexGuard::new(self) @@ -321,6 +322,7 @@ impl Mutex { /// ``` #[unstable(feature = "nonpoison_mutex", issue = "134645")] pub fn try_lock(&self) -> TryLockResult> { + // SAFETY: Untriaged. unsafe { if self.inner.try_lock() { Ok(MutexGuard::new(self)) } else { Err(WouldBlock) } } } @@ -456,6 +458,7 @@ impl Deref for MutexGuard<'_, T> { type Target = T; fn deref(&self) -> &T { + // SAFETY: Untriaged. unsafe { &*self.lock.data.get() } } } @@ -463,6 +466,7 @@ impl Deref for MutexGuard<'_, T> { #[unstable(feature = "nonpoison_mutex", issue = "134645")] impl DerefMut for MutexGuard<'_, T> { fn deref_mut(&mut self) -> &mut T { + // SAFETY: Untriaged. unsafe { &mut *self.lock.data.get() } } } @@ -471,6 +475,7 @@ impl DerefMut for MutexGuard<'_, T> { impl Drop for MutexGuard<'_, T> { #[inline] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { self.lock.inner.unlock(); } @@ -557,6 +562,7 @@ impl Deref for MappedMutexGuard<'_, T> { type Target = T; fn deref(&self) -> &T { + // SAFETY: Untriaged. unsafe { self.data.as_ref() } } } @@ -564,6 +570,7 @@ impl Deref for MappedMutexGuard<'_, T> { #[unstable(feature = "mapped_lock_guards", issue = "117108")] impl DerefMut for MappedMutexGuard<'_, T> { fn deref_mut(&mut self) -> &mut T { + // SAFETY: Untriaged. unsafe { self.data.as_mut() } } } @@ -572,6 +579,7 @@ impl DerefMut for MappedMutexGuard<'_, T> { impl Drop for MappedMutexGuard<'_, T> { #[inline] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { self.inner.unlock(); } diff --git a/library/std/src/sync/nonpoison/rwlock.rs b/library/std/src/sync/nonpoison/rwlock.rs index dc5d9479ba5a9..43ff5df1a027f 100644 --- a/library/std/src/sync/nonpoison/rwlock.rs +++ b/library/std/src/sync/nonpoison/rwlock.rs @@ -320,6 +320,7 @@ impl RwLock { #[inline] #[unstable(feature = "nonpoison_rwlock", issue = "134645")] pub fn read(&self) -> RwLockReadGuard<'_, T> { + // SAFETY: Untriaged. unsafe { self.inner.read(); RwLockReadGuard::new(self) @@ -359,6 +360,7 @@ impl RwLock { #[inline] #[unstable(feature = "nonpoison_rwlock", issue = "134645")] pub fn try_read(&self) -> TryLockResult> { + // SAFETY: Untriaged. unsafe { if self.inner.try_read() { Ok(RwLockReadGuard::new(self)) } else { Err(WouldBlock) } } @@ -394,6 +396,7 @@ impl RwLock { #[inline] #[unstable(feature = "nonpoison_rwlock", issue = "134645")] pub fn write(&self) -> RwLockWriteGuard<'_, T> { + // SAFETY: Untriaged. unsafe { self.inner.write(); RwLockWriteGuard::new(self) @@ -435,6 +438,7 @@ impl RwLock { #[inline] #[unstable(feature = "nonpoison_rwlock", issue = "134645")] pub fn try_write(&self) -> TryLockResult> { + // SAFETY: Untriaged. unsafe { if self.inner.try_write() { Ok(RwLockWriteGuard::new(self)) } else { Err(WouldBlock) } } @@ -605,6 +609,7 @@ impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> { /// instantiating this object. unsafe fn new(lock: &'rwlock RwLock) -> RwLockReadGuard<'rwlock, T> { RwLockReadGuard { + // SAFETY: Untriaged. data: unsafe { NonNull::new_unchecked(lock.data.get()) }, inner_lock: &lock.inner, } diff --git a/library/std/src/sync/once_lock.rs b/library/std/src/sync/once_lock.rs index de80164ed4f85..511e23c4265ce 100644 --- a/library/std/src/sync/once_lock.rs +++ b/library/std/src/sync/once_lock.rs @@ -155,6 +155,7 @@ impl OnceLock { pub fn get(&self) -> Option<&T> { if self.initialized() { // Safe b/c checked initialized + // SAFETY: Untriaged. Some(unsafe { self.get_unchecked() }) } else { None @@ -173,6 +174,7 @@ impl OnceLock { pub fn get_mut(&mut self) -> Option<&mut T> { if self.initialized_mut() { // Safe b/c checked initialized and we have a unique access + // SAFETY: Untriaged. Some(unsafe { self.get_unchecked_mut() }) } else { None @@ -203,6 +205,7 @@ impl OnceLock { pub fn wait(&self) -> &T { self.once.wait_force(); + // SAFETY: Untriaged. unsafe { self.get_unchecked() } } @@ -542,6 +545,7 @@ impl OnceLock { self.once.call_once_force(|p| { match f() { Ok(value) => { + // SAFETY: Untriaged. unsafe { (&mut *slot.get()).write(value) }; } Err(e) => { @@ -562,6 +566,7 @@ impl OnceLock { #[inline] unsafe fn get_unchecked(&self) -> &T { debug_assert!(self.initialized()); + // SAFETY: Untriaged. unsafe { (&*self.value.get()).assume_init_ref() } } @@ -571,6 +576,7 @@ impl OnceLock { #[inline] unsafe fn get_unchecked_mut(&mut self) -> &mut T { debug_assert!(self.initialized_mut()); + // SAFETY: Untriaged. unsafe { self.value.get_mut().assume_init_mut() } } } diff --git a/library/std/src/sync/poison/condvar.rs b/library/std/src/sync/poison/condvar.rs index fa9e1caada59b..6ed1fc7cc913b 100644 --- a/library/std/src/sync/poison/condvar.rs +++ b/library/std/src/sync/poison/condvar.rs @@ -123,6 +123,7 @@ impl Condvar { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_should_not_be_called_on_const_items] pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> LockResult> { + // SAFETY: Untriaged. let poisoned = unsafe { let lock = mutex::guard_lock(&guard); self.inner.wait(lock); @@ -325,6 +326,7 @@ impl Condvar { guard: MutexGuard<'a, T>, dur: Duration, ) -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> { + // SAFETY: Untriaged. let (poisoned, result) = unsafe { let lock = mutex::guard_lock(&guard); let success = self.inner.wait_timeout(lock, dur); diff --git a/library/std/src/sync/poison/mutex.rs b/library/std/src/sync/poison/mutex.rs index 6eccd8a875edd..82ed4fe51e55d 100644 --- a/library/std/src/sync/poison/mutex.rs +++ b/library/std/src/sync/poison/mutex.rs @@ -488,6 +488,7 @@ impl Mutex { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_should_not_be_called_on_const_items] pub fn lock(&self) -> LockResult> { + // SAFETY: Untriaged. unsafe { self.inner.lock(); MutexGuard::new(self) @@ -537,6 +538,7 @@ impl Mutex { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_should_not_be_called_on_const_items] pub fn try_lock(&self) -> TryLockResult> { + // SAFETY: Untriaged. unsafe { if self.inner.try_lock() { Ok(MutexGuard::new(self)?) @@ -726,6 +728,7 @@ impl Deref for MutexGuard<'_, T> { type Target = T; fn deref(&self) -> &T { + // SAFETY: Untriaged. unsafe { &*self.lock.data.get() } } } @@ -733,6 +736,7 @@ impl Deref for MutexGuard<'_, T> { #[stable(feature = "rust1", since = "1.0.0")] impl DerefMut for MutexGuard<'_, T> { fn deref_mut(&mut self) -> &mut T { + // SAFETY: Untriaged. unsafe { &mut *self.lock.data.get() } } } @@ -741,6 +745,7 @@ impl DerefMut for MutexGuard<'_, T> { impl Drop for MutexGuard<'_, T> { #[inline] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { self.lock.poison.done(&self.poison); self.lock.inner.unlock(); @@ -843,6 +848,7 @@ impl Deref for MappedMutexGuard<'_, T> { type Target = T; fn deref(&self) -> &T { + // SAFETY: Untriaged. unsafe { self.data.as_ref() } } } @@ -850,6 +856,7 @@ impl Deref for MappedMutexGuard<'_, T> { #[unstable(feature = "mapped_lock_guards", issue = "117108")] impl DerefMut for MappedMutexGuard<'_, T> { fn deref_mut(&mut self) -> &mut T { + // SAFETY: Untriaged. unsafe { self.data.as_mut() } } } @@ -858,6 +865,7 @@ impl DerefMut for MappedMutexGuard<'_, T> { impl Drop for MappedMutexGuard<'_, T> { #[inline] fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { self.poison_flag.done(&self.poison); self.inner.unlock(); diff --git a/library/std/src/sync/poison/rwlock.rs b/library/std/src/sync/poison/rwlock.rs index 4cfd9d19df74a..438c92b4ded3f 100644 --- a/library/std/src/sync/poison/rwlock.rs +++ b/library/std/src/sync/poison/rwlock.rs @@ -406,6 +406,7 @@ impl RwLock { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_should_not_be_called_on_const_items] pub fn read(&self) -> LockResult> { + // SAFETY: Untriaged. unsafe { self.inner.read(); RwLockReadGuard::new(self) @@ -453,6 +454,7 @@ impl RwLock { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_should_not_be_called_on_const_items] pub fn try_read(&self) -> TryLockResult> { + // SAFETY: Untriaged. unsafe { if self.inner.try_read() { Ok(RwLockReadGuard::new(self)?) @@ -499,6 +501,7 @@ impl RwLock { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_should_not_be_called_on_const_items] pub fn write(&self) -> LockResult> { + // SAFETY: Untriaged. unsafe { self.inner.write(); RwLockWriteGuard::new(self) @@ -547,6 +550,7 @@ impl RwLock { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_should_not_be_called_on_const_items] pub fn try_write(&self) -> TryLockResult> { + // SAFETY: Untriaged. unsafe { if self.inner.try_write() { Ok(RwLockWriteGuard::new(self)?) @@ -739,6 +743,7 @@ impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> { /// instantiating this object. unsafe fn new(lock: &'rwlock RwLock) -> LockResult> { poison::map_result(lock.poison.borrow(), |()| RwLockReadGuard { + // SAFETY: Untriaged. data: unsafe { NonNull::new_unchecked(lock.data.get()) }, inner_lock: &lock.inner, }) diff --git a/library/std/src/sync/reentrant_lock.rs b/library/std/src/sync/reentrant_lock.rs index f560b616dd922..52f6d5d3e10d6 100644 --- a/library/std/src/sync/reentrant_lock.rs +++ b/library/std/src/sync/reentrant_lock.rs @@ -159,6 +159,7 @@ cfg_select!( let tls_addr = tls_addr(); // SAFETY: See the comments in the struct definition. self.tls_addr.load(Ordering::Relaxed) == tls_addr +// SAFETY: Untriaged. && unsafe { *self.tid.get() } == owner.as_u64().get() } @@ -172,6 +173,7 @@ cfg_select!( let tls_addr = if tid.is_some() { tls_addr() } else { 0 }; let value = tid.map_or(0, |tid| tid.as_u64().get()); self.tls_addr.store(tls_addr, Ordering::Relaxed); +// SAFETY: Untriaged. unsafe { *self.tid.get() = value }; } } @@ -286,6 +288,7 @@ impl ReentrantLock { // Safety: We only touch lock_count when we own the inner mutex. // Additionally, we only call `self.owner.set()` while holding // the inner mutex, so no two threads can call it concurrently. + // SAFETY: Untriaged. unsafe { if self.owner.contains(this_thread) { self.increment_lock_count().expect("lock count overflow in reentrant mutex"); @@ -333,6 +336,7 @@ impl ReentrantLock { // Safety: We only touch lock_count when we own the inner mutex. // Additionally, we only call `self.owner.set()` while holding // the inner mutex, so no two threads can call it concurrently. + // SAFETY: Untriaged. unsafe { if self.owner.contains(this_thread) { self.increment_lock_count()?; @@ -360,6 +364,7 @@ impl ReentrantLock { } unsafe fn increment_lock_count(&self) -> Option<()> { + // SAFETY: Untriaged. unsafe { *self.lock_count.get() = (*self.lock_count.get()).checked_add(1)?; } @@ -421,6 +426,7 @@ impl Drop for ReentrantLockGuard<'_, T> { #[inline] fn drop(&mut self) { // Safety: We own the lock. + // SAFETY: Untriaged. unsafe { *self.lock.lock_count.get() -= 1; if *self.lock.lock_count.get() == 0 { diff --git a/library/std/src/sys/alloc/hermit.rs b/library/std/src/sys/alloc/hermit.rs index 9afcb315f4ab5..f03dd00d82175 100644 --- a/library/std/src/sys/alloc/hermit.rs +++ b/library/std/src/sys/alloc/hermit.rs @@ -4,6 +4,7 @@ use crate::alloc::Layout; pub unsafe fn alloc(layout: Layout) -> *mut u8 { let size = layout.size(); let align = layout.align(); + // SAFETY: Untriaged. unsafe { hermit_abi::malloc(size, align) } } @@ -11,6 +12,7 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { let size = layout.size(); let align = layout.align(); + // SAFETY: Untriaged. unsafe { hermit_abi::free(ptr, size, align); } @@ -20,5 +22,6 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { let size = layout.size(); let align = layout.align(); + // SAFETY: Untriaged. unsafe { hermit_abi::realloc(ptr, size, align, new_size) } } diff --git a/library/std/src/sys/alloc/mod.rs b/library/std/src/sys/alloc/mod.rs index 73d35781f09bf..e88c96bad36d4 100644 --- a/library/std/src/sys/alloc/mod.rs +++ b/library/std/src/sys/alloc/mod.rs @@ -126,8 +126,10 @@ cfg_select! { ) => { #[inline] pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { +// SAFETY: Untriaged. let ptr = unsafe { alloc(layout) }; if !ptr.is_null() { +// SAFETY: Untriaged. unsafe { ptr.write_bytes(0, layout.size()) }; } ptr diff --git a/library/std/src/sys/alloc/sgx.rs b/library/std/src/sys/alloc/sgx.rs index c20761259048e..98323c44949e6 100644 --- a/library/std/src/sys/alloc/sgx.rs +++ b/library/std/src/sys/alloc/sgx.rs @@ -86,11 +86,13 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 #[cfg(not(test))] #[unsafe(no_mangle)] pub unsafe extern "C" fn __rust_c_alloc(size: usize, align: usize) -> *mut u8 { + // SAFETY: Untriaged. unsafe { crate::alloc::alloc(Layout::from_size_align_unchecked(size, align)) } } #[cfg(not(test))] #[unsafe(no_mangle)] pub unsafe extern "C" fn __rust_c_dealloc(ptr: *mut u8, size: usize, align: usize) { + // SAFETY: Untriaged. unsafe { crate::alloc::dealloc(ptr, Layout::from_size_align_unchecked(size, align)) } } diff --git a/library/std/src/sys/alloc/solid.rs b/library/std/src/sys/alloc/solid.rs index 5d3f396f0dd11..9fa45fbb636fc 100644 --- a/library/std/src/sys/alloc/solid.rs +++ b/library/std/src/sys/alloc/solid.rs @@ -4,19 +4,23 @@ use crate::alloc::Layout; #[inline] pub unsafe fn alloc(layout: Layout) -> *mut u8 { if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { + // SAFETY: Untriaged. unsafe { libc::malloc(layout.size()) as *mut u8 } } else { + // SAFETY: Untriaged. unsafe { libc::memalign(layout.align(), layout.size()) as *mut u8 } } } #[inline] pub unsafe fn dealloc(ptr: *mut u8, _layout: Layout) { + // SAFETY: Untriaged. unsafe { libc::free(ptr as *mut libc::c_void) } } #[inline] pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + // SAFETY: Untriaged. unsafe { if layout.align() <= MIN_ALIGN && layout.align() <= new_size { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 diff --git a/library/std/src/sys/alloc/uefi.rs b/library/std/src/sys/alloc/uefi.rs index aa7fcc9fe110c..a488831218a47 100644 --- a/library/std/src/sys/alloc/uefi.rs +++ b/library/std/src/sys/alloc/uefi.rs @@ -25,10 +25,12 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { helpers::image_handle_protocol::(loaded_image::PROTOCOL_GUID) .unwrap(); // Gives allocations the memory type that the data sections were loaded as. + // SAFETY: Untriaged. unsafe { (*protocol.as_ptr()).image_data_type } }); // The caller must ensure non-0 layout + // SAFETY: Untriaged. unsafe { r_efi_alloc::raw::alloc(system_table, layout, *mem_type) } } @@ -41,6 +43,7 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { // If boot services is valid then SystemTable is not null. let system_table = crate::os::uefi::env::system_table().as_ptr().cast(); // The caller must ensure non-0 layout + // SAFETY: Untriaged. unsafe { r_efi_alloc::raw::dealloc(system_table, ptr, layout) } } diff --git a/library/std/src/sys/alloc/unix.rs b/library/std/src/sys/alloc/unix.rs index 2411ca0a48c48..6677d04c6c334 100644 --- a/library/std/src/sys/alloc/unix.rs +++ b/library/std/src/sys/alloc/unix.rs @@ -28,6 +28,7 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { // Also see and // . if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { + // SAFETY: Untriaged. unsafe { libc::malloc(layout.size()) as *mut u8 } } else { // `posix_memalign` returns a non-aligned value if supplied a very @@ -42,6 +43,7 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { return ptr::null_mut(); } } + // SAFETY: Untriaged. unsafe { aligned_malloc(&layout) } } } @@ -50,10 +52,13 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { // See the comment above in `alloc` for why this check looks the way it does. if layout.align() <= MIN_ALIGN && layout.align() <= layout.size() { + // SAFETY: Untriaged. unsafe { libc::calloc(layout.size(), 1) as *mut u8 } } else { + // SAFETY: Untriaged. let ptr = unsafe { alloc(layout) }; if !ptr.is_null() { + // SAFETY: Untriaged. unsafe { ptr::write_bytes(ptr, 0, layout.size()) }; } ptr @@ -62,14 +67,17 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { #[inline] pub unsafe fn dealloc(ptr: *mut u8, _layout: Layout) { + // SAFETY: Untriaged. unsafe { libc::free(ptr as *mut libc::c_void) } } #[inline] pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { if layout.align() <= MIN_ALIGN && layout.align() <= new_size { + // SAFETY: Untriaged. unsafe { libc::realloc(ptr as *mut libc::c_void, new_size) as *mut u8 } } else { + // SAFETY: Untriaged. unsafe { realloc_fallback(ptr, layout, new_size) } } } @@ -80,6 +88,7 @@ cfg_select! { any(target_os = "horizon", target_os = "vita") => { #[inline] unsafe fn aligned_malloc(layout: &Layout) -> *mut u8 { +// SAFETY: Untriaged. unsafe { libc::memalign(layout.align(), layout.size()) as *mut u8 } } } @@ -96,6 +105,7 @@ cfg_select! { // posix_memalign only has one, clear requirement: that the alignment be a multiple of // `sizeof(void*)`. Since these are all powers of 2, we can just use max. let align = layout.align().max(size_of::()); +// SAFETY: Untriaged. let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) }; if ret != 0 { ptr::null_mut() } else { out as *mut u8 } } diff --git a/library/std/src/sys/alloc/vexos.rs b/library/std/src/sys/alloc/vexos.rs index 6aba6dc474911..3e3b10a6f9e3b 100644 --- a/library/std/src/sys/alloc/vexos.rs +++ b/library/std/src/sys/alloc/vexos.rs @@ -23,6 +23,7 @@ unsafe impl dlmalloc::Allocator for Vexos { if !INIT.swap(true, Ordering::Relaxed) { // This target has no growable heap, as user memory has a fixed // size/location and VEXos does not manage allocation for us. + // SAFETY: Untriaged. unsafe { ( (&raw mut __heap_start).cast::(), diff --git a/library/std/src/sys/alloc/wasm.rs b/library/std/src/sys/alloc/wasm.rs index 995230aebaa01..3a0497ae4ff9c 100644 --- a/library/std/src/sys/alloc/wasm.rs +++ b/library/std/src/sys/alloc/wasm.rs @@ -31,6 +31,7 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access. // Calling malloc() is safe because preconditions on this function match the trait method preconditions. let _lock = lock::lock(); + // SAFETY: Untriaged. unsafe { (*DLMALLOC.get()).0.malloc(layout.size(), layout.align()) } } @@ -39,6 +40,7 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access. // Calling calloc() is safe because preconditions on this function match the trait method preconditions. let _lock = lock::lock(); + // SAFETY: Untriaged. unsafe { (*DLMALLOC.get()).0.calloc(layout.size(), layout.align()) } } @@ -47,6 +49,7 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access. // Calling free() is safe because preconditions on this function match the trait method preconditions. let _lock = lock::lock(); + // SAFETY: Untriaged. unsafe { (*DLMALLOC.get()).0.free(ptr, layout.size(), layout.align()) } } @@ -55,6 +58,7 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access. // Calling realloc() is safe because preconditions on this function match the trait method preconditions. let _lock = lock::lock(); + // SAFETY: Untriaged. unsafe { (*DLMALLOC.get()).0.realloc(ptr, layout.size(), layout.align(), new_size) } } diff --git a/library/std/src/sys/alloc/windows.rs b/library/std/src/sys/alloc/windows.rs index 1d75cbd9d54f1..b9e5321119f9c 100644 --- a/library/std/src/sys/alloc/windows.rs +++ b/library/std/src/sys/alloc/windows.rs @@ -166,6 +166,7 @@ unsafe fn allocate(layout: Layout, zeroed: bool) -> *mut u8 { pub unsafe fn alloc(layout: Layout) -> *mut u8 { // SAFETY: Pointers returned by `allocate` satisfy the guarantees of `System` let zeroed = false; + // SAFETY: Untriaged. unsafe { allocate(layout, zeroed) } } @@ -173,6 +174,7 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { // SAFETY: Pointers returned by `allocate` satisfy the guarantees of `System` let zeroed = true; + // SAFETY: Untriaged. unsafe { allocate(layout, zeroed) } } diff --git a/library/std/src/sys/alloc/xous.rs b/library/std/src/sys/alloc/xous.rs index 74229351f6d22..9afedc4bad3e0 100644 --- a/library/std/src/sys/alloc/xous.rs +++ b/library/std/src/sys/alloc/xous.rs @@ -18,6 +18,7 @@ pub unsafe fn alloc(layout: Layout) -> *mut u8 { // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access. // Calling malloc() is safe because preconditions on this function match the trait method preconditions. let _lock = lock::lock(); + // SAFETY: Untriaged. unsafe { DLMALLOC.malloc(layout.size(), layout.align()) } } @@ -26,6 +27,7 @@ pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 { // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access. // Calling calloc() is safe because preconditions on this function match the trait method preconditions. let _lock = lock::lock(); + // SAFETY: Untriaged. unsafe { DLMALLOC.calloc(layout.size(), layout.align()) } } @@ -34,6 +36,7 @@ pub unsafe fn dealloc(ptr: *mut u8, layout: Layout) { // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access. // Calling free() is safe because preconditions on this function match the trait method preconditions. let _lock = lock::lock(); + // SAFETY: Untriaged. unsafe { DLMALLOC.free(ptr, layout.size(), layout.align()) } } @@ -42,6 +45,7 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 // SAFETY: DLMALLOC access is guaranteed to be safe because the lock gives us unique and non-reentrant access. // Calling realloc() is safe because preconditions on this function match the trait method preconditions. let _lock = lock::lock(); + // SAFETY: Untriaged. unsafe { DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size) } } diff --git a/library/std/src/sys/alloc/zkvm.rs b/library/std/src/sys/alloc/zkvm.rs index 7f39d7fed777e..db2a3eabae21a 100644 --- a/library/std/src/sys/alloc/zkvm.rs +++ b/library/std/src/sys/alloc/zkvm.rs @@ -3,6 +3,7 @@ use crate::sys::pal::abi; #[inline] pub unsafe fn alloc(layout: Layout) -> *mut u8 { + // SAFETY: Untriaged. unsafe { abi::sys_alloc_aligned(layout.size(), layout.align()) } } diff --git a/library/std/src/sys/args/sgx.rs b/library/std/src/sys/args/sgx.rs index 6750cf33d7686..afcfe55cfac6d 100644 --- a/library/std/src/sys/args/sgx.rs +++ b/library/std/src/sys/args/sgx.rs @@ -16,6 +16,7 @@ static ARGS: OnceLock> = OnceLock::new(); #[cfg_attr(test, allow(dead_code))] pub unsafe fn init(argc: isize, argv: *const *const u8) { if argc != 0 { + // SAFETY: Untriaged. let args = unsafe { alloc::User::<[ByteBuffer]>::from_raw_parts(argv as _, argc as _) }; let args = args .iter() diff --git a/library/std/src/sys/args/uefi.rs b/library/std/src/sys/args/uefi.rs index edf6f6873f8d2..1791ebbee417c 100644 --- a/library/std/src/sys/args/uefi.rs +++ b/library/std/src/sys/args/uefi.rs @@ -15,6 +15,7 @@ pub fn args() -> Args { helpers::image_handle_protocol::(loaded_image::PROTOCOL_GUID) .unwrap(); + // SAFETY: Untriaged. let lp_size = unsafe { (*protocol.as_ptr()).load_options_size } as usize; // Break if we are sure that it cannot be UTF-16 if lp_size < size_of::() || lp_size % size_of::() != 0 { @@ -22,10 +23,12 @@ pub fn args() -> Args { } let lp_size = lp_size / size_of::(); + // SAFETY: Untriaged. let lp_cmd_line = unsafe { (*protocol.as_ptr()).load_options as *const u16 }; if !lp_cmd_line.is_aligned() { return Args::new(lazy_current_exe()); } + // SAFETY: Untriaged. let lp_cmd_line = unsafe { crate::slice::from_raw_parts(lp_cmd_line, lp_size) }; Args::new(parse_lp_cmd_line(lp_cmd_line).unwrap_or_else(lazy_current_exe)) diff --git a/library/std/src/sys/args/unix.rs b/library/std/src/sys/args/unix.rs index 197931d8cc8d2..0dc538c728cd6 100644 --- a/library/std/src/sys/args/unix.rs +++ b/library/std/src/sys/args/unix.rs @@ -14,6 +14,7 @@ use crate::os::unix::ffi::OsStringExt; /// One-time global initialization. pub unsafe fn init(argc: isize, argv: *const *const u8) { + // SAFETY: Untriaged. unsafe { imp::init(argc, argv) } } @@ -111,6 +112,7 @@ mod imp { pub unsafe fn init(argc: isize, argv: *const *const u8) { // on GNU/Linux if we are main then we will init argv and argc twice, it "duplicates work" // BUT edge-cases are real: only using .init_array can break most emulators, dlopen, etc. + // SAFETY: Untriaged. unsafe { really_init(argc, argv) }; } @@ -129,6 +131,7 @@ mod imp { argv: *const *const u8, _envp: *const *const u8, ) { + // SAFETY: Untriaged. unsafe { really_init(argc as isize, argv) }; } init_wrapper diff --git a/library/std/src/sys/args/wali.rs b/library/std/src/sys/args/wali.rs index dc6295a483334..4fca74f1bce26 100644 --- a/library/std/src/sys/args/wali.rs +++ b/library/std/src/sys/args/wali.rs @@ -2,6 +2,7 @@ pub use super::common::Args; /// One-time global initialization. pub unsafe fn init(argc: isize, argv: *const *const u8) { + // SAFETY: Untriaged. unsafe { imp::init(argc, argv) } } @@ -32,9 +33,11 @@ mod imp { } unsafe fn load_arg(idx: c_uint) -> OsString { + // SAFETY: Untriaged. let arg_len = unsafe { __cl_get_argv_len(idx) }; let arg_buf = CString::new(vec![b'x'; arg_len as usize]).unwrap(); let ptr = arg_buf.into_raw(); + // SAFETY: Untriaged. let arg_buf = unsafe { __cl_copy_argv(ptr, idx); CString::from_raw(ptr) @@ -43,7 +46,9 @@ mod imp { } fn argc_argv() -> Vec { + // SAFETY: Untriaged. let argc = unsafe { __cl_get_argc() }; + // SAFETY: Untriaged. (0..argc).map(|x| unsafe { load_arg(x) }).collect() } diff --git a/library/std/src/sys/args/wasip1.rs b/library/std/src/sys/args/wasip1.rs index c09175a23f50f..6206c1cc621ac 100644 --- a/library/std/src/sys/args/wasip1.rs +++ b/library/std/src/sys/args/wasip1.rs @@ -10,6 +10,7 @@ pub fn args() -> Args { } fn maybe_args() -> Option> { + // SAFETY: Untriaged. unsafe { let (argc, buf_size) = wasip1::args_sizes_get().ok()?; let mut argv = Vec::with_capacity(argc); diff --git a/library/std/src/sys/args/windows.rs b/library/std/src/sys/args/windows.rs index bd26db7fea553..7dd5b043bd248 100644 --- a/library/std/src/sys/args/windows.rs +++ b/library/std/src/sys/args/windows.rs @@ -369,6 +369,7 @@ pub(crate) fn from_wide_to_user_path(mut path: Vec) -> io::Result> match &path[..] { // `\\?\C:\...` => `C:\...` + // SAFETY: Untriaged. [SEP, SEP, QUERY, SEP, _, COLON, SEP, ..] => unsafe { let lpfilename = path[4..].as_ptr(); fill_utf16_buf( @@ -385,6 +386,7 @@ pub(crate) fn from_wide_to_user_path(mut path: Vec) -> io::Result> ) }, // `\\?\UNC\...` => `\\...` + // SAFETY: Untriaged. [SEP, SEP, QUERY, SEP, U, N, C, SEP, ..] => unsafe { // Change the `C` in `UNC\` to `\` so we can get a slice that starts with `\\`. path[6] = b'\\' as u16; diff --git a/library/std/src/sys/args/zkvm.rs b/library/std/src/sys/args/zkvm.rs index d26bf1eaff91f..05f8ebeef9bbd 100644 --- a/library/std/src/sys/args/zkvm.rs +++ b/library/std/src/sys/args/zkvm.rs @@ -9,20 +9,26 @@ pub fn args() -> Args { } fn get_args() -> Vec<&'static OsStr> { + // SAFETY: Untriaged. let argc = unsafe { abi::sys_argc() }; let mut args = Vec::with_capacity(argc); for i in 0..argc { // Get the size of the argument then the data. + // SAFETY: Untriaged. let arg_len = unsafe { abi::sys_argv(ptr::null_mut(), 0, i) }; let arg_len_words = (arg_len + WORD_SIZE - 1) / WORD_SIZE; + // SAFETY: Untriaged. let words = unsafe { abi::sys_alloc_words(arg_len_words) }; + // SAFETY: Untriaged. let arg_len2 = unsafe { abi::sys_argv(words, arg_len_words, i) }; debug_assert_eq!(arg_len, arg_len2); + // SAFETY: Untriaged. let arg_bytes = unsafe { slice::from_raw_parts(words.cast(), arg_len) }; + // SAFETY: Untriaged. args.push(unsafe { OsStr::from_encoded_bytes_unchecked(arg_bytes) }); } args diff --git a/library/std/src/sys/configure_builtins.rs b/library/std/src/sys/configure_builtins.rs index 7cdf04ebb8899..184418285de15 100644 --- a/library/std/src/sys/configure_builtins.rs +++ b/library/std/src/sys/configure_builtins.rs @@ -53,6 +53,7 @@ static RUST_LSE_INIT: extern "C" fn() = { } if arch::is_aarch64_feature_detected!("lse") { + // SAFETY: Untriaged. unsafe { __rust_enable_lse(); } diff --git a/library/std/src/sys/env/hermit.rs b/library/std/src/sys/env/hermit.rs index 445ecdeb6a39f..d498649d95e9c 100644 --- a/library/std/src/sys/env/hermit.rs +++ b/library/std/src/sys/env/hermit.rs @@ -17,6 +17,7 @@ pub fn init(env: *const *const c_char) { return; } + // SAFETY: Untriaged. unsafe { let mut environ = env; while !(*environ).is_null() { diff --git a/library/std/src/sys/env/solid.rs b/library/std/src/sys/env/solid.rs index 0ce5a22b42561..63a0c6ce717ef 100644 --- a/library/std/src/sys/env/solid.rs +++ b/library/std/src/sys/env/solid.rs @@ -21,6 +21,7 @@ pub fn env() -> Env { static mut environ: *const *const c_char; } + // SAFETY: Untriaged. unsafe { let _guard = env_read_lock(); let mut result = Vec::new(); @@ -58,6 +59,7 @@ pub fn getenv(k: &OsStr) -> Option { // always None as well run_with_cstr(k.as_bytes(), &|k| { let _guard = env_read_lock(); + // SAFETY: Untriaged. let v = unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char; if v.is_null() { @@ -77,6 +79,7 @@ pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { run_with_cstr(k.as_bytes(), &|k| { run_with_cstr(v.as_bytes(), &|v| { let _guard = ENV_LOCK.write(); + // SAFETY: Untriaged. cvt_env(unsafe { libc::setenv(k.as_ptr(), v.as_ptr(), 1) }).map(drop) }) }) @@ -85,6 +88,7 @@ pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { pub unsafe fn unsetenv(n: &OsStr) -> io::Result<()> { run_with_cstr(n.as_bytes(), &|nbuf| { let _guard = ENV_LOCK.write(); + // SAFETY: Untriaged. cvt_env(unsafe { libc::unsetenv(nbuf.as_ptr()) }).map(drop) }) } diff --git a/library/std/src/sys/env/uefi.rs b/library/std/src/sys/env/uefi.rs index bc2aed4231797..3f0655d979333 100644 --- a/library/std/src/sys/env/uefi.rs +++ b/library/std/src/sys/env/uefi.rs @@ -29,6 +29,7 @@ mod uefi_env { pub(crate) fn get(key: &OsStr) -> Option { let shell = helpers::open_shell()?; let mut key_ptr = helpers::os_string_to_raw(key)?; + // SAFETY: Untriaged. unsafe { get_raw(shell, key_ptr.as_mut_ptr()) } } @@ -37,12 +38,14 @@ mod uefi_env { .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "invalid key"))?; let mut val_ptr = helpers::os_string_to_raw(val) .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "invalid value"))?; + // SAFETY: Untriaged. unsafe { set_raw(key_ptr.as_mut_ptr(), val_ptr.as_mut_ptr()) } } pub(crate) fn unset(key: &OsStr) -> io::Result<()> { let mut key_ptr = helpers::os_string_to_raw(key) .ok_or(io::const_error!(io::ErrorKind::InvalidInput, "invalid key"))?; + // SAFETY: Untriaged. let r = unsafe { set_raw(key_ptr.as_mut_ptr(), crate::ptr::null_mut()) }; // The UEFI Shell spec only lists `EFI_SUCCESS` as a possible return value for @@ -63,6 +66,7 @@ mod uefi_env { let shell = helpers::open_shell().ok_or(unsupported_err())?; let mut vars = Vec::new(); + // SAFETY: Untriaged. let val = unsafe { ((*shell.as_ptr()).get_env)(crate::ptr::null_mut()) }; if val.is_null() { @@ -74,12 +78,14 @@ mod uefi_env { // UEFI Shell returns all keys separated by NULL. // End of string is denoted by two NULLs for i in 0.. { + // SAFETY: Untriaged. if unsafe { *val.add(i) } == 0 { // Two NULL signal end of string if i == start { break; } + // SAFETY: Untriaged. let key = OsString::from_wide(unsafe { crate::slice::from_raw_parts(val.add(start), i - start) }); @@ -99,6 +105,7 @@ mod uefi_env { shell: NonNull, key_ptr: *mut r_efi::efi::Char16, ) -> Option { + // SAFETY: Untriaged. let val = unsafe { ((*shell.as_ptr()).get_env)(key_ptr) }; helpers::os_string_from_raw(val) } @@ -109,6 +116,7 @@ mod uefi_env { ) -> io::Result<()> { let shell = helpers::open_shell().ok_or(unsupported_err())?; let volatile = r_efi::efi::Boolean::TRUE; + // SAFETY: Untriaged. let r = unsafe { ((*shell.as_ptr()).set_env)(key_ptr, val_ptr, volatile) }; if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } diff --git a/library/std/src/sys/env/unix.rs b/library/std/src/sys/env/unix.rs index f9ecec0c7304f..ed1459ab416d2 100644 --- a/library/std/src/sys/env/unix.rs +++ b/library/std/src/sys/env/unix.rs @@ -35,6 +35,7 @@ use crate::sys::helpers::run_with_cstr; // desirable anyhow? Though it also means that we have to link to Foundation. #[cfg(target_vendor = "apple")] pub unsafe fn environ() -> *mut *const *const c_char { + // SAFETY: Untriaged. unsafe { libc::_NSGetEnviron() as *mut *const *const c_char } } @@ -50,6 +51,7 @@ pub unsafe fn environ() -> *mut *const *const c_char { #[linkage = "extern_weak"] static environ: *mut *const *const c_char; } + // SAFETY: Untriaged. unsafe { environ } } @@ -71,6 +73,7 @@ pub fn env_read_lock() -> impl Drop { /// Returns a vector of (variable, value) byte-vector pairs for all the /// environment variables of the current process. pub fn env() -> Env { + // SAFETY: Untriaged. unsafe { let _guard = env_read_lock(); let mut result = Vec::new(); @@ -114,6 +117,7 @@ pub fn getenv(k: &OsStr) -> Option { // always None as well run_with_cstr(k.as_bytes(), &|k| { let _guard = env_read_lock(); + // SAFETY: Untriaged. let v = unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char; if v.is_null() { @@ -133,6 +137,7 @@ pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { run_with_cstr(k.as_bytes(), &|k| { run_with_cstr(v.as_bytes(), &|v| { let _guard = ENV_LOCK.write(); + // SAFETY: Untriaged. cvt(unsafe { libc::setenv(k.as_ptr(), v.as_ptr(), 1) }).map(drop) }) }) @@ -141,6 +146,7 @@ pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { pub unsafe fn unsetenv(n: &OsStr) -> io::Result<()> { run_with_cstr(n.as_bytes(), &|nbuf| { let _guard = ENV_LOCK.write(); + // SAFETY: Untriaged. cvt(unsafe { libc::unsetenv(nbuf.as_ptr()) }).map(drop) }) } diff --git a/library/std/src/sys/env/wasi.rs b/library/std/src/sys/env/wasi.rs index 6b892376fd0cf..b25b5b8f82f15 100644 --- a/library/std/src/sys/env/wasi.rs +++ b/library/std/src/sys/env/wasi.rs @@ -36,6 +36,7 @@ cfg_select! { } pub fn env() -> Env { + // SAFETY: Untriaged. unsafe { let _guard = env_read_lock(); @@ -76,6 +77,7 @@ pub fn getenv(k: &OsStr) -> Option { // always None as well run_with_cstr(k.as_bytes(), &|k| { let _guard = env_read_lock(); + // SAFETY: Untriaged. let v = unsafe { libc::getenv(k.as_ptr()) } as *const libc::c_char; if v.is_null() { @@ -93,6 +95,7 @@ pub fn getenv(k: &OsStr) -> Option { pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { run_with_cstr(k.as_bytes(), &|k| { + // SAFETY: Untriaged. run_with_cstr(v.as_bytes(), &|v| unsafe { let _guard = env_write_lock(); cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop) @@ -101,6 +104,7 @@ pub unsafe fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> { } pub unsafe fn unsetenv(n: &OsStr) -> io::Result<()> { + // SAFETY: Untriaged. run_with_cstr(n.as_bytes(), &|nbuf| unsafe { let _guard = env_write_lock(); cvt(libc::unsetenv(nbuf.as_ptr())).map(drop) diff --git a/library/std/src/sys/env/windows.rs b/library/std/src/sys/env/windows.rs index 219fcc4fb43f9..393a293a59789 100644 --- a/library/std/src/sys/env/windows.rs +++ b/library/std/src/sys/env/windows.rs @@ -33,6 +33,7 @@ impl Iterator for EnvIterator { fn next(&mut self) -> Option<(OsString, OsString)> { let Self(cur) = self; loop { + // SAFETY: Untriaged. unsafe { if **cur == 0 { return None; @@ -65,6 +66,7 @@ impl Iterator for EnvIterator { impl Drop for Env { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { c::FreeEnvironmentStringsW(self.base); } @@ -72,6 +74,7 @@ impl Drop for Env { } pub fn env() -> Env { + // SAFETY: Untriaged. unsafe { let ch = c::GetEnvironmentStringsW(); if ch.is_null() { @@ -84,6 +87,7 @@ pub fn env() -> Env { pub fn getenv(k: &OsStr) -> Option { let k = to_u16s(k).ok()?; fill_utf16_buf( + // SAFETY: Untriaged. |buf, sz| unsafe { c::GetEnvironmentVariableW(k.as_ptr(), buf, sz) }, OsStringExt::from_wide, ) diff --git a/library/std/src/sys/env/zkvm.rs b/library/std/src/sys/env/zkvm.rs index b672a03bf0ba7..6b2fd9c745fc7 100644 --- a/library/std/src/sys/env/zkvm.rs +++ b/library/std/src/sys/env/zkvm.rs @@ -10,14 +10,17 @@ use crate::sys::{FromInner, os_str}; pub fn getenv(varname: &OsStr) -> Option { let varname = varname.as_encoded_bytes(); let nbytes = +// SAFETY: Untriaged. unsafe { abi::sys_getenv(crate::ptr::null_mut(), 0, varname.as_ptr(), varname.len()) }; if nbytes == usize::MAX { return None; } let nwords = (nbytes + WORD_SIZE - 1) / WORD_SIZE; + // SAFETY: Untriaged. let words = unsafe { abi::sys_alloc_words(nwords) }; + // SAFETY: Untriaged. let nbytes2 = unsafe { abi::sys_getenv(words, nwords, varname.as_ptr(), varname.len()) }; debug_assert_eq!(nbytes, nbytes2); @@ -26,6 +29,7 @@ pub fn getenv(varname: &OsStr) -> Option { // FIXME: We can probably get rid of the extra copy here if we // reimplement "os_str" instead of just using the generic unix // "os_str". + // SAFETY: Untriaged. let u8s: &[u8] = unsafe { crate::slice::from_raw_parts(words.cast() as *const u8, nbytes) }; Some(OsString::from_inner(os_str::Buf { inner: u8s.to_vec() })) } diff --git a/library/std/src/sys/exit.rs b/library/std/src/sys/exit.rs index d0c67fbf6cbd7..6439416d425f4 100644 --- a/library/std/src/sys/exit.rs +++ b/library/std/src/sys/exit.rs @@ -50,6 +50,7 @@ cfg_select! { // Pause until the process exits. loop { // Safety: libc::pause is safe to call. +// SAFETY: Untriaged. unsafe { libc::pause(); } } } @@ -89,74 +90,80 @@ cfg_select! { pub fn exit(code: i32) -> ! { cfg_select! { - target_os = "hermit" => { - unsafe { hermit_abi::exit(code) } - } - target_os = "linux" => { - unsafe { - unique_thread_exit(); - libc::exit(code) + target_os = "hermit" => { + // SAFETY: Untriaged. + unsafe { hermit_abi::exit(code) } } - } - target_os = "motor" => { - moto_rt::process::exit(code) - } - all(target_vendor = "fortanix", target_env = "sgx") => { - crate::sys::pal::abi::exit_with_code(code as _) - } - target_os = "solid_asp3" => { - rtabort!("exit({}) called", code) - } - target_os = "teeos" => { - let _ = code; - panic!("TA should not call `exit`") - } - target_os = "uefi" => { - use r_efi::base::Status; + target_os = "linux" => { + // SAFETY: Untriaged. + unsafe { + unique_thread_exit(); + libc::exit(code) + } + } + target_os = "motor" => { + moto_rt::process::exit(code) + } + all(target_vendor = "fortanix", target_env = "sgx") => { + crate::sys::pal::abi::exit_with_code(code as _) + } + target_os = "solid_asp3" => { + rtabort!("exit({}) called", code) + } + target_os = "teeos" => { + let _ = code; + panic!("TA should not call `exit`") + } + target_os = "uefi" => { + use r_efi::base::Status; - use crate::os::uefi::env; + use crate::os::uefi::env; - if let (Some(boot_services), Some(handle)) = - (env::boot_services(), env::try_image_handle()) - { - let boot_services = boot_services.cast::(); - let _ = unsafe { - ((*boot_services.as_ptr()).exit)( - handle.as_ptr(), - Status::from_usize(code as usize), - 0, - crate::ptr::null_mut(), - ) - }; + if let (Some(boot_services), Some(handle)) = + (env::boot_services(), env::try_image_handle()) + { + let boot_services = boot_services.cast::(); + // SAFETY: Untriaged. + let _ = unsafe { + ((*boot_services.as_ptr()).exit)( + handle.as_ptr(), + Status::from_usize(code as usize), + 0, + crate::ptr::null_mut(), + ) + }; + } + crate::intrinsics::abort() } - crate::intrinsics::abort() - } - any( - target_family = "unix", - target_os = "wasi", - ) => { - unsafe { libc::exit(code as crate::ffi::c_int) } - } - target_os = "vexos" => { - let _ = code; + any( + target_family = "unix", + target_os = "wasi", + ) => { + // SAFETY: Untriaged. + unsafe { libc::exit(code as crate::ffi::c_int) } + } + target_os = "vexos" => { + let _ = code; - unsafe { - vex_sdk::vexSystemExitRequest(); + // SAFETY: Untriaged. + unsafe { + vex_sdk::vexSystemExitRequest(); - loop { - vex_sdk::vexTasksRun(); + loop { + vex_sdk::vexTasksRun(); + } } } + target_os = "windows" => { + // SAFETY: Untriaged. + unsafe { crate::sys::pal::c::ExitProcess(code as u32) } + } + target_os = "xous" => { + crate::os::xous::ffi::exit(code as u32) + } + _ => { + let _ = code; + crate::intrinsics::abort() + } } - target_os = "windows" => { - unsafe { crate::sys::pal::c::ExitProcess(code as u32) } - } - target_os = "xous" => { - crate::os::xous::ffi::exit(code as u32) - } - _ => { - let _ = code; - crate::intrinsics::abort() - } - } } diff --git a/library/std/src/sys/fd/hermit.rs b/library/std/src/sys/fd/hermit.rs index fe1b3082a0aa2..4d87b6919b92b 100644 --- a/library/std/src/sys/fd/hermit.rs +++ b/library/std/src/sys/fd/hermit.rs @@ -18,6 +18,7 @@ pub struct FileDesc { impl FileDesc { pub fn read(&self, buf: &mut [u8]) -> io::Result { let result = +// SAFETY: Untriaged. cvt(unsafe { hermit_abi::read(self.fd.as_raw_fd(), buf.as_mut_ptr(), buf.len()) })?; Ok(result as usize) } @@ -38,6 +39,7 @@ impl FileDesc { } pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + // SAFETY: Untriaged. let ret = cvt(unsafe { hermit_abi::readv( self.as_raw_fd(), @@ -60,11 +62,13 @@ impl FileDesc { pub fn write(&self, buf: &[u8]) -> io::Result { let result = +// SAFETY: Untriaged. cvt(unsafe { hermit_abi::write(self.fd.as_raw_fd(), buf.as_ptr(), buf.len()) })?; Ok(result as usize) } pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { + // SAFETY: Untriaged. let ret = cvt(unsafe { hermit_abi::writev( self.as_raw_fd(), @@ -88,6 +92,7 @@ impl FileDesc { SeekFrom::End(off) => (hermit_abi::SEEK_END, off), SeekFrom::Current(off) => (hermit_abi::SEEK_CUR, off), }; + // SAFETY: Untriaged. let n = cvt(unsafe { hermit_abi::lseek(self.as_raw_fd(), pos as isize, whence) })?; Ok(n as u64) } @@ -117,6 +122,7 @@ impl FileDesc { } pub fn fstat(&self, stat: *mut hermit_abi::stat) -> io::Result<()> { + // SAFETY: Untriaged. cvt(unsafe { hermit_abi::fstat(self.fd.as_raw_fd(), stat) })?; Ok(()) } @@ -142,6 +148,7 @@ impl FromInner for FileDesc { impl FromRawFd for FileDesc { unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + // SAFETY: Untriaged. let fd = unsafe { OwnedFd::from_raw_fd(raw_fd) }; Self { fd } } diff --git a/library/std/src/sys/fd/motor.rs b/library/std/src/sys/fd/motor.rs index b81072bcb50c7..2f01d995e5d36 100644 --- a/library/std/src/sys/fd/motor.rs +++ b/library/std/src/sys/fd/motor.rs @@ -118,6 +118,7 @@ impl IntoRawFd for FileDesc { impl FromRawFd for FileDesc { unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + // SAFETY: Untriaged. unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) } } } diff --git a/library/std/src/sys/fd/unix.rs b/library/std/src/sys/fd/unix.rs index d35a001bb6bab..5d4f76945dbc5 100644 --- a/library/std/src/sys/fd/unix.rs +++ b/library/std/src/sys/fd/unix.rs @@ -136,6 +136,7 @@ impl FileDesc { } pub fn read(&self, buf: &mut [u8]) -> io::Result { + // SAFETY: Untriaged. let ret = cvt(unsafe { libc::read( self.as_raw_fd(), @@ -153,6 +154,7 @@ impl FileDesc { target_os = "nuttx" )))] pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + // SAFETY: Untriaged. let ret = cvt(unsafe { libc::readv( self.as_raw_fd(), @@ -190,6 +192,7 @@ impl FileDesc { } pub fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result { + // SAFETY: Untriaged. cvt(unsafe { pread64( self.as_raw_fd(), @@ -250,6 +253,7 @@ impl FileDesc { all(target_os = "macos", target_arch = "aarch64"), ))] pub fn read_vectored_at(&self, bufs: &mut [IoSliceMut<'_>], offset: u64) -> io::Result { + // SAFETY: Untriaged. let ret = cvt(unsafe { libc::preadv( self.as_raw_fd(), @@ -296,6 +300,7 @@ impl FileDesc { ) -> isize; ); + // SAFETY: Untriaged. let ret = cvt(unsafe { preadv( self.as_raw_fd(), @@ -320,6 +325,7 @@ impl FileDesc { match preadv64.get() { Some(preadv) => { + // SAFETY: Untriaged. let ret = cvt(unsafe { preadv( self.as_raw_fd(), @@ -357,6 +363,7 @@ impl FileDesc { match preadv.get() { Some(preadv) => { + // SAFETY: Untriaged. let ret = cvt(unsafe { preadv( self.as_raw_fd(), @@ -372,6 +379,7 @@ impl FileDesc { } pub fn write(&self, buf: &[u8]) -> io::Result { + // SAFETY: Untriaged. let ret = cvt(unsafe { libc::write( self.as_raw_fd(), @@ -389,6 +397,7 @@ impl FileDesc { target_os = "nuttx" )))] pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { + // SAFETY: Untriaged. let ret = cvt(unsafe { libc::writev( self.as_raw_fd(), @@ -421,6 +430,7 @@ impl FileDesc { } pub fn write_at(&self, buf: &[u8], offset: u64) -> io::Result { + // SAFETY: Untriaged. unsafe { cvt(pwrite64( self.as_raw_fd(), @@ -446,6 +456,7 @@ impl FileDesc { all(target_os = "macos", target_arch = "aarch64"), ))] pub fn write_vectored_at(&self, bufs: &[IoSlice<'_>], offset: u64) -> io::Result { + // SAFETY: Untriaged. let ret = cvt(unsafe { libc::pwritev( self.as_raw_fd(), @@ -492,6 +503,7 @@ impl FileDesc { ) -> isize; ); + // SAFETY: Untriaged. let ret = cvt(unsafe { pwritev( self.as_raw_fd(), @@ -516,6 +528,7 @@ impl FileDesc { match pwritev64.get() { Some(pwritev) => { + // SAFETY: Untriaged. let ret = cvt(unsafe { pwritev( self.as_raw_fd(), @@ -553,6 +566,7 @@ impl FileDesc { match pwritev.get() { Some(pwritev) => { + // SAFETY: Untriaged. let ret = cvt(unsafe { pwritev( self.as_raw_fd(), @@ -584,6 +598,7 @@ impl FileDesc { target_os = "wasi", )))] pub fn set_cloexec(&self) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { cvt(libc::ioctl(self.as_raw_fd(), libc::FIOCLEX))?; Ok(()) @@ -609,6 +624,7 @@ impl FileDesc { target_os = "wasi", ))] pub fn set_cloexec(&self) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { let previous = cvt(libc::fcntl(self.as_raw_fd(), libc::F_GETFD))?; let new = previous | libc::FD_CLOEXEC; @@ -627,6 +643,7 @@ impl FileDesc { #[cfg(target_os = "linux")] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { let v = nonblocking as libc::c_int; cvt(libc::ioctl(self.as_raw_fd(), libc::FIONBIO, &v))?; @@ -636,6 +653,7 @@ impl FileDesc { #[cfg(not(target_os = "linux"))] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { let previous = cvt(libc::fcntl(self.as_raw_fd(), libc::F_GETFL))?; let new = if nonblocking { @@ -715,6 +733,7 @@ impl IntoRawFd for FileDesc { impl FromRawFd for FileDesc { unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + // SAFETY: Untriaged. Self(unsafe { FromRawFd::from_raw_fd(raw_fd) }) } } diff --git a/library/std/src/sys/fs/hermit.rs b/library/std/src/sys/fs/hermit.rs index 0d3732a83a9e9..dda3096a805bb 100644 --- a/library/std/src/sys/fs/hermit.rs +++ b/library/std/src/sys/fs/hermit.rs @@ -84,6 +84,7 @@ impl GetdentsBuffer { if self.pos >= self.filled { debug_assert!(self.pos == self.filled); + // SAFETY: Untriaged. let result = unsafe { cvt(hermit_abi::getdents64( fd.as_raw_fd(), @@ -264,9 +265,11 @@ impl Iterator for ReadDir { // to be in bounds of the same allocation, only the offset of the field // being referenced. + // SAFETY: Untriaged. self.buf.consume(usize::from(unsafe { (*entry_ptr).d_reclen })); // d_name is guaranteed to be null-terminated. + // SAFETY: Untriaged. let name = unsafe { CStr::from_ptr((&raw const (*entry_ptr).d_name).cast()) }; let name_bytes = name.to_bytes(); if name_bytes == b"." || name_bytes == b".." { @@ -275,7 +278,9 @@ impl Iterator for ReadDir { return Some(Ok(DirEntry { dir: Arc::clone(&self.inner), + // SAFETY: Untriaged. ino: unsafe { (*entry_ptr).d_ino }, + // SAFETY: Untriaged. type_: unsafe { (*entry_ptr).d_type }, name: OsString::from_vec(name_bytes.to_vec()), })); @@ -400,11 +405,14 @@ impl File { mode = 0; } + // SAFETY: Untriaged. let fd = unsafe { cvt(hermit_abi::open(path.as_ptr(), flags, mode))? }; + // SAFETY: Untriaged. Ok(File(unsafe { FileDesc::from_raw_fd(fd) })) } pub fn file_attr(&self) -> io::Result { + // SAFETY: Untriaged. let mut stat_val: stat_struct = unsafe { mem::zeroed() }; self.0.fstat(&mut stat_val)?; Ok(FileAttr::from_stat(stat_val)) @@ -509,6 +517,7 @@ impl DirBuilder { pub fn mkdir(&self, path: &Path) -> io::Result<()> { run_path_with_cstr(path, &|path| { + // SAFETY: Untriaged. cvt(unsafe { hermit_abi::mkdir(path.as_ptr().cast(), self.mode.into()) }).map(|_| ()) }) } @@ -566,6 +575,7 @@ impl IntoRawFd for File { impl FromRawFd for File { unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + // SAFETY: Untriaged. let file_desc = unsafe { FileDesc::from_raw_fd(raw_fd) }; Self(file_desc) } @@ -573,8 +583,10 @@ impl FromRawFd for File { pub fn readdir(path: &Path) -> io::Result { let fd_raw = run_path_with_cstr(path, &|path| { + // SAFETY: Untriaged. cvt(unsafe { hermit_abi::open(path.as_ptr(), O_RDONLY | O_DIRECTORY, 0) }) })?; + // SAFETY: Untriaged. let fd = unsafe { FileDesc::from_raw_fd(fd_raw) }; let root = path.to_path_buf(); @@ -586,6 +598,7 @@ pub fn readdir(path: &Path) -> io::Result { } pub fn unlink(path: &Path) -> io::Result<()> { + // SAFETY: Untriaged. run_path_with_cstr(path, &|path| cvt(unsafe { hermit_abi::unlink(path.as_ptr()) }).map(|_| ())) } @@ -610,6 +623,7 @@ pub fn set_times_nofollow(_p: &Path, _times: FileTimes) -> io::Result<()> { } pub fn rmdir(path: &Path) -> io::Result<()> { + // SAFETY: Untriaged. run_path_with_cstr(path, &|path| cvt(unsafe { hermit_abi::rmdir(path.as_ptr()) }).map(|_| ())) } @@ -631,7 +645,9 @@ pub fn link(_original: &Path, _link: &Path) -> io::Result<()> { pub fn stat(path: &Path) -> io::Result { run_path_with_cstr(path, &|path| { + // SAFETY: Untriaged. let mut stat_val: stat_struct = unsafe { mem::zeroed() }; + // SAFETY: Untriaged. cvt(unsafe { hermit_abi::stat(path.as_ptr(), &mut stat_val) })?; Ok(FileAttr::from_stat(stat_val)) }) @@ -639,7 +655,9 @@ pub fn stat(path: &Path) -> io::Result { pub fn lstat(path: &Path) -> io::Result { run_path_with_cstr(path, &|path| { + // SAFETY: Untriaged. let mut stat_val: stat_struct = unsafe { mem::zeroed() }; + // SAFETY: Untriaged. cvt(unsafe { hermit_abi::lstat(path.as_ptr(), &mut stat_val) })?; Ok(FileAttr::from_stat(stat_val)) }) diff --git a/library/std/src/sys/fs/motor.rs b/library/std/src/sys/fs/motor.rs index a76f64a47c24a..2f34f5098e8d3 100644 --- a/library/std/src/sys/fs/motor.rs +++ b/library/std/src/sys/fs/motor.rs @@ -169,6 +169,7 @@ impl File { pub fn open(path: &Path, opts: &OpenOptions) -> io::Result { let path = path.to_str().ok_or(io::Error::from(io::ErrorKind::InvalidFilename))?; moto_rt::fs::open(path, opts.rt_open_options) + // SAFETY: Untriaged. .map(|fd| unsafe { Self::from_raw_fd(fd) }) .map_err(map_motor_error) } @@ -246,6 +247,7 @@ impl File { pub fn duplicate(&self) -> io::Result { moto_rt::fs::duplicate(self.as_raw_fd()) + // SAFETY: Untriaged. .map(|fd| unsafe { Self::from_raw_fd(fd) }) .map_err(map_motor_error) } @@ -411,6 +413,7 @@ pub struct DirEntry { impl DirEntry { fn filename(&self) -> &str { + // SAFETY: Untriaged. core::str::from_utf8(unsafe { core::slice::from_raw_parts(self.inner.fname.as_ptr(), self.inner.fname_size as usize) }) @@ -485,6 +488,7 @@ impl IntoRawFd for File { impl FromRawFd for File { unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + // SAFETY: Untriaged. unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) } } } diff --git a/library/std/src/sys/fs/solid.rs b/library/std/src/sys/fs/solid.rs index bd963b1d2f038..1dcb795f50924 100644 --- a/library/std/src/sys/fs/solid.rs +++ b/library/std/src/sys/fs/solid.rs @@ -147,6 +147,7 @@ impl FileType { } pub fn readdir(p: &Path) -> io::Result { + // SAFETY: Untriaged. unsafe { let mut dir = MaybeUninit::uninit(); error::SolidError::err_if_negative(abi::SOLID_FS_OpenDir( @@ -171,6 +172,7 @@ impl Iterator for ReadDir { type Item = io::Result; fn next(&mut self) -> Option> { + // SAFETY: Untriaged. let entry = unsafe { let mut out_entry = MaybeUninit::uninit(); match error::SolidError::err_if_negative(abi::SOLID_FS_ReadDir( @@ -189,6 +191,7 @@ impl Iterator for ReadDir { impl Drop for InnerReadDir { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { abi::SOLID_FS_CloseDir(self.dirp) }; } } @@ -196,11 +199,13 @@ impl Drop for InnerReadDir { impl DirEntry { pub fn path(&self) -> PathBuf { self.inner.root.join(OsStr::from_bytes( + // SAFETY: Untriaged. unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()) }.to_bytes(), )) } pub fn file_name(&self) -> OsString { + // SAFETY: Untriaged. OsStr::from_bytes(unsafe { CStr::from_ptr(self.entry.d_name.as_ptr()) }.to_bytes()) .to_os_string() } @@ -321,6 +326,7 @@ impl File { let flags = opts.get_access_mode()? | opts.get_creation_mode()? | (opts.custom_flags as c_int & !abi::O_ACCMODE); + // SAFETY: Untriaged. unsafe { let mut fd = MaybeUninit::uninit(); error::SolidError::err_if_negative(abi::SOLID_FS_Open( @@ -370,6 +376,7 @@ impl File { } pub fn read(&self, buf: &mut [u8]) -> io::Result { + // SAFETY: Untriaged. unsafe { let mut out_num_bytes = MaybeUninit::uninit(); error::SolidError::err_if_negative(abi::SOLID_FS_Read( @@ -384,6 +391,7 @@ impl File { } pub fn read_buf(&self, mut cursor: BorrowedCursor<'_, u8>) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { let len = cursor.capacity(); let mut out_num_bytes = MaybeUninit::uninit(); @@ -416,6 +424,7 @@ impl File { } pub fn write(&self, buf: &[u8]) -> io::Result { + // SAFETY: Untriaged. unsafe { let mut out_num_bytes = MaybeUninit::uninit(); error::SolidError::err_if_negative(abi::SOLID_FS_Write( @@ -438,6 +447,7 @@ impl File { } pub fn flush(&self) -> io::Result<()> { + // SAFETY: Untriaged. error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Sync(self.fd.raw()) }) .map_err(|e| e.as_io_error())?; Ok(()) @@ -451,6 +461,7 @@ impl File { SeekFrom::End(off) => (abi::SEEK_END, off), SeekFrom::Current(off) => (abi::SEEK_CUR, off), }; + // SAFETY: Untriaged. error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Lseek(self.fd.raw(), pos, whence) }) @@ -464,6 +475,7 @@ impl File { } pub fn tell(&self) -> io::Result { + // SAFETY: Untriaged. unsafe { let mut out_offset = MaybeUninit::uninit(); error::SolidError::err_if_negative(abi::SOLID_FS_Ftell( @@ -490,6 +502,7 @@ impl File { impl Drop for File { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { abi::SOLID_FS_Close(self.fd.raw()) }; } } @@ -500,6 +513,7 @@ impl DirBuilder { } pub fn mkdir(&self, p: &Path) -> io::Result<()> { + // SAFETY: Untriaged. error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Mkdir(cstr(p)?.as_ptr()) }) .map_err(|e| e.as_io_error())?; Ok(()) @@ -516,6 +530,7 @@ pub fn unlink(p: &Path) -> io::Result<()> { if stat(p)?.file_type().is_dir() { Err(io::const_error!(io::ErrorKind::IsADirectory, "is a directory")) } else { + // SAFETY: Untriaged. error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Unlink(cstr(p)?.as_ptr()) }) .map_err(|e| e.as_io_error())?; Ok(()) @@ -523,6 +538,7 @@ pub fn unlink(p: &Path) -> io::Result<()> { } pub fn rename(old: &Path, new: &Path) -> io::Result<()> { + // SAFETY: Untriaged. error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Rename(cstr(old)?.as_ptr(), cstr(new)?.as_ptr()) }) @@ -536,6 +552,7 @@ pub fn set_perm(p: &Path, perm: FilePermissions) -> io::Result<()> { } pub fn set_perm_nofollow(p: &Path, perm: FilePermissions) -> io::Result<()> { + // SAFETY: Untriaged. error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Chmod(cstr(p)?.as_ptr(), perm.0.into()) }) @@ -553,6 +570,7 @@ pub fn set_times_nofollow(_p: &Path, _times: FileTimes) -> io::Result<()> { pub fn rmdir(p: &Path) -> io::Result<()> { if stat(p)?.file_type().is_dir() { + // SAFETY: Untriaged. error::SolidError::err_if_negative(unsafe { abi::SOLID_FS_Unlink(cstr(p)?.as_ptr()) }) .map_err(|e| e.as_io_error())?; Ok(()) @@ -604,6 +622,7 @@ pub fn stat(p: &Path) -> io::Result { } pub fn lstat(p: &Path) -> io::Result { + // SAFETY: Untriaged. unsafe { let mut out_stat = MaybeUninit::uninit(); error::SolidError::err_if_negative(abi::SOLID_FS_Stat( diff --git a/library/std/src/sys/fs/uefi.rs b/library/std/src/sys/fs/uefi.rs index 1a0da329ce1a3..a0d457dfe9996 100644 --- a/library/std/src/sys/fs/uefi.rs +++ b/library/std/src/sys/fs/uefi.rs @@ -86,6 +86,7 @@ impl FileAttr { } fn from_uefi(info: helpers::UefiBox) -> Self { + // SAFETY: Untriaged. unsafe { Self { attr: (*info.as_ptr()).attribute, @@ -315,6 +316,7 @@ impl File { pub fn truncate(&self, size: u64) -> io::Result<()> { let mut file_info = self.0.file_info()?; + // SAFETY: Untriaged. unsafe { (*file_info.as_mut_ptr()).file_size = size }; self.0.set_file_info(file_info) @@ -549,6 +551,7 @@ pub fn canonicalize(p: &Path) -> io::Result { fn set_perm_inner(f: &uefi_fs::File, perm: FilePermissions) -> io::Result<()> { let mut file_info = f.file_info()?; + // SAFETY: Untriaged. unsafe { (*file_info.as_mut_ptr()).attribute = ((*file_info.as_ptr()).attribute & !FILE_PERMISSIONS_MASK) | perm.to_attr() @@ -561,12 +564,14 @@ fn set_times_inner(f: &uefi_fs::File, times: FileTimes) -> io::Result<()> { let mut file_info = f.file_info()?; if let Some(x) = times.accessed { + // SAFETY: Untriaged. unsafe { (*file_info.as_mut_ptr()).last_access_time = uefi_fs::systemtime_to_uefi(x); } } if let Some(x) = times.modified { + // SAFETY: Untriaged. unsafe { (*file_info.as_mut_ptr()).modification_time = uefi_fs::systemtime_to_uefi(x); } @@ -653,6 +658,7 @@ mod uefi_fs { )?; let mut file_protocol = crate::ptr::null_mut(); + // SAFETY: Untriaged. let r = unsafe { ((*simple_file_system_protocol.as_ptr()).open_volume)( simple_file_system_protocol.as_ptr(), @@ -677,6 +683,7 @@ mod uefi_fs { let file_ptr = protocol.as_ptr(); let mut file_opened = crate::ptr::null_mut(); + // SAFETY: Untriaged. let r = unsafe { ((*file_ptr).open)(file_ptr, &mut file_opened, path.as_mut_ptr(), open_mode, attr) }; @@ -694,6 +701,7 @@ mod uefi_fs { let file_ptr = self.protocol.as_ptr(); let mut buf_size = buf.len(); + // SAFETY: Untriaged. let r = unsafe { ((*file_ptr).read)(file_ptr, &mut buf_size, buf.as_mut_ptr().cast()) }; if buf_size == 0 && r.is_error() { @@ -707,6 +715,7 @@ mod uefi_fs { let file_ptr = self.protocol.as_ptr(); let mut buf_size = 0; + // SAFETY: Untriaged. let r = unsafe { ((*file_ptr).read)(file_ptr, &mut buf_size, crate::ptr::null_mut()) }; if buf_size == 0 { @@ -720,6 +729,7 @@ mod uefi_fs { let mut info: UefiBox = UefiBox::new(buf_size)?; let r = +// SAFETY: Untriaged. unsafe { ((*file_ptr).read)(file_ptr, &mut buf_size, info.as_mut_ptr().cast()) }; if r.is_error() { @@ -733,6 +743,7 @@ mod uefi_fs { let file_ptr = self.protocol.as_ptr(); let mut buf_size = buf.len(); + // SAFETY: Untriaged. let r = unsafe { ((*file_ptr).write)( file_ptr, @@ -753,6 +764,7 @@ mod uefi_fs { let mut info_id = file::INFO_ID; let mut buf_size = 0; + // SAFETY: Untriaged. let r = unsafe { ((*file_ptr).get_info)( file_ptr, @@ -767,6 +779,7 @@ mod uefi_fs { } let mut info: UefiBox = UefiBox::new(buf_size)?; + // SAFETY: Untriaged. let r = unsafe { ((*file_ptr).get_info)( file_ptr, @@ -783,6 +796,7 @@ mod uefi_fs { let file_ptr = self.protocol.as_ptr(); let mut info_id = file::INFO_ID; + // SAFETY: Untriaged. let r = unsafe { ((*file_ptr).set_info)(file_ptr, &mut info_id, info.len(), info.as_mut_ptr().cast()) }; @@ -794,18 +808,21 @@ mod uefi_fs { let file_ptr = self.protocol.as_ptr(); let mut pos = 0; + // SAFETY: Untriaged. let r = unsafe { ((*file_ptr).get_position)(file_ptr, &mut pos) }; if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(pos) } } pub(crate) fn set_position(&self, pos: u64) -> io::Result<()> { let file_ptr = self.protocol.as_ptr(); + // SAFETY: Untriaged. let r = unsafe { ((*file_ptr).set_position)(file_ptr, pos) }; if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } pub(crate) fn delete(self) -> io::Result<()> { let file_ptr = self.protocol.as_ptr(); + // SAFETY: Untriaged. let r = unsafe { ((*file_ptr).delete)(file_ptr) }; // Spec states that even in case of failure, the file handle will be closed. @@ -816,6 +833,7 @@ mod uefi_fs { pub(crate) fn flush(&self) -> io::Result<()> { let file_ptr = self.protocol.as_ptr(); + // SAFETY: Untriaged. let r = unsafe { ((*file_ptr).flush)(file_ptr) }; if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } @@ -828,6 +846,7 @@ mod uefi_fs { impl Drop for File { fn drop(&mut self) { let file_ptr = self.protocol.as_ptr(); + // SAFETY: Untriaged. let _ = unsafe { ((*file_ptr).close)(file_ptr) }; } } diff --git a/library/std/src/sys/fs/unix.rs b/library/std/src/sys/fs/unix.rs index d34621083406a..c7fbdb2c78e6a 100644 --- a/library/std/src/sys/fs/unix.rs +++ b/library/std/src/sys/fs/unix.rs @@ -291,6 +291,7 @@ fn debug_path_fd<'a, 'b>( let mut b = f.debug_struct(name); fn get_mode(fd: c_int) -> Option<(bool, bool)> { + // SAFETY: Untriaged. let mode = unsafe { libc::fcntl(fd, libc::F_GETFL) }; if mode == -1 { return None; @@ -330,6 +331,7 @@ fn get_path_from_fd(fd: c_int) -> Option { // alternatives. If a better method is invented, it should be used // instead. let mut buf = vec![0; libc::PATH_MAX as usize]; + // SAFETY: Untriaged. let n = unsafe { libc::fcntl(fd, libc::F_GETPATH, buf.as_mut_ptr()) }; if n == -1 { cfg_select! { @@ -353,12 +355,15 @@ fn get_path_from_fd(fd: c_int) -> Option { #[cfg(target_os = "freebsd")] fn get_path(fd: c_int) -> Option { let info = Box::::new_zeroed(); + // SAFETY: Untriaged. let mut info = unsafe { info.assume_init() }; info.kf_structsize = size_of::() as libc::c_int; + // SAFETY: Untriaged. let n = unsafe { libc::fcntl(fd, libc::F_KINFO, &mut *info) }; if n == -1 { return None; } + // SAFETY: Untriaged. let buf = unsafe { CStr::from_ptr(info.kf_path.as_mut_ptr()).to_bytes().to_vec() }; Some(PathBuf::from(OsString::from_vec(buf))) } @@ -366,6 +371,7 @@ fn get_path_from_fd(fd: c_int) -> Option { #[cfg(target_os = "vxworks")] fn get_path(fd: c_int) -> Option { let mut buf = vec![0; libc::PATH_MAX as usize]; + // SAFETY: Untriaged. let n = unsafe { libc::ioctl(fd, libc::FIOGETNAME, buf.as_mut_ptr()) }; if n == -1 { return None; @@ -803,6 +809,7 @@ impl Iterator for ReadDir { return None; } + // SAFETY: Untriaged. unsafe { loop { // POSIX.1-2024 formalized what was already guaranteed by a lot @@ -965,6 +972,7 @@ pub(crate) fn debug_assert_fd_is_open(fd: RawFd) { // this is similar to assert_unsafe_precondition!() but it doesn't require const if core::ub_checks::check_library_ub() { + // SAFETY: Untriaged. if unsafe { libc::fcntl(fd, libc::F_GETFD) } == -1 && errno() == libc::EBADF { rtabort!("IO Safety violation: owned file descriptor already closed"); } @@ -988,9 +996,11 @@ impl Drop for DirStream { target_os = "nuttx", )))] { + // SAFETY: Untriaged. let fd = unsafe { libc::dirfd(self.0) }; debug_assert_fd_is_open(fd); } + // SAFETY: Untriaged. let r = unsafe { libc::closedir(self.0) }; assert!( r == 0 || crate::io::Error::last_os_error().is_interrupted(), @@ -1026,21 +1036,25 @@ impl DirEntry { not(miri) // no dirfd on Miri ))] pub fn metadata(&self) -> io::Result { + // SAFETY: Untriaged. let fd = cvt(unsafe { dirfd(self.dir.dirp.0) })?; let name = self.name.as_ptr(); cfg_has_statx! { - if let Some(ret) = unsafe { try_statx( - fd, - name, - libc::AT_SYMLINK_NOFOLLOW | libc::AT_STATX_SYNC_AS_STAT, - libc::STATX_BASIC_STATS | libc::STATX_BTIME, - ) } { - return ret; - } - } + // SAFETY: Untriaged. + if let Some(ret) = unsafe { try_statx( + fd, + name, + libc::AT_SYMLINK_NOFOLLOW | libc::AT_STATX_SYNC_AS_STAT, + libc::STATX_BASIC_STATS | libc::STATX_BTIME, + ) } { + return ret; + } + } + // SAFETY: Untriaged. let mut stat: stat64 = unsafe { mem::zeroed() }; + // SAFETY: Untriaged. cvt(unsafe { fstatat64(fd, name, &mut stat, libc::AT_SYMLINK_NOFOLLOW) })?; Ok(FileAttr::from_stat64(stat)) } @@ -1238,7 +1252,9 @@ impl File { // some platforms (like macOS, where `open64` is actually `open`), `mode_t` is `u16`. // However, since this is a variadic function, C integer promotion rules mean that on // the ABI level, this still gets passed as `c_int` (aka `u32` on Unix platforms). + // SAFETY: Untriaged. let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, opts.mode as c_int) })?; + // SAFETY: Untriaged. Ok(File(unsafe { FileDesc::from_raw_fd(fd) })) } @@ -1246,22 +1262,26 @@ impl File { let fd = self.as_raw_fd(); cfg_has_statx! { - if let Some(ret) = unsafe { try_statx( - fd, - c"".as_ptr() as *const c_char, - libc::AT_EMPTY_PATH | libc::AT_STATX_SYNC_AS_STAT, - libc::STATX_BASIC_STATS | libc::STATX_BTIME, - ) } { - return ret; - } - } + // SAFETY: Untriaged. + if let Some(ret) = unsafe { try_statx( + fd, + c"".as_ptr() as *const c_char, + libc::AT_EMPTY_PATH | libc::AT_STATX_SYNC_AS_STAT, + libc::STATX_BASIC_STATS | libc::STATX_BTIME, + ) } { + return ret; + } + } + // SAFETY: Untriaged. let mut stat: stat64 = unsafe { mem::zeroed() }; + // SAFETY: Untriaged. cvt(unsafe { fstat64(fd, &mut stat) })?; Ok(FileAttr::from_stat64(stat)) } pub fn fsync(&self) -> io::Result<()> { + // SAFETY: Untriaged. cvt_r(|| unsafe { os_fsync(self.as_raw_fd()) })?; return Ok(()); @@ -1276,6 +1296,7 @@ impl File { } pub fn datasync(&self) -> io::Result<()> { + // SAFETY: Untriaged. cvt_r(|| unsafe { os_datasync(self.as_raw_fd()) })?; return Ok(()); @@ -1320,149 +1341,155 @@ impl File { pub fn lock(&self) -> io::Result<()> { cfg_select! { - any( - target_os = "freebsd", - target_os = "fuchsia", - target_os = "hurd", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - target_os = "cygwin", - target_os = "illumos", - target_os = "aix", - target_os = "android", - target_vendor = "apple", - ) => { - cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_EX) })?; - return Ok(()); - } - _ => { - Err(io::const_error!(io::ErrorKind::Unsupported, "lock() not supported")) - } - } + any( + target_os = "freebsd", + target_os = "fuchsia", + target_os = "hurd", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "cygwin", + target_os = "illumos", + target_os = "aix", + target_os = "android", + target_vendor = "apple", + ) => { + // SAFETY: Untriaged. + cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_EX) })?; + return Ok(()); + } + _ => { + Err(io::const_error!(io::ErrorKind::Unsupported, "lock() not supported")) + } + } } pub fn lock_shared(&self) -> io::Result<()> { cfg_select! { - any( - target_os = "freebsd", - target_os = "fuchsia", - target_os = "hurd", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - target_os = "cygwin", - target_os = "illumos", - target_os = "aix", - target_os = "android", - target_vendor = "apple", - ) => { - cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_SH) })?; - return Ok(()); - } - _ => { - Err(io::const_error!(io::ErrorKind::Unsupported, "lock_shared() not supported")) - } - } + any( + target_os = "freebsd", + target_os = "fuchsia", + target_os = "hurd", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "cygwin", + target_os = "illumos", + target_os = "aix", + target_os = "android", + target_vendor = "apple", + ) => { + // SAFETY: Untriaged. + cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_SH) })?; + return Ok(()); + } + _ => { + Err(io::const_error!(io::ErrorKind::Unsupported, "lock_shared() not supported")) + } + } } pub fn try_lock(&self) -> Result<(), TryLockError> { cfg_select! { - any( - target_os = "freebsd", - target_os = "fuchsia", - target_os = "hurd", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - target_os = "cygwin", - target_os = "illumos", - target_os = "aix", - target_os = "android", - target_vendor = "apple", - ) => { - let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) }); - if let Err(err) = result { - if err.kind() == io::ErrorKind::WouldBlock { - Err(TryLockError::WouldBlock) - } else { - Err(TryLockError::Error(err)) + any( + target_os = "freebsd", + target_os = "fuchsia", + target_os = "hurd", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "cygwin", + target_os = "illumos", + target_os = "aix", + target_os = "android", + target_vendor = "apple", + ) => { + // SAFETY: Untriaged. + let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_EX | libc::LOCK_NB) }); + if let Err(err) = result { + if err.kind() == io::ErrorKind::WouldBlock { + Err(TryLockError::WouldBlock) + } else { + Err(TryLockError::Error(err)) + } + } else { + Ok(()) + } + } + _ => { + Err(TryLockError::Error(io::const_error!( + io::ErrorKind::Unsupported, + "try_lock() not supported" + ))) } - } else { - Ok(()) } - } - _ => { - Err(TryLockError::Error(io::const_error!( - io::ErrorKind::Unsupported, - "try_lock() not supported" - ))) - } - } } pub fn try_lock_shared(&self) -> Result<(), TryLockError> { cfg_select! { - any( - target_os = "freebsd", - target_os = "fuchsia", - target_os = "hurd", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - target_os = "cygwin", - target_os = "illumos", - target_os = "aix", - target_os = "android", - target_vendor = "apple", - ) => { - let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_SH | libc::LOCK_NB) }); - if let Err(err) = result { - if err.kind() == io::ErrorKind::WouldBlock { - Err(TryLockError::WouldBlock) - } else { - Err(TryLockError::Error(err)) + any( + target_os = "freebsd", + target_os = "fuchsia", + target_os = "hurd", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "cygwin", + target_os = "illumos", + target_os = "aix", + target_os = "android", + target_vendor = "apple", + ) => { + // SAFETY: Untriaged. + let result = cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_SH | libc::LOCK_NB) }); + if let Err(err) = result { + if err.kind() == io::ErrorKind::WouldBlock { + Err(TryLockError::WouldBlock) + } else { + Err(TryLockError::Error(err)) + } + } else { + Ok(()) + } + } + _ => { + Err(TryLockError::Error(io::const_error!( + io::ErrorKind::Unsupported, + "try_lock_shared() not supported" + ))) } - } else { - Ok(()) } - } - _ => { - Err(TryLockError::Error(io::const_error!( - io::ErrorKind::Unsupported, - "try_lock_shared() not supported" - ))) - } - } } pub fn unlock(&self) -> io::Result<()> { cfg_select! { - any( - target_os = "freebsd", - target_os = "fuchsia", - target_os = "hurd", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - target_os = "cygwin", - target_os = "illumos", - target_os = "aix", - target_os = "android", - target_vendor = "apple", - ) => { - cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_UN) })?; - return Ok(()); - } - _ => { - Err(io::const_error!(io::ErrorKind::Unsupported, "unlock() not supported")) - } - } + any( + target_os = "freebsd", + target_os = "fuchsia", + target_os = "hurd", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "cygwin", + target_os = "illumos", + target_os = "aix", + target_os = "android", + target_vendor = "apple", + ) => { + // SAFETY: Untriaged. + cvt(unsafe { libc::flock(self.as_raw_fd(), libc::LOCK_UN) })?; + return Ok(()); + } + _ => { + Err(io::const_error!(io::ErrorKind::Unsupported, "unlock() not supported")) + } + } } pub fn truncate(&self, size: u64) -> io::Result<()> { let size: off64_t = size.try_into().map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))?; + // SAFETY: Untriaged. cvt_r(|| unsafe { ftruncate64(self.as_raw_fd(), size) }).map(drop) } @@ -1529,6 +1556,7 @@ impl File { SeekFrom::End(off) => (libc::SEEK_END, off), SeekFrom::Current(off) => (libc::SEEK_CUR, off), }; + // SAFETY: Untriaged. let n = cvt(unsafe { lseek64(self.as_raw_fd(), pos as off64_t, whence) })?; Ok(n as u64) } @@ -1551,73 +1579,78 @@ impl File { } pub fn set_permissions(&self, perm: FilePermissions) -> io::Result<()> { + // SAFETY: Untriaged. cvt_r(|| unsafe { libc::fchmod(self.as_raw_fd(), perm.mode) })?; Ok(()) } pub fn set_times(&self, times: FileTimes) -> io::Result<()> { cfg_select! { - any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx", target_os = "l4re") => { - // Redox doesn't appear to support `UTIME_OMIT`. - // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore - // the same as for Redox. - let _ = times; - Err(io::const_error!( - io::ErrorKind::Unsupported, - "setting file times not supported", - )) - } - target_vendor = "apple" => { - let ta = TimesAttrlist::from_times(×)?; - cvt(unsafe { libc::fsetattrlist( - self.as_raw_fd(), - ta.attrlist(), - ta.times_buf(), - ta.times_buf_size(), - 0 - ) })?; - Ok(()) - } - target_os = "android" => { - let times = [file_time_to_timespec(times.accessed)?, file_time_to_timespec(times.modified)?]; - // futimens requires Android API level 19 - cvt(unsafe { - weak!( - fn futimens(fd: c_int, times: *const libc::timespec) -> c_int; - ); - match futimens.get() { - Some(futimens) => futimens(self.as_raw_fd(), times.as_ptr()), - None => return Err(io::const_error!( + any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx", target_os = "l4re") => { + // Redox doesn't appear to support `UTIME_OMIT`. + // ESP-IDF and HorizonOS do not support `futimens` at all and the behavior for those OS is therefore + // the same as for Redox. + let _ = times; + Err(io::const_error!( io::ErrorKind::Unsupported, - "setting file times requires Android API level >= 19", - )), + "setting file times not supported", + )) } - })?; - Ok(()) - } - _ => { - #[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32", not(target_arch = "riscv32")))] - { - use crate::sys::pal::{time::__timespec64, weak::weak}; - - // Added in glibc 2.34 - weak!( - fn __futimens64(fd: c_int, times: *const __timespec64) -> c_int; - ); - - if let Some(futimens64) = __futimens64.get() { - let to_timespec = |time: Option| time.map(|time| time.t.to_timespec64()) - .unwrap_or(__timespec64::new(0, libc::UTIME_OMIT as _)); - let times = [to_timespec(times.accessed), to_timespec(times.modified)]; - cvt(unsafe { futimens64(self.as_raw_fd(), times.as_ptr()) })?; - return Ok(()); + target_vendor = "apple" => { + let ta = TimesAttrlist::from_times(×)?; + // SAFETY: Untriaged. + cvt(unsafe { libc::fsetattrlist( + self.as_raw_fd(), + ta.attrlist(), + ta.times_buf(), + ta.times_buf_size(), + 0 + ) })?; + Ok(()) + } + target_os = "android" => { + let times = [file_time_to_timespec(times.accessed)?, file_time_to_timespec(times.modified)?]; + // futimens requires Android API level 19 + // SAFETY: Untriaged. + cvt(unsafe { + weak!( + fn futimens(fd: c_int, times: *const libc::timespec) -> c_int; + ); + match futimens.get() { + Some(futimens) => futimens(self.as_raw_fd(), times.as_ptr()), + None => return Err(io::const_error!( + io::ErrorKind::Unsupported, + "setting file times requires Android API level >= 19", + )), + } + })?; + Ok(()) + } + _ => { + #[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32", not(target_arch = "riscv32")))] + { + use crate::sys::pal::{time::__timespec64, weak::weak}; + + // Added in glibc 2.34 + weak!( + fn __futimens64(fd: c_int, times: *const __timespec64) -> c_int; + ); + + if let Some(futimens64) = __futimens64.get() { + let to_timespec = |time: Option| time.map(|time| time.t.to_timespec64()) + .unwrap_or(__timespec64::new(0, libc::UTIME_OMIT as _)); + let times = [to_timespec(times.accessed), to_timespec(times.modified)]; + // SAFETY: Untriaged. + cvt(unsafe { futimens64(self.as_raw_fd(), times.as_ptr()) })?; + return Ok(()); + } + } + let times = [file_time_to_timespec(times.accessed)?, file_time_to_timespec(times.modified)?]; + // SAFETY: Untriaged. + cvt(unsafe { libc::futimens(self.as_raw_fd(), times.as_ptr()) })?; + Ok(()) } } - let times = [file_time_to_timespec(times.accessed)?, file_time_to_timespec(times.modified)?]; - cvt(unsafe { libc::futimens(self.as_raw_fd(), times.as_ptr()) })?; - Ok(()) - } - } } } @@ -1659,6 +1692,7 @@ impl TimesAttrlist { fn from_times(times: &FileTimes) -> io::Result { let mut this = Self { buf: [mem::MaybeUninit::::uninit(); 3], + // SAFETY: Untriaged. attrlist: unsafe { mem::zeroed() }, num_times: 0, }; @@ -1700,6 +1734,7 @@ impl DirBuilder { } pub fn mkdir(&self, p: &Path) -> io::Result<()> { + // SAFETY: Untriaged. run_path_with_cstr(p, &|p| cvt(unsafe { libc::mkdir(p.as_ptr(), self.mode) }).map(|_| ())) } @@ -1844,6 +1879,7 @@ impl fmt::Debug for Mode { } pub fn readdir(path: &Path) -> io::Result { + // SAFETY: Untriaged. let ptr = run_path_with_cstr(path, &|p| unsafe { Ok(libc::opendir(p.as_ptr())) })?; if ptr.is_null() { Err(Error::last_os_error()) @@ -1855,14 +1891,17 @@ pub fn readdir(path: &Path) -> io::Result { } pub fn unlink(p: &CStr) -> io::Result<()> { + // SAFETY: Untriaged. cvt(unsafe { libc::unlink(p.as_ptr()) }).map(|_| ()) } pub fn rename(old: &CStr, new: &CStr) -> io::Result<()> { + // SAFETY: Untriaged. cvt(unsafe { libc::rename(old.as_ptr(), new.as_ptr()) }).map(|_| ()) } pub fn set_perm(p: &CStr, perm: FilePermissions) -> io::Result<()> { + // SAFETY: Untriaged. cvt_r(|| unsafe { libc::chmod(p.as_ptr(), perm.mode) }).map(|_| ()) } @@ -1870,37 +1909,40 @@ pub fn set_perm_nofollow(p: &CStr, perm: FilePermissions) -> io::Result<()> { // ESP-IDF and Horizon do not support O_NOFOLLOW, so we skip setting it. // Their filesystems do not have symbolic links, so no special handling is required. cfg_select! { - // wasm32-wasip1 targets do not support fchmodat, so we fall down to - // open + fchmod - target_os = "wasi" => { - use crate::fs::OpenOptions; - use crate::fs::Permissions; - use crate::os::wasi::ffi::OsStrExt; - use crate::os::wasi::fs::OpenOptionsExt; - - let mut options = OpenOptions::new(); - options.custom_flags(libc::O_NOFOLLOW); - - let bytes = p.to_bytes(); - let os_str = OsStr::from_bytes(bytes); - options.open(Path::new(os_str))?.set_permissions(Permissions::from_inner(perm)) - } - all(target_os = "linux", not(any(target_os = "espidf", target_os = "horizon"))) => { - cvt_r(|| unsafe { - libc::fchmodat(libc::AT_FDCWD, p.as_ptr(), perm.mode, libc::AT_SYMLINK_NOFOLLOW) - }) - .map(|_| ()) - }, - _ => { - cvt_r(|| unsafe { - libc::fchmodat(libc::AT_FDCWD, p.as_ptr(), perm.mode, 0) - }) - .map(|_| ()) + // wasm32-wasip1 targets do not support fchmodat, so we fall down to + // open + fchmod + target_os = "wasi" => { + use crate::fs::OpenOptions; + use crate::fs::Permissions; + use crate::os::wasi::ffi::OsStrExt; + use crate::os::wasi::fs::OpenOptionsExt; + + let mut options = OpenOptions::new(); + options.custom_flags(libc::O_NOFOLLOW); + + let bytes = p.to_bytes(); + let os_str = OsStr::from_bytes(bytes); + options.open(Path::new(os_str))?.set_permissions(Permissions::from_inner(perm)) + } + all(target_os = "linux", not(any(target_os = "espidf", target_os = "horizon"))) => { + // SAFETY: Untriaged. + cvt_r(|| unsafe { + libc::fchmodat(libc::AT_FDCWD, p.as_ptr(), perm.mode, libc::AT_SYMLINK_NOFOLLOW) + }) + .map(|_| ()) + }, + _ => { + // SAFETY: Untriaged. + cvt_r(|| unsafe { + libc::fchmodat(libc::AT_FDCWD, p.as_ptr(), perm.mode, 0) + }) + .map(|_| ()) + } } - } } pub fn rmdir(p: &CStr) -> io::Result<()> { + // SAFETY: Untriaged. cvt(unsafe { libc::rmdir(p.as_ptr()) }).map(|_| ()) } @@ -1911,8 +1953,10 @@ pub fn readlink(c_path: &CStr) -> io::Result { loop { let buf_read = +// SAFETY: Untriaged. cvt(unsafe { libc::readlink(p, buf.as_mut_ptr() as *mut _, buf.capacity()) })? as usize; + // SAFETY: Untriaged. unsafe { buf.set_len(buf_read); } @@ -1931,75 +1975,86 @@ pub fn readlink(c_path: &CStr) -> io::Result { } pub fn symlink(original: &CStr, link: &CStr) -> io::Result<()> { + // SAFETY: Untriaged. cvt(unsafe { libc::symlink(original.as_ptr(), link.as_ptr()) }).map(|_| ()) } pub fn link(original: &CStr, link: &CStr) -> io::Result<()> { cfg_select! { - any( - // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. - // POSIX leaves it implementation-defined whether `link` follows - // symlinks, so rely on the `symlink_hard_link` test in - // library/std/src/fs/tests.rs to check the behavior. - target_os = "vxworks", - target_os = "redox", - target_os = "espidf", - // Other misc platforms - target_os = "horizon", - target_os = "vita", - target_os = "l4re", - target_env = "nto70", - ) => { - cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?; - } - _ => { - // Where we can, use `linkat` instead of `link`; see the comment above - // this one for details on why. - cvt(unsafe { libc::linkat(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?; + any( + // VxWorks, Redox and ESP-IDF lack `linkat`, so use `link` instead. + // POSIX leaves it implementation-defined whether `link` follows + // symlinks, so rely on the `symlink_hard_link` test in + // library/std/src/fs/tests.rs to check the behavior. + target_os = "vxworks", + target_os = "redox", + target_os = "espidf", + // Other misc platforms + target_os = "horizon", + target_os = "vita", + target_os = "l4re", + target_env = "nto70", + ) => { + // SAFETY: Untriaged. + cvt(unsafe { libc::link(original.as_ptr(), link.as_ptr()) })?; + } + _ => { + // Where we can, use `linkat` instead of `link`; see the comment above + // this one for details on why. + // SAFETY: Untriaged. + cvt(unsafe { libc::linkat(libc::AT_FDCWD, original.as_ptr(), libc::AT_FDCWD, link.as_ptr(), 0) })?; + } } - } Ok(()) } pub fn stat(p: &CStr) -> io::Result { cfg_has_statx! { - if let Some(ret) = unsafe { try_statx( - libc::AT_FDCWD, - p.as_ptr(), - libc::AT_STATX_SYNC_AS_STAT, - libc::STATX_BASIC_STATS | libc::STATX_BTIME, - ) } { - return ret; + // SAFETY: Untriaged. + if let Some(ret) = unsafe { try_statx( + libc::AT_FDCWD, + p.as_ptr(), + libc::AT_STATX_SYNC_AS_STAT, + libc::STATX_BASIC_STATS | libc::STATX_BTIME, + ) } { + return ret; + } } - } + // SAFETY: Untriaged. let mut stat: stat64 = unsafe { mem::zeroed() }; + // SAFETY: Untriaged. cvt(unsafe { stat64(p.as_ptr(), &mut stat) })?; Ok(FileAttr::from_stat64(stat)) } pub fn lstat(p: &CStr) -> io::Result { cfg_has_statx! { - if let Some(ret) = unsafe { try_statx( - libc::AT_FDCWD, - p.as_ptr(), - libc::AT_SYMLINK_NOFOLLOW | libc::AT_STATX_SYNC_AS_STAT, - libc::STATX_BASIC_STATS | libc::STATX_BTIME, - ) } { - return ret; + // SAFETY: Untriaged. + if let Some(ret) = unsafe { try_statx( + libc::AT_FDCWD, + p.as_ptr(), + libc::AT_SYMLINK_NOFOLLOW | libc::AT_STATX_SYNC_AS_STAT, + libc::STATX_BASIC_STATS | libc::STATX_BTIME, + ) } { + return ret; + } } - } + // SAFETY: Untriaged. let mut stat: stat64 = unsafe { mem::zeroed() }; + // SAFETY: Untriaged. cvt(unsafe { lstat64(p.as_ptr(), &mut stat) })?; Ok(FileAttr::from_stat64(stat)) } pub fn canonicalize(path: &CStr) -> io::Result { + // SAFETY: Untriaged. let r = unsafe { libc::realpath(path.as_ptr(), ptr::null_mut()) }; if r.is_null() { return Err(io::Error::last_os_error()); } + // SAFETY: Untriaged. Ok(PathBuf::from(OsString::from_vec(unsafe { let buf = CStr::from_ptr(r).to_bytes().to_vec(); libc::free(r as *mut _); @@ -2021,73 +2076,77 @@ fn open_from(from: &Path) -> io::Result<(crate::fs::File, crate::fs::Metadata)> fn set_times_impl(p: &CStr, times: FileTimes, follow_symlinks: bool) -> io::Result<()> { cfg_select! { - any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx", target_os = "vita", target_os = "rtems") => { - let _ = (p, times, follow_symlinks); - Err(io::const_error!( - io::ErrorKind::Unsupported, - "setting file times not supported", - )) - } - target_vendor = "apple" => { - // Apple platforms use setattrlist which supports setting times on symlinks - let ta = TimesAttrlist::from_times(×)?; - let options = if follow_symlinks { - 0 - } else { - libc::FSOPT_NOFOLLOW - }; + any(target_os = "redox", target_os = "espidf", target_os = "horizon", target_os = "nuttx", target_os = "vita", target_os = "rtems") => { + let _ = (p, times, follow_symlinks); + Err(io::const_error!( + io::ErrorKind::Unsupported, + "setting file times not supported", + )) + } + target_vendor = "apple" => { + // Apple platforms use setattrlist which supports setting times on symlinks + let ta = TimesAttrlist::from_times(×)?; + let options = if follow_symlinks { + 0 + } else { + libc::FSOPT_NOFOLLOW + }; - cvt(unsafe { libc::setattrlist( - p.as_ptr(), - ta.attrlist(), - ta.times_buf(), - ta.times_buf_size(), - options as u32 - ) })?; - Ok(()) - } - target_os = "android" => { - let times = [file_time_to_timespec(times.accessed)?, file_time_to_timespec(times.modified)?]; - let flags = if follow_symlinks { 0 } else { libc::AT_SYMLINK_NOFOLLOW }; - // utimensat requires Android API level 19 - cvt(unsafe { - weak!( - fn utimensat(dirfd: c_int, path: *const libc::c_char, times: *const libc::timespec, flags: c_int) -> c_int; - ); - match utimensat.get() { - Some(utimensat) => utimensat(libc::AT_FDCWD, p.as_ptr(), times.as_ptr(), flags), - None => return Err(io::const_error!( - io::ErrorKind::Unsupported, - "setting file times requires Android API level >= 19", - )), - } - })?; - Ok(()) - } - _ => { - let flags = if follow_symlinks { 0 } else { libc::AT_SYMLINK_NOFOLLOW }; - #[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32", not(target_arch = "riscv32")))] - { - use crate::sys::pal::{time::__timespec64, weak::weak}; - - // Added in glibc 2.34 - weak!( - fn __utimensat64(dirfd: c_int, path: *const c_char, times: *const __timespec64, flags: c_int) -> c_int; - ); - - if let Some(utimensat64) = __utimensat64.get() { - let to_timespec = |time: Option| time.map(|time| time.t.to_timespec64()) - .unwrap_or(__timespec64::new(0, libc::UTIME_OMIT as _)); - let times = [to_timespec(times.accessed), to_timespec(times.modified)]; - cvt(unsafe { utimensat64(libc::AT_FDCWD, p.as_ptr(), times.as_ptr(), flags) })?; - return Ok(()); + // SAFETY: Untriaged. + cvt(unsafe { libc::setattrlist( + p.as_ptr(), + ta.attrlist(), + ta.times_buf(), + ta.times_buf_size(), + options as u32 + ) })?; + Ok(()) + } + target_os = "android" => { + let times = [file_time_to_timespec(times.accessed)?, file_time_to_timespec(times.modified)?]; + let flags = if follow_symlinks { 0 } else { libc::AT_SYMLINK_NOFOLLOW }; + // utimensat requires Android API level 19 + // SAFETY: Untriaged. + cvt(unsafe { + weak!( + fn utimensat(dirfd: c_int, path: *const libc::c_char, times: *const libc::timespec, flags: c_int) -> c_int; + ); + match utimensat.get() { + Some(utimensat) => utimensat(libc::AT_FDCWD, p.as_ptr(), times.as_ptr(), flags), + None => return Err(io::const_error!( + io::ErrorKind::Unsupported, + "setting file times requires Android API level >= 19", + )), + } + })?; + Ok(()) + } + _ => { + let flags = if follow_symlinks { 0 } else { libc::AT_SYMLINK_NOFOLLOW }; + #[cfg(all(target_os = "linux", target_env = "gnu", target_pointer_width = "32", not(target_arch = "riscv32")))] + { + use crate::sys::pal::{time::__timespec64, weak::weak}; + + // Added in glibc 2.34 + weak!( + fn __utimensat64(dirfd: c_int, path: *const c_char, times: *const __timespec64, flags: c_int) -> c_int; + ); + + if let Some(utimensat64) = __utimensat64.get() { + let to_timespec = |time: Option| time.map(|time| time.t.to_timespec64()) + .unwrap_or(__timespec64::new(0, libc::UTIME_OMIT as _)); + let times = [to_timespec(times.accessed), to_timespec(times.modified)]; + // SAFETY: Untriaged. + cvt(unsafe { utimensat64(libc::AT_FDCWD, p.as_ptr(), times.as_ptr(), flags) })?; + return Ok(()); + } } - } - let times = [file_time_to_timespec(times.accessed)?, file_time_to_timespec(times.modified)?]; - cvt(unsafe { libc::utimensat(libc::AT_FDCWD, p.as_ptr(), times.as_ptr(), flags) })?; - Ok(()) - } - } + let times = [file_time_to_timespec(times.accessed)?, file_time_to_timespec(times.modified)?]; + // SAFETY: Untriaged. + cvt(unsafe { libc::utimensat(libc::AT_FDCWD, p.as_ptr(), times.as_ptr(), flags) })?; + Ok(()) + } + } } #[inline(always)] @@ -2206,6 +2265,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { impl Drop for FreeOnDrop { fn drop(&mut self) { // The code below ensures that `FreeOnDrop` is never a null pointer + // SAFETY: Untriaged. unsafe { // `copyfile_state_free` returns -1 if the `to` or `from` files // cannot be closed. However, this is not considered an error. @@ -2217,6 +2277,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { let (reader, reader_metadata) = open_from(from)?; let clonefile_result = run_path_with_cstr(to, &|to| { + // SAFETY: Untriaged. cvt(unsafe { libc::fclonefileat(reader.as_raw_fd(), libc::AT_FDCWD, to.as_ptr(), 0) }) }); match clonefile_result { @@ -2236,6 +2297,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { // We ensure that `FreeOnDrop` never contains a null pointer so it is // always safe to call `copyfile_state_free` + // SAFETY: Untriaged. let state = unsafe { let state = libc::copyfile_state_alloc(); if state.is_null() { @@ -2246,9 +2308,11 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { let flags = if writer_metadata.is_file() { COPYFILE_ALL } else { libc::COPYFILE_DATA }; + // SAFETY: Untriaged. cvt(unsafe { libc::fcopyfile(reader.as_raw_fd(), writer.as_raw_fd(), state.0, flags) })?; let mut bytes_copied: libc::off_t = 0; + // SAFETY: Untriaged. cvt(unsafe { libc::copyfile_state_get( state.0, @@ -2262,6 +2326,7 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { #[cfg(not(target_os = "wasi"))] pub fn chown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { run_path_with_cstr(path, &|path| { + // SAFETY: Untriaged. cvt(unsafe { libc::chown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) }) .map(|_| ()) }) @@ -2269,6 +2334,7 @@ pub fn chown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { #[cfg(not(target_os = "wasi"))] pub fn fchown(fd: c_int, uid: u32, gid: u32) -> io::Result<()> { + // SAFETY: Untriaged. cvt(unsafe { libc::fchown(fd, uid as libc::uid_t, gid as libc::gid_t) })?; Ok(()) } @@ -2276,6 +2342,7 @@ pub fn fchown(fd: c_int, uid: u32, gid: u32) -> io::Result<()> { #[cfg(not(any(target_os = "vxworks", target_os = "wasi")))] pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { run_path_with_cstr(path, &|path| { + // SAFETY: Untriaged. cvt(unsafe { libc::lchown(path.as_ptr(), uid as libc::uid_t, gid as libc::gid_t) }) .map(|_| ()) }) @@ -2289,6 +2356,7 @@ pub fn lchown(path: &Path, uid: u32, gid: u32) -> io::Result<()> { #[cfg(not(any(target_os = "fuchsia", target_os = "vxworks", target_os = "wasi")))] pub fn chroot(dir: &Path) -> io::Result<()> { + // SAFETY: Untriaged. run_path_with_cstr(dir, &|dir| cvt(unsafe { libc::chroot(dir.as_ptr()) }).map(|_| ())) } @@ -2301,6 +2369,7 @@ pub fn chroot(dir: &Path) -> io::Result<()> { #[cfg(not(target_os = "wasi"))] pub fn mkfifo(path: &Path, mode: u32) -> io::Result<()> { run_path_with_cstr(path, &|path| { + // SAFETY: Untriaged. cvt(unsafe { libc::mkfifo(path.as_ptr(), mode.try_into().unwrap()) }).map(|_| ()) }) } @@ -2352,6 +2421,7 @@ mod remove_dir_impl { use crate::sys::{cvt, cvt_r}; pub fn openat_nofollow_dironly(parent_fd: Option, p: &CStr) -> io::Result { + // SAFETY: Untriaged. let fd = cvt_r(|| unsafe { openat( parent_fd.unwrap_or(libc::AT_FDCWD), @@ -2359,10 +2429,12 @@ mod remove_dir_impl { libc::O_CLOEXEC | libc::O_RDONLY | libc::O_NOFOLLOW | libc::O_DIRECTORY, ) })?; + // SAFETY: Untriaged. Ok(unsafe { OwnedFd::from_raw_fd(fd) }) } fn fdreaddir(dir_fd: OwnedFd) -> io::Result<(ReadDir, RawFd)> { + // SAFETY: Untriaged. let ptr = unsafe { fdopendir(dir_fd.as_raw_fd()) }; if ptr.is_null() { return Err(io::Error::last_os_error()); @@ -2422,6 +2494,7 @@ mod remove_dir_impl { return match parent_fd { // unlink... Some(parent_fd) => { + // SAFETY: Untriaged. cvt(unsafe { unlinkat(parent_fd, path.as_ptr(), 0) }).map(drop) } // ...unless this was supposed to be the deletion root directory @@ -2454,6 +2527,7 @@ mod remove_dir_impl { remove_dir_all_recursive(Some(fd), &child.name)?; } Some(false) => { + // SAFETY: Untriaged. cvt(unsafe { unlinkat(fd, child.name.as_ptr(), 0) })?; } None => { @@ -2471,6 +2545,7 @@ mod remove_dir_impl { } // unlink the directory after removing its contents + // SAFETY: Untriaged. ignore_notfound(cvt(unsafe { unlinkat(parent_fd.unwrap_or(libc::AT_FDCWD), path.as_ptr(), libc::AT_REMOVEDIR) }))?; diff --git a/library/std/src/sys/fs/unix/dir.rs b/library/std/src/sys/fs/unix/dir.rs index f3f612a225ed1..b91d5cb296703 100644 --- a/library/std/src/sys/fs/unix/dir.rs +++ b/library/std/src/sys/fs/unix/dir.rs @@ -67,7 +67,9 @@ impl Dir { | opts.get_access_mode()? | opts.get_creation_mode()? | (opts.custom_flags as c_int & !libc::O_ACCMODE); + // SAFETY: Untriaged. let fd = cvt_r(|| unsafe { open64(path.as_ptr(), flags, opts.mode as c_int) })?; + // SAFETY: Untriaged. Ok(Self(unsafe { OwnedFd::from_raw_fd(fd) })) } @@ -76,13 +78,16 @@ impl Dir { | opts.get_access_mode()? | opts.get_creation_mode()? | (opts.custom_flags as c_int & !libc::O_ACCMODE); + // SAFETY: Untriaged. let fd = cvt_r(|| unsafe { openat64(self.0.as_raw_fd(), path.as_ptr(), flags, opts.mode as c_int) })?; + // SAFETY: Untriaged. Ok(File(unsafe { FileDesc::from_raw_fd(fd) })) } fn remove_c(&self, path: &CStr, remove_dir: bool) -> io::Result<()> { + // SAFETY: Untriaged. cvt(unsafe { unlinkat( self.0.as_raw_fd(), @@ -94,6 +99,7 @@ impl Dir { } fn rename_c(&self, from: &CStr, to_dir: &Self, to: &CStr) -> io::Result<()> { + // SAFETY: Untriaged. cvt(unsafe { renameat(self.0.as_raw_fd(), from.as_ptr(), to_dir.0.as_raw_fd(), to.as_ptr()) }) @@ -126,6 +132,7 @@ impl IntoRawFd for fs::Dir { #[unstable(feature = "dirfd", issue = "120426")] impl FromRawFd for fs::Dir { unsafe fn from_raw_fd(fd: RawFd) -> Self { + // SAFETY: Untriaged. Self::from_inner(Dir(unsafe { FromRawFd::from_raw_fd(fd) })) } } diff --git a/library/std/src/sys/fs/vexos.rs b/library/std/src/sys/fs/vexos.rs index 1357787c44c77..7e2e4bdfc019c 100644 --- a/library/std/src/sys/fs/vexos.rs +++ b/library/std/src/sys/fs/vexos.rs @@ -198,6 +198,7 @@ impl File { // the requirements that `create_new` can't have an existing file and `!create` // doesn't create a file ourselves. if !opts.read && (opts.write || opts.append) && (opts.create_new || !opts.create) { + // SAFETY: Untriaged. let status = unsafe { vex_sdk::vexFileStatus(path.as_ptr()) }; if opts.create_new && status != 0 { @@ -227,6 +228,7 @@ impl File { truncate: false, create: false, create_new: false, + // SAFETY: Untriaged. } => unsafe { vex_sdk::vexFileOpen(path.as_ptr(), c"".as_ptr()) }, // append @@ -237,6 +239,7 @@ impl File { truncate: false, create: _, create_new: _, + // SAFETY: Untriaged. } => unsafe { vex_sdk::vexFileOpenWrite(path.as_ptr()) }, // write @@ -247,6 +250,7 @@ impl File { truncate, create: _, create_new: _, + // SAFETY: Untriaged. } => unsafe { if *truncate { vex_sdk::vexFileOpenCreate(path.as_ptr()) @@ -273,6 +277,7 @@ impl File { pub fn file_attr(&self) -> io::Result { // `vexFileSize` returns -1 upon error, so u64::try_from will fail on error. + // SAFETY: Untriaged. if let Ok(size) = u64::try_from(unsafe { // SAFETY: `self.fd` contains a valid pointer to `FIL` for this struct's lifetime. vex_sdk::vexFileSize(self.fd.0) @@ -318,6 +323,7 @@ impl File { pub fn read(&self, buf: &mut [u8]) -> io::Result { let len = buf.len() as u32; let buf_ptr = buf.as_mut_ptr(); + // SAFETY: Untriaged. let read = unsafe { // SAFETY: `self.fd` contains a valid pointer to `FIL` for this struct's lifetime. vex_sdk::vexFileRead(buf_ptr.cast::(), 1, len, self.fd.0) @@ -346,6 +352,7 @@ impl File { pub fn write(&self, buf: &[u8]) -> io::Result { let len = buf.len() as u32; let buf_ptr = buf.as_ptr(); + // SAFETY: Untriaged. let written = unsafe { // SAFETY: `self.fd` contains a valid pointer to `FIL` for this struct's lifetime. vex_sdk::vexFileWrite(buf_ptr.cast_mut().cast::(), 1, len, self.fd.0) @@ -368,6 +375,7 @@ impl File { } pub fn flush(&self) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { // SAFETY: `self.fd` contains a valid pointer to `FIL` for this struct's lifetime. vex_sdk::vexFileSync(self.fd.0); @@ -404,9 +412,11 @@ impl File { // SAFETY: `self.fd` contains a valid pointer to `FIL` for this struct's lifetime. match pos { + // SAFETY: Untriaged. SeekFrom::Start(offset) => unsafe { map_fresult(vex_sdk::vexFileSeek(self.fd.0, try_convert_offset(offset)?, SEEK_SET))? }, + // SAFETY: Untriaged. SeekFrom::End(offset) => unsafe { if offset >= 0 { map_fresult(vex_sdk::vexFileSeek( @@ -431,6 +441,7 @@ impl File { ))? } }, + // SAFETY: Untriaged. SeekFrom::Current(offset) => unsafe { if offset >= 0 { map_fresult(vex_sdk::vexFileSeek( @@ -473,6 +484,7 @@ impl fmt::Debug for File { } impl Drop for File { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { vex_sdk::vexFileClose(self.fd.0) }; } } @@ -505,6 +517,7 @@ pub fn set_times_nofollow(_p: &Path, _times: FileTimes) -> io::Result<()> { } pub fn exists(path: &Path) -> io::Result { + // SAFETY: Untriaged. run_path_with_cstr(path, &|path| Ok(unsafe { vex_sdk::vexFileStatus(path.as_ptr()) } != 0)) } @@ -514,6 +527,7 @@ pub fn stat(p: &Path) -> io::Result { const FILE_STATUS_DIR: u32 = 3; run_path_with_cstr(p, &|c_path| { + // SAFETY: Untriaged. let file_type = unsafe { vex_sdk::vexFileStatus(c_path.as_ptr()) }; // We can't get the size if its a directory because we cant open it as a file diff --git a/library/std/src/sys/fs/windows.rs b/library/std/src/sys/fs/windows.rs index a94a6f61cf118..49e625c2d6efd 100644 --- a/library/std/src/sys/fs/windows.rs +++ b/library/std/src/sys/fs/windows.rs @@ -131,6 +131,7 @@ impl Iterator for ReadDir { return Some(Ok(e)); } } + // SAFETY: Untriaged. unsafe { let mut wfd = mem::zeroed(); loop { @@ -153,6 +154,7 @@ impl Iterator for ReadDir { impl Drop for FindNextFileHandle { fn drop(&mut self) { + // SAFETY: Untriaged. let r = unsafe { c::FindClose(self.0) }; debug_assert!(r != 0); } @@ -349,6 +351,7 @@ impl File { lpSecurityDescriptor: ptr::null_mut(), bInheritHandle: opts.inherit_handle as c::BOOL, }; + // SAFETY: Untriaged. let handle = unsafe { c::CreateFileW( path.as_ptr(), @@ -360,11 +363,13 @@ impl File { ptr::null_mut(), ) }; + // SAFETY: Untriaged. let handle = unsafe { HandleOrInvalid::from_raw_handle(handle) }; if let Ok(handle) = OwnedHandle::try_from(handle) { if opts.freeze_last_access_time || opts.freeze_last_write_time { let file_time = c::FILETIME { dwLowDateTime: 0xFFFFFFFF, dwHighDateTime: 0xFFFFFFFF }; + // SAFETY: Untriaged. cvt(unsafe { c::SetFileTime( handle.as_raw_handle(), @@ -398,6 +403,7 @@ impl File { } pub fn fsync(&self) -> io::Result<()> { + // SAFETY: Untriaged. cvt(unsafe { c::FlushFileBuffers(self.handle.as_raw_handle()) })?; Ok(()) } @@ -407,6 +413,7 @@ impl File { } fn acquire_lock(&self, flags: c::LOCK_FILE_FLAGS) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { let mut overlapped: c::OVERLAPPED = mem::zeroed(); let event = c::CreateEventW(ptr::null_mut(), c::FALSE, c::FALSE, ptr::null()); @@ -456,6 +463,7 @@ impl File { } pub fn try_lock(&self) -> Result<(), TryLockError> { + // SAFETY: Untriaged. let result = cvt(unsafe { let mut overlapped = mem::zeroed(); c::LockFileEx( @@ -478,6 +486,7 @@ impl File { } pub fn try_lock_shared(&self) -> Result<(), TryLockError> { + // SAFETY: Untriaged. let result = cvt(unsafe { let mut overlapped = mem::zeroed(); c::LockFileEx( @@ -504,8 +513,10 @@ impl File { // both an exclusive and shared lock, in which case the documentation states that: // "...two unlock operations are necessary to unlock the region; the first unlock operation // unlocks the exclusive lock, the second unlock operation unlocks the shared lock" + // SAFETY: Untriaged. cvt(unsafe { c::UnlockFile(self.handle.as_raw_handle(), 0, 0, u32::MAX, u32::MAX) })?; let result = +// SAFETY: Untriaged. cvt(unsafe { c::UnlockFile(self.handle.as_raw_handle(), 0, 0, u32::MAX, u32::MAX) }); match result { Ok(_) => Ok(()), @@ -521,6 +532,7 @@ impl File { #[cfg(not(target_vendor = "uwp"))] pub fn file_attr(&self) -> io::Result { + // SAFETY: Untriaged. unsafe { let mut info: c::BY_HANDLE_FILE_INFORMATION = mem::zeroed(); cvt(c::GetFileInformationByHandle(self.handle.as_raw_handle(), &mut info))?; @@ -556,6 +568,7 @@ impl File { #[cfg(target_vendor = "uwp")] pub fn file_attr(&self) -> io::Result { + // SAFETY: Untriaged. unsafe { let mut info: c::FILE_BASIC_INFO = mem::zeroed(); let size = size_of_val(&info); @@ -671,6 +684,7 @@ impl File { }; let pos = pos as i64; let mut newpos = 0; + // SAFETY: Untriaged. cvt(unsafe { c::SetFilePointerEx(self.handle.as_raw_handle(), pos, &mut newpos, whence) })?; Ok(newpos as u64) } @@ -678,6 +692,7 @@ impl File { pub fn size(&self) -> Option> { let mut result = 0; Some( + // SAFETY: Untriaged. cvt(unsafe { c::GetFileSizeEx(self.handle.as_raw_handle(), &mut result) }) .map(|_| result as u64), ) @@ -698,6 +713,7 @@ impl File { &self, space: &mut Align8<[MaybeUninit]>, ) -> io::Result<(u32, *mut c::REPARSE_DATA_BUFFER)> { + // SAFETY: Untriaged. unsafe { let mut bytes = 0; cvt({ @@ -724,6 +740,7 @@ impl File { let mut space = Align8([MaybeUninit::::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE as usize]); let (_bytes, buf) = self.reparse_point(&mut space)?; + // SAFETY: Untriaged. unsafe { let (path_buffer, subst_off, subst_len, relative) = match (*buf).ReparseTag { c::IO_REPARSE_TAG_SYMLINK => { @@ -803,6 +820,7 @@ impl File { "cannot set file timestamp to 0xFFFF_FFFF_FFFF_FFFF", )); } + // SAFETY: Untriaged. cvt(unsafe { let created = times.created.as_ref().map(|a| a as *const c::FILETIME).unwrap_or(ptr::null()); @@ -817,6 +835,7 @@ impl File { /// Gets only basic file information such as attributes and file times. fn basic_info(&self) -> io::Result { + // SAFETY: Untriaged. unsafe { let mut info: c::FILE_BASIC_INFO = mem::zeroed(); let size = size_of_val(&info); @@ -890,6 +909,7 @@ impl File { let class = if restart { c::FileIdBothDirectoryRestartInfo } else { c::FileIdBothDirectoryInfo }; + // SAFETY: Untriaged. unsafe { let result = c::GetFileInformationByHandleEx( self.as_raw_handle(), @@ -917,6 +937,7 @@ impl DirBuff { Self { // Safety: `Align8<[MaybeUninit; N]>` does not need // initialization. + // SAFETY: Untriaged. buffer: unsafe { Box::new_uninit().assume_init() }, } } @@ -997,6 +1018,7 @@ impl<'a> Iterator for DirBuffIter<'a> { } unsafe fn from_maybe_unaligned<'a>(p: *const u16, len: usize) -> Cow<'a, [u16]> { + // SAFETY: Untriaged. unsafe { if p.is_aligned() { Cow::Borrowed(crate::slice::from_raw_parts(p, len)) @@ -1045,6 +1067,7 @@ impl IntoRawHandle for File { impl FromRawHandle for File { unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self { + // SAFETY: Untriaged. unsafe { Self { handle: FromInner::from_inner(FromRawHandle::from_raw_handle(raw_handle)) } } @@ -1227,6 +1250,7 @@ impl DirBuilder { pub fn mkdir(&self, p: &Path) -> io::Result<()> { let p = maybe_verbatim(p)?; + // SAFETY: Untriaged. cvt(unsafe { c::CreateDirectoryW(p.as_ptr(), ptr::null_mut()) })?; Ok(()) } @@ -1245,6 +1269,7 @@ pub fn readdir(p: &Path) -> io::Result { let star = p.join("*"); let path = maybe_verbatim(&star)?; + // SAFETY: Untriaged. unsafe { let mut wfd: c::WIN32_FIND_DATAW = mem::zeroed(); // this is like FindFirstFileW (see https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-findfirstfileexw), @@ -1296,6 +1321,7 @@ pub fn readdir(p: &Path) -> io::Result { } pub fn unlink(path: &WCStr) -> io::Result<()> { + // SAFETY: Untriaged. if unsafe { c::DeleteFileW(path.as_ptr()) } == 0 { let err = api::get_last_error(); // if `DeleteFileW` fails with ERROR_ACCESS_DENIED then try to remove @@ -1319,6 +1345,7 @@ pub fn unlink(path: &WCStr) -> io::Result<()> { } pub fn rename(old: &WCStr, new: &WCStr) -> io::Result<()> { + // SAFETY: Untriaged. if unsafe { c::MoveFileExW(old.as_ptr(), new.as_ptr(), c::MOVEFILE_REPLACE_EXISTING) } == 0 { let err = api::get_last_error(); // if `MoveFileExW` fails with ERROR_ACCESS_DENIED then try to move @@ -1366,6 +1393,7 @@ pub fn rename(old: &WCStr, new: &WCStr) -> io::Result<()> { ); } + // SAFETY: Untriaged. let result = unsafe { c::SetFileInformationByHandle( f.as_raw_handle(), @@ -1374,6 +1402,7 @@ pub fn rename(old: &WCStr, new: &WCStr) -> io::Result<()> { struct_size, ) }; + // SAFETY: Untriaged. unsafe { dealloc(file_rename_info.cast::(), layout) }; if result == 0 { if api::get_last_error() == WinError::DIR_NOT_EMPTY { @@ -1390,6 +1419,7 @@ pub fn rename(old: &WCStr, new: &WCStr) -> io::Result<()> { } pub fn rmdir(p: &WCStr) -> io::Result<()> { + // SAFETY: Untriaged. cvt(unsafe { c::RemoveDirectoryW(p.as_ptr()) })?; Ok(()) } @@ -1435,6 +1465,7 @@ pub fn symlink_inner(original: &Path, link: &Path, dir: bool) -> io::Result<()> // Creators Update, Microsoft loosened this to allow unprivileged symlink creation if the // computer is in Developer Mode, but SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE must be // added to dwFlags to opt into this behavior. + // SAFETY: Untriaged. let result = cvt(unsafe { c::CreateSymbolicLinkW( link.as_ptr(), @@ -1446,6 +1477,7 @@ pub fn symlink_inner(original: &Path, link: &Path, dir: bool) -> io::Result<()> if err.raw_os_error() == Some(c::ERROR_INVALID_PARAMETER as i32) { // Older Windows objects to SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE, // so if we encounter ERROR_INVALID_PARAMETER, retry without that flag. + // SAFETY: Untriaged. cvt(unsafe { c::CreateSymbolicLinkW(link.as_ptr(), original.as_ptr(), flags) as c::BOOL })?; @@ -1458,6 +1490,7 @@ pub fn symlink_inner(original: &Path, link: &Path, dir: bool) -> io::Result<()> #[cfg(not(target_vendor = "uwp"))] pub fn link(original: &WCStr, link: &WCStr) -> io::Result<()> { + // SAFETY: Untriaged. cvt(unsafe { c::CreateHardLinkW(link.as_ptr(), original.as_ptr(), ptr::null_mut()) })?; Ok(()) } @@ -1518,6 +1551,7 @@ fn metadata(path: &WCStr, reparse: ReparsePoint) -> io::Result { // Usually if a file is locked you can still read some metadata. // However, there are special system files, such as // `C:\hiberfil.sys`, that are locked in a way that denies even that. + // SAFETY: Untriaged. unsafe { // `FindFirstFileExW` accepts wildcard file names. // Fortunately wildcards are not valid file names and @@ -1558,6 +1592,7 @@ fn metadata(path: &WCStr, reparse: ReparsePoint) -> io::Result { } pub fn set_perm(p: &WCStr, perm: FilePermissions) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { cvt(c::SetFileAttributesW(p.as_ptr(), perm.attrs))?; Ok(()) @@ -1592,6 +1627,7 @@ pub fn set_times_nofollow(p: &WCStr, times: FileTimes) -> io::Result<()> { fn get_path(f: impl AsRawHandle) -> io::Result { fill_utf16_buf( + // SAFETY: Untriaged. |buf, sz| unsafe { c::GetFinalPathNameByHandleW(f.as_raw_handle(), buf, sz, c::VOLUME_NAME_DOS) }, @@ -1621,6 +1657,7 @@ pub fn copy(from: &WCStr, to: &WCStr) -> io::Result { _hDestinationFile: c::HANDLE, lpData: *const c_void, ) -> u32 { + // SAFETY: Untriaged. unsafe { if dwStreamNumber == 1 { *(lpData as *mut i64) = StreamBytesTransferred; @@ -1629,6 +1666,7 @@ pub fn copy(from: &WCStr, to: &WCStr) -> io::Result { } } let mut size = 0i64; + // SAFETY: Untriaged. cvt(unsafe { c::CopyFileExW( from.as_ptr(), @@ -1657,18 +1695,22 @@ pub fn junction_point(original: &Path, link: &Path) -> io::Result<()> { let abs_path: Vec = if path_bytes.starts_with(br"\\?\") || path_bytes.starts_with(br"\??\") { // It's already an absolute path, we just need to convert the prefix to `\??\` + // SAFETY: Untriaged. let bytes = unsafe { OsStr::from_encoded_bytes_unchecked(&path_bytes[4..]) }; r"\??\".encode_utf16().chain(bytes.encode_wide()).collect() } else { // Get an absolute path and then convert the prefix to `\??\` let abs_path = crate::path::absolute(original)?.into_os_string().into_encoded_bytes(); if abs_path.len() > 0 && abs_path[1..].starts_with(br":\") { + // SAFETY: Untriaged. let bytes = unsafe { OsStr::from_encoded_bytes_unchecked(&abs_path) }; r"\??\".encode_utf16().chain(bytes.encode_wide()).collect() } else if abs_path.starts_with(br"\\.\") { + // SAFETY: Untriaged. let bytes = unsafe { OsStr::from_encoded_bytes_unchecked(&abs_path[4..]) }; r"\??\".encode_utf16().chain(bytes.encode_wide()).collect() } else if abs_path.starts_with(br"\\") { + // SAFETY: Untriaged. let bytes = unsafe { OsStr::from_encoded_bytes_unchecked(&abs_path[2..]) }; r"\??\UNC\".encode_utf16().chain(bytes.encode_wide()).collect() } else { @@ -1718,6 +1760,7 @@ pub fn junction_point(original: &Path, link: &Path) -> io::Result<()> { // `SubstituteNameLength + PrintNameLength + 12`. header.ReparseDataLength = (total_len - offset_of!(MountPointBuffer, SubstituteNameOffset)) as u16; + // SAFETY: Untriaged. unsafe { let mut ret = 0; cvt(c::DeviceIoControl( diff --git a/library/std/src/sys/fs/windows/dir.rs b/library/std/src/sys/fs/windows/dir.rs index 5e69515b66599..23abc68fc0cd2 100644 --- a/library/std/src/sys/fs/windows/dir.rs +++ b/library/std/src/sys/fs/windows/dir.rs @@ -38,6 +38,7 @@ unsafe fn nt_create_file( let access = opts.get_access_mode()? | c::SYNCHRONIZE; // one of FILE_SYNCHRONOUS_IO_{,NON}ALERT is required for later operations to succeed. let options = create_options | c::FILE_SYNCHRONOUS_IO_NONALERT; + // SAFETY: Untriaged. let status = unsafe { c::NtCreateFile( &mut handle, @@ -57,6 +58,7 @@ unsafe fn nt_create_file( // SAFETY: nt_success guarantees that handle is no longer null unsafe { Ok(Handle::from_raw_handle(handle)) } } else { + // SAFETY: Untriaged. Err(WinError::new(unsafe { c::RtlNtStatusToDosError(status) })).io_result() } } @@ -94,6 +96,7 @@ impl Dir { lpSecurityDescriptor: ptr::null_mut(), bInheritHandle: opts.inherit_handle as c::BOOL, }; + // SAFETY: Untriaged. let handle = unsafe { c::CreateFileW( path.as_ptr(), @@ -106,6 +109,7 @@ impl Dir { ptr::null_mut(), ) }; + // SAFETY: Untriaged. match OwnedHandle::try_from(unsafe { HandleOrInvalid::from_raw_handle(handle) }) { Ok(handle) => Ok(Self { handle: Handle::from_inner(handle) }), Err(_) => Err(io::Error::last_os_error()), @@ -120,6 +124,7 @@ impl Dir { ..c::OBJECT_ATTRIBUTES::with_length() }; let create_opt = if dir { c::FILE_DIRECTORY_FILE } else { c::FILE_NON_DIRECTORY_FILE }; + // SAFETY: Untriaged. unsafe { nt_create_file(opts, &object_attributes, create_opt) } } @@ -171,6 +176,7 @@ impl Dir { ); } + // SAFETY: Untriaged. let status = unsafe { c::NtSetInformationFile( handle.as_raw_handle(), @@ -180,11 +186,13 @@ impl Dir { c::FileRenameInformation, ) }; + // SAFETY: Untriaged. unsafe { dealloc(file_rename_info.cast::(), layout) }; if c::nt_success(status) { // SAFETY: nt_success guarantees that handle is no longer null Ok(()) } else { + // SAFETY: Untriaged. Err(WinError::new(unsafe { c::RtlNtStatusToDosError(status) })) } .io_result() @@ -225,6 +233,7 @@ impl IntoRawHandle for fs::Dir { #[unstable(feature = "dirfd", issue = "120426")] impl FromRawHandle for fs::Dir { unsafe fn from_raw_handle(handle: RawHandle) -> Self { + // SAFETY: Untriaged. Self::from_inner(Dir { handle: unsafe { FromRawHandle::from_raw_handle(handle) } }) } } diff --git a/library/std/src/sys/fs/windows/remove_dir_all.rs b/library/std/src/sys/fs/windows/remove_dir_all.rs index c8b1a07676855..d99d6fc42b291 100644 --- a/library/std/src/sys/fs/windows/remove_dir_all.rs +++ b/library/std/src/sys/fs/windows/remove_dir_all.rs @@ -48,6 +48,7 @@ unsafe fn nt_open_file( share: u32, options: u32, ) -> Result { + // SAFETY: Untriaged. unsafe { let mut handle = ptr::null_mut(); let mut io_status = c::IO_STATUS_BLOCK::PENDING; @@ -89,6 +90,7 @@ fn open_link_no_reparse( // earlier versions of Windows. static ATTRIBUTES: Atomic = AtomicU32::new(c::OBJ_DONT_REPARSE); + // SAFETY: Untriaged. let result = unsafe { let mut object = c::OBJECT_ATTRIBUTES { ObjectName: path.as_ptr(), diff --git a/library/std/src/sys/helpers/small_c_string.rs b/library/std/src/sys/helpers/small_c_string.rs index f54505a856e05..a78c5631385c7 100644 --- a/library/std/src/sys/helpers/small_c_string.rs +++ b/library/std/src/sys/helpers/small_c_string.rs @@ -25,6 +25,7 @@ pub fn run_with_cstr(bytes: &[u8], f: &dyn Fn(&CStr) -> io::Result) -> io: if bytes.len() >= MAX_STACK_ALLOCATION { run_with_cstr_allocating(bytes, f) } else { + // SAFETY: Untriaged. unsafe { run_with_cstr_stack(bytes, f) } } } @@ -39,11 +40,13 @@ unsafe fn run_with_cstr_stack( let mut buf = MaybeUninit::<[u8; MAX_STACK_ALLOCATION]>::uninit(); let buf_ptr = buf.as_mut_ptr() as *mut u8; + // SAFETY: Untriaged. unsafe { ptr::copy_nonoverlapping(bytes.as_ptr(), buf_ptr, bytes.len()); buf_ptr.add(bytes.len()).write(0); } + // SAFETY: Untriaged. match CStr::from_bytes_with_nul(unsafe { slice::from_raw_parts(buf_ptr, bytes.len() + 1) }) { Ok(s) => f(s), Err(_) => Err(NUL_ERR), diff --git a/library/std/src/sys/io/error/hermit.rs b/library/std/src/sys/io/error/hermit.rs index 5f42144bb7cfb..60a0d2a194fe4 100644 --- a/library/std/src/sys/io/error/hermit.rs +++ b/library/std/src/sys/io/error/hermit.rs @@ -1,6 +1,7 @@ use crate::io; pub fn errno() -> i32 { + // SAFETY: Untriaged. unsafe { hermit_abi::get_errno() } } diff --git a/library/std/src/sys/io/error/unix.rs b/library/std/src/sys/io/error/unix.rs index 5c51c5705a7aa..702ad38a05685 100644 --- a/library/std/src/sys/io/error/unix.rs +++ b/library/std/src/sys/io/error/unix.rs @@ -53,6 +53,7 @@ unsafe extern "C" { )))] #[inline] pub fn errno() -> i32 { + // SAFETY: Untriaged. unsafe { (*errno_location()) as i32 } } @@ -69,12 +70,14 @@ pub fn errno() -> i32 { )))] #[inline] pub fn set_errno(e: i32) { + // SAFETY: Untriaged. unsafe { *errno_location() = e as c_int } } #[cfg(target_os = "vxworks")] #[inline] pub fn errno() -> i32 { + // SAFETY: Untriaged. unsafe { libc::errnoGet() } } @@ -86,6 +89,7 @@ pub fn errno() -> i32 { static _tls_errno: c_int; } + // SAFETY: Untriaged. unsafe { _tls_errno as i32 } } @@ -97,6 +101,7 @@ pub fn errno() -> i32 { static mut errno: c_int; } + // SAFETY: Untriaged. unsafe { errno as i32 } } @@ -108,6 +113,7 @@ pub fn set_errno(e: i32) { static mut errno: c_int; } + // SAFETY: Untriaged. unsafe { errno = e }; } @@ -120,11 +126,13 @@ unsafe extern "C" { #[cfg(target_os = "wasi")] pub fn errno() -> i32 { + // SAFETY: Untriaged. unsafe { libc_errno as i32 } } #[cfg(target_os = "wasi")] pub fn set_errno(val: i32) { + // SAFETY: Untriaged. unsafe { libc_errno = val; } @@ -214,6 +222,7 @@ pub fn error_string(errno: i32) -> String { let mut buf = [0 as c_char; TMPBUF_SZ]; let p = buf.as_mut_ptr(); + // SAFETY: Untriaged. unsafe { if strerror_r(errno as c_int, p, buf.len()) < 0 { panic!("strerror_r failure"); diff --git a/library/std/src/sys/io/error/windows.rs b/library/std/src/sys/io/error/windows.rs index 3e6e281c61a75..25bb9267cada2 100644 --- a/library/std/src/sys/io/error/windows.rs +++ b/library/std/src/sys/io/error/windows.rs @@ -97,6 +97,7 @@ pub fn decode_error_kind(errno: i32) -> io::ErrorKind { pub fn error_string(mut errnum: i32) -> String { let mut buf = [0 as c::WCHAR; 2048]; + // SAFETY: Untriaged. unsafe { let mut module = ptr::null_mut(); let mut flags = 0; diff --git a/library/std/src/sys/io/is_terminal/isatty.rs b/library/std/src/sys/io/is_terminal/isatty.rs index 6e0b46211b907..113a911b1c75d 100644 --- a/library/std/src/sys/io/is_terminal/isatty.rs +++ b/library/std/src/sys/io/is_terminal/isatty.rs @@ -2,5 +2,6 @@ use crate::os::fd::{AsFd, AsRawFd}; pub fn is_terminal(fd: &impl AsFd) -> bool { let fd = fd.as_fd(); + // SAFETY: Untriaged. unsafe { libc::isatty(fd.as_raw_fd()) != 0 } } diff --git a/library/std/src/sys/io/is_terminal/windows.rs b/library/std/src/sys/io/is_terminal/windows.rs index b0c718d71f9f3..de0454b1916e9 100644 --- a/library/std/src/sys/io/is_terminal/windows.rs +++ b/library/std/src/sys/io/is_terminal/windows.rs @@ -13,6 +13,7 @@ fn handle_is_console(handle: BorrowedHandle<'_>) -> bool { } let mut out = 0; + // SAFETY: Untriaged. if unsafe { c::GetConsoleMode(handle.as_raw_handle(), &mut out) != 0 } { // False positives aren't possible. If we got a console then we definitely have a console. return true; @@ -24,6 +25,7 @@ fn handle_is_console(handle: BorrowedHandle<'_>) -> bool { fn msys_tty_on(handle: BorrowedHandle<'_>) -> bool { // Early return if the handle is not a pipe. + // SAFETY: Untriaged. if unsafe { c::GetFileType(handle.as_raw_handle()) != c::FILE_TYPE_PIPE } { return false; } @@ -40,6 +42,7 @@ fn msys_tty_on(handle: BorrowedHandle<'_>) -> bool { } let mut name_info = FILE_NAME_INFO { FileNameLength: 0, FileName: [0; c::MAX_PATH as usize] }; // Safety: buffer length is fixed. + // SAFETY: Untriaged. let res = unsafe { c::GetFileInformationByHandleEx( handle.as_raw_handle(), diff --git a/library/std/src/sys/io/kernel_copy/linux.rs b/library/std/src/sys/io/kernel_copy/linux.rs index 433fabc3f9733..552320a46c80c 100644 --- a/library/std/src/sys/io/kernel_copy/linux.rs +++ b/library/std/src/sys/io/kernel_copy/linux.rs @@ -639,6 +639,7 @@ impl CopyWrite for CachedFileMetadata { fn fd_to_meta(fd: &T) -> FdMeta { let fd = fd.as_raw_fd(); + // SAFETY: Untriaged. let file: ManuallyDrop = ManuallyDrop::new(unsafe { File::from_raw_fd(fd) }); match file.metadata() { Ok(meta) => FdMeta::Metadata(meta), @@ -707,6 +708,7 @@ fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> CopyResult // In some cases, we cannot determine availability from the first // `copy_file_range` call. In this case, we probe with an invalid file // descriptor so that the results are easily interpretable. + // SAFETY: Untriaged. match unsafe { cvt(copy_file_range(INVALID_FD, ptr::null_mut(), INVALID_FD, ptr::null_mut(), 1, 0)) .map_err(|e| e.raw_os_error()) @@ -727,6 +729,7 @@ fn copy_regular_files(reader: RawFd, writer: RawFd, max_len: u64) -> CopyResult // this allows us to copy large chunks without hitting EOVERFLOW, // unless someone sets a file offset close to u64::MAX - 1GB, in which case a fallback would be required let bytes_to_copy = cmp::min(bytes_to_copy as usize, 0x4000_0000usize); + // SAFETY: Untriaged. let copy_result = unsafe { // We actually don't have to adjust the offsets, // because copy_file_range adjusts the file offset automatically @@ -846,8 +849,10 @@ fn sendfile_splice(mode: SpliceMode, reader: RawFd, writer: RawFd, len: u64) -> let result = match mode { SpliceMode::Sendfile => { + // SAFETY: Untriaged. cvt(unsafe { sendfile64(writer, reader, ptr::null_mut(), chunk_size) }) } + // SAFETY: Untriaged. SpliceMode::Splice => cvt(unsafe { splice(reader, ptr::null_mut(), writer, ptr::null_mut(), chunk_size, 0) }), diff --git a/library/std/src/sys/net/connection/motor.rs b/library/std/src/sys/net/connection/motor.rs index d42c70352367d..3a184df1292ff 100644 --- a/library/std/src/sys/net/connection/motor.rs +++ b/library/std/src/sys/net/connection/motor.rs @@ -30,6 +30,7 @@ impl TcpStream { pub fn connect(addr: A) -> io::Result { let addr = into_netc(&addr.to_socket_addrs()?.next().unwrap()); moto_rt::net::tcp_connect(&addr, Duration::MAX, false) + // SAFETY: Untriaged. .map(|fd| Self { inner: unsafe { Socket::from_raw_fd(fd) } }) .map_err(map_motor_error) } @@ -37,6 +38,7 @@ impl TcpStream { pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result { let addr = into_netc(addr); moto_rt::net::tcp_connect(&addr, timeout, false) + // SAFETY: Untriaged. .map(|fd| Self { inner: unsafe { Socket::from_raw_fd(fd) } }) .map_err(map_motor_error) } @@ -70,6 +72,7 @@ impl TcpStream { } pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + // SAFETY: Untriaged. let bufs: &mut [&mut [u8]] = unsafe { core::mem::transmute(bufs) }; moto_rt::fs::read_vectored(self.inner.as_raw_fd(), bufs).map_err(map_motor_error) } @@ -83,6 +86,7 @@ impl TcpStream { } pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { + // SAFETY: Untriaged. let bufs: &[&[u8]] = unsafe { core::mem::transmute(bufs) }; moto_rt::fs::write_vectored(self.inner.as_raw_fd(), bufs).map_err(map_motor_error) } @@ -115,6 +119,7 @@ impl TcpStream { pub fn duplicate(&self) -> io::Result { moto_rt::fs::duplicate(self.inner.as_raw_fd()) + // SAFETY: Untriaged. .map(|fd| Self { inner: unsafe { Socket::from_raw_fd(fd) } }) .map_err(map_motor_error) } @@ -180,6 +185,7 @@ impl TcpListener { pub fn bind(addr: A) -> io::Result { let addr = into_netc(&addr.to_socket_addrs()?.next().unwrap()); moto_rt::net::bind(moto_rt::net::PROTO_TCP, &addr) + // SAFETY: Untriaged. .map(|fd| Self { inner: unsafe { Socket::from_raw_fd(fd) } }) .map_err(map_motor_error) } @@ -193,6 +199,7 @@ impl TcpListener { pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { moto_rt::net::accept(self.inner.as_raw_fd()) .map(|(fd, addr)| { + // SAFETY: Untriaged. (TcpStream { inner: unsafe { Socket::from_raw_fd(fd) } }, from_netc(&addr)) }) .map_err(map_motor_error) @@ -200,6 +207,7 @@ impl TcpListener { pub fn duplicate(&self) -> io::Result { moto_rt::fs::duplicate(self.inner.as_raw_fd()) + // SAFETY: Untriaged. .map(|fd| Self { inner: unsafe { Socket::from_raw_fd(fd) } }) .map_err(map_motor_error) } @@ -248,6 +256,7 @@ impl UdpSocket { pub fn bind(addr: A) -> io::Result { let addr = into_netc(&addr.to_socket_addrs()?.next().unwrap()); moto_rt::net::bind(moto_rt::net::PROTO_UDP, &addr) + // SAFETY: Untriaged. .map(|fd| Self { inner: unsafe { Socket::from_raw_fd(fd) } }) .map_err(map_motor_error) } @@ -283,6 +292,7 @@ impl UdpSocket { pub fn duplicate(&self) -> io::Result { moto_rt::fs::duplicate(self.inner.as_raw_fd()) + // SAFETY: Untriaged. .map(|fd| Self { inner: unsafe { Socket::from_raw_fd(fd) } }) .map_err(map_motor_error) } @@ -453,7 +463,9 @@ fn from_netc(addr: &netc::sockaddr) -> SocketAddr { // SAFETY: all variants of union netc::sockaddr have `sin_family` at the same offset. let family = unsafe { addr.v4.sin_family }; match family { + // SAFETY: Untriaged. netc::AF_INET => SocketAddr::V4(crate::net::SocketAddrV4::from(unsafe { addr.v4 })), + // SAFETY: Untriaged. netc::AF_INET6 => SocketAddr::V6(crate::net::SocketAddrV6::from(unsafe { addr.v6 })), _ => panic!("bad sin_family {family}"), } diff --git a/library/std/src/sys/net/connection/socket/hermit.rs b/library/std/src/sys/net/connection/socket/hermit.rs index f43395ce8fd80..5750880505f52 100644 --- a/library/std/src/sys/net/connection/socket/hermit.rs +++ b/library/std/src/sys/net/connection/socket/hermit.rs @@ -37,7 +37,9 @@ pub struct Socket(FileDesc); impl Socket { pub fn new(fam: i32, ty: i32) -> io::Result { + // SAFETY: Untriaged. let fd = cvt(unsafe { netc::socket(fam, ty, 0) })?; + // SAFETY: Untriaged. Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) })) } @@ -47,12 +49,14 @@ impl Socket { pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> { let (addr, len) = socket_addr_to_c(addr); + // SAFETY: Untriaged. cvt_r(|| unsafe { netc::connect(self.as_raw_fd(), addr.as_ptr(), len) })?; Ok(()) } pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> { self.set_nonblocking(true)?; + // SAFETY: Untriaged. let r = unsafe { let (addr, len) = socket_addr_to_c(addr); cvt(netc::connect(self.as_raw_fd(), addr.as_ptr(), len)) @@ -91,6 +95,7 @@ impl Socket { let timeout = cmp::min(timeout, c_int::MAX as u64) as c_int; + // SAFETY: Untriaged. match unsafe { netc::poll(&mut pollfd, 1, timeout) } { -1 => { let err = io::Error::last_os_error(); @@ -123,16 +128,21 @@ impl Socket { storage: *mut netc::sockaddr, len: *mut netc::socklen_t, ) -> io::Result { + // SAFETY: Untriaged. let fd = cvt(unsafe { netc::accept(self.0.as_raw_fd(), storage, len) })?; + // SAFETY: Untriaged. Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) })) } pub fn duplicate(&self) -> io::Result { + // SAFETY: Untriaged. let fd = cvt(unsafe { netc::dup(self.0.as_raw_fd()) })?; + // SAFETY: Untriaged. Ok(Socket(unsafe { FileDesc::from_raw_fd(fd) })) } fn recv_with_flags(&self, mut buf: BorrowedCursor<'_, u8>, flags: i32) -> io::Result<()> { + // SAFETY: Untriaged. let ret = cvt(unsafe { netc::recv( self.0.as_raw_fd(), @@ -141,6 +151,7 @@ impl Socket { flags, ) })?; + // SAFETY: Untriaged. unsafe { buf.advance(ret as usize); } @@ -173,9 +184,11 @@ impl Socket { } fn recv_from_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<(usize, SocketAddr)> { + // SAFETY: Untriaged. let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() }; let mut addrlen = size_of_val(&storage) as netc::socklen_t; + // SAFETY: Untriaged. let n = cvt(unsafe { netc::recvfrom( self.as_raw_fd(), @@ -186,6 +199,7 @@ impl Socket { &mut addrlen, ) })?; + // SAFETY: Untriaged. Ok((n as usize, unsafe { socket_addr_from_c(&storage, addrlen as usize)? })) } @@ -233,10 +247,12 @@ impl Socket { None => netc::timeval { tv_sec: 0, tv_usec: 0 }, }; + // SAFETY: Untriaged. unsafe { setsockopt(self, netc::SOL_SOCKET, kind, timeout) } } pub fn timeout(&self, kind: i32) -> io::Result> { + // SAFETY: Untriaged. let raw: netc::timeval = unsafe { getsockopt(self, netc::SOL_SOCKET, kind)? }; if raw.tv_sec == 0 && raw.tv_usec == 0 { Ok(None) @@ -253,6 +269,7 @@ impl Socket { Shutdown::Read => netc::SHUT_RD, Shutdown::Both => netc::SHUT_RDWR, }; + // SAFETY: Untriaged. cvt(unsafe { netc::shutdown(self.as_raw_fd(), how) })?; Ok(()) } @@ -263,36 +280,43 @@ impl Socket { l_linger: cmp::min(linger.unwrap_or_default().as_secs(), c_int::MAX as u64) as c_int, }; + // SAFETY: Untriaged. unsafe { setsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER, linger) } } pub fn linger(&self) -> io::Result> { + // SAFETY: Untriaged. let val: netc::linger = unsafe { getsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER)? }; Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64))) } pub fn set_keepalive(&self, keepalive: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(self, netc::SOL_SOCKET, netc::SO_KEEPALIVE, keepalive as c_int) } } pub fn keepalive(&self) -> io::Result { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(self, netc::SOL_SOCKET, netc::SO_KEEPALIVE)? }; Ok(raw != 0) } pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { let value: i32 = if nodelay { 1 } else { 0 }; + // SAFETY: Untriaged. unsafe { setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, value) } } pub fn nodelay(&self) -> io::Result { + // SAFETY: Untriaged. let raw: i32 = unsafe { getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)? }; Ok(raw != 0) } pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { let mut nonblocking: i32 = if nonblocking { 1 } else { 0 }; + // SAFETY: Untriaged. cvt(unsafe { netc::ioctl( self.as_raw_fd(), @@ -304,6 +328,7 @@ impl Socket { } pub fn take_error(&self) -> io::Result> { + // SAFETY: Untriaged. let raw = unsafe { getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)? }; if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw))) } } diff --git a/library/std/src/sys/net/connection/socket/mod.rs b/library/std/src/sys/net/connection/socket/mod.rs index b7840d2c054c3..ad4a852f4b10b 100644 --- a/library/std/src/sys/net/connection/socket/mod.rs +++ b/library/std/src/sys/net/connection/socket/mod.rs @@ -123,6 +123,7 @@ fn socket_addr_v4_to_c(addr: &SocketAddrV4) -> c::sockaddr_in { sin_family: c::AF_INET as c::sa_family_t, sin_port: addr.port().to_be(), sin_addr: ip_v4_addr_to_c(addr.ip()), + // SAFETY: Untriaged. ..unsafe { mem::zeroed() } } } @@ -134,6 +135,7 @@ fn socket_addr_v6_to_c(addr: &SocketAddrV6) -> c::sockaddr_in6 { sin6_addr: ip_v6_addr_to_c(addr.ip()), sin6_flowinfo: addr.flowinfo(), sin6_scope_id: addr.scope_id(), + // SAFETY: Untriaged. ..unsafe { mem::zeroed() } } } @@ -199,12 +201,14 @@ unsafe fn socket_addr_from_c( match (*storage).ss_family as c_int { c::AF_INET => { assert!(len >= size_of::()); + // SAFETY: Untriaged. Ok(SocketAddr::V4(socket_addr_v4_from_c(unsafe { *(storage as *const _ as *const c::sockaddr_in) }))) } c::AF_INET6 => { assert!(len >= size_of::()); + // SAFETY: Untriaged. Ok(SocketAddr::V6(socket_addr_v6_from_c(unsafe { *(storage as *const _ as *const c::sockaddr_in6) }))) @@ -322,6 +326,7 @@ impl Iterator for LookupHost { type Item = SocketAddr; fn next(&mut self) -> Option { loop { + // SAFETY: Untriaged. unsafe { let cur = self.cur.as_ref()?; self.cur = cur.ai_next; @@ -342,6 +347,7 @@ unsafe impl Send for LookupHost {} impl Drop for LookupHost { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { c::freeaddrinfo(self.original) } } } @@ -349,9 +355,11 @@ impl Drop for LookupHost { pub fn lookup_host(host: &str, port: u16) -> io::Result { init(); run_with_cstr(host.as_bytes(), &|c_host| { + // SAFETY: Untriaged. let mut hints: c::addrinfo = unsafe { mem::zeroed() }; hints.ai_socktype = c::SOCK_STREAM; let mut res = ptr::null_mut(); + // SAFETY: Untriaged. unsafe { cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res)) .map(|_| LookupHost { original: res, cur: res, port }) @@ -435,6 +443,7 @@ impl TcpStream { pub fn write(&self, buf: &[u8]) -> io::Result { let len = cmp::min(buf.len(), MAX_SEND_LEN) as wrlen_t; + // SAFETY: Untriaged. let ret = cvt(unsafe { c::send(self.inner.as_raw(), buf.as_ptr() as *const c_void, len, MSG_NOSIGNAL) })?; @@ -451,10 +460,12 @@ impl TcpStream { } pub fn peer_addr(&self) -> io::Result { + // SAFETY: Untriaged. unsafe { sockname(|buf, len| c::getpeername(self.inner.as_raw(), buf, len)) } } pub fn socket_addr(&self) -> io::Result { + // SAFETY: Untriaged. unsafe { sockname(|buf, len| c::getsockname(self.inner.as_raw(), buf, len)) } } @@ -491,10 +502,12 @@ impl TcpStream { } pub fn set_ttl(&self, ttl: u32) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int) } } pub fn ttl(&self) -> io::Result { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)? }; Ok(raw as u32) } @@ -562,12 +575,14 @@ impl TcpListener { // which allows “socket hijacking”, so we explicitly don't set it here. // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse #[cfg(not(windows))] + // SAFETY: Untriaged. unsafe { setsockopt(&sock, c::SOL_SOCKET, c::SO_REUSEADDR, 1 as c_int)? }; // Bind our new socket let (addr, len) = socket_addr_to_c(addr); + // SAFETY: Untriaged. cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?; let backlog = if cfg!(target_os = "horizon") { @@ -585,6 +600,7 @@ impl TcpListener { }; // Start listening + // SAFETY: Untriaged. cvt(unsafe { c::listen(sock.as_raw(), backlog) })?; Ok(TcpListener { inner: sock }) } @@ -600,6 +616,7 @@ impl TcpListener { } pub fn socket_addr(&self) -> io::Result { + // SAFETY: Untriaged. unsafe { sockname(|buf, len| c::getsockname(self.inner.as_raw(), buf, len)) } } @@ -610,6 +627,7 @@ impl TcpListener { let mut storage = MaybeUninit::::uninit(); let mut len = size_of::() as c::socklen_t; let sock = self.inner.accept(storage.as_mut_ptr() as *mut _, &mut len)?; + // SAFETY: Untriaged. let addr = unsafe { socket_addr_from_c(storage.as_ptr(), len as usize)? }; Ok((TcpStream { inner: sock }, addr)) } @@ -619,19 +637,23 @@ impl TcpListener { } pub fn set_ttl(&self, ttl: u32) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int) } } pub fn ttl(&self) -> io::Result { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)? }; Ok(raw as u32) } pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY, only_v6 as c_int) } } pub fn only_v6(&self) -> io::Result { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY)? }; Ok(raw != 0) } @@ -680,6 +702,7 @@ impl UdpSocket { fn inner(addr: &SocketAddr) -> io::Result { let sock = Socket::new(addr_family(addr), c::SOCK_DGRAM)?; let (addr, len) = socket_addr_to_c(addr); + // SAFETY: Untriaged. cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?; Ok(UdpSocket { inner: sock }) } @@ -695,10 +718,12 @@ impl UdpSocket { } pub fn peer_addr(&self) -> io::Result { + // SAFETY: Untriaged. unsafe { sockname(|buf, len| c::getpeername(self.inner.as_raw(), buf, len)) } } pub fn socket_addr(&self) -> io::Result { + // SAFETY: Untriaged. unsafe { sockname(|buf, len| c::getsockname(self.inner.as_raw(), buf, len)) } } @@ -717,6 +742,7 @@ impl UdpSocket { return Err(io::Error::from_raw_os_error(c::EMSGSIZE)); } let (dst, dstlen) = socket_addr_to_c(dst); + // SAFETY: Untriaged. let ret = cvt(unsafe { c::sendto( self.inner.as_raw(), @@ -751,15 +777,18 @@ impl UdpSocket { } pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST, broadcast as c_int) } } pub fn broadcast(&self) -> io::Result { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST)? }; Ok(raw != 0) } pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt( &self.inner, @@ -772,11 +801,13 @@ impl UdpSocket { pub fn multicast_loop_v4(&self) -> io::Result { let raw: IpV4MultiCastType = +// SAFETY: Untriaged. unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)? }; Ok(raw != 0) } pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt( &self.inner, @@ -789,11 +820,13 @@ impl UdpSocket { pub fn multicast_ttl_v4(&self) -> io::Result { let raw: IpV4MultiCastType = +// SAFETY: Untriaged. unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)? }; Ok(raw as u32) } pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt( &self.inner, @@ -806,6 +839,7 @@ impl UdpSocket { pub fn multicast_loop_v6(&self) -> io::Result { let raw: c_int = +// SAFETY: Untriaged. unsafe { getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP)? }; Ok(raw != 0) } @@ -815,6 +849,7 @@ impl UdpSocket { imr_multiaddr: ip_v4_addr_to_c(multiaddr), imr_interface: ip_v4_addr_to_c(interface), }; + // SAFETY: Untriaged. unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) } } @@ -823,6 +858,7 @@ impl UdpSocket { ipv6mr_multiaddr: ip_v6_addr_to_c(multiaddr), ipv6mr_interface: to_ipv6mr_interface(interface), }; + // SAFETY: Untriaged. unsafe { setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq) } } @@ -831,6 +867,7 @@ impl UdpSocket { imr_multiaddr: ip_v4_addr_to_c(multiaddr), imr_interface: ip_v4_addr_to_c(interface), }; + // SAFETY: Untriaged. unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) } } @@ -839,14 +876,17 @@ impl UdpSocket { ipv6mr_multiaddr: ip_v6_addr_to_c(multiaddr), ipv6mr_interface: to_ipv6mr_interface(interface), }; + // SAFETY: Untriaged. unsafe { setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, mreq) } } pub fn set_ttl(&self, ttl: u32) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int) } } pub fn ttl(&self) -> io::Result { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)? }; Ok(raw as u32) } @@ -873,6 +913,7 @@ impl UdpSocket { if buf.len() > MAX_SEND_LEN { return Err(io::Error::from_raw_os_error(c::EMSGSIZE)); } + // SAFETY: Untriaged. let ret = cvt(unsafe { c::send( self.inner.as_raw(), @@ -889,6 +930,7 @@ impl UdpSocket { fn inner(this: &UdpSocket, addr: &SocketAddr) -> io::Result<()> { let (addr, len) = socket_addr_to_c(addr); + // SAFETY: Untriaged. cvt_r(|| unsafe { c::connect(this.inner.as_raw(), addr.as_ptr(), len) }).map(drop) } } diff --git a/library/std/src/sys/net/connection/socket/solid.rs b/library/std/src/sys/net/connection/socket/solid.rs index 9fe08ec951e75..eb4cd164df8e4 100644 --- a/library/std/src/sys/net/connection/socket/solid.rs +++ b/library/std/src/sys/net/connection/socket/solid.rs @@ -74,10 +74,12 @@ where /// Returns the last error from the network subsystem. fn last_error() -> io::Error { + // SAFETY: Untriaged. io::Error::from_raw_os_error(unsafe { netc::SOLID_NET_GetLastError() }) } pub fn error_name(er: abi::ER) -> Option<&'static str> { + // SAFETY: Untriaged. unsafe { CStr::from_ptr(netc::strerror(er)) }.to_str().ok() } @@ -116,12 +118,15 @@ pub struct Socket(OwnedFd); impl Socket { pub fn new(fam: c_int, ty: c_int) -> io::Result { + // SAFETY: Untriaged. let fd = cvt(unsafe { netc::socket(fam, ty, 0) })?; + // SAFETY: Untriaged. Ok(unsafe { Self::from_raw_fd(fd) }) } pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> { let (addr, len) = socket_addr_to_c(addr); + // SAFETY: Untriaged. cvt(unsafe { netc::connect(self.as_raw_fd(), addr.as_ptr(), len) })?; Ok(()) } @@ -158,6 +163,7 @@ impl Socket { let mut writefds = fds; let mut errorfds = fds; + // SAFETY: Untriaged. let n = unsafe { cvt(netc::select( self.as_raw_fd() + 1, @@ -183,7 +189,9 @@ impl Socket { } pub fn accept(&self, storage: *mut sockaddr, len: *mut socklen_t) -> io::Result { + // SAFETY: Untriaged. let fd = cvt_r(|| unsafe { netc::accept(self.as_raw_fd(), storage, len) })?; + // SAFETY: Untriaged. unsafe { Ok(Self::from_raw_fd(fd)) } } @@ -192,9 +200,11 @@ impl Socket { } fn recv_with_flags(&self, mut buf: BorrowedCursor<'_, u8>, flags: c_int) -> io::Result<()> { + // SAFETY: Untriaged. let ret = cvt(unsafe { netc::recv(self.as_raw_fd(), buf.as_mut().as_mut_ptr().cast(), buf.capacity(), flags) })?; + // SAFETY: Untriaged. unsafe { buf.advance(ret as usize); } @@ -218,6 +228,7 @@ impl Socket { } pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + // SAFETY: Untriaged. let ret = cvt(unsafe { netc::readv( self.as_raw_fd(), @@ -238,9 +249,11 @@ impl Socket { buf: &mut [u8], flags: c_int, ) -> io::Result<(usize, SocketAddr)> { + // SAFETY: Untriaged. let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() }; let mut addrlen = size_of_val(&storage) as netc::socklen_t; + // SAFETY: Untriaged. let n = cvt(unsafe { netc::recvfrom( self.as_raw_fd(), @@ -251,6 +264,7 @@ impl Socket { &mut addrlen, ) })?; + // SAFETY: Untriaged. Ok((n as usize, unsafe { socket_addr_from_c(&storage, addrlen as usize)? })) } @@ -263,6 +277,7 @@ impl Socket { } pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { + // SAFETY: Untriaged. let ret = cvt(unsafe { netc::writev( self.as_raw_fd(), @@ -298,10 +313,12 @@ impl Socket { } None => netc::timeval { tv_sec: 0, tv_usec: 0 }, }; + // SAFETY: Untriaged. unsafe { setsockopt(self, netc::SOL_SOCKET, kind, timeout) } } pub fn timeout(&self, kind: c_int) -> io::Result> { + // SAFETY: Untriaged. let raw: netc::timeval = unsafe { getsockopt(self, netc::SOL_SOCKET, kind)? }; if raw.tv_sec == 0 && raw.tv_usec == 0 { Ok(None) @@ -318,6 +335,7 @@ impl Socket { Shutdown::Read => netc::SHUT_RD, Shutdown::Both => netc::SHUT_RDWR, }; + // SAFETY: Untriaged. cvt(unsafe { netc::shutdown(self.as_raw_fd(), how) })?; Ok(()) } @@ -329,10 +347,12 @@ impl Socket { as netc::c_int, }; + // SAFETY: Untriaged. unsafe { setsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER, linger) } } pub fn linger(&self) -> io::Result> { + // SAFETY: Untriaged. let val: netc::linger = unsafe { getsockopt(self, netc::SOL_SOCKET, netc::SO_LINGER)? }; Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64))) @@ -347,16 +367,19 @@ impl Socket { } pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY, nodelay as c_int) } } pub fn nodelay(&self) -> io::Result { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(self, netc::IPPROTO_TCP, netc::TCP_NODELAY)? }; Ok(raw != 0) } pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { let mut nonblocking = nonblocking as c_int; + // SAFETY: Untriaged. cvt(unsafe { netc::ioctl(self.as_raw_fd(), netc::FIONBIO, (&mut nonblocking) as *mut c_int as _) }) @@ -364,6 +387,7 @@ impl Socket { } pub fn take_error(&self) -> io::Result> { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(self, netc::SOL_SOCKET, netc::SO_ERROR)? }; if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } } @@ -404,6 +428,7 @@ impl AsRawFd for Socket { impl FromRawFd for Socket { #[inline] unsafe fn from_raw_fd(fd: c_int) -> Socket { + // SAFETY: Untriaged. unsafe { Self(FromRawFd::from_raw_fd(fd)) } } } diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs index 3062d53d879a8..56755d453d25b 100644 --- a/library/std/src/sys/net/connection/socket/unix.rs +++ b/library/std/src/sys/net/connection/socket/unix.rs @@ -47,6 +47,7 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> { } #[cfg(not(any(target_os = "espidf", target_os = "nuttx")))] + // SAFETY: Untriaged. let detail = unsafe { // We can't always expect a UTF-8 environment. When we don't get that luxury, // it's better to give a low-quality error message than none at all. @@ -65,51 +66,58 @@ pub fn cvt_gai(err: c_int) -> io::Result<()> { impl Socket { pub fn new(family: c_int, ty: c_int) -> io::Result { cfg_select! { - any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "hurd", - target_os = "linux", - target_os = "netbsd", - target_os = "openbsd", - target_os = "cygwin", - target_os = "nto", - target_os = "qnx", - target_os = "solaris", - ) => { - // On platforms that support it we pass the SOCK_CLOEXEC - // flag to atomically create the socket and set it as - // CLOEXEC. On Linux this was added in 2.6.27. - let fd = cvt(unsafe { libc::socket(family, ty | libc::SOCK_CLOEXEC, 0) })?; - let socket = Socket(unsafe { FileDesc::from_raw_fd(fd) }); - - // DragonFlyBSD, FreeBSD and NetBSD use `SO_NOSIGPIPE` as a `setsockopt` - // flag to disable `SIGPIPE` emission on socket. - #[cfg(any(target_os = "freebsd", target_os = "netbsd", target_os = "dragonfly"))] - unsafe { setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)? }; - - Ok(socket) - } - _ => { - let fd = cvt(unsafe { libc::socket(family, ty, 0) })?; - let fd = unsafe { FileDesc::from_raw_fd(fd) }; - fd.set_cloexec()?; - let socket = Socket(fd); - - // macOS and iOS use `SO_NOSIGPIPE` as a `setsockopt` - // flag to disable `SIGPIPE` emission on socket. - #[cfg(target_vendor = "apple")] - unsafe { setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)? }; - - Ok(socket) - } - } + any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "hurd", + target_os = "linux", + target_os = "netbsd", + target_os = "openbsd", + target_os = "cygwin", + target_os = "nto", + target_os = "qnx", + target_os = "solaris", + ) => { + // On platforms that support it we pass the SOCK_CLOEXEC + // flag to atomically create the socket and set it as + // CLOEXEC. On Linux this was added in 2.6.27. + // SAFETY: Untriaged. + let fd = cvt(unsafe { libc::socket(family, ty | libc::SOCK_CLOEXEC, 0) })?; + // SAFETY: Untriaged. + let socket = Socket(unsafe { FileDesc::from_raw_fd(fd) }); + + // DragonFlyBSD, FreeBSD and NetBSD use `SO_NOSIGPIPE` as a `setsockopt` + // flag to disable `SIGPIPE` emission on socket. + #[cfg(any(target_os = "freebsd", target_os = "netbsd", target_os = "dragonfly"))] + // SAFETY: Untriaged. + unsafe { setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)? }; + + Ok(socket) + } + _ => { + // SAFETY: Untriaged. + let fd = cvt(unsafe { libc::socket(family, ty, 0) })?; + // SAFETY: Untriaged. + let fd = unsafe { FileDesc::from_raw_fd(fd) }; + fd.set_cloexec()?; + let socket = Socket(fd); + + // macOS and iOS use `SO_NOSIGPIPE` as a `setsockopt` + // flag to disable `SIGPIPE` emission on socket. + #[cfg(target_vendor = "apple")] + // SAFETY: Untriaged. + unsafe { setsockopt(&socket, libc::SOL_SOCKET, libc::SO_NOSIGPIPE, 1)? }; + + Ok(socket) + } + } } #[cfg(not(any(target_os = "vxworks", target_os = "wasi")))] pub fn new_pair(fam: c_int, ty: c_int) -> io::Result<(Socket, Socket)> { + // SAFETY: Untriaged. unsafe { let mut fds = [0, 0]; @@ -151,6 +159,7 @@ impl Socket { pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> { let (addr, len) = socket_addr_to_c(addr); loop { + // SAFETY: Untriaged. let result = unsafe { libc::connect(self.as_raw_fd(), addr.as_ptr(), len) }; if result.is_minus_one() { let err = crate::sys::io::errno(); @@ -166,6 +175,7 @@ impl Socket { pub fn connect_timeout(&self, addr: &SocketAddr, timeout: Duration) -> io::Result<()> { self.set_nonblocking(true)?; + // SAFETY: Untriaged. let r = unsafe { let (addr, len) = socket_addr_to_c(addr); cvt(libc::connect(self.as_raw_fd(), addr.as_ptr(), len)) @@ -204,6 +214,7 @@ impl Socket { let timeout = cmp::min(timeout, c_int::MAX as u64) as c_int; + // SAFETY: Untriaged. match unsafe { libc::poll(&mut pollfd, 1, timeout) } { -1 => { let err = io::Error::last_os_error(); @@ -246,31 +257,33 @@ impl Socket { // platforms that support it. On Linux, this was added in 2.6.28, // glibc 2.10 and musl 0.9.5. cfg_select! { - any( - target_os = "android", - target_os = "dragonfly", - target_os = "freebsd", - target_os = "illumos", - target_os = "linux", - target_os = "hurd", - target_os = "netbsd", - target_os = "openbsd", - target_os = "cygwin", - ) => { - unsafe { - let fd = cvt_r(|| libc::accept4(self.as_raw_fd(), storage, len, libc::SOCK_CLOEXEC))?; - Ok(Socket(FileDesc::from_raw_fd(fd))) - } - } - _ => { - unsafe { - let fd = cvt_r(|| libc::accept(self.as_raw_fd(), storage, len))?; - let fd = FileDesc::from_raw_fd(fd); - fd.set_cloexec()?; - Ok(Socket(fd)) + any( + target_os = "android", + target_os = "dragonfly", + target_os = "freebsd", + target_os = "illumos", + target_os = "linux", + target_os = "hurd", + target_os = "netbsd", + target_os = "openbsd", + target_os = "cygwin", + ) => { + // SAFETY: Untriaged. + unsafe { + let fd = cvt_r(|| libc::accept4(self.as_raw_fd(), storage, len, libc::SOCK_CLOEXEC))?; + Ok(Socket(FileDesc::from_raw_fd(fd))) + } + } + _ => { + // SAFETY: Untriaged. + unsafe { + let fd = cvt_r(|| libc::accept(self.as_raw_fd(), storage, len))?; + let fd = FileDesc::from_raw_fd(fd); + fd.set_cloexec()?; + Ok(Socket(fd)) + } + } } - } - } } pub fn duplicate(&self) -> io::Result { @@ -280,6 +293,7 @@ impl Socket { #[cfg(not(target_os = "wasi"))] pub fn send_with_flags(&self, buf: &[u8], flags: c_int) -> io::Result { let len = cmp::min(buf.len(), super::MAX_SEND_LEN) as wrlen_t; + // SAFETY: Untriaged. let ret = cvt(unsafe { libc::send(self.as_raw_fd(), buf.as_ptr() as *const c_void, len, flags) })?; @@ -287,6 +301,7 @@ impl Socket { } fn recv_with_flags(&self, mut buf: BorrowedCursor<'_, u8>, flags: c_int) -> io::Result<()> { + // SAFETY: Untriaged. let ret = cvt(unsafe { libc::recv( self.as_raw_fd(), @@ -295,6 +310,7 @@ impl Socket { flags, ) })?; + // SAFETY: Untriaged. unsafe { buf.advance(ret as usize); } @@ -337,6 +353,7 @@ impl Socket { let mut storage: mem::MaybeUninit = mem::MaybeUninit::uninit(); let mut addrlen = size_of_val(&storage) as libc::socklen_t; + // SAFETY: Untriaged. let n = cvt(unsafe { libc::recvfrom( self.as_raw_fd(), @@ -347,6 +364,7 @@ impl Socket { &mut addrlen, ) })?; + // SAFETY: Untriaged. Ok((n as usize, unsafe { socket_addr_from_c(storage.as_ptr(), addrlen as usize)? })) } @@ -356,6 +374,7 @@ impl Socket { #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))] pub fn recv_msg(&self, msg: &mut libc::msghdr) -> io::Result { + // SAFETY: Untriaged. let n = cvt(unsafe { libc::recvmsg(self.as_raw_fd(), msg, libc::MSG_CMSG_CLOEXEC) })?; Ok(n as usize) } @@ -380,6 +399,7 @@ impl Socket { #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))] pub fn send_msg(&self, msg: &mut libc::msghdr) -> io::Result { + // SAFETY: Untriaged. let n = cvt(unsafe { libc::sendmsg(self.as_raw_fd(), msg, 0) })?; Ok(n as usize) } @@ -404,10 +424,12 @@ impl Socket { } None => libc::timeval { tv_sec: 0, tv_usec: 0 }, }; + // SAFETY: Untriaged. unsafe { setsockopt(self, libc::SOL_SOCKET, kind, timeout) } } pub fn timeout(&self, kind: libc::c_int) -> io::Result> { + // SAFETY: Untriaged. let raw: libc::timeval = unsafe { getsockopt(self, libc::SOL_SOCKET, kind)? }; if raw.tv_sec == 0 && raw.tv_usec == 0 { Ok(None) @@ -424,6 +446,7 @@ impl Socket { Shutdown::Read => libc::SHUT_RD, Shutdown::Both => libc::SHUT_RDWR, }; + // SAFETY: Untriaged. cvt(unsafe { libc::shutdown(self.as_raw_fd(), how) })?; Ok(()) } @@ -435,6 +458,7 @@ impl Socket { l_linger: cmp::min(linger.unwrap_or_default().as_secs(), c_int::MAX as u64) as c_int, }; + // SAFETY: Untriaged. unsafe { setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger) } } @@ -446,40 +470,48 @@ impl Socket { as libc::c_ushort, }; + // SAFETY: Untriaged. unsafe { setsockopt(self, libc::SOL_SOCKET, SO_LINGER, linger) } } pub fn linger(&self) -> io::Result> { + // SAFETY: Untriaged. let val: libc::linger = unsafe { getsockopt(self, libc::SOL_SOCKET, SO_LINGER)? }; Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64))) } pub fn set_keepalive(&self, keepalive: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(self, libc::SOL_SOCKET, libc::SO_KEEPALIVE, keepalive as c_int) } } pub fn keepalive(&self) -> io::Result { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(self, libc::SOL_SOCKET, libc::SO_KEEPALIVE)? }; Ok(raw != 0) } pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY, nodelay as c_int) } } pub fn nodelay(&self) -> io::Result { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(self, libc::IPPROTO_TCP, libc::TCP_NODELAY)? }; Ok(raw != 0) } #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))] pub fn set_quickack(&self, quickack: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK, quickack as c_int) } } #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))] pub fn quickack(&self) -> io::Result { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(self, libc::IPPROTO_TCP, libc::TCP_QUICKACK)? }; Ok(raw != 0) } @@ -488,11 +520,13 @@ impl Socket { #[cfg(target_os = "linux")] pub fn set_deferaccept(&self, accept: Duration) -> io::Result<()> { let val = cmp::min(accept.as_secs(), c_int::MAX as u64) as c_int; + // SAFETY: Untriaged. unsafe { setsockopt(self, libc::IPPROTO_TCP, libc::TCP_DEFER_ACCEPT, val) } } #[cfg(target_os = "linux")] pub fn deferaccept(&self) -> io::Result { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(self, libc::IPPROTO_TCP, libc::TCP_DEFER_ACCEPT)? }; Ok(Duration::from_secs(raw as _)) } @@ -505,10 +539,13 @@ impl Socket { for (src, dst) in name.to_bytes().iter().zip(&mut buf[..AF_NAME_MAX - 1]) { *dst = *src as libc::c_char; } + // SAFETY: Untriaged. let mut arg: libc::accept_filter_arg = unsafe { mem::zeroed() }; arg.af_name = buf; + // SAFETY: Untriaged. unsafe { setsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER, &mut arg) } } else { + // SAFETY: Untriaged. unsafe { setsockopt( self, @@ -523,8 +560,10 @@ impl Socket { #[cfg(any(target_os = "freebsd", target_os = "netbsd"))] pub fn acceptfilter(&self) -> io::Result<&CStr> { let arg: libc::accept_filter_arg = +// SAFETY: Untriaged. unsafe { getsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER)? }; let s: &[u8] = +// SAFETY: Untriaged. unsafe { core::slice::from_raw_parts(arg.af_name.as_ptr() as *const u8, 16) }; let name = CStr::from_bytes_with_nul(s).unwrap(); Ok(name) @@ -534,6 +573,7 @@ impl Socket { pub fn set_exclbind(&self, excl: bool) -> io::Result<()> { // not yet on libc crate const SO_EXCLBIND: i32 = 0x1015; + // SAFETY: Untriaged. unsafe { setsockopt(self, libc::SOL_SOCKET, SO_EXCLBIND, excl) } } @@ -541,36 +581,42 @@ impl Socket { pub fn exclbind(&self) -> io::Result { // not yet on libc crate const SO_EXCLBIND: i32 = 0x1015; + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(self, libc::SOL_SOCKET, SO_EXCLBIND)? }; Ok(raw != 0) } #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))] pub fn set_passcred(&self, passcred: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int) } } #[cfg(any(target_os = "android", target_os = "linux", target_os = "cygwin"))] pub fn passcred(&self) -> io::Result { let passcred: libc::c_int = +// SAFETY: Untriaged. unsafe { getsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED)? }; Ok(passcred != 0) } #[cfg(target_os = "netbsd")] pub fn set_local_creds(&self, local_creds: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(self, 0 as libc::c_int, libc::LOCAL_CREDS, local_creds as libc::c_int) } } #[cfg(target_os = "netbsd")] pub fn local_creds(&self) -> io::Result { let local_creds: libc::c_int = +// SAFETY: Untriaged. unsafe { getsockopt(self, 0 as libc::c_int, libc::LOCAL_CREDS)? }; Ok(local_creds != 0) } #[cfg(target_os = "freebsd")] pub fn set_local_creds_persistent(&self, local_creds_persistent: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt( self, @@ -584,6 +630,7 @@ impl Socket { #[cfg(target_os = "freebsd")] pub fn local_creds_persistent(&self) -> io::Result { let local_creds_persistent: libc::c_int = +// SAFETY: Untriaged. unsafe { getsockopt(self, libc::AF_LOCAL, libc::LOCAL_CREDS_PERSISTENT)? }; Ok(local_creds_persistent != 0) } @@ -591,12 +638,14 @@ impl Socket { #[cfg(not(any(target_os = "solaris", target_os = "illumos", target_os = "vita")))] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { let mut nonblocking = nonblocking as libc::c_int; + // SAFETY: Untriaged. cvt(unsafe { libc::ioctl(self.as_raw_fd(), libc::FIONBIO, &mut nonblocking) }).map(drop) } #[cfg(target_os = "vita")] pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { let option = nonblocking as libc::c_int; + // SAFETY: Untriaged. unsafe { setsockopt(self, libc::SOL_SOCKET, libc::SO_NONBLOCK, option) } } @@ -615,10 +664,12 @@ impl Socket { let option = libc::SO_USER_COOKIE; #[cfg(target_os = "openbsd")] let option = libc::SO_RTABLE; + // SAFETY: Untriaged. unsafe { setsockopt(self, libc::SOL_SOCKET, option, mark as libc::c_int) } } pub fn take_error(&self) -> io::Result> { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(self, libc::SOL_SOCKET, libc::SO_ERROR)? }; if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } } @@ -695,6 +746,7 @@ fn on_resolver_failure() { // If the version fails to parse, we treat it the same as "not glibc". if let Some(version) = sys::pal::conf::glibc_version() { if version < (2, 26) { + // SAFETY: Untriaged. unsafe { libc::res_init() }; } } diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs index 075e77bc4457c..5d77b9a5b9918 100644 --- a/library/std/src/sys/net/connection/socket/windows.rs +++ b/library/std/src/sys/net/connection/socket/windows.rs @@ -88,6 +88,7 @@ pub(super) mod netc { } pub unsafe fn send(socket: SOCKET, buf: *const c_void, len: c_int, flags: c_int) -> c_int { + // SAFETY: Untriaged. unsafe { c::send(socket, buf.cast::(), len, flags) } } pub unsafe fn sendto( @@ -98,6 +99,7 @@ pub(super) mod netc { addr: *const SOCKADDR, addrlen: c_int, ) -> c_int { + // SAFETY: Untriaged. unsafe { c::sendto(socket, buf.cast::(), len, flags, addr, addrlen) } } pub unsafe fn getaddrinfo( @@ -106,6 +108,7 @@ pub(super) mod netc { hints: *const ADDRINFOA, res: *mut *mut ADDRINFOA, ) -> c_int { + // SAFETY: Untriaged. unsafe { c::getaddrinfo(node.cast::(), service.cast::(), hints, res) } } } @@ -117,6 +120,7 @@ pub struct Socket(OwnedSocket); impl Socket { pub fn new(family: c_int, ty: c_int) -> io::Result { + // SAFETY: Untriaged. let socket = unsafe { c::WSASocketW( family, @@ -129,8 +133,10 @@ impl Socket { }; if socket != c::INVALID_SOCKET { + // SAFETY: Untriaged. unsafe { Ok(Self::from_raw(socket)) } } else { + // SAFETY: Untriaged. let error = unsafe { c::WSAGetLastError() }; if error != c::WSAEPROTOTYPE && error != c::WSAEINVAL { @@ -138,12 +144,14 @@ impl Socket { } let socket = +// SAFETY: Untriaged. unsafe { c::WSASocketW(family, ty, 0, ptr::null_mut(), 0, c::WSA_FLAG_OVERLAPPED) }; if socket == c::INVALID_SOCKET { return Err(last_error()); } + // SAFETY: Untriaged. unsafe { let socket = Self::from_raw(socket); socket.0.set_no_inherit()?; @@ -154,6 +162,7 @@ impl Socket { pub fn connect(&self, addr: &SocketAddr) -> io::Result<()> { let (addr, len) = socket_addr_to_c(addr); + // SAFETY: Untriaged. let result = unsafe { c::connect(self.as_raw(), addr.as_ptr(), len) }; cvt(result).map(drop) } @@ -179,6 +188,7 @@ impl Socket { } let fds = { + // SAFETY: Untriaged. let mut fds = unsafe { mem::zeroed::() }; fds.fd_count = 1; fds.fd_array[0] = self.as_raw(); @@ -189,6 +199,7 @@ impl Socket { let mut errorfds = fds; let count = { + // SAFETY: Untriaged. let result = unsafe { c::select(1, ptr::null_mut(), &mut writefds, &mut errorfds, &timeout) }; @@ -213,10 +224,12 @@ impl Socket { } pub fn accept(&self, storage: *mut c::SOCKADDR, len: *mut c_int) -> io::Result { + // SAFETY: Untriaged. let socket = unsafe { c::accept(self.as_raw(), storage, len) }; match socket { c::INVALID_SOCKET => Err(last_error()), + // SAFETY: Untriaged. _ => unsafe { Ok(Self::from_raw(socket)) }, } } @@ -230,10 +243,12 @@ impl Socket { // do the same on windows to map a shut down socket to returning EOF. let length = cmp::min(buf.capacity(), i32::MAX as usize) as i32; let result = +// SAFETY: Untriaged. unsafe { c::recv(self.as_raw(), buf.as_mut().as_mut_ptr() as *mut _, length, flags) }; match result { c::SOCKET_ERROR => { + // SAFETY: Untriaged. let error = unsafe { c::WSAGetLastError() }; if error == c::WSAESHUTDOWN { @@ -243,6 +258,7 @@ impl Socket { } } _ => { + // SAFETY: Untriaged. unsafe { buf.advance(result as usize) }; Ok(()) } @@ -265,6 +281,7 @@ impl Socket { let length = cmp::min(bufs.len(), u32::MAX as usize) as u32; let mut nread = 0; let mut flags = 0; + // SAFETY: Untriaged. let result = unsafe { c::WSARecv( self.as_raw(), @@ -280,6 +297,7 @@ impl Socket { match result { 0 => Ok(nread as usize), _ => { + // SAFETY: Untriaged. let error = unsafe { c::WSAGetLastError() }; if error == c::WSAESHUTDOWN { @@ -307,12 +325,14 @@ impl Socket { buf: &mut [u8], flags: c_int, ) -> io::Result<(usize, SocketAddr)> { + // SAFETY: Untriaged. let mut storage = unsafe { mem::zeroed::() }; let mut addrlen = size_of_val(&storage) as netc::socklen_t; let length = cmp::min(buf.len(), ::MAX as usize) as wrlen_t; // On unix when a socket is shut down all further reads return 0, so we // do the same on windows to map a shut down socket to returning EOF. + // SAFETY: Untriaged. let result = unsafe { c::recvfrom( self.as_raw(), @@ -326,14 +346,17 @@ impl Socket { match result { c::SOCKET_ERROR => { + // SAFETY: Untriaged. let error = unsafe { c::WSAGetLastError() }; if error == c::WSAESHUTDOWN { + // SAFETY: Untriaged. Ok((0, unsafe { socket_addr_from_c(&storage, addrlen as usize)? })) } else { Err(io::Error::from_raw_os_error(error)) } } + // SAFETY: Untriaged. _ => Ok((result as usize, unsafe { socket_addr_from_c(&storage, addrlen as usize)? })), } } @@ -349,6 +372,7 @@ impl Socket { pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result { let length = cmp::min(bufs.len(), u32::MAX as usize) as u32; let mut nwritten = 0; + // SAFETY: Untriaged. let result = unsafe { c::WSASend( self.as_raw(), @@ -379,10 +403,12 @@ impl Socket { } None => 0, }; + // SAFETY: Untriaged. unsafe { setsockopt(self, c::SOL_SOCKET, kind, timeout) } } pub fn timeout(&self, kind: c_int) -> io::Result> { + // SAFETY: Untriaged. let raw: u32 = unsafe { getsockopt(self, c::SOL_SOCKET, kind)? }; if raw == 0 { Ok(None) @@ -399,6 +425,7 @@ impl Socket { Shutdown::Read => c::SD_RECEIVE, Shutdown::Both => c::SD_BOTH, }; + // SAFETY: Untriaged. let result = unsafe { c::shutdown(self.as_raw(), how) }; cvt(result).map(drop) } @@ -406,6 +433,7 @@ impl Socket { pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { let mut nonblocking = nonblocking as c_ulong; let result = +// SAFETY: Untriaged. unsafe { c::ioctlsocket(self.as_raw(), c::FIONBIO as c_int, &mut nonblocking) }; cvt(result).map(drop) } @@ -417,34 +445,41 @@ impl Socket { as c_ushort, }; + // SAFETY: Untriaged. unsafe { setsockopt(self, c::SOL_SOCKET, c::SO_LINGER, linger) } } pub fn linger(&self) -> io::Result> { + // SAFETY: Untriaged. let val: c::LINGER = unsafe { getsockopt(self, c::SOL_SOCKET, c::SO_LINGER)? }; Ok((val.l_onoff != 0).then(|| Duration::from_secs(val.l_linger as u64))) } pub fn set_keepalive(&self, keepalive: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(self, c::SOL_SOCKET, c::SO_KEEPALIVE, keepalive as c::BOOL) } } pub fn keepalive(&self) -> io::Result { + // SAFETY: Untriaged. let raw: c::BOOL = unsafe { getsockopt(self, c::SOL_SOCKET, c::SO_KEEPALIVE)? }; Ok(raw != 0) } pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { setsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY, nodelay as c::BOOL) } } pub fn nodelay(&self) -> io::Result { + // SAFETY: Untriaged. let raw: c::BOOL = unsafe { getsockopt(self, c::IPPROTO_TCP, c::TCP_NODELAY)? }; Ok(raw != 0) } pub fn take_error(&self) -> io::Result> { + // SAFETY: Untriaged. let raw: c_int = unsafe { getsockopt(self, c::SOL_SOCKET, c::SO_ERROR)? }; if raw == 0 { Ok(None) } else { Ok(Some(io::Error::from_raw_os_error(raw as i32))) } } @@ -457,6 +492,7 @@ impl Socket { pub unsafe fn from_raw(raw: c::SOCKET) -> Self { debug_assert_eq!(size_of::(), size_of::()); debug_assert_eq!(align_of::(), align_of::()); + // SAFETY: Untriaged. unsafe { Self::from_raw_socket(raw as RawSocket) } } } @@ -506,6 +542,7 @@ impl IntoRawSocket for Socket { impl FromRawSocket for Socket { unsafe fn from_raw_socket(raw_socket: RawSocket) -> Self { + // SAFETY: Untriaged. unsafe { Self(FromRawSocket::from_raw_socket(raw_socket)) } } } diff --git a/library/std/src/sys/net/connection/uefi/tcp.rs b/library/std/src/sys/net/connection/uefi/tcp.rs index 85962ce880d55..0363617d784dd 100644 --- a/library/std/src/sys/net/connection/uefi/tcp.rs +++ b/library/std/src/sys/net/connection/uefi/tcp.rs @@ -87,6 +87,7 @@ impl Tcp { Self::V4(client) => { let temp = client.get_mode_data()?; match NonNull::new(temp.control_option) { + // SAFETY: Untriaged. Some(x) => unsafe { Ok(x.as_ref().enable_nagle.into()) }, None => unsupported(), } diff --git a/library/std/src/sys/net/connection/uefi/tcp4.rs b/library/std/src/sys/net/connection/uefi/tcp4.rs index ac38dd901e4d3..a84f67a8966cd 100644 --- a/library/std/src/sys/net/connection/uefi/tcp4.rs +++ b/library/std/src/sys/net/connection/uefi/tcp4.rs @@ -67,6 +67,7 @@ impl Tcp4 { control_option: ptr::null_mut(), }; + // SAFETY: Untriaged. let r = unsafe { ((*protocol).configure)(protocol, &mut config_data) }; if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } @@ -75,6 +76,7 @@ impl Tcp4 { let mut config_data = tcp4::ConfigData::default(); let protocol = self.protocol.as_ptr(); + // SAFETY: Untriaged. let r = unsafe { ((*protocol).get_mode_data)( protocol, @@ -90,6 +92,7 @@ impl Tcp4 { } pub(crate) fn accept(&self) -> io::Result { + // SAFETY: Untriaged. let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -97,11 +100,13 @@ impl Tcp4 { tcp4::ListenToken { completion_token, new_child_handle: ptr::null_mut() }; let protocol = self.protocol.as_ptr(); + // SAFETY: Untriaged. let r = unsafe { ((*protocol).accept)(protocol, &mut listen_token) }; if r.is_error() { return Err(io::Error::from_raw_os_error(r.as_usize())); } + // SAFETY: Untriaged. unsafe { self.wait_or_cancel(None, &mut listen_token.completion_token) }?; if completion_token.status.is_error() { @@ -128,6 +133,7 @@ impl Tcp4 { } pub(crate) fn connect(&self, timeout: Option) -> io::Result<()> { + // SAFETY: Untriaged. let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -135,11 +141,13 @@ impl Tcp4 { let protocol = self.protocol.as_ptr(); let mut conn_token = tcp4::ConnectionToken { completion_token }; + // SAFETY: Untriaged. let r = unsafe { ((*protocol).connect)(protocol, &mut conn_token) }; if r.is_error() { return Err(io::Error::from_raw_os_error(r.as_usize())); } + // SAFETY: Untriaged. unsafe { self.wait_or_cancel(timeout, &mut conn_token.completion_token) }?; if completion_token.status.is_error() { @@ -196,6 +204,7 @@ impl Tcp4 { fragment_count, fragment_table: [], }); + // SAFETY: Untriaged. unsafe { // SAFETY: IoSlice and FragmentData are guaranteed to have same layout. crate::ptr::copy_nonoverlapping( @@ -213,6 +222,7 @@ impl Tcp4 { tx_data: *mut tcp4::TransmitData, timeout: Option, ) -> io::Result<()> { + // SAFETY: Untriaged. let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -220,11 +230,13 @@ impl Tcp4 { let protocol = self.protocol.as_ptr(); let mut token = tcp4::IoToken { completion_token, packet: tcp4::IoTokenPacket { tx_data } }; + // SAFETY: Untriaged. let r = unsafe { ((*protocol).transmit)(protocol, &mut token) }; if r.is_error() { return Err(io::Error::from_raw_os_error(r.as_usize())); } + // SAFETY: Untriaged. unsafe { self.wait_or_cancel(timeout, &mut token.completion_token) }?; if completion_token.status.is_error() { @@ -279,6 +291,7 @@ impl Tcp4 { fragment_count, fragment_table: [], }); + // SAFETY: Untriaged. unsafe { // SAFETY: IoSlice and FragmentData are guaranteed to have same layout. crate::ptr::copy_nonoverlapping( @@ -296,6 +309,7 @@ impl Tcp4 { rx_data: *mut tcp4::ReceiveData, timeout: Option, ) -> io::Result { + // SAFETY: Untriaged. let evt = unsafe { self.create_evt() }?; let completion_token = tcp4::CompletionToken { event: evt.as_ptr(), status: Status::SUCCESS }; @@ -303,16 +317,19 @@ impl Tcp4 { let protocol = self.protocol.as_ptr(); let mut token = tcp4::IoToken { completion_token, packet: tcp4::IoTokenPacket { rx_data } }; + // SAFETY: Untriaged. let r = unsafe { ((*protocol).receive)(protocol, &mut token) }; if r.is_error() { return Err(io::Error::from_raw_os_error(r.as_usize())); } + // SAFETY: Untriaged. unsafe { self.wait_or_cancel(timeout, &mut token.completion_token) }?; if completion_token.status.is_error() { Err(io::Error::from_raw_os_error(completion_token.status.as_usize())) } else { + // SAFETY: Untriaged. let data_length = unsafe { (*rx_data).data_length }; Ok(data_length as usize) } @@ -335,6 +352,7 @@ impl Tcp4 { token: *mut tcp4::CompletionToken, ) -> io::Result<()> { if !self.wait_for_flag(timeout) { + // SAFETY: Untriaged. let _ = unsafe { self.cancel(token) }; return Err(io::Error::new(io::ErrorKind::TimedOut, "Operation Timed out")); } @@ -354,6 +372,7 @@ impl Tcp4 { unsafe fn cancel(&self, token: *mut tcp4::CompletionToken) -> io::Result<()> { let protocol = self.protocol.as_ptr(); + // SAFETY: Untriaged. let r = unsafe { ((*protocol).cancel)(protocol, token) }; if r.is_error() { return Err(io::Error::from_raw_os_error(r.as_usize())); @@ -368,6 +387,7 @@ impl Tcp4 { efi::EVT_NOTIFY_SIGNAL, efi::TPL_CALLBACK, Some(toggle_atomic_flag), + // SAFETY: Untriaged. Some(unsafe { NonNull::new_unchecked(self.flag.as_ptr().cast()) }), ) } @@ -389,6 +409,7 @@ impl Tcp4 { fn poll(&self) -> io::Result<()> { let protocol = self.protocol.as_ptr(); + // SAFETY: Untriaged. let r = unsafe { ((*protocol).poll)(protocol) }; if r.is_error() { Err(io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } @@ -397,11 +418,13 @@ impl Tcp4 { impl Drop for Tcp4 { fn drop(&mut self) { + // SAFETY: Untriaged. let _ = unsafe { self.service_binding.destroy_child(self.handle) }; } } extern "efiapi" fn toggle_atomic_flag(_: r_efi::efi::Event, ctx: *mut crate::ffi::c_void) { + // SAFETY: Untriaged. let flag = unsafe { AtomicBool::from_ptr(ctx.cast()) }; flag.store(true, Ordering::Relaxed); } diff --git a/library/std/src/sys/net/connection/wasip1.rs b/library/std/src/sys/net/connection/wasip1.rs index d461ea85f9fea..0b47637f5a16f 100644 --- a/library/std/src/sys/net/connection/wasip1.rs +++ b/library/std/src/sys/net/connection/wasip1.rs @@ -54,6 +54,7 @@ impl IntoRawFd for Socket { impl FromRawFd for Socket { unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { + // SAFETY: Untriaged. unsafe { Self(FromRawFd::from_raw_fd(raw_fd)) } } } @@ -130,6 +131,7 @@ impl TcpStream { Shutdown::Both => wasip1::SDFLAGS_RD | wasip1::SDFLAGS_WR, }; + // SAFETY: Untriaged. unsafe { wasip1::sock_shutdown(self.socket().as_raw_fd() as _, wasi_how).map_err(err2io) } } @@ -174,6 +176,7 @@ impl TcpStream { } pub fn set_nonblocking(&self, state: bool) -> io::Result<()> { + // SAFETY: Untriaged. let fdstat = unsafe { wasip1::fd_fdstat_get(self.socket().as_inner().as_raw_fd() as wasip1::Fd) .map_err(err2io)? @@ -187,6 +190,7 @@ impl TcpStream { flags &= !wasip1::FDFLAGS_NONBLOCK; } + // SAFETY: Untriaged. unsafe { wasip1::fd_fdstat_set_flags(self.socket().as_inner().as_raw_fd() as wasip1::Fd, flags) .map_err(err2io) @@ -229,11 +233,13 @@ impl TcpListener { } pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> { + // SAFETY: Untriaged. let fd = unsafe { wasip1::sock_accept(self.as_inner().as_inner().as_raw_fd() as _, 0).map_err(err2io)? }; Ok(( + // SAFETY: Untriaged. TcpStream::from_inner(unsafe { Socket::from_raw_fd(fd as _) }), // WASI has no concept of SocketAddr yet // return an unspecified IPv4Addr @@ -266,6 +272,7 @@ impl TcpListener { } pub fn set_nonblocking(&self, state: bool) -> io::Result<()> { + // SAFETY: Untriaged. let fdstat = unsafe { wasip1::fd_fdstat_get(self.socket().as_inner().as_raw_fd() as wasip1::Fd) .map_err(err2io)? @@ -279,6 +286,7 @@ impl TcpListener { flags &= !wasip1::FDFLAGS_NONBLOCK; } + // SAFETY: Untriaged. unsafe { wasip1::fd_fdstat_set_flags(self.socket().as_inner().as_raw_fd() as wasip1::Fd, flags) .map_err(err2io) diff --git a/library/std/src/sys/net/hostname/unix.rs b/library/std/src/sys/net/hostname/unix.rs index d444182f3fde6..f3b199de2d4f3 100644 --- a/library/std/src/sys/net/hostname/unix.rs +++ b/library/std/src/sys/net/hostname/unix.rs @@ -5,6 +5,7 @@ use crate::sys::io::errno; pub fn hostname() -> io::Result { // Query the system for the maximum host name length. + // SAFETY: Untriaged. let host_name_max = match unsafe { libc::sysconf(libc::_SC_HOST_NAME_MAX) } { // If this fails (possibly because there is no maximum length), then // assume a maximum length of _POSIX_HOST_NAME_MAX (255). diff --git a/library/std/src/sys/os_str/bytes.rs b/library/std/src/sys/os_str/bytes.rs index a57da01a5d85d..a2a95f4646dd3 100644 --- a/library/std/src/sys/os_str/bytes.rs +++ b/library/std/src/sys/os_str/bytes.rs @@ -174,16 +174,19 @@ impl Buf { #[inline] pub fn leak<'a>(self) -> &'a mut Slice { + // SAFETY: Untriaged. unsafe { mem::transmute(self.inner.leak()) } } #[inline] pub fn into_box(self) -> Box { + // SAFETY: Untriaged. unsafe { mem::transmute(self.inner.into_boxed_slice()) } } #[inline] pub fn from_box(boxed: Box) -> Buf { + // SAFETY: Untriaged. let inner: Box<[u8]> = unsafe { mem::transmute(boxed) }; Buf { inner: inner.into_vec() } } @@ -232,6 +235,7 @@ impl Slice { #[inline] pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice { + // SAFETY: Untriaged. unsafe { mem::transmute(s) } } @@ -288,6 +292,7 @@ impl Slice { #[inline] pub fn from_str(s: &str) -> &Slice { + // SAFETY: Untriaged. unsafe { Slice::from_encoded_bytes_unchecked(s.as_bytes()) } } @@ -314,18 +319,21 @@ impl Slice { #[inline] pub fn empty_box() -> Box { let boxed: Box<[u8]> = Default::default(); + // SAFETY: Untriaged. unsafe { mem::transmute(boxed) } } #[inline] pub fn into_arc(&self) -> Arc { let arc: Arc<[u8]> = Arc::from(&self.inner); + // SAFETY: Untriaged. unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) } } #[inline] pub fn into_rc(&self) -> Rc { let rc: Rc<[u8]> = Rc::from(&self.inner); + // SAFETY: Untriaged. unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) } } diff --git a/library/std/src/sys/os_str/utf8.rs b/library/std/src/sys/os_str/utf8.rs index 289f58aa480f7..ccdca4471e71e 100644 --- a/library/std/src/sys/os_str/utf8.rs +++ b/library/std/src/sys/os_str/utf8.rs @@ -83,6 +83,7 @@ impl Buf { #[inline] pub unsafe fn from_encoded_bytes_unchecked(s: Vec) -> Self { + // SAFETY: Untriaged. unsafe { Self { inner: String::from_utf8_unchecked(s) } } } @@ -168,11 +169,13 @@ impl Buf { #[inline] pub fn into_box(self) -> Box { + // SAFETY: Untriaged. unsafe { mem::transmute(self.inner.into_boxed_str()) } } #[inline] pub fn from_box(boxed: Box) -> Buf { + // SAFETY: Untriaged. let inner: Box = unsafe { mem::transmute(boxed) }; Buf { inner: inner.into_string() } } @@ -209,6 +212,7 @@ impl Buf { /// `other` must be valid UTF-8. #[inline] pub unsafe fn extend_from_slice_unchecked(&mut self, other: &[u8]) { + // SAFETY: Untriaged. self.inner.push_str(unsafe { str::from_utf8_unchecked(other) }); } } @@ -221,6 +225,7 @@ impl Slice { #[inline] pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice { + // SAFETY: Untriaged. Slice::from_str(unsafe { str::from_utf8_unchecked(s) }) } @@ -273,24 +278,28 @@ impl Slice { #[inline] pub fn into_box(&self) -> Box { let boxed: Box = self.inner.into(); + // SAFETY: Untriaged. unsafe { mem::transmute(boxed) } } #[inline] pub fn empty_box() -> Box { let boxed: Box = Default::default(); + // SAFETY: Untriaged. unsafe { mem::transmute(boxed) } } #[inline] pub fn into_arc(&self) -> Arc { let arc: Arc = Arc::from(&self.inner); + // SAFETY: Untriaged. unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) } } #[inline] pub fn into_rc(&self) -> Rc { let rc: Rc = Rc::from(&self.inner); + // SAFETY: Untriaged. unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) } } diff --git a/library/std/src/sys/os_str/wtf8.rs b/library/std/src/sys/os_str/wtf8.rs index 9a32ab3f3ea12..17bea6c48c2e0 100644 --- a/library/std/src/sys/os_str/wtf8.rs +++ b/library/std/src/sys/os_str/wtf8.rs @@ -85,6 +85,7 @@ impl Buf { #[inline] pub unsafe fn from_encoded_bytes_unchecked(s: Vec) -> Self { + // SAFETY: Untriaged. unsafe { Self { inner: Wtf8Buf::from_bytes_unchecked(s) } } } @@ -173,16 +174,19 @@ impl Buf { #[inline] pub fn leak<'a>(self) -> &'a mut Slice { + // SAFETY: Untriaged. unsafe { mem::transmute(self.inner.leak()) } } #[inline] pub fn into_box(self) -> Box { + // SAFETY: Untriaged. unsafe { mem::transmute(self.inner.into_box()) } } #[inline] pub fn from_box(boxed: Box) -> Buf { + // SAFETY: Untriaged. let inner: Box = unsafe { mem::transmute(boxed) }; Buf { inner: Wtf8Buf::from_box(inner) } } @@ -223,6 +227,7 @@ impl Buf { /// must not start with a trailing surrogate half. #[inline] pub unsafe fn extend_from_slice_unchecked(&mut self, other: &[u8]) { + // SAFETY: Untriaged. unsafe { self.inner.extend_from_slice_unchecked(other); } @@ -237,6 +242,7 @@ impl Slice { #[inline] pub unsafe fn from_encoded_bytes_unchecked(s: &[u8]) -> &Slice { + // SAFETY: Untriaged. unsafe { mem::transmute(Wtf8::from_bytes_unchecked(s)) } } @@ -253,6 +259,7 @@ impl Slice { #[inline] pub fn from_str(s: &str) -> &Slice { + // SAFETY: Untriaged. unsafe { mem::transmute(Wtf8::from_str(s)) } } @@ -278,18 +285,21 @@ impl Slice { #[inline] pub fn empty_box() -> Box { + // SAFETY: Untriaged. unsafe { mem::transmute(Wtf8::empty_box()) } } #[inline] pub fn into_arc(&self) -> Arc { let arc = self.inner.into_arc(); + // SAFETY: Untriaged. unsafe { Arc::from_raw(Arc::into_raw(arc) as *const Slice) } } #[inline] pub fn into_rc(&self) -> Rc { let rc = self.inner.into_rc(); + // SAFETY: Untriaged. unsafe { Rc::from_raw(Rc::into_raw(rc) as *const Slice) } } diff --git a/library/std/src/sys/pal/hermit/mod.rs b/library/std/src/sys/pal/hermit/mod.rs index e8c9bf70b99df..abab8ddaf67d1 100644 --- a/library/std/src/sys/pal/hermit/mod.rs +++ b/library/std/src/sys/pal/hermit/mod.rs @@ -33,12 +33,14 @@ pub fn unsupported_err() -> io::Error { } pub fn abort_internal() -> ! { + // SAFETY: Untriaged. unsafe { hermit_abi::abort() } } // SAFETY: must be called only once during runtime initialization. // NOTE: this is not guaranteed to run, for example when Rust code is called externally. pub unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) { + // SAFETY: Untriaged. unsafe { crate::sys::args::init(argc, argv); } @@ -62,13 +64,16 @@ pub unsafe extern "C" fn runtime_entry( // initialize environment env::init(env); + // SAFETY: Untriaged. let result = unsafe { main(argc as isize, argv) }; + // SAFETY: Untriaged. unsafe { crate::sys::thread_local::destructors::run(); } crate::rt::thread_cleanup(); + // SAFETY: Untriaged. unsafe { hermit_abi::exit(result); } diff --git a/library/std/src/sys/pal/itron/spin.rs b/library/std/src/sys/pal/itron/spin.rs index bc4f83260bbd0..a000600f73bc8 100644 --- a/library/std/src/sys/pal/itron/spin.rs +++ b/library/std/src/sys/pal/itron/spin.rs @@ -25,12 +25,15 @@ impl SpinMutex { #[inline] fn drop(&mut self) { self.0.store(false, Ordering::Release); + // SAFETY: Untriaged. unsafe { abi::ena_dsp() }; } } let _guard; + // SAFETY: Untriaged. if unsafe { abi::sns_dsp() } == 0 { + // SAFETY: Untriaged. let er = unsafe { abi::dis_dsp() }; debug_assert!(er >= 0); @@ -40,6 +43,7 @@ impl SpinMutex { _guard = SpinMutexGuard(&self.locked); } + // SAFETY: Untriaged. f(unsafe { &mut *self.data.get() }) } } @@ -71,6 +75,7 @@ impl SpinIdOnceCell { pub fn get(&self) -> Option<(abi::ID, &T)> { match self.id.load(Ordering::Acquire) { ID_UNINIT => None, + // SAFETY: Untriaged. id => Some((id as abi::ID, unsafe { (&*self.extra.get()).assume_init_ref() })), } } @@ -79,12 +84,14 @@ impl SpinIdOnceCell { pub fn get_mut(&mut self) -> Option<(abi::ID, &mut T)> { match *self.id.get_mut() { ID_UNINIT => None, + // SAFETY: Untriaged. id => Some((id as abi::ID, unsafe { (&mut *self.extra.get()).assume_init_mut() })), } } #[inline] pub unsafe fn get_unchecked(&self) -> (abi::ID, &T) { + // SAFETY: Untriaged. (self.id.load(Ordering::Acquire) as abi::ID, unsafe { (&*self.extra.get()).assume_init_ref() }) @@ -100,6 +107,7 @@ impl SpinIdOnceCell { debug_assert!(usize::try_from(id).is_ok()); let id = id as usize; + // SAFETY: Untriaged. unsafe { *self.extra.get() = MaybeUninit::new(extra) }; self.id.store(id, Ordering::Release); } @@ -125,6 +133,7 @@ impl SpinIdOnceCell { debug_assert!(self.get().is_some()); // Safety: The inner value has been initialized + // SAFETY: Untriaged. Ok(unsafe { self.get_unchecked() }) } @@ -143,6 +152,7 @@ impl SpinIdOnceCell { // Store the initialized contents. Use the release ordering to // make sure the write is visible to the callers of `get`. + // SAFETY: Untriaged. unsafe { *self.extra.get() = MaybeUninit::new(initialized_extra) }; self.id.store(initialized_id, Ordering::Release); } @@ -155,6 +165,7 @@ impl Drop for SpinIdOnceCell { #[inline] fn drop(&mut self) { if self.get_mut().is_some() { + // SAFETY: Untriaged. unsafe { (&mut *self.extra.get()).assume_init_drop() }; } } diff --git a/library/std/src/sys/pal/itron/task.rs b/library/std/src/sys/pal/itron/task.rs index 49c420baca2f3..c26c573379b27 100644 --- a/library/std/src/sys/pal/itron/task.rs +++ b/library/std/src/sys/pal/itron/task.rs @@ -17,6 +17,7 @@ pub fn current_task_id_aborting() -> abi::ID { /// Gets the ID of the task in Running state. #[inline] pub fn try_current_task_id() -> Result { + // SAFETY: Untriaged. unsafe { let mut out = MaybeUninit::uninit(); ItronError::err_if_negative(abi::get_tid(out.as_mut_ptr()))?; @@ -33,6 +34,7 @@ pub fn task_priority(task: abi::ID) -> abi::PRI { /// Gets the specified task's priority. #[inline] pub fn try_task_priority(task: abi::ID) -> Result { + // SAFETY: Untriaged. unsafe { let mut out = MaybeUninit::uninit(); ItronError::err_if_negative(abi::get_pri(task, out.as_mut_ptr()))?; diff --git a/library/std/src/sys/pal/itron/thread_parking.rs b/library/std/src/sys/pal/itron/thread_parking.rs index fe9934439d152..8bd994abb0177 100644 --- a/library/std/src/sys/pal/itron/thread_parking.rs +++ b/library/std/src/sys/pal/itron/thread_parking.rs @@ -8,6 +8,7 @@ pub type ThreadId = abi::ID; pub use super::task::current_task_id_aborting as current; pub fn park(_hint: usize) { + // SAFETY: Untriaged. match unsafe { abi::slp_tsk() } { abi::E_OK | abi::E_RLWAI => {} err => { @@ -17,6 +18,7 @@ pub fn park(_hint: usize) { } pub fn park_timeout(dur: Duration, _hint: usize) { + // SAFETY: Untriaged. match with_tmos(dur, |tmo| unsafe { abi::tslp_tsk(tmo) }) { abi::E_OK | abi::E_RLWAI | abi::E_TMOUT => {} err => { @@ -26,6 +28,7 @@ pub fn park_timeout(dur: Duration, _hint: usize) { } pub fn unpark(id: ThreadId, _hint: usize) { + // SAFETY: Untriaged. match unsafe { abi::wup_tsk(id) } { // It is allowed to try to wake up a destroyed or unrelated task, so we ignore all // errors that could result from that situation. diff --git a/library/std/src/sys/pal/itron/time.rs b/library/std/src/sys/pal/itron/time.rs index ff3cffd2069e9..e5e829132073b 100644 --- a/library/std/src/sys/pal/itron/time.rs +++ b/library/std/src/sys/pal/itron/time.rs @@ -9,6 +9,7 @@ mod tests; #[inline] pub fn get_tim() -> abi::SYSTIM { // Safety: The provided pointer is valid + // SAFETY: Untriaged. unsafe { let mut out = MaybeUninit::uninit(); expect_success(abi::get_tim(out.as_mut_ptr()), &"get_tim"); diff --git a/library/std/src/sys/pal/motor/mod.rs b/library/std/src/sys/pal/motor/mod.rs index 5bf217db9013a..0bee90ce0ffc0 100644 --- a/library/std/src/sys/pal/motor/mod.rs +++ b/library/std/src/sys/pal/motor/mod.rs @@ -17,6 +17,7 @@ pub extern "C" fn motor_start() -> ! { unsafe extern "C" { fn main(_: isize, _: *const *const u8, _: u8) -> i32; } + // SAFETY: Untriaged. let result = unsafe { main(0, core::ptr::null(), 0) }; // Terminate the process. diff --git a/library/std/src/sys/pal/sgx/abi/mem.rs b/library/std/src/sys/pal/sgx/abi/mem.rs index e6ce15bed3cfd..57099bb739fe6 100644 --- a/library/std/src/sys/pal/sgx/abi/mem.rs +++ b/library/std/src/sys/pal/sgx/abi/mem.rs @@ -20,11 +20,13 @@ unsafe extern "C" { /// Returns the base memory address of the heap pub(crate) fn heap_base() -> *const u8 { + // SAFETY: Untriaged. unsafe { rel_ptr_mut(HEAP_BASE) } } /// Returns the size of the heap pub(crate) fn heap_size() -> usize { + // SAFETY: Untriaged. unsafe { HEAP_SIZE } } @@ -36,6 +38,7 @@ pub(crate) fn heap_size() -> usize { #[unstable(feature = "sgx_platform", issue = "56975")] pub fn image_base() -> u64 { let base: u64; + // SAFETY: Untriaged. unsafe { asm!( "lea IMAGE_BASE(%rip), {}", @@ -66,6 +69,7 @@ pub fn is_enclave_range(p: *const u8, len: usize) -> bool { }; let base = image_base() as usize; + // SAFETY: Untriaged. start >= base && end <= base + (unsafe { ENCLAVE_SIZE } - 1) // unsafe ok: link-time constant } @@ -89,5 +93,6 @@ pub fn is_user_range(p: *const u8, len: usize) -> bool { }; let base = image_base() as usize; + // SAFETY: Untriaged. end < base || start > base + (unsafe { ENCLAVE_SIZE } - 1) // unsafe ok: link-time constant } diff --git a/library/std/src/sys/pal/sgx/abi/mod.rs b/library/std/src/sys/pal/sgx/abi/mod.rs index 3314f4f3b6223..3e5c10fc81441 100644 --- a/library/std/src/sys/pal/sgx/abi/mod.rs +++ b/library/std/src/sys/pal/sgx/abi/mod.rs @@ -67,6 +67,7 @@ extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64 // We use the System allocator here such that the global allocator may use // thread-locals. let tls = Box::new_in(tls::Tls::new(), System); + // SAFETY: Untriaged. let tls_guard = unsafe { tls.activate() }; if secondary { @@ -85,6 +86,7 @@ extern "C" fn entry(p1: u64, p2: u64, p3: u64, secondary: bool, p4: u64, p5: u64 rtassert!(p4 == 0); rtassert!(p5 == 0); + // SAFETY: Untriaged. unsafe { // The actual types of these arguments are `p1: *const Arg, p2: // usize`. We can't currently customize the argument list of Rust's diff --git a/library/std/src/sys/pal/sgx/abi/panic.rs b/library/std/src/sys/pal/sgx/abi/panic.rs index 67af062b0fffe..4db4e445a17b3 100644 --- a/library/std/src/sys/pal/sgx/abi/panic.rs +++ b/library/std/src/sys/pal/sgx/abi/panic.rs @@ -10,15 +10,18 @@ unsafe extern "C" { pub(crate) struct SgxPanicOutput(Option<&'static mut UserRef<[u8]>>); fn empty_user_slice() -> &'static mut UserRef<[u8]> { + // SAFETY: Untriaged. unsafe { UserRef::from_raw_parts_mut(1 as *mut u8, 0) } } impl SgxPanicOutput { pub(crate) fn new() -> Option { + // SAFETY: Untriaged. if unsafe { DEBUG == 0 } { None } else { Some(SgxPanicOutput(None)) } } fn init(&mut self) -> &mut &'static mut UserRef<[u8]> { + // SAFETY: Untriaged. self.0.get_or_insert_with(|| unsafe { let ptr = take_debug_panic_buf_ptr(); if ptr.is_null() { empty_user_slice() } else { UserRef::from_raw_parts_mut(ptr, 1024) } diff --git a/library/std/src/sys/pal/sgx/abi/reloc.rs b/library/std/src/sys/pal/sgx/abi/reloc.rs index a4f5e4a0936f4..78c26e6e9f2f4 100644 --- a/library/std/src/sys/pal/sgx/abi/reloc.rs +++ b/library/std/src/sys/pal/sgx/abi/reloc.rs @@ -16,10 +16,12 @@ pub fn relocate_elf_rela() { static RELACOUNT: usize; } + // SAFETY: Untriaged. if unsafe { RELACOUNT } == 0 { return; } // unsafe ok: link-time constant + // SAFETY: Untriaged. let relas = unsafe { from_raw_parts::>(mem::rel_ptr(RELA), RELACOUNT) // unsafe ok: link-time constant }; @@ -27,6 +29,7 @@ pub fn relocate_elf_rela() { if rela.info != (/*0 << 32 |*/R_X86_64_RELATIVE as u64) { rtabort!("Invalid relocation"); } + // SAFETY: Untriaged. unsafe { *mem::rel_ptr_mut::<*const ()>(rela.offset) = mem::rel_ptr(rela.addend) }; } } diff --git a/library/std/src/sys/pal/sgx/abi/thread.rs b/library/std/src/sys/pal/sgx/abi/thread.rs index 9b37e2baf3642..7b819f7a18f93 100644 --- a/library/std/src/sys/pal/sgx/abi/thread.rs +++ b/library/std/src/sys/pal/sgx/abi/thread.rs @@ -9,6 +9,7 @@ pub fn current() -> Tcs { unsafe extern "C" { fn get_tcs_addr() -> *mut u8; } + // SAFETY: Untriaged. let addr = unsafe { get_tcs_addr() }; match Tcs::new(addr) { Some(tcs) => tcs, diff --git a/library/std/src/sys/pal/sgx/abi/tls/mod.rs b/library/std/src/sys/pal/sgx/abi/tls/mod.rs index 553814dcb5fda..4e0a06d4e81f7 100644 --- a/library/std/src/sys/pal/sgx/abi/tls/mod.rs +++ b/library/std/src/sys/pal/sgx/abi/tls/mod.rs @@ -60,6 +60,7 @@ impl<'a> Drop for ActiveTls<'a> { fn drop(&mut self) { let value_with_destructor = |key: usize| { let ptr = TLS_DESTRUCTOR[key].load(Ordering::Relaxed); + // SAFETY: Untriaged. unsafe { mem::transmute::<_, Option>(ptr) } .map(|dtor| (&self.tls.data[key], dtor)) }; @@ -71,6 +72,7 @@ impl<'a> Drop for ActiveTls<'a> { let value = value.replace(ptr::null_mut()); if !value.is_null() { any_non_null_dtor = true; + // SAFETY: Untriaged. unsafe { dtor(value) } } } @@ -85,12 +87,14 @@ impl Tls { pub unsafe fn activate(&self) -> ActiveTls<'_> { // FIXME: Needs safety information. See entry.S for `set_tls_ptr` definition. + // SAFETY: Untriaged. unsafe { set_tls_ptr(self as *const Tls as _) }; ActiveTls { tls: self } } unsafe fn current<'a>() -> &'a Tls { // FIXME: Needs safety information. See entry.S for `set_tls_ptr` definition. + // SAFETY: Untriaged. unsafe { &*(get_tls_ptr() as *const Tls) } } @@ -101,6 +105,7 @@ impl Tls { rtabort!("TLS limit exceeded") }; TLS_DESTRUCTOR[index].store(dtor.map_or(0, |f| f as usize), Ordering::Relaxed); + // SAFETY: Untriaged. unsafe { Self::current() }.data[index].set(ptr::null_mut()); Key::from_index(index) } @@ -108,12 +113,14 @@ impl Tls { pub fn set(key: Key, value: *mut u8) { let index = key.to_index(); rtassert!(TLS_KEY_IN_USE.get(index)); + // SAFETY: Untriaged. unsafe { Self::current() }.data[index].set(value); } pub fn get(key: Key) -> *mut u8 { let index = key.to_index(); rtassert!(TLS_KEY_IN_USE.get(index)); + // SAFETY: Untriaged. unsafe { Self::current() }.data[index].get() } diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs index f4115ca6124a7..d94f2d2ba5085 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs @@ -95,6 +95,7 @@ pub unsafe trait UserSafe { assert!(ptr.wrapping_add(size) >= ptr); // SAFETY: The caller has guaranteed the pointer is valid let ret = unsafe { Self::from_raw_sized_unchecked(ptr, size) }; + // SAFETY: Untriaged. unsafe { Self::check_ptr(ret); NonNull::new_unchecked(ret as _) @@ -119,6 +120,7 @@ pub unsafe trait UserSafe { let is_aligned = |p: *const u8| -> bool { p.is_aligned_to(Self::align_of()) }; assert!(is_aligned(ptr as *const u8)); + // SAFETY: Untriaged. assert!(is_user_range(ptr as _, size_of_val(unsafe { &*ptr }))); assert!(!ptr.is_null()); } @@ -250,6 +252,7 @@ where // optimizing compiler. This is achieved by returning a pointer from // from outside as obtained by `super::alloc`. fn new_uninit_bytes(size: usize) -> Self { + // SAFETY: Untriaged. unsafe { // Mustn't call alloc with size 0. let ptr = if size > 0 { @@ -269,6 +272,7 @@ where /// Copies `val` into freshly allocated space in user memory. pub fn new_from_enclave(val: &T) -> Self { + // SAFETY: Untriaged. unsafe { let mut user = Self::new_uninit_bytes(size_of_val(val)); user.copy_from_enclave(val); @@ -291,6 +295,7 @@ where pub unsafe fn from_raw(ptr: *mut T) -> Self { // SAFETY: the caller must uphold the safety contract for `from_raw`. unsafe { T::check_ptr(ptr) }; + // SAFETY: Untriaged. User(unsafe { NonNull::new_userref(ptr) }) } @@ -337,6 +342,7 @@ where /// * The pointed-to range does not fit in the address space /// * The pointed-to range is not in user memory pub unsafe fn from_raw_parts(ptr: *mut T, len: usize) -> Self { + // SAFETY: Untriaged. User(unsafe { NonNull::new_userref(<[T]>::from_raw_sized(ptr as _, len * size_of::())) }) } } @@ -373,6 +379,7 @@ fn u64_align_to_guaranteed(ptr: *const u8, mut len: usize) -> (usize, usize, usi } unsafe fn copy_quadwords(src: *const u8, dst: *mut u8, len: usize) { + // SAFETY: Untriaged. unsafe { asm!( "rep movsq (%rsi), (%rdi)", @@ -409,6 +416,7 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize) return; } + // SAFETY: Untriaged. unsafe { let mut seg_sel: u16 = 0; for off in 0..len { @@ -436,6 +444,7 @@ pub(crate) unsafe fn copy_to_userspace(src: *const u8, dst: *mut u8, len: usize) assert!(!src.addr().overflowing_add(len).1); assert!(!dst.addr().overflowing_add(len).1); + // SAFETY: Untriaged. unsafe { let (len1, len2, len3) = u64_align_to_guaranteed(dst, len); let (src1, dst1) = (src, dst); @@ -473,6 +482,7 @@ pub(crate) unsafe fn copy_from_userspace(src: *const u8, dst: *mut u8, len: usiz return; } + // SAFETY: Untriaged. unsafe { let offset: usize; let data: u64; @@ -502,6 +512,7 @@ pub(crate) unsafe fn copy_from_userspace(src: *const u8, dst: *mut u8, len: usiz assert!(!(src as usize).overflowing_add(len).1); assert!(!(dst as usize).overflowing_add(len).1); + // SAFETY: Untriaged. unsafe { let (len1, len2, len3) = u64_align_to_guaranteed(src, len); let (src1, dst1) = (src, dst); @@ -533,6 +544,7 @@ where pub unsafe fn from_ptr<'a>(ptr: *const T) -> &'a Self { // SAFETY: The caller must uphold the safety contract for `from_ptr`. unsafe { T::check_ptr(ptr) }; + // SAFETY: Untriaged. unsafe { &*(ptr as *const Self) } } @@ -551,6 +563,7 @@ where pub unsafe fn from_mut_ptr<'a>(ptr: *mut T) -> &'a mut Self { // SAFETY: The caller must uphold the safety contract for `from_mut_ptr`. unsafe { T::check_ptr(ptr) }; + // SAFETY: Untriaged. unsafe { &mut *(ptr as *mut Self) } } @@ -560,6 +573,7 @@ where /// This function panics if the destination doesn't have the same size as /// the source. This can happen for dynamically-sized types such as slices. pub fn copy_from_enclave(&mut self, val: &T) { + // SAFETY: Untriaged. unsafe { assert_eq!(size_of_val(val), size_of_val(&*self.0.get())); copy_to_userspace( @@ -576,6 +590,7 @@ where /// This function panics if the destination doesn't have the same size as /// the source. This can happen for dynamically-sized types such as slices. pub fn copy_to_enclave>(&self, dest: &mut U) { + // SAFETY: Untriaged. unsafe { assert_eq!(size_of_val(dest), size_of_val(&*self.0.get())); copy_from_userspace( @@ -604,6 +619,7 @@ where { /// Copies the value from user memory into enclave memory. pub fn to_enclave(&self) -> T { + // SAFETY: Untriaged. unsafe { let mut data = mem::MaybeUninit::uninit(); copy_from_userspace(self.0.get() as _, data.as_mut_ptr() as _, size_of::()); @@ -667,6 +683,7 @@ where /// Obtain the number of elements in this user slice. pub fn len(&self) -> usize { + // SAFETY: Untriaged. unsafe { self.0.get().len() } } @@ -690,6 +707,7 @@ where where T: UserSafe, // FIXME: should be implied by [T]: UserSafe? { + // SAFETY: Untriaged. unsafe { Iter((&*self.as_raw_ptr()).iter()) } } @@ -698,6 +716,7 @@ where where T: UserSafe, // FIXME: should be implied by [T]: UserSafe? { + // SAFETY: Untriaged. unsafe { IterMut((&mut *self.as_raw_mut_ptr()).iter_mut()) } } } @@ -714,6 +733,7 @@ impl<'a, T: UserSafe> Iterator for Iter<'a, T> { #[inline] fn next(&mut self) -> Option { + // SAFETY: Untriaged. unsafe { self.0.next().map(|e| UserRef::from_ptr(e)) } } } @@ -730,6 +750,7 @@ impl<'a, T: UserSafe> Iterator for IterMut<'a, T> { #[inline] fn next(&mut self) -> Option { + // SAFETY: Untriaged. unsafe { self.0.next().map(|e| UserRef::from_mut_ptr(e)) } } } @@ -742,6 +763,7 @@ where type Target = UserRef; fn deref(&self) -> &Self::Target { + // SAFETY: Untriaged. unsafe { &*self.0.as_ptr() } } } @@ -752,6 +774,7 @@ where T: UserSafe, { fn deref_mut(&mut self) -> &mut Self::Target { + // SAFETY: Untriaged. unsafe { &mut *self.0.as_ptr() } } } @@ -762,6 +785,7 @@ where T: UserSafe, { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { let ptr = (*self.0.as_ptr()).0.get(); super::free(ptr as _, size_of_val(&mut *ptr), T::align_of()); @@ -783,6 +807,7 @@ where #[inline] fn index(&self, index: I) -> &UserRef { + // SAFETY: Untriaged. unsafe { if let Some(slice) = index.get(&*self.as_raw_ptr()) { UserRef::from_ptr(slice) @@ -802,6 +827,7 @@ where { #[inline] fn index_mut(&mut self, index: I) -> &mut UserRef { + // SAFETY: Untriaged. unsafe { if let Some(slice) = index.get_mut(&mut *self.as_raw_mut_ptr()) { UserRef::from_mut_ptr(slice) @@ -824,6 +850,7 @@ impl UserRef { /// * The pointed-to range does not fit in the address space /// * The pointed-to range is not in user memory pub fn copy_user_buffer(&self) -> Vec { + // SAFETY: Untriaged. unsafe { let buf = self.to_enclave(); if buf.len > 0 { diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs index 2378028ccab92..87b8dd2c2859b 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/mod.rs @@ -17,6 +17,7 @@ use self::raw::*; /// `bufs`. To read to a single buffer, just pass a slice of length one. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn read(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> io::Result { + // SAFETY: Untriaged. unsafe { let total_len = bufs.iter().fold(0usize, |sum, buf| sum.saturating_add(buf.len())); let mut userbuf = alloc::User::<[u8]>::uninitialized(total_len); @@ -40,6 +41,7 @@ pub fn read(fd: Fd, bufs: &mut [IoSliceMut<'_>]) -> io::Result { /// more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn read_buf(fd: Fd, mut buf: BorrowedCursor<'_, u8>) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { let mut userbuf = alloc::User::<[u8]>::uninitialized(buf.capacity()); let len = raw::read(fd, userbuf.as_mut_ptr().cast(), userbuf.len()).from_sgx_result()?; @@ -52,6 +54,7 @@ pub fn read_buf(fd: Fd, mut buf: BorrowedCursor<'_, u8>) -> io::Result<()> { /// Usercall `read_alloc`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn read_alloc(fd: Fd) -> io::Result> { + // SAFETY: Untriaged. unsafe { let userbuf = ByteBuffer { data: crate::ptr::null_mut(), len: 0 }; let mut userbuf = alloc::User::new_from_enclave(&userbuf); @@ -66,6 +69,7 @@ pub fn read_alloc(fd: Fd) -> io::Result> { /// `bufs`. To write from a single buffer, just pass a slice of length one. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn write(fd: Fd, bufs: &[IoSlice<'_>]) -> io::Result { + // SAFETY: Untriaged. unsafe { let total_len = bufs.iter().fold(0usize, |sum, buf| sum.saturating_add(buf.len())); let mut userbuf = alloc::User::<[u8]>::uninitialized(total_len); @@ -86,12 +90,14 @@ pub fn write(fd: Fd, bufs: &[IoSlice<'_>]) -> io::Result { /// Usercall `flush`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn flush(fd: Fd) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { raw::flush(fd).from_sgx_result() } } /// Usercall `close`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn close(fd: Fd) { + // SAFETY: Untriaged. unsafe { raw::close(fd) } } @@ -103,6 +109,7 @@ fn string_from_bytebuffer(buf: &alloc::UserRef, usercall: &str, arg: /// Usercall `bind_stream`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn bind_stream(addr: &str) -> io::Result<(Fd, String)> { + // SAFETY: Untriaged. unsafe { let addr_user = alloc::User::new_from_enclave(addr.as_bytes()); let mut local = alloc::User::::uninitialized(); @@ -116,6 +123,7 @@ pub fn bind_stream(addr: &str) -> io::Result<(Fd, String)> { /// Usercall `accept_stream`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn accept_stream(fd: Fd) -> io::Result<(Fd, String, String)> { + // SAFETY: Untriaged. unsafe { let mut bufs = alloc::User::<[ByteBuffer; 2]>::uninitialized(); let mut buf_it = alloc::UserRef::iter_mut(&mut *bufs); // FIXME: can this be done @@ -132,6 +140,7 @@ pub fn accept_stream(fd: Fd) -> io::Result<(Fd, String, String)> { /// Usercall `connect_stream`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn connect_stream(addr: &str) -> io::Result<(Fd, String, String)> { + // SAFETY: Untriaged. unsafe { let addr_user = alloc::User::new_from_enclave(addr.as_bytes()); let mut bufs = alloc::User::<[ByteBuffer; 2]>::uninitialized(); @@ -161,6 +170,7 @@ pub unsafe fn launch_thread() -> io::Result<()> { /// Usercall `exit`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn exit(panic: bool) -> ! { + // SAFETY: Untriaged. unsafe { raw::exit(panic) } } @@ -181,6 +191,7 @@ pub fn wait(event_mask: u64, mut timeout: u64) -> io::Result { timeout = timeout_signed.saturating_add(deviation) as _; } } + // SAFETY: Untriaged. unsafe { raw::wait(event_mask, timeout).from_sgx_result() } } @@ -261,12 +272,14 @@ where /// Usercall `send`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn send(event_set: u64, tcs: Option) -> io::Result<()> { + // SAFETY: Untriaged. unsafe { raw::send(event_set, tcs).from_sgx_result() } } /// Usercall `insecure_time`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn insecure_time() -> Duration { + // SAFETY: Untriaged. let t = unsafe { raw::insecure_time().0 }; Duration::new(t / 1_000_000_000, (t % 1_000_000_000) as _) } @@ -274,6 +287,7 @@ pub fn insecure_time() -> Duration { /// Usercall `alloc`. See the ABI documentation for more information. #[unstable(feature = "sgx_platform", issue = "56975")] pub fn alloc(size: usize, alignment: usize) -> io::Result<*mut u8> { + // SAFETY: Untriaged. unsafe { raw::alloc(size, alignment).from_sgx_result() } } diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs b/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs index 28fbbc3c51816..2f7a2e0fd6ef0 100644 --- a/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs +++ b/library/std/src/sys/pal/sgx/abi/usercalls/raw.rs @@ -34,6 +34,7 @@ pub unsafe fn do_usercall( p4: u64, abort: bool, ) -> (u64, u64) { + // SAFETY: Untriaged. let UsercallReturn(a, b) = unsafe { usercall(nr, p1, p2, abort as _, p3, p4) }; (a, b) } @@ -194,6 +195,7 @@ macro_rules! enclave_usercalls_internal_define_usercalls { #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3, $n4: $t4) -> $r { +// SAFETY: Untriaged. ReturnValue::from_registers(stringify!($f), unsafe { do_usercall( rtunwrap!(Some, NonZero::new(Usercalls::$f as Register)), RegisterArgument::into_register($n1), @@ -210,6 +212,7 @@ macro_rules! enclave_usercalls_internal_define_usercalls { #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f($n1: $t1, $n2: $t2, $n3: $t3) -> $r { +// SAFETY: Untriaged. ReturnValue::from_registers(stringify!($f), unsafe { do_usercall( rtunwrap!(Some, NonZero::new(Usercalls::$f as Register)), RegisterArgument::into_register($n1), @@ -226,6 +229,7 @@ macro_rules! enclave_usercalls_internal_define_usercalls { #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f($n1: $t1, $n2: $t2) -> $r { +// SAFETY: Untriaged. ReturnValue::from_registers(stringify!($f), unsafe { do_usercall( rtunwrap!(Some, NonZero::new(Usercalls::$f as Register)), RegisterArgument::into_register($n1), @@ -241,6 +245,7 @@ macro_rules! enclave_usercalls_internal_define_usercalls { #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f($n1: $t1) -> $r { +// SAFETY: Untriaged. ReturnValue::from_registers(stringify!($f), unsafe { do_usercall( rtunwrap!(Some, NonZero::new(Usercalls::$f as Register)), RegisterArgument::into_register($n1), @@ -255,6 +260,7 @@ macro_rules! enclave_usercalls_internal_define_usercalls { #[unstable(feature = "sgx_platform", issue = "56975")] #[inline(always)] pub unsafe fn $f() -> $r { +// SAFETY: Untriaged. ReturnValue::from_registers(stringify!($f), unsafe { do_usercall( rtunwrap!(Some, NonZero::new(Usercalls::$f as Register)), 0,0,0,0, diff --git a/library/std/src/sys/pal/sgx/libunwind_integration.rs b/library/std/src/sys/pal/sgx/libunwind_integration.rs index b5419ad05decd..4fa76f0f9f799 100644 --- a/library/std/src/sys/pal/sgx/libunwind_integration.rs +++ b/library/std/src/sys/pal/sgx/libunwind_integration.rs @@ -9,6 +9,7 @@ use crate::{slice, str}; // Verify that the byte pattern libunwind uses to initialize an RwLock is // equivalent to the value of RwLock::new(). If the value changes, // `src/UnwindRustSgx.h` in libunwind needs to be changed too. +// SAFETY: Untriaged. const _: () = unsafe { let bits_rust: usize = crate::mem::transmute(RwLock::new()); assert!(bits_rust == 0); @@ -24,6 +25,7 @@ pub unsafe extern "C" fn __rust_rwlock_rdlock(p: *mut RwLock) -> i32 { // We cannot differentiate between reads an writes in unlock and therefore // always use a write-lock. Unwinding isn't really in the hot path anyway. + // SAFETY: Untriaged. unsafe { (*p).write() }; return 0; } @@ -33,6 +35,7 @@ pub unsafe extern "C" fn __rust_rwlock_wrlock(p: *mut RwLock) -> i32 { if p.is_null() { return EINVAL; } + // SAFETY: Untriaged. unsafe { (*p).write() }; return 0; } @@ -42,6 +45,7 @@ pub unsafe extern "C" fn __rust_rwlock_unlock(p: *mut RwLock) -> i32 { if p.is_null() { return EINVAL; } + // SAFETY: Untriaged. unsafe { (*p).write_unlock() }; return 0; } @@ -51,6 +55,7 @@ pub unsafe extern "C" fn __rust_print_err(m: *mut u8, s: i32) { if s < 0 { return; } + // SAFETY: Untriaged. let buf = unsafe { slice::from_raw_parts(m as *const u8, s as _) }; if let Ok(s) = str::from_utf8(&buf[..buf.iter().position(|&b| b == 0).unwrap_or(buf.len())]) { eprint!("{s}"); diff --git a/library/std/src/sys/pal/sgx/mod.rs b/library/std/src/sys/pal/sgx/mod.rs index 6ed6e39c61897..678a39ae14404 100644 --- a/library/std/src/sys/pal/sgx/mod.rs +++ b/library/std/src/sys/pal/sgx/mod.rs @@ -16,6 +16,7 @@ pub mod waitqueue; // SAFETY: must be called only once during runtime initialization. // NOTE: this is not guaranteed to run, for example when Rust code is called externally. pub unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) { + // SAFETY: Untriaged. unsafe { crate::sys::args::init(argc, argv); } diff --git a/library/std/src/sys/pal/sgx/waitqueue/mod.rs b/library/std/src/sys/pal/sgx/waitqueue/mod.rs index 41d1413fcdee9..bc32c1412a871 100644 --- a/library/std/src/sys/pal/sgx/waitqueue/mod.rs +++ b/library/std/src/sys/pal/sgx/waitqueue/mod.rs @@ -129,6 +129,7 @@ impl WaitQueue { /// this function will abort. pub fn wait(mut guard: SpinMutexGuard<'_, WaitVariable>, before_wait: F) { // very unsafe: check requirements of UnsafeList::push + // SAFETY: Untriaged. unsafe { let mut entry = UnsafeListEntry::new(SpinMutex::new(WaitEntry { tcs: thread::current(), @@ -160,6 +161,7 @@ impl WaitQueue { before_wait: F, ) -> bool { // very unsafe: check requirements of UnsafeList::push + // SAFETY: Untriaged. unsafe { let mut entry = UnsafeListEntry::new(SpinMutex::new(WaitEntry { tcs: thread::current(), diff --git a/library/std/src/sys/pal/sgx/waitqueue/spin_mutex.rs b/library/std/src/sys/pal/sgx/waitqueue/spin_mutex.rs index 73c7a101d601d..2808bccac3c3c 100644 --- a/library/std/src/sys/pal/sgx/waitqueue/spin_mutex.rs +++ b/library/std/src/sys/pal/sgx/waitqueue/spin_mutex.rs @@ -63,12 +63,14 @@ impl<'a, T> Deref for SpinMutexGuard<'a, T> { type Target = T; fn deref(&self) -> &T { + // SAFETY: Untriaged. unsafe { &*self.mutex.value.get() } } } impl<'a, T> DerefMut for SpinMutexGuard<'a, T> { fn deref_mut(&mut self) -> &mut T { + // SAFETY: Untriaged. unsafe { &mut *self.mutex.value.get() } } } diff --git a/library/std/src/sys/pal/sgx/waitqueue/unsafe_list.rs b/library/std/src/sys/pal/sgx/waitqueue/unsafe_list.rs index c736cab576e4d..fa0455aa0787f 100644 --- a/library/std/src/sys/pal/sgx/waitqueue/unsafe_list.rs +++ b/library/std/src/sys/pal/sgx/waitqueue/unsafe_list.rs @@ -31,6 +31,7 @@ pub struct UnsafeList { impl UnsafeList { pub const fn new() -> Self { + // SAFETY: Untriaged. unsafe { UnsafeList { head_tail: NonNull::new_unchecked(1 as _), head_tail_entry: None } } } @@ -40,15 +41,18 @@ impl UnsafeList { self.head_tail_entry = Some(UnsafeListEntry::dummy()); // SAFETY: `head_tail_entry` must be non-null, which it is because we assign it above. self.head_tail = +// SAFETY: Untriaged. unsafe { NonNull::new_unchecked(self.head_tail_entry.as_mut().unwrap()) }; // SAFETY: `self.head_tail` must meet all requirements for a mutable reference. unsafe { self.head_tail.as_mut() }.next = self.head_tail; + // SAFETY: Untriaged. unsafe { self.head_tail.as_mut() }.prev = self.head_tail; } } pub fn is_empty(&self) -> bool { if self.head_tail_entry.is_some() { + // SAFETY: Untriaged. let first = unsafe { self.head_tail.as_ref() }.next; if first == self.head_tail { // ,-------> /---------\ next ---, @@ -74,6 +78,7 @@ impl UnsafeList { /// care must be taken in the caller of `push` to ensure unwinding does /// not destroy the stack frame containing the entry. pub unsafe fn push<'a>(&mut self, entry: &'a mut UnsafeListEntry) -> &'a T { + // SAFETY: Untriaged. unsafe { self.init() }; // BEFORE: @@ -85,14 +90,18 @@ impl UnsafeList { // /---------\ next ---> /-----\ next ---> /---------\ // ... |prev_tail| |entry| |head_tail| ... // \---------/ <--- prev \-----/ <--- prev \---------/ + // SAFETY: Untriaged. let mut entry = unsafe { NonNull::new_unchecked(entry) }; + // SAFETY: Untriaged. let mut prev_tail = mem::replace(&mut unsafe { self.head_tail.as_mut() }.prev, entry); // SAFETY: `entry` must meet all requirements for a mutable reference. unsafe { entry.as_mut() }.prev = prev_tail; + // SAFETY: Untriaged. unsafe { entry.as_mut() }.next = self.head_tail; // SAFETY: `prev_tail` must meet all requirements for a mutable reference. unsafe { prev_tail.as_mut() }.next = entry; // unwrap ok: always `Some` on non-dummy entries + // SAFETY: Untriaged. unsafe { (*entry.as_ptr()).value.as_ref() }.unwrap() } @@ -103,6 +112,7 @@ impl UnsafeList { /// The caller must make sure to synchronize ending the borrow of the /// return value and deallocation of the containing entry. pub unsafe fn pop<'a>(&mut self) -> Option<&'a T> { + // SAFETY: Untriaged. unsafe { self.init() }; if self.is_empty() { @@ -117,13 +127,20 @@ impl UnsafeList { // /---------\ next ---> /------\ // ... |head_tail| |second| ... // \---------/ <--- prev \------/ + // SAFETY: Untriaged. let mut first = unsafe { self.head_tail.as_mut() }.next; + // SAFETY: Untriaged. let mut second = unsafe { first.as_mut() }.next; + // SAFETY: Untriaged. unsafe { self.head_tail.as_mut() }.next = second; + // SAFETY: Untriaged. unsafe { second.as_mut() }.prev = self.head_tail; + // SAFETY: Untriaged. unsafe { first.as_mut() }.next = NonNull::dangling(); + // SAFETY: Untriaged. unsafe { first.as_mut() }.prev = NonNull::dangling(); // unwrap ok: always `Some` on non-dummy entries + // SAFETY: Untriaged. Some(unsafe { (*first.as_ptr()).value.as_ref() }.unwrap()) } } @@ -149,6 +166,7 @@ impl UnsafeList { let mut next = entry.next; // SAFETY: `prev` and `next` must meet all requirements for a mutable reference.entry unsafe { prev.as_mut() }.next = next; + // SAFETY: Untriaged. unsafe { next.as_mut() }.prev = prev; entry.next = NonNull::dangling(); entry.prev = NonNull::dangling(); diff --git a/library/std/src/sys/pal/solid/mod.rs b/library/std/src/sys/pal/solid/mod.rs index c3f9e47945901..f8f5dd2daeeeb 100644 --- a/library/std/src/sys/pal/solid/mod.rs +++ b/library/std/src/sys/pal/solid/mod.rs @@ -38,5 +38,6 @@ pub fn unsupported_err() -> io::Error { #[inline] pub fn abort_internal() -> ! { + // SAFETY: Untriaged. unsafe { libc::abort() } } diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index 5caed277dbf59..3dca9e39fe7e9 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -21,6 +21,7 @@ pub mod sync { use crate::io; pub fn abort_internal() -> ! { + // SAFETY: Untriaged. unsafe { libc::abort() } } diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs index 9db72db606779..5b34e6cbd83b7 100644 --- a/library/std/src/sys/pal/uefi/helpers.rs +++ b/library/std/src/sys/pal/uefi/helpers.rs @@ -47,6 +47,7 @@ pub(crate) fn locate_handles(mut guid: Guid) -> io::Result io::Result<()> { + // SAFETY: Untriaged. let r = unsafe { ((*boot_services.as_ptr()).locate_handle)( r_efi::efi::BY_PROTOCOL, @@ -81,6 +82,7 @@ pub(crate) fn locate_handles(mut guid: Guid) -> io::Result { // This is safe because the call will succeed only if buf_len >= required length. // Also, on success, the `buf_len` is updated with the size of bufferv (in bytes) written + // SAFETY: Untriaged. unsafe { buf.set_len(num_of_handles) }; Ok(buf.into_iter().filter_map(|x| NonNull::new(x)).collect()) } @@ -105,6 +107,7 @@ pub(crate) fn open_protocol( let system_handle = uefi::env::image_handle(); let mut protocol: MaybeUninit<*mut T> = MaybeUninit::uninit(); + // SAFETY: Untriaged. let r = unsafe { ((*boot_services.as_ptr()).open_protocol)( handle.as_ptr(), @@ -119,6 +122,7 @@ pub(crate) fn open_protocol( if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { + // SAFETY: Untriaged. NonNull::new(unsafe { protocol.assume_init() }) .ok_or(const_error!(io::ErrorKind::Other, "null protocol")) } @@ -138,6 +142,7 @@ pub(crate) fn device_path_to_text(path: NonNull) -> io::R protocol: NonNull, path: NonNull, ) -> io::Result { + // SAFETY: Untriaged. let path_ptr: *mut r_efi::efi::Char16 = unsafe { ((*protocol.as_ptr()).convert_device_path_to_text)( path.as_ptr(), @@ -153,6 +158,7 @@ pub(crate) fn device_path_to_text(path: NonNull) -> io::R if let Some(boot_services) = crate::os::uefi::env::boot_services() { let boot_services: NonNull = boot_services.cast(); + // SAFETY: Untriaged. unsafe { ((*boot_services.as_ptr()).free_pool)(path_ptr.cast()); } @@ -192,6 +198,7 @@ fn device_node_to_text(path: NonNull) -> io::Result, path: NonNull, ) -> io::Result { + // SAFETY: Untriaged. let path_ptr: *mut r_efi::efi::Char16 = unsafe { ((*protocol.as_ptr()).convert_device_node_to_text)( path.as_ptr(), @@ -207,6 +214,7 @@ fn device_node_to_text(path: NonNull) -> io::Result = boot_services.cast(); + // SAFETY: Untriaged. unsafe { ((*boot_services.as_ptr()).free_pool)(path_ptr.cast()); } @@ -245,6 +253,7 @@ fn device_node_to_text(path: NonNull) -> io::Result Option> { let system_table: NonNull = crate::os::uefi::env::try_system_table()?.cast(); + // SAFETY: Untriaged. let runtime_services = unsafe { (*system_table.as_ptr()).runtime_services }; NonNull::new(runtime_services) } @@ -266,6 +275,7 @@ impl OwnedDevicePath { } let path = +// SAFETY: Untriaged. unsafe { ((*protocol.as_ptr()).convert_text_to_device_path)(path_vec.as_ptr()) }; NonNull::new(path) @@ -315,6 +325,7 @@ impl Drop for OwnedDevicePath { fn drop(&mut self) { if let Some(bt) = boot_services() { let bt: NonNull = bt.cast(); + // SAFETY: Untriaged. unsafe { ((*bt.as_ptr()).free_pool)(self.0.as_ptr() as *mut crate::ffi::c_void); } @@ -373,6 +384,7 @@ impl<'a> Iterator for DevicePathIterator<'a> { fn next(&mut self) -> Option { let cur_node = self.0?; + // SAFETY: Untriaged. let next_node = unsafe { cur_node.next_node() }; self.0 = if next_node.is_end() { None } else { Some(next_node) }; @@ -392,15 +404,18 @@ impl<'a> DevicePathNode<'a> { } pub(crate) const fn length(&self) -> u16 { + // SAFETY: Untriaged. let len = unsafe { (*self.protocol.as_ptr()).length }; u16::from_le_bytes(len) } pub(crate) const fn node_type(&self) -> u8 { + // SAFETY: Untriaged. unsafe { (*self.protocol.as_ptr()).r#type } } pub(crate) const fn sub_type(&self) -> u8 { + // SAFETY: Untriaged. unsafe { (*self.protocol.as_ptr()).sub_type } } @@ -410,7 +425,9 @@ impl<'a> DevicePathNode<'a> { // Some nodes do not have any special data if length > 4 { let raw_ptr: *const u8 = self.protocol.as_ptr().cast(); + // SAFETY: Untriaged. let data = unsafe { raw_ptr.add(4) }; + // SAFETY: Untriaged. unsafe { crate::slice::from_raw_parts(data, length - 4) } } else { &[] @@ -428,6 +445,7 @@ impl<'a> DevicePathNode<'a> { } pub(crate) unsafe fn next_node(&self) -> Self { + // SAFETY: Untriaged. let node = unsafe { self.protocol .cast::() @@ -494,8 +512,10 @@ impl OwnedProtocol { // FIXME: Move into r-efi once extended_varargs_abi_support is stabilized let func: BootInstallMultipleProtocolInterfaces = +// SAFETY: Untriaged. unsafe { crate::mem::transmute((*bt.as_ptr()).install_multiple_protocol_interfaces) }; + // SAFETY: Untriaged. let r = unsafe { func( &mut handle, @@ -506,6 +526,7 @@ impl OwnedProtocol { }; if r.is_error() { + // SAFETY: Untriaged. drop(unsafe { Box::from_raw(protocol) }); return Err(crate::io::Error::from_raw_os_error(r.as_usize())); }; @@ -527,9 +548,11 @@ impl Drop for OwnedProtocol { if let Some(bt) = boot_services() { let bt: NonNull = bt.cast(); // FIXME: Move into r-efi once extended_varargs_abi_support is stabilized + // SAFETY: Untriaged. let func: BootUninstallMultipleProtocolInterfaces = unsafe { crate::mem::transmute((*bt.as_ptr()).uninstall_multiple_protocol_interfaces) }; + // SAFETY: Untriaged. let status = unsafe { func( self.handle.as_ptr(), @@ -541,6 +564,7 @@ impl Drop for OwnedProtocol { // Leak the protocol in case uninstall fails if status == r_efi::efi::Status::SUCCESS { + // SAFETY: Untriaged. let _ = unsafe { Box::from_raw(self.protocol) }; } } @@ -549,6 +573,7 @@ impl Drop for OwnedProtocol { impl AsRef for OwnedProtocol { fn as_ref(&self) -> &T { + // SAFETY: Untriaged. unsafe { self.protocol.as_ref().unwrap() } } } @@ -562,6 +587,7 @@ impl OwnedTable { pub(crate) fn from_table_header(hdr: &r_efi::efi::TableHeader) -> Self { let header_size = hdr.header_size as usize; let layout = crate::alloc::Layout::from_size_align(header_size, 8).unwrap(); + // SAFETY: Untriaged. let ptr = unsafe { crate::alloc::alloc(layout) as *mut T }; Self { layout, ptr } } @@ -577,9 +603,11 @@ impl OwnedTable { impl OwnedTable { pub(crate) fn from_table(tbl: *const r_efi::efi::SystemTable) -> Self { + // SAFETY: Untriaged. let hdr = unsafe { (*tbl).hdr }; let owned_tbl = Self::from_table_header(&hdr); + // SAFETY: Untriaged. unsafe { crate::ptr::copy_nonoverlapping( tbl as *const u8, @@ -594,13 +622,16 @@ impl OwnedTable { impl Drop for OwnedTable { fn drop(&mut self) { + // SAFETY: Untriaged. unsafe { crate::alloc::dealloc(self.ptr as *mut u8, self.layout) }; } } /// Create OsString from a pointer to NULL terminated UTF-16 string pub(crate) fn os_string_from_raw(ptr: *mut r_efi::efi::Char16) -> Option { + // SAFETY: Untriaged. let path_len = unsafe { WStrUnits::new(ptr)?.count() }; + // SAFETY: Untriaged. Some(OsString::from_wide(unsafe { slice::from_raw_parts(ptr.cast(), path_len) })) } @@ -642,6 +673,7 @@ pub(crate) fn get_device_path_from_map(map: &Path) -> io::Result(handle, service_guid) { + // SAFETY: Untriaged. if let Ok(child_handle) = unsafe { Self::create_child(protocol) } { return Ok((Self { service_guid, handle }, child_handle)); } @@ -705,6 +738,7 @@ impl ServiceProtocol { ) -> io::Result<()> { let sbp = open_protocol::(self.handle, self.service_guid)?; + // SAFETY: Untriaged. let r = unsafe { ((*sbp.as_ptr()).destroy_child)(sbp.as_ptr(), handle.as_ptr()) }; if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) } } @@ -725,6 +759,7 @@ impl OwnedEvent { let mut event: r_efi::efi::Event = crate::ptr::null_mut(); let context = context.map(NonNull::as_ptr).unwrap_or(crate::ptr::null_mut()); + // SAFETY: Untriaged. let r = unsafe { let create_event = (*boot_services.as_ptr()).create_event; (create_event)(signal, tpl, handler, context, &mut event) @@ -751,6 +786,7 @@ impl OwnedEvent { /// SAFETY: Assumes that ptr is a non-null valid UEFI event pub(crate) unsafe fn from_raw(ptr: *mut crate::ffi::c_void) -> Self { + // SAFETY: Untriaged. Self(unsafe { NonNull::new_unchecked(ptr) }) } } @@ -759,6 +795,7 @@ impl Drop for OwnedEvent { fn drop(&mut self) { if let Some(boot_services) = boot_services() { let bt: NonNull = boot_services.cast(); + // SAFETY: Untriaged. unsafe { let close_event = (*bt.as_ptr()).close_event; (close_event)(self.0.as_ptr()) @@ -787,6 +824,7 @@ impl UefiBox { assert!(len >= size_of::()); // UEFI always expects types to be 8 byte aligned. let layout = Layout::from_size_align(len, 8).unwrap(); + // SAFETY: Untriaged. let ptr = unsafe { crate::alloc::alloc(layout) }; match NonNull::new(ptr.cast()) { @@ -796,6 +834,7 @@ impl UefiBox { } pub(crate) fn write(&mut self, data: T) { + // SAFETY: Untriaged. unsafe { self.inner.write(data) } } @@ -815,16 +854,19 @@ impl UefiBox { impl Drop for UefiBox { fn drop(&mut self) { let layout = Layout::from_size_align(self.size, 8).unwrap(); + // SAFETY: Untriaged. unsafe { crate::alloc::dealloc(self.inner.as_ptr().cast(), layout) }; } } impl UefiBox { fn size(&self) -> u64 { + // SAFETY: Untriaged. unsafe { (*self.as_ptr()).size } } fn set_size(&mut self, s: u64) { + // SAFETY: Untriaged. unsafe { (*self.as_mut_ptr()).size = s } } @@ -834,12 +876,14 @@ impl UefiBox { } pub(crate) fn file_name(&self) -> &[u16] { + // SAFETY: Untriaged. unsafe { crate::slice::from_raw_parts((*self.as_ptr()).file_name.as_ptr(), self.file_name_len()) } } fn file_name_mut(&mut self) -> &mut [u16] { + // SAFETY: Untriaged. unsafe { crate::slice::from_raw_parts_mut( (*self.as_mut_ptr()).file_name.as_mut_ptr(), @@ -864,6 +908,7 @@ impl UefiBox { let mut new_box = UefiBox::new(new_size)?; + // SAFETY: Untriaged. unsafe { crate::ptr::copy_nonoverlapping(self.as_ptr(), new_box.as_mut_ptr(), 1); } diff --git a/library/std/src/sys/pal/uefi/mod.rs b/library/std/src/sys/pal/uefi/mod.rs index 67499d2c6f17c..5005050826f82 100644 --- a/library/std/src/sys/pal/uefi/mod.rs +++ b/library/std/src/sys/pal/uefi/mod.rs @@ -33,8 +33,11 @@ static EXIT_BOOT_SERVICE_EVENT: Atomic<*mut crate::ffi::c_void> = /// - argv must be &[Handle, *mut SystemTable]. pub(crate) unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) { assert_eq!(argc, 2); + // SAFETY: Untriaged. let image_handle = unsafe { NonNull::new(*argv as *mut crate::ffi::c_void).unwrap() }; + // SAFETY: Untriaged. let system_table = unsafe { NonNull::new(*argv.add(1) as *mut crate::ffi::c_void).unwrap() }; + // SAFETY: Untriaged. unsafe { uefi::env::init_globals(image_handle, system_table) }; // Register exit boot services handler @@ -68,6 +71,7 @@ pub unsafe fn cleanup() { if let Some(exit_boot_service_event) = NonNull::new(EXIT_BOOT_SERVICE_EVENT.swap(crate::ptr::null_mut(), Ordering::Acquire)) { + // SAFETY: Untriaged. let _ = unsafe { helpers::OwnedEvent::from_raw(exit_boot_service_event.as_ptr()) }; } } @@ -86,6 +90,7 @@ pub fn abort_internal() -> ! { if let Some(exit_boot_service_event) = NonNull::new(EXIT_BOOT_SERVICE_EVENT.load(Ordering::Acquire)) { + // SAFETY: Untriaged. let _ = unsafe { helpers::OwnedEvent::from_raw(exit_boot_service_event.as_ptr()) }; } @@ -93,6 +98,7 @@ pub fn abort_internal() -> ! { (uefi::env::boot_services(), uefi::env::try_image_handle()) { let boot_services: NonNull = boot_services.cast(); + // SAFETY: Untriaged. let _ = unsafe { ((*boot_services.as_ptr()).exit)( handle.as_ptr(), diff --git a/library/std/src/sys/pal/uefi/system_time.rs b/library/std/src/sys/pal/uefi/system_time.rs index 557a49b27c2d1..9e283cb914f89 100644 --- a/library/std/src/sys/pal/uefi/system_time.rs +++ b/library/std/src/sys/pal/uefi/system_time.rs @@ -15,11 +15,13 @@ pub(crate) fn now() -> Time { helpers::runtime_services().expect("Runtime services are not available"); let mut t: MaybeUninit