rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Boqun Feng <boqun.feng@gmail.com>
To: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-mm@kvack.org
Cc: "Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Wedson Almeida Filho" <wedsonaf@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <benno.lossin@proton.me>,
	"Martin Rodriguez Reboredo" <yakoyoku@gmail.com>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Dariusz Sosnowski" <dsosnowski@dsosnowski.pl>,
	"Geoffrey Thomas" <geofft@ldpreload.com>,
	"Fox Chen" <foxhlchen@gmail.com>,
	"John Baublitz" <john.m.baublitz@gmail.com>,
	"Christoph Lameter" <cl@linux.com>,
	"Pekka Enberg" <penberg@kernel.org>,
	"David Rientjes" <rientjes@google.com>,
	"Joonsoo Kim" <iamjoonsoo.kim@lge.com>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	"Vlastimil Babka" <vbabka@suse.cz>,
	"Roman Gushchin" <roman.gushchin@linux.dev>,
	"Hyeonggon Yoo" <42.hyeyoo@gmail.com>,
	"Kees Cook" <keescook@chromium.org>,
	"Andreas Hindborg" <nmi@metaspace.dk>,
	stable@vger.kernel.org
Subject: [PATCH] rust: allocator: Prevents mis-aligned allocation
Date: Tue, 13 Jun 2023 09:42:58 -0700	[thread overview]
Message-ID: <20230613164258.3831917-1-boqun.feng@gmail.com> (raw)

Currently the KernelAllocator simply passes the size of the type Layout
to krealloc(), and in theory the alignment requirement from the type
Layout may be larger than the guarantee provided by SLAB, which means
the allocated object is mis-aligned.

Fixes this by adjusting the allocation size to the nearest power of two,
which SLAB always guarantees a size-aligned allocation. And because Rust
guarantees that original size must be a multiple of alignment and the
alignment must be a power of two, then the alignment requirement is
satisfied.

Suggested-by: Vlastimil Babka <vbabka@suse.cz>
Co-developed-by: Andreas Hindborg (Samsung) <nmi@metaspace.dk>
Signed-off-by: Andreas Hindborg (Samsung) <nmi@metaspace.dk>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Cc: stable@vger.kernel.org # v6.1+
---
Some more explanation:

* Layout is a data structure describing a particular memory layout,
  conceptionally it has two fields: align and size.

  * align is guaranteed to be a power of two.
  * size can be smaller than align (only when the Layout is created via
    Layout::from_align_size())
  * After pad_to_align(), the size is guaranteed to be a multiple of
    align

For more information, please see: 

	https://doc.rust-lang.org/stable/std/alloc/struct.Layout.html

 rust/bindings/bindings_helper.h |  1 +
 rust/kernel/allocator.rs        | 17 ++++++++++++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index 3e601ce2548d..6619ce95dd37 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -15,3 +15,4 @@
 /* `bindgen` gets confused at certain things. */
 const gfp_t BINDINGS_GFP_KERNEL = GFP_KERNEL;
 const gfp_t BINDINGS___GFP_ZERO = __GFP_ZERO;
+const size_t BINDINGS_ARCH_SLAB_MINALIGN = ARCH_SLAB_MINALIGN;
diff --git a/rust/kernel/allocator.rs b/rust/kernel/allocator.rs
index 397a3dd57a9b..66575cf87ce2 100644
--- a/rust/kernel/allocator.rs
+++ b/rust/kernel/allocator.rs
@@ -11,9 +11,24 @@
 
 unsafe impl GlobalAlloc for KernelAllocator {
     unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        // Customized layouts from `Layout::from_size_align()` can have size < align, so pads first.
+        let layout = layout.pad_to_align();
+
+        let mut size = layout.size();
+
+        if layout.align() > bindings::BINDINGS_ARCH_SLAB_MINALIGN {
+            // The alignment requirement exceeds the slab guarantee, then tries to enlarges 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 muliples of
+            // `layout.align()`, so `next_power_of_two` gives enough alignment guarantee.
+            size = size.next_power_of_two();
+        }
+
         // `krealloc()` is used instead of `kmalloc()` because the latter is
         // an inline function and cannot be bound to as a result.
-        unsafe { bindings::krealloc(ptr::null(), layout.size(), bindings::GFP_KERNEL) as *mut u8 }
+        unsafe { bindings::krealloc(ptr::null(), size, bindings::GFP_KERNEL) as *mut u8 }
     }
 
     unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
-- 
2.39.2


             reply	other threads:[~2023-06-13 16:44 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-13 16:42 Boqun Feng [this message]
2023-06-13 19:27 ` [PATCH] rust: allocator: Prevents mis-aligned allocation Gary Guo
2023-06-13 20:38 ` Alice Ryhl
2023-06-14 14:32 ` Benno Lossin
2023-06-14 16:30 ` Martin Rodriguez Reboredo
2023-07-29 14:01 ` Miguel Ojeda
2023-07-29 23:40   ` Boqun Feng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230613164258.3831917-1-boqun.feng@gmail.com \
    --to=boqun.feng@gmail.com \
    --cc=42.hyeyoo@gmail.com \
    --cc=akpm@linux-foundation.org \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=cl@linux.com \
    --cc=dsosnowski@dsosnowski.pl \
    --cc=foxhlchen@gmail.com \
    --cc=gary@garyguo.net \
    --cc=geofft@ldpreload.com \
    --cc=iamjoonsoo.kim@lge.com \
    --cc=john.m.baublitz@gmail.com \
    --cc=keescook@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=nmi@metaspace.dk \
    --cc=ojeda@kernel.org \
    --cc=penberg@kernel.org \
    --cc=rientjes@google.com \
    --cc=roman.gushchin@linux.dev \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=vbabka@suse.cz \
    --cc=wedsonaf@gmail.com \
    --cc=yakoyoku@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).