* [PATCH] rust: kernel: use strict provenance APIs
@ 2026-05-22 17:19 Tamir Duberstein
2026-05-25 13:48 ` Miguel Ojeda
2026-05-27 11:13 ` Gary Guo
0 siblings, 2 replies; 5+ messages in thread
From: Tamir Duberstein @ 2026-05-22 17:19 UTC (permalink / raw)
To: Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
Liam R. Howlett, Uladzislau Rezki, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Greg Kroah-Hartman, Rafael J. Wysocki,
Daniel Almeida, Rob Herring, Saravana Kannan, Bjorn Helgaas,
Krzysztof Wilczyński
Cc: rust-for-linux, linux-kernel, driver-core, devicetree, linux-pci,
Tamir Duberstein, Benno Lossin
Replace existing pointer-to-integer and integer-to-pointer conversions
with calls to the strict provenance APIs.
The strict provenance APIs were stabilized in Rust 1.84.0 [1]. Since
commit f32fb9c58a5b ("rust: bump Rust minimum supported version to
1.85.0 (Debian Trixie)"), the minimum supported Rust version is 1.85.0,
so no polyfills are needed.
Link: https://blog.rust-lang.org/2025/01/09/Rust-1.84.0.html#strict-provenance-apis [1]
Suggested-by: Benno Lossin <benno.lossin@proton.me>
Link: https://lore.kernel.org/all/D8EIXDMRXMJP.36TFCGWZBRS3Y@proton.me/
Signed-off-by: Tamir Duberstein <tamird@kernel.org>
---
rust/kernel/alloc.rs | 2 +-
rust/kernel/alloc/allocator.rs | 2 +-
rust/kernel/devres.rs | 4 ++--
rust/kernel/error.rs | 2 +-
rust/kernel/io.rs | 10 ++++++----
rust/kernel/io/mem.rs | 4 ++--
rust/kernel/of.rs | 2 +-
rust/kernel/pci/io.rs | 4 ++--
rust/kernel/str.rs | 16 ++++++----------
rust/kernel/uaccess.rs | 2 +-
10 files changed, 23 insertions(+), 25 deletions(-)
diff --git a/rust/kernel/alloc.rs b/rust/kernel/alloc.rs
index e38720349dcf..332e7fff15c4 100644
--- a/rust/kernel/alloc.rs
+++ b/rust/kernel/alloc.rs
@@ -262,7 +262,7 @@ unsafe fn free(ptr: NonNull<u8>, layout: Layout) {
/// Returns a properly aligned dangling pointer from the given `layout`.
pub(crate) fn dangling_from_layout(layout: Layout) -> NonNull<u8> {
- let ptr = layout.align() as *mut u8;
+ let ptr = core::ptr::without_provenance_mut(layout.align());
// SAFETY: `layout.align()` (and hence `ptr`) is guaranteed to be non-zero.
unsafe { NonNull::new_unchecked(ptr) }
diff --git a/rust/kernel/alloc/allocator.rs b/rust/kernel/alloc/allocator.rs
index 63bfb91b3671..9a56d2407d8f 100644
--- a/rust/kernel/alloc/allocator.rs
+++ b/rust/kernel/alloc/allocator.rs
@@ -280,7 +280,7 @@ fn new() -> Result<Self> {
fn is_aligned_to(&self, align: usize) -> bool {
assert!(align.is_power_of_two());
- let addr = self.0.as_ptr() as usize;
+ let addr = self.0.as_ptr().addr();
addr & (align - 1) == 0
}
}
diff --git a/rust/kernel/devres.rs b/rust/kernel/devres.rs
index 9e5f93aed20c..ecba524e41df 100644
--- a/rust/kernel/devres.rs
+++ b/rust/kernel/devres.rs
@@ -93,14 +93,14 @@ struct Inner<T> {
/// return Err(ENOMEM);
/// }
///
-/// Ok(IoMem(MmioRaw::new(addr as usize, SIZE)?))
+/// Ok(IoMem(MmioRaw::new(addr.expose_provenance(), SIZE)?))
/// }
/// }
///
/// impl<const SIZE: usize> Drop for IoMem<SIZE> {
/// fn drop(&mut self) {
/// // SAFETY: `self.0.addr()` is guaranteed to be properly mapped by `Self::new`.
-/// unsafe { bindings::iounmap(self.0.addr() as *mut c_void); };
+/// unsafe { bindings::iounmap(core::ptr::with_exposed_provenance_mut(self.0.addr())); };
/// }
/// }
///
diff --git a/rust/kernel/error.rs b/rust/kernel/error.rs
index 05cf869ac090..37eb14c71fb0 100644
--- a/rust/kernel/error.rs
+++ b/rust/kernel/error.rs
@@ -483,7 +483,7 @@ pub fn to_result(err: crate::ffi::c_int) -> Result {
/// # core::ptr::null_mut()
/// # }
/// # pub(super) unsafe fn non_null_ptr() -> *mut kernel::ffi::c_void {
-/// # 0x1234 as *mut kernel::ffi::c_void
+/// # core::ptr::without_provenance_mut(0x1234)
/// # }
/// # }
/// // SAFETY: ...
diff --git a/rust/kernel/io.rs b/rust/kernel/io.rs
index fcc7678fd9e3..a416221fb4a5 100644
--- a/rust/kernel/io.rs
+++ b/rust/kernel/io.rs
@@ -109,14 +109,14 @@ pub fn maxsize(&self) -> usize {
/// return Err(ENOMEM);
/// }
///
-/// Ok(IoMem(MmioRaw::new(addr as usize, SIZE)?))
+/// Ok(IoMem(MmioRaw::new(addr.expose_provenance(), SIZE)?))
/// }
/// }
///
/// impl<const SIZE: usize> Drop for IoMem<SIZE> {
/// fn drop(&mut self) {
/// // SAFETY: `self.0.addr()` is guaranteed to be properly mapped by `Self::new`.
-/// unsafe { bindings::iounmap(self.0.addr() as *mut c_void); };
+/// unsafe { bindings::iounmap(core::ptr::with_exposed_provenance_mut(self.0.addr())); };
/// }
/// }
///
@@ -733,12 +733,14 @@ macro_rules! impl_mmio_io_capable {
impl<const SIZE: usize> IoCapable<$ty> for $mmio<SIZE> {
unsafe fn io_read(&self, address: usize) -> $ty {
// SAFETY: By the trait invariant `address` is a valid address for MMIO operations.
- unsafe { bindings::$read_fn(address as *const c_void) }
+ unsafe { bindings::$read_fn(core::ptr::with_exposed_provenance(address)) }
}
unsafe fn io_write(&self, value: $ty, address: usize) {
// SAFETY: By the trait invariant `address` is a valid address for MMIO operations.
- unsafe { bindings::$write_fn(value, address as *mut c_void) }
+ unsafe {
+ bindings::$write_fn(value, core::ptr::with_exposed_provenance_mut(address))
+ }
}
}
};
diff --git a/rust/kernel/io/mem.rs b/rust/kernel/io/mem.rs
index 7dc78d547f7a..e7e909c6bb2d 100644
--- a/rust/kernel/io/mem.rs
+++ b/rust/kernel/io/mem.rs
@@ -266,7 +266,7 @@ fn ioremap(resource: &Resource) -> Result<Self> {
return Err(ENOMEM);
}
- let io = MmioRaw::new(addr as usize, size)?;
+ let io = MmioRaw::new(addr.expose_provenance(), size)?;
let io = IoMem { io };
Ok(io)
@@ -284,7 +284,7 @@ pub fn new<'a>(io_request: IoRequest<'a>) -> impl PinInit<Devres<Self>, Error> +
impl<const SIZE: usize> Drop for IoMem<SIZE> {
fn drop(&mut self) {
// SAFETY: Safe as by the invariant of `Io`.
- unsafe { bindings::iounmap(self.io.addr() as *mut c_void) }
+ unsafe { bindings::iounmap(core::ptr::with_exposed_provenance_mut(self.io.addr())) }
}
}
diff --git a/rust/kernel/of.rs b/rust/kernel/of.rs
index 58b20c367f99..95ef14b9a615 100644
--- a/rust/kernel/of.rs
+++ b/rust/kernel/of.rs
@@ -27,7 +27,7 @@ unsafe impl RawDeviceIdIndex for DeviceId {
const DRIVER_DATA_OFFSET: usize = core::mem::offset_of!(bindings::of_device_id, data);
fn index(&self) -> usize {
- self.0.data as usize
+ self.0.data.addr()
}
}
diff --git a/rust/kernel/pci/io.rs b/rust/kernel/pci/io.rs
index ae78676c927f..b5e3a68a7a11 100644
--- a/rust/kernel/pci/io.rs
+++ b/rust/kernel/pci/io.rs
@@ -175,7 +175,7 @@ pub(super) fn new(pdev: &Device, num: u32, name: &CStr) -> Result<Self> {
// `pdev` is valid by the invariants of `Device`.
// `num` is checked for validity by a previous call to `Device::resource_len`.
// `name` is always valid.
- let ioptr: usize = unsafe { bindings::pci_iomap(pdev.as_raw(), num, 0) } as usize;
+ let ioptr = unsafe { bindings::pci_iomap(pdev.as_raw(), num, 0) }.expose_provenance();
if ioptr == 0 {
// SAFETY:
// `pdev` is valid by the invariants of `Device`.
@@ -212,7 +212,7 @@ unsafe fn do_release(pdev: &Device, ioptr: usize, num: i32) {
// `ioptr` is valid by the safety requirements.
// `num` is valid by the safety requirements.
unsafe {
- bindings::pci_iounmap(pdev.as_raw(), ioptr as *mut c_void);
+ bindings::pci_iounmap(pdev.as_raw(), core::ptr::with_exposed_provenance_mut(ioptr));
bindings::pci_release_region(pdev.as_raw(), num);
}
}
diff --git a/rust/kernel/str.rs b/rust/kernel/str.rs
index 8311d91549e1..67aba11c9702 100644
--- a/rust/kernel/str.rs
+++ b/rust/kernel/str.rs
@@ -564,9 +564,9 @@ fn new() -> Self {
pub(crate) unsafe fn from_ptrs(pos: *mut u8, end: *mut u8) -> Self {
// INVARIANT: The safety requirements guarantee the type invariants.
Self {
- beg: pos as usize,
- pos: pos as usize,
- end: end as usize,
+ beg: pos.expose_provenance(),
+ pos: pos.expose_provenance(),
+ end: end.expose_provenance(),
}
}
@@ -577,7 +577,7 @@ pub(crate) unsafe fn from_ptrs(pos: *mut u8, end: *mut u8) -> Self {
/// The memory region starting at `buf` and extending for `len` bytes must be valid for writes
/// for the lifetime of the returned [`RawFormatter`].
pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self {
- let pos = buf as usize;
+ let pos = buf.expose_provenance();
// INVARIANT: We ensure that `end` is never less than `buf`, and the safety requirements
// guarantees that the memory region is valid for writes.
Self {
@@ -591,7 +591,7 @@ pub(crate) unsafe fn from_buffer(buf: *mut u8, len: usize) -> Self {
///
/// N.B. It may point to invalid memory.
pub(crate) fn pos(&self) -> *mut u8 {
- self.pos as *mut u8
+ core::ptr::with_exposed_provenance_mut(self.pos)
}
/// Returns the number of bytes written to the formatter.
@@ -613,11 +613,7 @@ fn write_str(&mut self, s: &str) -> fmt::Result {
// SAFETY: If `len_to_copy` is non-zero, then we know `pos` has not gone past `end`
// yet, so it is valid for write per the type invariants.
unsafe {
- core::ptr::copy_nonoverlapping(
- s.as_bytes().as_ptr(),
- self.pos as *mut u8,
- len_to_copy,
- )
+ core::ptr::copy_nonoverlapping(s.as_bytes().as_ptr(), self.pos(), len_to_copy)
};
}
diff --git a/rust/kernel/uaccess.rs b/rust/kernel/uaccess.rs
index 5f6c4d7a1a51..f06b4c1637ca 100644
--- a/rust/kernel/uaccess.rs
+++ b/rust/kernel/uaccess.rs
@@ -28,7 +28,7 @@ impl UserPtr {
/// Create a `UserPtr` from an integer representing the userspace address.
#[inline]
pub fn from_addr(addr: usize) -> Self {
- Self(addr as *mut c_void)
+ Self(core::ptr::without_provenance_mut(addr))
}
/// Create a `UserPtr` from a pointer representing the userspace address.
---
base-commit: 5d6919055dec134de3c40167a490f33c74c12581
change-id: 20260521-strict-provenance-redux-d58178caada3
Best regards,
--
Tamir Duberstein <tamird@kernel.org>
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] rust: kernel: use strict provenance APIs
2026-05-22 17:19 [PATCH] rust: kernel: use strict provenance APIs Tamir Duberstein
@ 2026-05-25 13:48 ` Miguel Ojeda
2026-05-26 9:09 ` Tamir Duberstein
2026-05-27 11:13 ` Gary Guo
1 sibling, 1 reply; 5+ messages in thread
From: Miguel Ojeda @ 2026-05-25 13:48 UTC (permalink / raw)
To: Tamir Duberstein
Cc: Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
Liam R. Howlett, Uladzislau Rezki, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Greg Kroah-Hartman, Rafael J. Wysocki,
Daniel Almeida, Rob Herring, Saravana Kannan, Bjorn Helgaas,
Krzysztof Wilczyński, rust-for-linux, linux-kernel,
driver-core, devicetree, linux-pci
On Fri, May 22, 2026 at 7:19 PM Tamir Duberstein <tamird@kernel.org> wrote:
>
> Suggested-by: Benno Lossin <benno.lossin@proton.me>
> Link: https://lore.kernel.org/all/D8EIXDMRXMJP.36TFCGWZBRS3Y@proton.me/
The linked suggestion seems to be about enabling the lints, not using
the provenance APIs (which we have been discussing for a long time).
Do we want to enable the lints after this? Or what am I missing?
In any case, some of these are not equivalent to the `as` casts, so
they are not a mechanical change. Could we have, at least for those,
the reason why it is OK to perform the change? (perhaps as separate
commits?)
Thanks for cleaning this up!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] rust: kernel: use strict provenance APIs
2026-05-25 13:48 ` Miguel Ojeda
@ 2026-05-26 9:09 ` Tamir Duberstein
0 siblings, 0 replies; 5+ messages in thread
From: Tamir Duberstein @ 2026-05-26 9:09 UTC (permalink / raw)
To: Miguel Ojeda
Cc: Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
Liam R. Howlett, Uladzislau Rezki, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Greg Kroah-Hartman, Rafael J. Wysocki,
Daniel Almeida, Rob Herring, Saravana Kannan, Bjorn Helgaas,
Krzysztof Wilczyński, rust-for-linux, linux-kernel,
driver-core, devicetree, linux-pci
On Mon, May 25, 2026 at 9:48 AM Miguel Ojeda
<miguel.ojeda.sandonis@gmail.com> wrote:
>
> On Fri, May 22, 2026 at 7:19 PM Tamir Duberstein <tamird@kernel.org> wrote:
> >
> > Suggested-by: Benno Lossin <benno.lossin@proton.me>
> > Link: https://lore.kernel.org/all/D8EIXDMRXMJP.36TFCGWZBRS3Y@proton.me/
>
> The linked suggestion seems to be about enabling the lints, not using
> the provenance APIs (which we have been discussing for a long time).
> Do we want to enable the lints after this? Or what am I missing?
You're right; I carried over the tag from the previous iteration
thinking it addressed usage when it actually suggested the lints. The
lints can't be enabled yet because they are not stable (not just in
our MSRV).
> In any case, some of these are not equivalent to the `as` casts, so
> they are not a mechanical change. Could we have, at least for those,
> the reason why it is OK to perform the change? (perhaps as separate
> commits?)
Correct. There are both behavior-preserving exposed-provenance
spellings and cases that deliberately avoid exposing provenance. I
will split those as you suggest.
> Thanks for cleaning this up!
Thanks for reviewing!
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] rust: kernel: use strict provenance APIs
2026-05-22 17:19 [PATCH] rust: kernel: use strict provenance APIs Tamir Duberstein
2026-05-25 13:48 ` Miguel Ojeda
@ 2026-05-27 11:13 ` Gary Guo
2026-05-27 13:12 ` Tamir Duberstein
1 sibling, 1 reply; 5+ messages in thread
From: Gary Guo @ 2026-05-27 11:13 UTC (permalink / raw)
To: Tamir Duberstein, Danilo Krummrich, Lorenzo Stoakes,
Vlastimil Babka, Liam R. Howlett, Uladzislau Rezki, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Greg Kroah-Hartman,
Rafael J. Wysocki, Daniel Almeida, Rob Herring, Saravana Kannan,
Bjorn Helgaas, Krzysztof Wilczyński
Cc: rust-for-linux, linux-kernel, driver-core, devicetree, linux-pci
On Fri May 22, 2026 at 6:19 PM BST, Tamir Duberstein wrote:
> Replace existing pointer-to-integer and integer-to-pointer conversions
> with calls to the strict provenance APIs.
>
> The strict provenance APIs were stabilized in Rust 1.84.0 [1]. Since
> commit f32fb9c58a5b ("rust: bump Rust minimum supported version to
> 1.85.0 (Debian Trixie)"), the minimum supported Rust version is 1.85.0,
> so no polyfills are needed.
>
> Link: https://blog.rust-lang.org/2025/01/09/Rust-1.84.0.html#strict-provenance-apis [1]
> Suggested-by: Benno Lossin <benno.lossin@proton.me>
> Link: https://lore.kernel.org/all/D8EIXDMRXMJP.36TFCGWZBRS3Y@proton.me/
> Signed-off-by: Tamir Duberstein <tamird@kernel.org>
> ---
> rust/kernel/alloc.rs | 2 +-
> rust/kernel/alloc/allocator.rs | 2 +-
> rust/kernel/devres.rs | 4 ++--
> rust/kernel/error.rs | 2 +-
> rust/kernel/io.rs | 10 ++++++----
> rust/kernel/io/mem.rs | 4 ++--
> rust/kernel/of.rs | 2 +-
> rust/kernel/pci/io.rs | 4 ++--
> rust/kernel/str.rs | 16 ++++++----------
> rust/kernel/uaccess.rs | 2 +-
This touches many subsystems, so you'd need to break this up.
I'm also refactoring in my I/O projection series which I've already
converted most stuff that I touched to strict provenance:
https://lore.kernel.org/rust-for-linux/20260421-io_projection-v2-0-4c251c692ef4@garyguo.net/
Best,
Gary
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] rust: kernel: use strict provenance APIs
2026-05-27 11:13 ` Gary Guo
@ 2026-05-27 13:12 ` Tamir Duberstein
0 siblings, 0 replies; 5+ messages in thread
From: Tamir Duberstein @ 2026-05-27 13:12 UTC (permalink / raw)
To: Gary Guo
Cc: Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
Liam R. Howlett, Uladzislau Rezki, Miguel Ojeda, Boqun Feng,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Greg Kroah-Hartman, Rafael J. Wysocki,
Daniel Almeida, Rob Herring, Saravana Kannan, Bjorn Helgaas,
Krzysztof Wilczyński, rust-for-linux, linux-kernel,
driver-core, devicetree, linux-pci
On Wed, May 27, 2026 at 7:13 AM Gary Guo <gary@garyguo.net> wrote:
>
> On Fri May 22, 2026 at 6:19 PM BST, Tamir Duberstein wrote:
> > Replace existing pointer-to-integer and integer-to-pointer conversions
> > with calls to the strict provenance APIs.
> >
> > The strict provenance APIs were stabilized in Rust 1.84.0 [1]. Since
> > commit f32fb9c58a5b ("rust: bump Rust minimum supported version to
> > 1.85.0 (Debian Trixie)"), the minimum supported Rust version is 1.85.0,
> > so no polyfills are needed.
> >
> > Link: https://blog.rust-lang.org/2025/01/09/Rust-1.84.0.html#strict-provenance-apis [1]
> > Suggested-by: Benno Lossin <benno.lossin@proton.me>
> > Link: https://lore.kernel.org/all/D8EIXDMRXMJP.36TFCGWZBRS3Y@proton.me/
> > Signed-off-by: Tamir Duberstein <tamird@kernel.org>
> > ---
> > rust/kernel/alloc.rs | 2 +-
> > rust/kernel/alloc/allocator.rs | 2 +-
> > rust/kernel/devres.rs | 4 ++--
> > rust/kernel/error.rs | 2 +-
> > rust/kernel/io.rs | 10 ++++++----
> > rust/kernel/io/mem.rs | 4 ++--
> > rust/kernel/of.rs | 2 +-
> > rust/kernel/pci/io.rs | 4 ++--
> > rust/kernel/str.rs | 16 ++++++----------
> > rust/kernel/uaccess.rs | 2 +-
>
> This touches many subsystems, so you'd need to break this up.
Ack.
> I'm also refactoring in my I/O projection series which I've already
> converted most stuff that I touched to strict provenance:
> https://lore.kernel.org/rust-for-linux/20260421-io_projection-v2-0-4c251c692ef4@garyguo.net/
Will wait until this lands to re-spin.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-05-27 13:13 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-22 17:19 [PATCH] rust: kernel: use strict provenance APIs Tamir Duberstein
2026-05-25 13:48 ` Miguel Ojeda
2026-05-26 9:09 ` Tamir Duberstein
2026-05-27 11:13 ` Gary Guo
2026-05-27 13:12 ` Tamir Duberstein
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox