[PATCH v3 1/2] rust: uaccess: add UserSliceWriter::clear()
From: Deborah Brouwer
Date: Fri Oct 16 2026 - 16:46:27 EST
Add a method to zero the remaining bytes in a UserSliceWriter.
If userspace provides a buffer that is larger than necessary, provide
a method to zero out the remaining UserSliceWriter buffer. This avoids
userspace consuming potentially uninitialized memory and/or mistaking it
for data intentionally provided by the kernel.
Use the #[inline] annotation to make this clear() method available for
inlining outside of the kernel crate.
Since clear_user() is architecturally defined and may be a macro or inline
function, add a rust helper to make clear_user() callable from rust.
Reviewed-by: Alice Ryhl <aliceryhl@xxxxxxxxxx>
Signed-off-by: Deborah Brouwer <deborah.brouwer@xxxxxxxxxxxxx>
---
rust/helpers/uaccess.c | 6 ++++++
rust/kernel/uaccess.rs | 24 ++++++++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/rust/helpers/uaccess.c b/rust/helpers/uaccess.c
index 6e59cc9c665c..e799d9ac9804 100644
--- a/rust/helpers/uaccess.c
+++ b/rust/helpers/uaccess.c
@@ -27,3 +27,9 @@ unsigned long rust_helper__copy_to_user(void __user *to, const void *from, unsig
return _inline_copy_to_user(to, from, n);
}
#endif
+
+__rust_helper unsigned long
+rust_helper_clear_user(void __user *to, unsigned long n)
+{
+ return clear_user(to, n);
+}
diff --git a/rust/kernel/uaccess.rs b/rust/kernel/uaccess.rs
index f1aecda7a90c..8e18285ec44b 100644
--- a/rust/kernel/uaccess.rs
+++ b/rust/kernel/uaccess.rs
@@ -638,6 +638,30 @@ pub fn write<T: AsBytes>(&mut self, value: &T) -> Result {
pub fn write_truncated<T: AsBytes>(&mut self, value: &T) -> Result<usize> {
self.write_slice_partial(value.as_bytes(), 0)
}
+
+ /// Zeros remaining bytes in the userspace buffer.
+ ///
+ /// Fails with [`EFAULT`] if the userspace memory cannot be cleared.
+ #[inline]
+ pub fn clear(&mut self) -> Result {
+ let len = self.length;
+
+ if len == 0 {
+ return Ok(());
+ }
+ // SAFETY: `clear_user` checks the userspace address and range and handles
+ // faults when accessing userspace memory
+ let res = unsafe { bindings::clear_user(self.ptr.as_mut_ptr(), len) };
+
+ if res != 0 {
+ return Err(EFAULT);
+ }
+
+ self.ptr = self.ptr.wrapping_byte_add(len);
+ self.length = 0;
+
+ Ok(())
+ }
}
/// Reads a nul-terminated string into `dst` and returns the length.
--
2.56.0