Netdev List
 help / color / mirror / Atom feed
* [PATCH] rust: net: netlink: Migrate to zerocopy's `IntoBytes`
@ 2026-09-12  6:25 Sagar Taunk
  2026-09-13  1:38 ` Alexandre Courbot
  0 siblings, 1 reply; 2+ messages in thread
From: Sagar Taunk @ 2026-09-12  6:25 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, Miguel Ojeda, Boqun Feng, Gary Guo,
	Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
	Trevor Gross, Danilo Krummrich, Daniel Almeida, Tamir Duberstein,
	Alexandre Courbot, Onur Özkan, netdev, rust-for-linux,
	linux-kernel
  Cc: Sagar Taunk

Replace the kernel's own `transmute::FromBytes` and `AsBytes` traits
with their zerocopy equivalents. Specifically, this updates
`GenlMsg::put` to rely on `IntoBytes` for converting attributes into
byte slices.

Also, add `Immutable` trait bound on `GenlMsg::put` as zerocopy
splits the `no interior mutability` guarantee that `AsBytes` bundled
together.

Moreover, shashiko pointed out `put()` trusted an unchecked `as` cast
from `usize` to `c_int` for the attribute length. A length larger than
`i32::MAX` wraps to a negative value in that cast, which can pass
`nla_put()`'s own signed `skb_tailroom()` check and then be reinterpreted
as an enormous unsigned length via `__nla_reserve()`/`skb_put()`, leading
to a kernel panic via `skb_over_panic()`. Validate the length with
`c_int::try_from()` and reject it with `EMSGSIZE` instead.

Link: https://github.com/Rust-for-Linux/linux/issues/1241
Signed-off-by: Sagar Taunk <sagartaunk@proton.me>
---
 rust/kernel/net/netlink.rs | 23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/rust/kernel/net/netlink.rs b/rust/kernel/net/netlink.rs
index 22ef3dde36fa..f929f63b32c1 100644
--- a/rust/kernel/net/netlink.rs
+++ b/rust/kernel/net/netlink.rs
@@ -12,11 +12,12 @@
     alloc::{self, AllocError},
     error::to_result,
     prelude::*,
-    transmute::AsBytes,
     types::Opaque,
     ThisModule,
 };
 
+use zerocopy::{Immutable, IntoBytes};
+
 use core::{
     mem::ManuallyDrop,
     ptr::NonNull, //
@@ -84,14 +85,22 @@ impl GenlMsg {
     #[inline]
     fn put<T>(&mut self, attrtype: c_int, value: &T) -> Result
     where
-        T: ?Sized + AsBytes,
+        T: ?Sized + IntoBytes + Immutable,
     {
         let skb = self.skb.skb.as_ptr();
-        let len = size_of_val(value);
-        let ptr = core::ptr::from_ref(value).cast::<c_void>();
-        // SAFETY: `skb` is valid by `NetlinkSkBuff` type invariants, and the provided value is
-        // readable and initialized for its `size_of` bytes.
-        to_result(unsafe { bindings::nla_put(skb, attrtype, len as c_int, ptr) })
+        let bytes = value.as_bytes();
+        // `nla_put()` takes attrlen as a plain `c_int`. If `bytes.len()`
+        // doesn't fit, an `as` cast would wrap around a negative value.
+        // Which then, would feed a huge unsigned length to `__nla_reserve()`
+        // and `skb_put()` causing it to panic via `skb_over_panic()`. So,
+        // the following check will reject it instead.
+        let len = c_int::try_from(bytes.len()).map_err(|_| EMSGSIZE)?;
+        let ptr = bytes.as_ptr().cast::<c_void>();
+        // SAFETY: `skb` is valid as per `NetlinkSkBuff` type invariants.
+        // `bytes` is a valid Rust slice, so `ptr` is readable for `len`
+        // bytes, and `T: Immutable` guarantees nothing can mutate `*value`
+        // while `nla_put()` copies it.
+        to_result(unsafe { bindings::nla_put(skb, attrtype, len, ptr) })
     }
 
     /// Puts a `u32` attribute into the message.
-- 
2.55.0



^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-09-13  1:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-12  6:25 [PATCH] rust: net: netlink: Migrate to zerocopy's `IntoBytes` Sagar Taunk
2026-09-13  1:38 ` Alexandre Courbot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox