Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'rust-fixes-6.5-rc5' of https://github.com/Rust-for-Linux/linux

Pull rust fixes from Miguel Ojeda:

- Allocator: prevent mis-aligned allocation

- Types: delete 'ForeignOwnable::borrow_mut'. A sound replacement is
planned for the merge window

- Build: fix bindgen error with UBSAN_BOUNDS_STRICT

* tag 'rust-fixes-6.5-rc5' of https://github.com/Rust-for-Linux/linux:
rust: fix bindgen build error with UBSAN_BOUNDS_STRICT
rust: delete `ForeignOwnable::borrow_mut`
rust: allocator: Prevent mis-aligned allocation

+64 -38
+1 -1
rust/Makefile
··· 257 257 -fno-partial-inlining -fplugin-arg-arm_ssp_per_task_plugin-% \ 258 258 -fno-reorder-blocks -fno-allow-store-data-races -fasan-shadow-offset=% \ 259 259 -fzero-call-used-regs=% -fno-stack-clash-protection \ 260 - -fno-inline-functions-called-once \ 260 + -fno-inline-functions-called-once -fsanitize=bounds-strict \ 261 261 --param=% --param asan-% 262 262 263 263 # Derived from `scripts/Makefile.clang`.
+1
rust/bindings/bindings_helper.h
··· 13 13 #include <linux/sched.h> 14 14 15 15 /* `bindgen` gets confused at certain things. */ 16 + const size_t BINDINGS_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN; 16 17 const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL; 17 18 const gfp_t BINDINGS___GFP_ZERO = __GFP_ZERO;
+59 -15
rust/kernel/allocator.rs
··· 9 9 10 10 struct KernelAllocator; 11 11 12 + /// Calls `krealloc` with a proper size to alloc a new object aligned to `new_layout`'s alignment. 13 + /// 14 + /// # Safety 15 + /// 16 + /// - `ptr` can be either null or a pointer which has been allocated by this allocator. 17 + /// - `new_layout` must have a non-zero size. 18 + unsafe fn krealloc_aligned(ptr: *mut u8, new_layout: Layout, flags: bindings::gfp_t) -> *mut u8 { 19 + // Customized layouts from `Layout::from_size_align()` can have size < align, so pad first. 20 + let layout = new_layout.pad_to_align(); 21 + 22 + let mut size = layout.size(); 23 + 24 + if layout.align() > bindings::BINDINGS_ARCH_SLAB_MINALIGN { 25 + // The alignment requirement exceeds the slab guarantee, thus try to enlarge the size 26 + // to use the "power-of-two" size/alignment guarantee (see comments in `kmalloc()` for 27 + // more information). 28 + // 29 + // Note that `layout.size()` (after padding) is guaranteed to be a multiple of 30 + // `layout.align()`, so `next_power_of_two` gives enough alignment guarantee. 31 + size = size.next_power_of_two(); 32 + } 33 + 34 + // SAFETY: 35 + // - `ptr` is either null or a pointer returned from a previous `k{re}alloc()` by the 36 + // function safety requirement. 37 + // - `size` is greater than 0 since it's either a `layout.size()` (which cannot be zero 38 + // according to the function safety requirement) or a result from `next_power_of_two()`. 39 + unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags) as *mut u8 } 40 + } 41 + 12 42 unsafe impl GlobalAlloc for KernelAllocator { 13 43 unsafe fn alloc(&self, layout: Layout) -> *mut u8 { 14 44 // `krealloc()` is used instead of `kmalloc()` because the latter is ··· 60 30 // to extract the object file that has them from the archive. For the moment, 61 31 // let's generate them ourselves instead. 62 32 // 33 + // Note: Although these are *safe* functions, they are called by the compiler 34 + // with parameters that obey the same `GlobalAlloc` function safety 35 + // requirements: size and align should form a valid layout, and size is 36 + // greater than 0. 37 + // 63 38 // Note that `#[no_mangle]` implies exported too, nowadays. 64 39 #[no_mangle] 65 - fn __rust_alloc(size: usize, _align: usize) -> *mut u8 { 66 - unsafe { bindings::krealloc(core::ptr::null(), size, bindings::GFP_KERNEL) as *mut u8 } 40 + fn __rust_alloc(size: usize, align: usize) -> *mut u8 { 41 + // SAFETY: See assumption above. 42 + let layout = unsafe { Layout::from_size_align_unchecked(size, align) }; 43 + 44 + // SAFETY: `ptr::null_mut()` is null, per assumption above the size of `layout` is greater 45 + // than 0. 46 + unsafe { krealloc_aligned(ptr::null_mut(), layout, bindings::GFP_KERNEL) } 67 47 } 68 48 69 49 #[no_mangle] ··· 82 42 } 83 43 84 44 #[no_mangle] 85 - fn __rust_realloc(ptr: *mut u8, _old_size: usize, _align: usize, new_size: usize) -> *mut u8 { 86 - unsafe { 87 - bindings::krealloc( 88 - ptr as *const core::ffi::c_void, 89 - new_size, 90 - bindings::GFP_KERNEL, 91 - ) as *mut u8 92 - } 45 + fn __rust_realloc(ptr: *mut u8, _old_size: usize, align: usize, new_size: usize) -> *mut u8 { 46 + // SAFETY: See assumption above. 47 + let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, align) }; 48 + 49 + // SAFETY: Per assumption above, `ptr` is allocated by `__rust_*` before, and the size of 50 + // `new_layout` is greater than 0. 51 + unsafe { krealloc_aligned(ptr, new_layout, bindings::GFP_KERNEL) } 93 52 } 94 53 95 54 #[no_mangle] 96 - fn __rust_alloc_zeroed(size: usize, _align: usize) -> *mut u8 { 55 + fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8 { 56 + // SAFETY: See assumption above. 57 + let layout = unsafe { Layout::from_size_align_unchecked(size, align) }; 58 + 59 + // SAFETY: `ptr::null_mut()` is null, per assumption above the size of `layout` is greater 60 + // than 0. 97 61 unsafe { 98 - bindings::krealloc( 99 - core::ptr::null(), 100 - size, 62 + krealloc_aligned( 63 + ptr::null_mut(), 64 + layout, 101 65 bindings::GFP_KERNEL | bindings::__GFP_ZERO, 102 - ) as *mut u8 66 + ) 103 67 } 104 68 }
+1 -2
rust/kernel/sync/arc.rs
··· 243 243 let inner = NonNull::new(ptr as *mut ArcInner<T>).unwrap(); 244 244 245 245 // SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive 246 - // for the lifetime of the returned value. Additionally, the safety requirements of 247 - // `ForeignOwnable::borrow_mut` ensure that no new mutable references are created. 246 + // for the lifetime of the returned value. 248 247 unsafe { ArcBorrow::new(inner) } 249 248 } 250 249
+2 -20
rust/kernel/types.rs
··· 35 35 /// 36 36 /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for 37 37 /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet. 38 - /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow_mut`] 39 - /// for this object must have been dropped. 40 38 unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Self::Borrowed<'a>; 41 - 42 - /// Mutably borrows a foreign-owned object. 43 - /// 44 - /// # Safety 45 - /// 46 - /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for 47 - /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet. 48 - /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] and 49 - /// [`ForeignOwnable::borrow_mut`] for this object must have been dropped. 50 - unsafe fn borrow_mut(ptr: *const core::ffi::c_void) -> ScopeGuard<Self, fn(Self)> { 51 - // SAFETY: The safety requirements ensure that `ptr` came from a previous call to 52 - // `into_foreign`. 53 - ScopeGuard::new_with_data(unsafe { Self::from_foreign(ptr) }, |d| { 54 - d.into_foreign(); 55 - }) 56 - } 57 39 58 40 /// Converts a foreign-owned object back to a Rust-owned one. 59 41 /// ··· 43 61 /// 44 62 /// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for 45 63 /// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet. 46 - /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] and 47 - /// [`ForeignOwnable::borrow_mut`] for this object must have been dropped. 64 + /// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] for 65 + /// this object must have been dropped. 48 66 unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self; 49 67 } 50 68