mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git
synced 2026-05-02 18:17:50 -04:00
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
This commit is contained in:
@@ -257,7 +257,7 @@ bindgen_skip_c_flags := -mno-fp-ret-in-387 -mpreferred-stack-boundary=% \
|
||||
-fno-partial-inlining -fplugin-arg-arm_ssp_per_task_plugin-% \
|
||||
-fno-reorder-blocks -fno-allow-store-data-races -fasan-shadow-offset=% \
|
||||
-fzero-call-used-regs=% -fno-stack-clash-protection \
|
||||
-fno-inline-functions-called-once \
|
||||
-fno-inline-functions-called-once -fsanitize=bounds-strict \
|
||||
--param=% --param asan-%
|
||||
|
||||
# Derived from `scripts/Makefile.clang`.
|
||||
|
||||
@@ -13,5 +13,6 @@
|
||||
#include <linux/sched.h>
|
||||
|
||||
/* `bindgen` gets confused at certain things. */
|
||||
const size_t BINDINGS_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN;
|
||||
const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL;
|
||||
const gfp_t BINDINGS___GFP_ZERO = __GFP_ZERO;
|
||||
|
||||
@@ -9,6 +9,36 @@ use crate::bindings;
|
||||
|
||||
struct KernelAllocator;
|
||||
|
||||
/// Calls `krealloc` with a proper size to alloc a new object aligned to `new_layout`'s alignment.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// - `ptr` can be either null or a pointer which has been allocated by this allocator.
|
||||
/// - `new_layout` must have a non-zero size.
|
||||
unsafe fn krealloc_aligned(ptr: *mut u8, new_layout: Layout, flags: bindings::gfp_t) -> *mut u8 {
|
||||
// Customized layouts from `Layout::from_size_align()` can have size < align, so pad first.
|
||||
let layout = new_layout.pad_to_align();
|
||||
|
||||
let mut size = layout.size();
|
||||
|
||||
if layout.align() > bindings::BINDINGS_ARCH_SLAB_MINALIGN {
|
||||
// The alignment requirement exceeds the slab guarantee, thus try to enlarge the size
|
||||
// to use the "power-of-two" size/alignment guarantee (see comments in `kmalloc()` for
|
||||
// more information).
|
||||
//
|
||||
// Note that `layout.size()` (after padding) is guaranteed to be a multiple of
|
||||
// `layout.align()`, so `next_power_of_two` gives enough alignment guarantee.
|
||||
size = size.next_power_of_two();
|
||||
}
|
||||
|
||||
// SAFETY:
|
||||
// - `ptr` is either null or a pointer returned from a previous `k{re}alloc()` by the
|
||||
// function safety requirement.
|
||||
// - `size` is greater than 0 since it's either a `layout.size()` (which cannot be zero
|
||||
// according to the function safety requirement) or a result from `next_power_of_two()`.
|
||||
unsafe { bindings::krealloc(ptr as *const core::ffi::c_void, size, flags) as *mut u8 }
|
||||
}
|
||||
|
||||
unsafe impl GlobalAlloc for KernelAllocator {
|
||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
// `krealloc()` is used instead of `kmalloc()` because the latter is
|
||||
@@ -30,10 +60,20 @@ static ALLOCATOR: KernelAllocator = KernelAllocator;
|
||||
// to extract the object file that has them from the archive. For the moment,
|
||||
// let's generate them ourselves instead.
|
||||
//
|
||||
// Note: Although these are *safe* functions, they are called by the compiler
|
||||
// with parameters that obey the same `GlobalAlloc` function safety
|
||||
// requirements: size and align should form a valid layout, and size is
|
||||
// greater than 0.
|
||||
//
|
||||
// Note that `#[no_mangle]` implies exported too, nowadays.
|
||||
#[no_mangle]
|
||||
fn __rust_alloc(size: usize, _align: usize) -> *mut u8 {
|
||||
unsafe { bindings::krealloc(core::ptr::null(), size, bindings::GFP_KERNEL) as *mut u8 }
|
||||
fn __rust_alloc(size: usize, align: usize) -> *mut u8 {
|
||||
// SAFETY: See assumption above.
|
||||
let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
|
||||
|
||||
// SAFETY: `ptr::null_mut()` is null, per assumption above the size of `layout` is greater
|
||||
// than 0.
|
||||
unsafe { krealloc_aligned(ptr::null_mut(), layout, bindings::GFP_KERNEL) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
@@ -42,23 +82,27 @@ fn __rust_dealloc(ptr: *mut u8, _size: usize, _align: usize) {
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn __rust_realloc(ptr: *mut u8, _old_size: usize, _align: usize, new_size: usize) -> *mut u8 {
|
||||
unsafe {
|
||||
bindings::krealloc(
|
||||
ptr as *const core::ffi::c_void,
|
||||
new_size,
|
||||
bindings::GFP_KERNEL,
|
||||
) as *mut u8
|
||||
}
|
||||
fn __rust_realloc(ptr: *mut u8, _old_size: usize, align: usize, new_size: usize) -> *mut u8 {
|
||||
// SAFETY: See assumption above.
|
||||
let new_layout = unsafe { Layout::from_size_align_unchecked(new_size, align) };
|
||||
|
||||
// SAFETY: Per assumption above, `ptr` is allocated by `__rust_*` before, and the size of
|
||||
// `new_layout` is greater than 0.
|
||||
unsafe { krealloc_aligned(ptr, new_layout, bindings::GFP_KERNEL) }
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn __rust_alloc_zeroed(size: usize, _align: usize) -> *mut u8 {
|
||||
fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8 {
|
||||
// SAFETY: See assumption above.
|
||||
let layout = unsafe { Layout::from_size_align_unchecked(size, align) };
|
||||
|
||||
// SAFETY: `ptr::null_mut()` is null, per assumption above the size of `layout` is greater
|
||||
// than 0.
|
||||
unsafe {
|
||||
bindings::krealloc(
|
||||
core::ptr::null(),
|
||||
size,
|
||||
krealloc_aligned(
|
||||
ptr::null_mut(),
|
||||
layout,
|
||||
bindings::GFP_KERNEL | bindings::__GFP_ZERO,
|
||||
) as *mut u8
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,8 +243,7 @@ impl<T: 'static> ForeignOwnable for Arc<T> {
|
||||
let inner = NonNull::new(ptr as *mut ArcInner<T>).unwrap();
|
||||
|
||||
// SAFETY: The safety requirements of `from_foreign` ensure that the object remains alive
|
||||
// for the lifetime of the returned value. Additionally, the safety requirements of
|
||||
// `ForeignOwnable::borrow_mut` ensure that no new mutable references are created.
|
||||
// for the lifetime of the returned value.
|
||||
unsafe { ArcBorrow::new(inner) }
|
||||
}
|
||||
|
||||
|
||||
@@ -35,34 +35,16 @@ pub trait ForeignOwnable: Sized {
|
||||
///
|
||||
/// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
|
||||
/// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
|
||||
/// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow_mut`]
|
||||
/// for this object must have been dropped.
|
||||
unsafe fn borrow<'a>(ptr: *const core::ffi::c_void) -> Self::Borrowed<'a>;
|
||||
|
||||
/// Mutably borrows a foreign-owned object.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
|
||||
/// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
|
||||
/// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] and
|
||||
/// [`ForeignOwnable::borrow_mut`] for this object must have been dropped.
|
||||
unsafe fn borrow_mut(ptr: *const core::ffi::c_void) -> ScopeGuard<Self, fn(Self)> {
|
||||
// SAFETY: The safety requirements ensure that `ptr` came from a previous call to
|
||||
// `into_foreign`.
|
||||
ScopeGuard::new_with_data(unsafe { Self::from_foreign(ptr) }, |d| {
|
||||
d.into_foreign();
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts a foreign-owned object back to a Rust-owned one.
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// `ptr` must have been returned by a previous call to [`ForeignOwnable::into_foreign`] for
|
||||
/// which a previous matching [`ForeignOwnable::from_foreign`] hasn't been called yet.
|
||||
/// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] and
|
||||
/// [`ForeignOwnable::borrow_mut`] for this object must have been dropped.
|
||||
/// Additionally, all instances (if any) of values returned by [`ForeignOwnable::borrow`] for
|
||||
/// this object must have been dropped.
|
||||
unsafe fn from_foreign(ptr: *const core::ffi::c_void) -> Self;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user