* [PATCH v7 0/4] rust: Add safe pointer formatting support
@ 2025-12-29 7:21 Ke Sun
2025-12-29 7:21 ` [PATCH v7 1/4] lib/vsprintf: Export functions for Rust " Ke Sun
` (4 more replies)
0 siblings, 5 replies; 18+ messages in thread
From: Ke Sun @ 2025-12-29 7:21 UTC (permalink / raw)
To: Dirk Behme, Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt,
Timur Tabi, Danilo Krummrich, Benno Lossin
Cc: John Ogness, Andy Shevchenko, Rasmus Villemoes, Andrew Morton,
Gary Guo, Björn Roy Baron, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Tamir Duberstein, Ke Sun, rust-for-linux, Ke Sun
This patch series adds safe pointer formatting support for Rust kernel code,
providing three pointer wrapper types (HashedPtr, RawPtr, RestrictedPtr) that
correspond to C kernel's printk format specifiers %p, %px, and %pK.
The implementation ensures that raw pointers are automatically hashed when
formatted with {:p}, providing safe default behavior that prevents information
leaks about kernel memory layout. Users can also explicitly use wrapper types
when they need specific formatting behavior.
---
v7:
- Refactor kptr_restrict handling: extract kptr_restrict_value() from
restricted_pointer() in lib/vsprintf.c and export it for Rust use, and
improve RestrictedPtr::fmt() implementation to directly handle
kptr_restrict_value() return values (0, 1, 2, -1) for better code clarity
- Remove Debug derive from pointer wrapper types (HashedPtr, RestrictedPtr, RawPtr)
v6: https://lore.kernel.org/rust-for-linux/20251227033958.3713232-1-sunke@kylinos.cn/
- Fix placeholder formatting to use `f.pad()` instead of `f.write_str()` in
format_hashed_ptr(), ensuring width, alignment, and padding options are
correctly applied to PTR_PLACEHOLDER
v5: https://lore.kernel.org/rust-for-linux/20251226140751.2215563-1-sunke@kylinos.cn/
- Format use statements in rust/kernel/ptr.rs and rust/kernel/fmt.rs using kernel
vertical style with alphabetical ordering
- Remove unnecessary SAFETY comment in rust/kernel/ptr.rs (addressed Clippy warning)
- Update type ordering to alphabetical (HashedPtr, RawPtr, RestrictedPtr) in
fmt.rs macro invocation
v4: https://lore.kernel.org/rust-for-linux/20251225225709.3944255-1-sunke@kylinos.cn/
- Use Pointer::fmt() instead of write!(f, "{:p}", ...) to preserve formatting
options (width, alignment, padding characters)
- Improve code structure: reduce unsafe block scope, use early return pattern
- Add doctests with formatting option tests for all pointer wrapper types
- Enhance documentation with detailed formatting options section, including
examples for width, alignment, and padding
- Fix RestrictedPtr example to use pr_info! instead of seq_print! in docs
v3: https://lore.kernel.org/rust-for-linux/20251224081315.729684-1-sunke@kylinos.cn/
- Export ptr_to_hashval() from lib/vsprintf.c for Rust pointer hashing
- Add three pointer wrapper types (HashedPtr, RestrictedPtr, RawPtr) in
rust/kernel/ptr.rs corresponding to %p, %pK, and %px
- Make raw pointers automatically use HashedPtr when formatted with {:p}
- Add documentation for pointer wrapper types
v2: https://lore.kernel.org/rust-for-linux/20251223033018.2814732-1-sunke@kylinos.cn/
- Disabled {:p} raw pointer printing by default to prevent accidental
information leaks
v1: https://lore.kernel.org/rust-for-linux/20251218032709.2184890-1-sunke@kylinos.cn/
- Initial implementation that directly printed raw pointers
---
Ke Sun (4):
lib/vsprintf: Export functions for Rust pointer formatting support
rust: kernel: Add pointer wrapper types for safe pointer formatting
rust: fmt: Default raw pointer formatting to HashedPtr
docs: rust: Add pointer formatting documentation
Documentation/rust/index.rst | 1 +
Documentation/rust/pointer-formatting.rst | 101 +++++++++
include/linux/printk.h | 10 +
lib/vsprintf.c | 55 +++--
rust/kernel/fmt.rs | 69 +++++-
rust/kernel/ptr.rs | 254 +++++++++++++++++++++-
6 files changed, 473 insertions(+), 17 deletions(-)
create mode 100644 Documentation/rust/pointer-formatting.rst
base-commit: 9448598b22c50c8a5bb77a9103e2d49f134c9578
--
2.43.0
^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v7 1/4] lib/vsprintf: Export functions for Rust pointer formatting support
2025-12-29 7:21 [PATCH v7 0/4] rust: Add safe pointer formatting support Ke Sun
@ 2025-12-29 7:21 ` Ke Sun
2025-12-29 10:44 ` Dirk Behme
2025-12-29 14:18 ` Andy Shevchenko
2025-12-29 7:21 ` [PATCH v7 2/4] rust: kernel: Add pointer wrapper types for safe pointer formatting Ke Sun
` (3 subsequent siblings)
4 siblings, 2 replies; 18+ messages in thread
From: Ke Sun @ 2025-12-29 7:21 UTC (permalink / raw)
To: Dirk Behme, Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt,
Timur Tabi, Danilo Krummrich, Benno Lossin
Cc: John Ogness, Andy Shevchenko, Rasmus Villemoes, Andrew Morton,
Gary Guo, Björn Roy Baron, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Tamir Duberstein, Ke Sun, rust-for-linux, Ke Sun
Export ptr_to_hashval() and extract kptr_restrict_value() to enable
Rust code to use kernel pointer formatting functionality.
- Export ptr_to_hashval() with EXPORT_SYMBOL_GPL for pointer hashing.
This function is used to hash kernel pointers before printing them,
preventing information leaks about kernel memory layout.
- Extract kptr_restrict handling logic from restricted_pointer() into
a separate exported function kptr_restrict_value() that can be
reused by both restricted_pointer() (for %pK format specifier) and
Rust code.
The kptr_restrict_value() function:
- Returns 0, 1, or 2 to indicate the kptr_restrict sysctl value
- Returns -1 for error case (IRQ context with kptr_restrict==1)
- Modifies the pointer value through @pptr parameter when needed
(sets to NULL when access should be restricted)
These functions are needed for the HashedPtr and RestrictedPtr wrapper
types in rust/kernel/ptr.rs to provide safe pointer formatting that
matches C kernel patterns.
This refactoring:
- Allows restricted_pointer() to reuse the common logic while
maintaining the same behavior
- Enables Rust code to use the same kptr_restrict handling logic
- Reduces code duplication
Signed-off-by: Ke Sun <sunke@kylinos.cn>
Suggested-by: Boqun Feng <boqun.feng@gmail.com>
---
include/linux/printk.h | 10 ++++++++
lib/vsprintf.c | 55 ++++++++++++++++++++++++++++++++----------
2 files changed, 52 insertions(+), 13 deletions(-)
diff --git a/include/linux/printk.h b/include/linux/printk.h
index 45c663124c9bd..91380b1eff1a1 100644
--- a/include/linux/printk.h
+++ b/include/linux/printk.h
@@ -385,6 +385,16 @@ extern void __printk_cpu_sync_put(void);
extern int kptr_restrict;
+/**
+ * kptr_restrict_value - Determine what pointer value should be used for %pK
+ * @pptr: Pointer to the pointer value (may be modified)
+ *
+ * Returns:
+ * - 0, 1, or 2: The kptr_restrict value if pointer should be used
+ * - -1: Error case (IRQ context with kptr_restrict==1), *pptr unchanged
+ */
+int kptr_restrict_value(const void **pptr);
+
/**
* pr_fmt - used by the pr_*() macros to generate the printk format string
* @fmt: format string passed from a pr_*() macro
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index a3790c43a0aba..29d2e681c6e73 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -811,6 +811,7 @@ int ptr_to_hashval(const void *ptr, unsigned long *hashval_out)
{
return __ptr_to_hashval(ptr, hashval_out);
}
+EXPORT_SYMBOL_GPL(ptr_to_hashval);
static char *ptr_to_id(char *buf, char *end, const void *ptr,
struct printf_spec spec)
@@ -857,14 +858,28 @@ static char *default_pointer(char *buf, char *end, const void *ptr,
int kptr_restrict __read_mostly;
-static noinline_for_stack
-char *restricted_pointer(char *buf, char *end, const void *ptr,
- struct printf_spec spec)
+/**
+ * kptr_restrict_value - Determine what pointer value should be used for %pK
+ * @pptr: Pointer to the pointer value (may be modified)
+ *
+ * This function determines what pointer value should be printed based on the
+ * kptr_restrict sysctl setting:
+ *
+ * - kptr_restrict == 0: Return 0 (use original pointer, will be hashed)
+ * - kptr_restrict == 1: Return 1 if current process has CAP_SYSLOG and same
+ * euid/egid, otherwise set *pptr to NULL and return 1
+ * - kptr_restrict >= 2: Set *pptr to NULL and return 2
+ *
+ * Returns:
+ * - 0, 1, or 2: The kptr_restrict value if pointer should be used
+ * - -1: Error case (IRQ context with kptr_restrict==1), *pptr unchanged
+ */
+int kptr_restrict_value(const void **pptr)
{
switch (kptr_restrict) {
case 0:
/* Handle as %p, hash and do _not_ leak addresses. */
- return default_pointer(buf, end, ptr, spec);
+ return 0;
case 1: {
const struct cred *cred;
@@ -872,11 +887,8 @@ char *restricted_pointer(char *buf, char *end, const void *ptr,
* kptr_restrict==1 cannot be used in IRQ context
* because its test for CAP_SYSLOG would be meaningless.
*/
- if (in_hardirq() || in_serving_softirq() || in_nmi()) {
- if (spec.field_width == -1)
- spec.field_width = 2 * sizeof(ptr);
- return error_string(buf, end, "pK-error", spec);
- }
+ if (in_hardirq() || in_serving_softirq() || in_nmi())
+ return -1;
/*
* Only print the real pointer value if the current
@@ -891,15 +903,32 @@ char *restricted_pointer(char *buf, char *end, const void *ptr,
if (!has_capability_noaudit(current, CAP_SYSLOG) ||
!uid_eq(cred->euid, cred->uid) ||
!gid_eq(cred->egid, cred->gid))
- ptr = NULL;
- break;
+ *pptr = NULL;
+ return 1;
}
case 2:
default:
/* Always print 0's for %pK */
- ptr = NULL;
- break;
+ *pptr = NULL;
+ return 2;
}
+}
+EXPORT_SYMBOL_GPL(kptr_restrict_value);
+
+static noinline_for_stack
+char *restricted_pointer(char *buf, char *end, const void *ptr,
+ struct printf_spec spec)
+{
+ int ret = kptr_restrict_value(&ptr);
+
+ if (ret < 0) {
+ if (spec.field_width == -1)
+ spec.field_width = 2 * sizeof(ptr);
+ return error_string(buf, end, "pK-error", spec);
+ }
+
+ if (ret == 0)
+ return default_pointer(buf, end, ptr, spec);
return pointer_string(buf, end, ptr, spec);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v7 2/4] rust: kernel: Add pointer wrapper types for safe pointer formatting
2025-12-29 7:21 [PATCH v7 0/4] rust: Add safe pointer formatting support Ke Sun
2025-12-29 7:21 ` [PATCH v7 1/4] lib/vsprintf: Export functions for Rust " Ke Sun
@ 2025-12-29 7:21 ` Ke Sun
2025-12-29 9:03 ` Alice Ryhl
2025-12-29 7:21 ` [PATCH v7 3/4] rust: fmt: Default raw pointer formatting to HashedPtr Ke Sun
` (2 subsequent siblings)
4 siblings, 1 reply; 18+ messages in thread
From: Ke Sun @ 2025-12-29 7:21 UTC (permalink / raw)
To: Dirk Behme, Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt,
Timur Tabi, Danilo Krummrich, Benno Lossin
Cc: John Ogness, Andy Shevchenko, Rasmus Villemoes, Andrew Morton,
Gary Guo, Björn Roy Baron, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Tamir Duberstein, Ke Sun, rust-for-linux, Ke Sun
Add three pointer wrapper types (HashedPtr, RestrictedPtr, RawPtr) to
rust/kernel/ptr.rs that correspond to C kernel's printk format specifiers
%p, %pK, and %px. These types provide type-safe pointer formatting that
matches C kernel patterns.
These wrapper types implement core::fmt::Pointer and delegate to the
corresponding kernel formatting functions, enabling safe pointer
formatting in Rust code that prevents information leaks about kernel
memory layout.
Users can explicitly use these types:
pr_info!("{:p}\n", HashedPtr::from(ptr));
pr_info!("{:p}\n", RestrictedPtr::from(ptr));
pr_info!("{:p}\n", RawPtr::from(ptr));
Signed-off-by: Ke Sun <sunke@kylinos.cn>
Suggested-by: Dirk Behme <dirk.behme@gmail.com>
---
rust/kernel/ptr.rs | 254 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 251 insertions(+), 3 deletions(-)
diff --git a/rust/kernel/ptr.rs b/rust/kernel/ptr.rs
index e3893ed04049d..ccc5aa83b612c 100644
--- a/rust/kernel/ptr.rs
+++ b/rust/kernel/ptr.rs
@@ -1,11 +1,22 @@
// SPDX-License-Identifier: GPL-2.0
//! Types and functions to work with pointers and addresses.
+//!
+//! This module provides wrapper types for formatting kernel pointers that correspond to the
+//! C kernel's printk format specifiers `%p`, `%pK`, and `%px`.
-use core::mem::align_of;
-use core::num::NonZero;
+use core::{
+ fmt,
+ fmt::Pointer,
+ mem::align_of,
+ num::NonZero, //
+};
-use crate::build_assert;
+use crate::{
+ bindings,
+ build_assert,
+ ffi::c_void, //
+};
/// Type representing an alignment, which is always a power of two.
///
@@ -225,3 +236,240 @@ fn align_up(self, alignment: Alignment) -> Option<Self> {
}
impl_alignable_uint!(u8, u16, u32, u64, usize);
+
+/// Placeholder string used when pointer hashing is not ready yet.
+const PTR_PLACEHOLDER: &str = if core::mem::size_of::<*const c_void>() == 8 {
+ "(____ptrval____)"
+} else {
+ "(ptrval)"
+};
+
+/// Macro to implement common methods for pointer wrapper types.
+macro_rules! impl_ptr_wrapper {
+ ($($name:ident),* $(,)?) => {
+ $(
+ impl $name {
+ /// Creates a new instance from a raw pointer.
+ #[inline]
+ pub fn from<T>(ptr: *const T) -> Self {
+ Self(ptr.cast())
+ }
+
+ /// Creates a new instance from a mutable raw pointer.
+ #[inline]
+ pub fn from_mut<T>(ptr: *mut T) -> Self {
+ Self(ptr.cast())
+ }
+
+ /// Returns the inner raw pointer.
+ #[inline]
+ pub fn as_ptr(&self) -> *const c_void {
+ self.0
+ }
+ }
+
+ impl<T> From<*const T> for $name {
+ #[inline]
+ fn from(ptr: *const T) -> Self {
+ Self::from(ptr)
+ }
+ }
+
+ impl<T> From<*mut T> for $name {
+ #[inline]
+ fn from(ptr: *mut T) -> Self {
+ Self::from_mut(ptr)
+ }
+ }
+ )*
+ };
+}
+
+/// Helper function to hash a pointer and format it.
+///
+/// Returns `Ok(())` if the hash was successfully computed and formatted,
+/// or the placeholder string if hashing is not ready yet.
+fn format_hashed_ptr(ptr: *const c_void, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let mut hashval: crate::ffi::c_ulong = 0;
+ // SAFETY: We're calling the kernel's ptr_to_hashval function which handles
+ // hashing. This is safe as long as ptr is a valid pointer value.
+ let ret = unsafe { bindings::ptr_to_hashval(ptr, core::ptr::addr_of_mut!(hashval)) };
+
+ if ret != 0 {
+ // Hash not ready yet, print placeholder with formatting options applied
+ // Using `pad()` ensures width, alignment, and padding options are respected
+ return f.pad(PTR_PLACEHOLDER);
+ }
+
+ // Successfully got hash value, format it using Pointer::fmt to preserve
+ // formatting options (width, alignment, padding, etc.)
+ Pointer::fmt(&(hashval as *const c_void), f)
+}
+
+/// A pointer that will be hashed when printed (corresponds to `%p`).
+///
+/// This is the default behavior for kernel pointers - they are hashed to prevent
+/// leaking information about the kernel memory layout.
+///
+/// # Example
+///
+/// ```
+/// use kernel::{
+/// prelude::fmt,
+/// ptr::HashedPtr,
+/// str::CString, //
+/// };
+///
+/// let ptr = HashedPtr::from(0x12345678 as *const u8);
+/// pr_info!("Hashed pointer: {:016p}\n", ptr);
+///
+/// // Width option test
+/// let cstr = CString::try_from_fmt(fmt!("{:30p}", ptr))?;
+/// let width_30 = cstr.to_str()?;
+/// assert_eq!(width_30.len(), 30);
+/// # Ok::<(), kernel::error::Error>(())
+/// ```
+#[repr(transparent)]
+#[derive(Copy, Clone)]
+pub struct HashedPtr(*const c_void);
+
+impl fmt::Pointer for HashedPtr {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ // Handle NULL pointers - print them directly
+ if self.0.is_null() {
+ return Pointer::fmt(&self.0, f);
+ }
+
+ format_hashed_ptr(self.0, f)
+ }
+}
+
+/// A pointer that will be restricted based on `kptr_restrict` when printed (corresponds to `%pK`).
+///
+/// This is intended for use in procfs/sysfs files that are read by userspace.
+/// The behavior depends on the `kptr_restrict` sysctl setting.
+///
+/// # Example
+///
+/// ```
+/// use kernel::{
+/// prelude::fmt,
+/// ptr::RestrictedPtr,
+/// str::CString, //
+/// };
+///
+/// let ptr = RestrictedPtr::from(0x12345678 as *const u8);
+/// pr_info!("Restricted pointer: {:016p}\n", ptr);
+///
+/// // Width option test
+/// let cstr = CString::try_from_fmt(fmt!("{:30p}", ptr))?;
+/// let width_30 = cstr.to_str()?;
+/// assert_eq!(width_30.len(), 30);
+/// # Ok::<(), kernel::error::Error>(())
+/// ```
+#[repr(transparent)]
+#[derive(Copy, Clone)]
+pub struct RestrictedPtr(*const c_void);
+
+impl fmt::Pointer for RestrictedPtr {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ // Handle NULL pointers
+ if self.0.is_null() {
+ return Pointer::fmt(&self.0, f);
+ }
+
+ // Use kptr_restrict_value to handle all kptr_restrict cases.
+ // - Returns 0: kptr_restrict == 0, use original pointer (needs hashing)
+ // - Returns 1: kptr_restrict == 1, *pptr may be modified to NULL if no permission
+ // - Returns 2: kptr_restrict >= 2, *pptr is set to NULL
+ // - Returns -1: IRQ context with kptr_restrict == 1 (error case)
+ let mut ptr_value = self.0;
+ // SAFETY: kptr_restrict_value handles capability checks and IRQ context.
+ // It may modify ptr_value to NULL if there's no permission.
+ let ret = unsafe { bindings::kptr_restrict_value(core::ptr::addr_of_mut!(ptr_value)) };
+
+ match ret {
+ -1 => {
+ // IRQ context with kptr_restrict == 1 - print error placeholder
+ // This should not happen in normal Rust code, but handle it gracefully
+ f.pad("(pK-error)")
+ }
+ 0 => {
+ // kptr_restrict == 0: hash the pointer (same as %p)
+ format_hashed_ptr(self.0, f)
+ }
+ 1 => {
+ // kptr_restrict == 1: print raw pointer if ptr_value is non-null,
+ // otherwise print 0 (no permission)
+ if ptr_value.is_null() {
+ Pointer::fmt(&core::ptr::null::<c_void>(), f)
+ } else {
+ // Print the raw pointer directly (like %px)
+ // This matches C behavior: pointer_string() prints the raw address
+ Pointer::fmt(&ptr_value, f)
+ }
+ }
+ _ => {
+ // kptr_restrict >= 2: always print 0
+ // ptr_value should already be NULL, but check to be safe
+ Pointer::fmt(&core::ptr::null::<c_void>(), f)
+ }
+ }
+ }
+}
+
+/// A pointer that will be printed as its raw address (corresponds to `%px`).
+///
+/// **Warning**: This exposes the real kernel address and should only be used
+/// for debugging purposes. Consider using [`HashedPtr`] or [`RestrictedPtr`] instead.
+///
+/// # Example
+///
+/// ```
+/// use kernel::{
+/// prelude::fmt,
+/// ptr::RawPtr,
+/// str::CString, //
+/// };
+///
+/// let ptr = RawPtr::from(0x12345678 as *const u8);
+///
+/// // Basic formatting
+/// let cstr = CString::try_from_fmt(fmt!("{:p}", ptr))?;
+/// let formatted = cstr.to_str()?;
+/// assert_eq!(formatted, "0x12345678");
+///
+/// // Right align with zero padding, width 30
+/// let cstr = CString::try_from_fmt(fmt!("{:0>30p}", ptr))?;
+/// let right_zero = cstr.to_str()?;
+/// assert_eq!(right_zero, "000000000000000000000x12345678");
+///
+/// // Left align with zero padding, width 30
+/// let cstr = CString::try_from_fmt(fmt!("{:0<30p}", ptr))?;
+/// let left_zero = cstr.to_str()?;
+/// assert_eq!(left_zero, "0x1234567800000000000000000000");
+///
+/// // Center align with zero padding, width 30
+/// let cstr = CString::try_from_fmt(fmt!("{:0^30p}", ptr))?;
+/// let center_zero = cstr.to_str()?;
+/// assert_eq!(center_zero, "00000000000x123456780000000000");
+/// # Ok::<(), kernel::error::Error>(())
+/// ```
+#[repr(transparent)]
+#[derive(Copy, Clone)]
+pub struct RawPtr(*const c_void);
+
+impl fmt::Pointer for RawPtr {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ // Directly format the raw address - no hashing or restriction.
+ // This corresponds to %px behavior.
+ Pointer::fmt(&self.0, f)
+ }
+}
+
+// Implement common methods for all pointer wrapper types
+impl_ptr_wrapper!(
+ HashedPtr,
+ RawPtr,
+ RestrictedPtr, //
+);
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v7 3/4] rust: fmt: Default raw pointer formatting to HashedPtr
2025-12-29 7:21 [PATCH v7 0/4] rust: Add safe pointer formatting support Ke Sun
2025-12-29 7:21 ` [PATCH v7 1/4] lib/vsprintf: Export functions for Rust " Ke Sun
2025-12-29 7:21 ` [PATCH v7 2/4] rust: kernel: Add pointer wrapper types for safe pointer formatting Ke Sun
@ 2025-12-29 7:21 ` Ke Sun
2025-12-29 7:21 ` [PATCH v7 4/4] docs: rust: Add pointer formatting documentation Ke Sun
2025-12-29 14:11 ` [PATCH v7 0/4] rust: Add safe pointer formatting support Andy Shevchenko
4 siblings, 0 replies; 18+ messages in thread
From: Ke Sun @ 2025-12-29 7:21 UTC (permalink / raw)
To: Dirk Behme, Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt,
Timur Tabi, Danilo Krummrich, Benno Lossin
Cc: John Ogness, Andy Shevchenko, Rasmus Villemoes, Andrew Morton,
Gary Guo, Björn Roy Baron, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Tamir Duberstein, Ke Sun, rust-for-linux, Ke Sun
Make raw pointers (*const T, *mut T) automatically use HashedPtr when
formatted with {:p}, providing safe default behavior for kernel pointers.
This allows users to format raw pointers directly:
pr_info!("{:p}\n", ptr); // Automatically hashed
While still allowing explicit use of wrapper types when needed:
pr_info!("{:p}\n", RestrictedPtr::from(ptr));
pr_info!("{:p}\n", RawPtr::from(ptr));
Signed-off-by: Ke Sun <sunke@kylinos.cn>
---
rust/kernel/fmt.rs | 69 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 68 insertions(+), 1 deletion(-)
diff --git a/rust/kernel/fmt.rs b/rust/kernel/fmt.rs
index 84d634201d90a..197687261b4e9 100644
--- a/rust/kernel/fmt.rs
+++ b/rust/kernel/fmt.rs
@@ -6,6 +6,12 @@
pub use core::fmt::{Arguments, Debug, Error, Formatter, Result, Write};
+use crate::ptr::{
+ HashedPtr,
+ RawPtr,
+ RestrictedPtr, //
+};
+
/// Internal adapter used to route allow implementations of formatting traits for foreign types.
///
/// It is inserted automatically by the [`fmt!`] macro and is not meant to be used directly.
@@ -28,7 +34,68 @@ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
}
use core::fmt::{Binary, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex};
-impl_fmt_adapter_forward!(Debug, LowerHex, UpperHex, Octal, Binary, Pointer, LowerExp, UpperExp);
+impl_fmt_adapter_forward!(Debug, LowerHex, UpperHex, Octal, Binary, LowerExp, UpperExp);
+
+// Special handling for Pointer: default to HashedPtr for raw pointers.
+// This overrides the default Pointer implementation for raw pointers to use hashing,
+// which is the safe default behavior for kernel pointers.
+impl<T> Pointer for Adapter<*const T> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ let Self(ptr) = self;
+ Pointer::fmt(&HashedPtr::from(*ptr), f)
+ }
+}
+
+impl<T> Pointer for Adapter<*mut T> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ let Self(ptr) = self;
+ Pointer::fmt(&HashedPtr::from_mut(*ptr), f)
+ }
+}
+
+// Handle references to raw pointers (needed when pointers are passed by reference in macros).
+impl<T> Pointer for Adapter<&*const T> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ let Self(ptr) = self;
+ Pointer::fmt(&HashedPtr::from(**ptr), f)
+ }
+}
+
+impl<T> Pointer for Adapter<&*mut T> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ let Self(ptr) = self;
+ Pointer::fmt(&HashedPtr::from_mut(**ptr), f)
+ }
+}
+
+// For wrapper types that implement Pointer (like HashedPtr, RawPtr, RestrictedPtr),
+// forward to their implementation. This allows explicit wrapper types to use their
+// own formatting logic instead of being converted to HashedPtr.
+macro_rules! impl_pointer_adapter_forward {
+ ($($ty:ty),* $(,)?) => {
+ $(
+ impl Pointer for Adapter<$ty> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ let Self(t) = self;
+ Pointer::fmt(t, f)
+ }
+ }
+
+ impl Pointer for Adapter<&$ty> {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ let Self(t) = self;
+ Pointer::fmt(*t, f)
+ }
+ }
+ )*
+ };
+}
+
+impl_pointer_adapter_forward!(
+ HashedPtr,
+ RawPtr,
+ RestrictedPtr, //
+);
/// A copy of [`core::fmt::Display`] that allows us to implement it for foreign types.
///
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v7 4/4] docs: rust: Add pointer formatting documentation
2025-12-29 7:21 [PATCH v7 0/4] rust: Add safe pointer formatting support Ke Sun
` (2 preceding siblings ...)
2025-12-29 7:21 ` [PATCH v7 3/4] rust: fmt: Default raw pointer formatting to HashedPtr Ke Sun
@ 2025-12-29 7:21 ` Ke Sun
2025-12-29 14:11 ` [PATCH v7 0/4] rust: Add safe pointer formatting support Andy Shevchenko
4 siblings, 0 replies; 18+ messages in thread
From: Ke Sun @ 2025-12-29 7:21 UTC (permalink / raw)
To: Dirk Behme, Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt,
Timur Tabi, Danilo Krummrich, Benno Lossin
Cc: John Ogness, Andy Shevchenko, Rasmus Villemoes, Andrew Morton,
Gary Guo, Björn Roy Baron, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Tamir Duberstein, Ke Sun, rust-for-linux, Ke Sun
Add a brief documentation for Rust pointer wrapper types (HashedPtr,
RestrictedPtr, RawPtr) that correspond to C kernel's printk format
specifiers %p, %pK, and %px.
The documentation provides:
- Overview of the three wrapper types
- Usage examples for each type
- When to use each type
- Security considerations
This complements the general pointer formatting documentation in
Documentation/core-api/printk-formats.rst.
Signed-off-by: Ke Sun <sunke@kylinos.cn>
---
Documentation/rust/index.rst | 1 +
Documentation/rust/pointer-formatting.rst | 101 ++++++++++++++++++++++
2 files changed, 102 insertions(+)
create mode 100644 Documentation/rust/pointer-formatting.rst
diff --git a/Documentation/rust/index.rst b/Documentation/rust/index.rst
index ec62001c7d8c7..4f4f8b393031e 100644
--- a/Documentation/rust/index.rst
+++ b/Documentation/rust/index.rst
@@ -55,6 +55,7 @@ more details.
coding-guidelines
arch-support
testing
+ pointer-formatting
You can also find learning materials for Rust in its section in
:doc:`../process/kernel-docs`.
diff --git a/Documentation/rust/pointer-formatting.rst b/Documentation/rust/pointer-formatting.rst
new file mode 100644
index 0000000000000..9407307216c9a
--- /dev/null
+++ b/Documentation/rust/pointer-formatting.rst
@@ -0,0 +1,101 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Pointer Formatting in Rust
+===========================
+
+This document describes how to format kernel pointers safely in Rust code,
+corresponding to the C kernel's printk format specifiers ``%p``, ``%pK``, and ``%px``.
+
+For general information about pointer formatting in the kernel, please refer to
+:doc:`../core-api/printk-formats`.
+
+Overview
+--------
+
+The Rust kernel provides three wrapper types for formatting kernel pointers:
+
+- **``HashedPtr``** → ``%p`` (hashed, default)
+- **``RestrictedPtr``** → ``%pK`` (restricted, respects ``kptr_restrict``)
+- **``RawPtr``** → ``%px`` (raw address, debug only)
+
+When formatting raw pointers (``*const T`` or ``*mut T``) with ``{:p}``,
+they are automatically wrapped with ``HashedPtr``, providing safe default behavior.
+
+HashedPtr (%p)
+--------------
+
+Use ``HashedPtr`` for general kernel logging. Pointers are hashed before printing
+to prevent leaking information about the kernel memory layout.
+
+**Example**::
+
+ use kernel::ptr::HashedPtr;
+
+ pr_info!("Device pointer: {:p}\n", HashedPtr::from(ptr));
+
+RestrictedPtr (%pK)
+-------------------
+
+Use ``RestrictedPtr`` when producing content of a file read by userspace from
+e.g. procfs or sysfs (using e.g. ``seq_print!()``, not ``pr_info!()``). The behavior
+depends on the ``kptr_restrict`` sysctl setting.
+
+**Example**::
+
+ use kernel::ptr::RestrictedPtr;
+
+ seq_print!(seq_file, "Pointer: {:p}\n", RestrictedPtr::from(ptr));
+
+For more details about ``kptr_restrict``, see :doc:`../admin-guide/sysctl/kernel`.
+
+RawPtr (%px)
+------------
+
+**Warning**: This exposes the real kernel address and should **only** be used
+for debugging purposes.
+
+**Example**::
+
+ use kernel::ptr::RawPtr;
+
+ pr_info!("Debug pointer: {:p}\n", RawPtr::from(ptr));
+
+Formatting Options
+------------------
+
+All pointer wrapper types support standard Rust formatting options including
+width, alignment, and padding characters. These options are preserved through
+the formatting system.
+
+The following examples demonstrate formatting options using ``RawPtr`` for
+predictable output. The same options work with ``HashedPtr`` and
+``RestrictedPtr``, though the exact output may vary due to pointer hashing::
+
+ use kernel::ptr::RawPtr;
+
+ // Basic formatting
+ pr_info!("Pointer: {:p}\n", RawPtr::from(ptr));
+
+ // Minimum width
+ pr_info!("Pointer: {:30p}\n", RawPtr::from(ptr));
+
+ // Right align with zero padding
+ pr_info!("Pointer: {:0>30p}\n", RawPtr::from(ptr));
+
+ // Left align with zero padding
+ pr_info!("Pointer: {:0<30p}\n", RawPtr::from(ptr));
+
+ // Center align with zero padding
+ pr_info!("Pointer: {:0^30p}\n", RawPtr::from(ptr));
+
+ // Right align with space padding (default)
+ pr_info!("Pointer: {:>30p}\n", RawPtr::from(ptr));
+
+ // Center align with custom padding character
+ pr_info!("Pointer: {:*^30p}\n", RawPtr::from(ptr));
+
+See Also
+--------
+
+- :doc:`../core-api/printk-formats` - General pointer formatting documentation
+- `rust/kernel/ptr.rs <srctree/rust/kernel/ptr.rs>`_ - Implementation
--
2.43.0
^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v7 2/4] rust: kernel: Add pointer wrapper types for safe pointer formatting
2025-12-29 7:21 ` [PATCH v7 2/4] rust: kernel: Add pointer wrapper types for safe pointer formatting Ke Sun
@ 2025-12-29 9:03 ` Alice Ryhl
2025-12-29 14:07 ` Ke Sun
0 siblings, 1 reply; 18+ messages in thread
From: Alice Ryhl @ 2025-12-29 9:03 UTC (permalink / raw)
To: Ke Sun
Cc: Dirk Behme, Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt,
Timur Tabi, Danilo Krummrich, Benno Lossin, John Ogness,
Andy Shevchenko, Rasmus Villemoes, Andrew Morton, Gary Guo,
Björn Roy Baron, Andreas Hindborg, Trevor Gross,
Tamir Duberstein, Ke Sun, rust-for-linux
On Mon, Dec 29, 2025 at 03:21:20PM +0800, Ke Sun wrote:
> Add three pointer wrapper types (HashedPtr, RestrictedPtr, RawPtr) to
> rust/kernel/ptr.rs that correspond to C kernel's printk format specifiers
> %p, %pK, and %px. These types provide type-safe pointer formatting that
> matches C kernel patterns.
>
> These wrapper types implement core::fmt::Pointer and delegate to the
> corresponding kernel formatting functions, enabling safe pointer
> formatting in Rust code that prevents information leaks about kernel
> memory layout.
>
> Users can explicitly use these types:
> pr_info!("{:p}\n", HashedPtr::from(ptr));
> pr_info!("{:p}\n", RestrictedPtr::from(ptr));
> pr_info!("{:p}\n", RawPtr::from(ptr));
These ::from calls are inconvenient. Why not just make the field public
and let users write:
pr_info!("{:p}\n", HashedPtr(ptr));
pr_info!("{:p}\n", RestrictedPtr(ptr));
pr_info!("{:p}\n", RawPtr(ptr));
If the only concern is casts, then just make the struct generic:
pub struct HashedPtr<T>(pub *const T);
Since *mut T will automatically downgrade to *const T, this should allow
HashedPtr(ptr) to work with any raw pointer.
> -use crate::build_assert;
> +use crate::{
> + bindings,
> + build_assert,
> + ffi::c_void, //
> +};
Please use prelude::* instead of ffi::c_void.
> /// Type representing an alignment, which is always a power of two.
> ///
> @@ -225,3 +236,240 @@ fn align_up(self, alignment: Alignment) -> Option<Self> {
> }
>
> impl_alignable_uint!(u8, u16, u32, u64, usize);
> +
> +/// Placeholder string used when pointer hashing is not ready yet.
> +const PTR_PLACEHOLDER: &str = if core::mem::size_of::<*const c_void>() == 8 {
size_of is in the kernel prelude.
> +impl fmt::Pointer for RestrictedPtr {
> + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
> + // Handle NULL pointers
> + if self.0.is_null() {
> + return Pointer::fmt(&self.0, f);
> + }
> +
> + // Use kptr_restrict_value to handle all kptr_restrict cases.
> + // - Returns 0: kptr_restrict == 0, use original pointer (needs hashing)
> + // - Returns 1: kptr_restrict == 1, *pptr may be modified to NULL if no permission
> + // - Returns 2: kptr_restrict >= 2, *pptr is set to NULL
> + // - Returns -1: IRQ context with kptr_restrict == 1 (error case)
> + let mut ptr_value = self.0;
> + // SAFETY: kptr_restrict_value handles capability checks and IRQ context.
> + // It may modify ptr_value to NULL if there's no permission.
> + let ret = unsafe { bindings::kptr_restrict_value(core::ptr::addr_of_mut!(ptr_value)) };
Simplifies to:
let ret = unsafe { bindings::kptr_restrict_value(&raw mut ptr_value) };
or even:
let ret = unsafe { bindings::kptr_restrict_value(&mut ptr_value) };
> + match ret {
> + -1 => {
> + // IRQ context with kptr_restrict == 1 - print error placeholder
> + // This should not happen in normal Rust code, but handle it gracefully
> + f.pad("(pK-error)")
Why can't this happen in Rust code? Rust can run in IRQ context.
> + }
> + 0 => {
> + // kptr_restrict == 0: hash the pointer (same as %p)
> + format_hashed_ptr(self.0, f)
> + }
> + 1 => {
> + // kptr_restrict == 1: print raw pointer if ptr_value is non-null,
> + // otherwise print 0 (no permission)
> + if ptr_value.is_null() {
> + Pointer::fmt(&core::ptr::null::<c_void>(), f)
> + } else {
> + // Print the raw pointer directly (like %px)
> + // This matches C behavior: pointer_string() prints the raw address
> + Pointer::fmt(&ptr_value, f)
> + }
> + }
> + _ => {
> + // kptr_restrict >= 2: always print 0
> + // ptr_value should already be NULL, but check to be safe
> + Pointer::fmt(&core::ptr::null::<c_void>(), f)
> + }
> + }
> + }
> +}
Alice
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v7 1/4] lib/vsprintf: Export functions for Rust pointer formatting support
2025-12-29 7:21 ` [PATCH v7 1/4] lib/vsprintf: Export functions for Rust " Ke Sun
@ 2025-12-29 10:44 ` Dirk Behme
2025-12-31 2:46 ` Ke Sun
2025-12-29 14:18 ` Andy Shevchenko
1 sibling, 1 reply; 18+ messages in thread
From: Dirk Behme @ 2025-12-29 10:44 UTC (permalink / raw)
To: Ke Sun, Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt,
Timur Tabi, Danilo Krummrich, Benno Lossin
Cc: John Ogness, Andy Shevchenko, Rasmus Villemoes, Andrew Morton,
Gary Guo, Björn Roy Baron, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Tamir Duberstein, Ke Sun, rust-for-linux
On 29.12.25 08:21, Ke Sun wrote:
> Export ptr_to_hashval() and extract kptr_restrict_value() to enable
> Rust code to use kernel pointer formatting functionality.
>
> - Export ptr_to_hashval() with EXPORT_SYMBOL_GPL for pointer hashing.
> This function is used to hash kernel pointers before printing them,
> preventing information leaks about kernel memory layout.
>
> - Extract kptr_restrict handling logic from restricted_pointer() into
> a separate exported function kptr_restrict_value() that can be
> reused by both restricted_pointer() (for %pK format specifier) and
> Rust code.
>
> The kptr_restrict_value() function:
> - Returns 0, 1, or 2 to indicate the kptr_restrict sysctl value
> - Returns -1 for error case (IRQ context with kptr_restrict==1)
> - Modifies the pointer value through @pptr parameter when needed
> (sets to NULL when access should be restricted)
>
> These functions are needed for the HashedPtr and RestrictedPtr wrapper
> types in rust/kernel/ptr.rs to provide safe pointer formatting that
> matches C kernel patterns.
>
> This refactoring:
> - Allows restricted_pointer() to reuse the common logic while
> maintaining the same behavior
> - Enables Rust code to use the same kptr_restrict handling logic
> - Reduces code duplication
>
> Signed-off-by: Ke Sun <sunke@kylinos.cn>
> Suggested-by: Boqun Feng <boqun.feng@gmail.com>
> ---
> include/linux/printk.h | 10 ++++++++
> lib/vsprintf.c | 55 ++++++++++++++++++++++++++++++++----------
> 2 files changed, 52 insertions(+), 13 deletions(-)
>
> diff --git a/include/linux/printk.h b/include/linux/printk.h
> index 45c663124c9bd..91380b1eff1a1 100644
> --- a/include/linux/printk.h
> +++ b/include/linux/printk.h
> @@ -385,6 +385,16 @@ extern void __printk_cpu_sync_put(void);
>
> extern int kptr_restrict;
>
> +/**
> + * kptr_restrict_value - Determine what pointer value should be used for %pK
> + * @pptr: Pointer to the pointer value (may be modified)
> + *
> + * Returns:
> + * - 0, 1, or 2: The kptr_restrict value if pointer should be used
> + * - -1: Error case (IRQ context with kptr_restrict==1), *pptr unchanged
> + */
> +int kptr_restrict_value(const void **pptr);
> +
> /**
> * pr_fmt - used by the pr_*() macros to generate the printk format string
> * @fmt: format string passed from a pr_*() macro
> diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> index a3790c43a0aba..29d2e681c6e73 100644
> --- a/lib/vsprintf.c
> +++ b/lib/vsprintf.c
> @@ -811,6 +811,7 @@ int ptr_to_hashval(const void *ptr, unsigned long *hashval_out)
> {
> return __ptr_to_hashval(ptr, hashval_out);
> }
> +EXPORT_SYMBOL_GPL(ptr_to_hashval);
>
> static char *ptr_to_id(char *buf, char *end, const void *ptr,
> struct printf_spec spec)
> @@ -857,14 +858,28 @@ static char *default_pointer(char *buf, char *end, const void *ptr,
>
> int kptr_restrict __read_mostly;
>
> -static noinline_for_stack
> -char *restricted_pointer(char *buf, char *end, const void *ptr,
> - struct printf_spec spec)
> +/**
> + * kptr_restrict_value - Determine what pointer value should be used for %pK
> + * @pptr: Pointer to the pointer value (may be modified)
> + *
> + * This function determines what pointer value should be printed based on the
> + * kptr_restrict sysctl setting:
> + *
> + * - kptr_restrict == 0: Return 0 (use original pointer, will be hashed)
> + * - kptr_restrict == 1: Return 1 if current process has CAP_SYSLOG and same
> + * euid/egid, otherwise set *pptr to NULL and return 1
> + * - kptr_restrict >= 2: Set *pptr to NULL and return 2
> + *
> + * Returns:
> + * - 0, 1, or 2: The kptr_restrict value if pointer should be used
> + * - -1: Error case (IRQ context with kptr_restrict==1), *pptr unchanged
> + */
> +int kptr_restrict_value(const void **pptr)
Would it be an improvment to not modify the pptr itself? But instead
to work with some kind of in ptr (not modified) and out_ptr (returned
to the caller then)?
kptr_restrict_value(const void *ptr, const void **out_ptr)
And an enum for the result? With something like
enum kptr_restict_result {
KPTR_RESTICT_ERROR = -1,
KPTR_RESTICT_NONE = 0,
KPTR_RESTICT_PARTIAL = 1,
KPTR_RESTICT_FULL = 2,
}
What would result in something like
enum kptr_restict_result kptr_restrict_value(const void *ptr, const
void **out_ptr)
Opinions?
Dirk
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v7 2/4] rust: kernel: Add pointer wrapper types for safe pointer formatting
2025-12-29 9:03 ` Alice Ryhl
@ 2025-12-29 14:07 ` Ke Sun
0 siblings, 0 replies; 18+ messages in thread
From: Ke Sun @ 2025-12-29 14:07 UTC (permalink / raw)
To: Alice Ryhl
Cc: Dirk Behme, Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt,
Timur Tabi, Danilo Krummrich, Benno Lossin, John Ogness,
Andy Shevchenko, Rasmus Villemoes, Andrew Morton, Gary Guo,
Björn Roy Baron, Andreas Hindborg, Trevor Gross,
Tamir Duberstein, rust-for-linux
Alice Ryhl <aliceryhl@google.com> 于2025年12月29日周一 17:03写道:
>
> On Mon, Dec 29, 2025 at 03:21:20PM +0800, Ke Sun wrote:
> > Add three pointer wrapper types (HashedPtr, RestrictedPtr, RawPtr) to
> > rust/kernel/ptr.rs that correspond to C kernel's printk format specifiers
> > %p, %pK, and %px. These types provide type-safe pointer formatting that
> > matches C kernel patterns.
> >
> > These wrapper types implement core::fmt::Pointer and delegate to the
> > corresponding kernel formatting functions, enabling safe pointer
> > formatting in Rust code that prevents information leaks about kernel
> > memory layout.
> >
> > Users can explicitly use these types:
> > pr_info!("{:p}\n", HashedPtr::from(ptr));
> > pr_info!("{:p}\n", RestrictedPtr::from(ptr));
> > pr_info!("{:p}\n", RawPtr::from(ptr));
>
> These ::from calls are inconvenient. Why not just make the field public
> and let users write:
>
> pr_info!("{:p}\n", HashedPtr(ptr));
> pr_info!("{:p}\n", RestrictedPtr(ptr));
> pr_info!("{:p}\n", RawPtr(ptr));
>
> If the only concern is casts, then just make the struct generic:
>
> pub struct HashedPtr<T>(pub *const T);
>
> Since *mut T will automatically downgrade to *const T, this should allow
> HashedPtr(ptr) to work with any raw pointer.
I'll try implementing these suggestions you mentioned.
>
> > -use crate::build_assert;
> > +use crate::{
> > + bindings,
> > + build_assert,
> > + ffi::c_void, //
> > +};
>
> Please use prelude::* instead of ffi::c_void.
>
> > /// Type representing an alignment, which is always a power of two.
> > ///
> > @@ -225,3 +236,240 @@ fn align_up(self, alignment: Alignment) -> Option<Self> {
> > }
> >
> > impl_alignable_uint!(u8, u16, u32, u64, usize);
> > +
> > +/// Placeholder string used when pointer hashing is not ready yet.
> > +const PTR_PLACEHOLDER: &str = if core::mem::size_of::<*const c_void>() == 8 {
>
> size_of is in the kernel prelude.
>
> > +impl fmt::Pointer for RestrictedPtr {
> > + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
> > + // Handle NULL pointers
> > + if self.0.is_null() {
> > + return Pointer::fmt(&self.0, f);
> > + }
> > +
> > + // Use kptr_restrict_value to handle all kptr_restrict cases.
> > + // - Returns 0: kptr_restrict == 0, use original pointer (needs hashing)
> > + // - Returns 1: kptr_restrict == 1, *pptr may be modified to NULL if no permission
> > + // - Returns 2: kptr_restrict >= 2, *pptr is set to NULL
> > + // - Returns -1: IRQ context with kptr_restrict == 1 (error case)
> > + let mut ptr_value = self.0;
> > + // SAFETY: kptr_restrict_value handles capability checks and IRQ context.
> > + // It may modify ptr_value to NULL if there's no permission.
> > + let ret = unsafe { bindings::kptr_restrict_value(core::ptr::addr_of_mut!(ptr_value)) };
>
> Simplifies to:
>
> let ret = unsafe { bindings::kptr_restrict_value(&raw mut ptr_value) };
>
> or even:
>
> let ret = unsafe { bindings::kptr_restrict_value(&mut ptr_value) };
>
> > + match ret {
> > + -1 => {
> > + // IRQ context with kptr_restrict == 1 - print error placeholder
> > + // This should not happen in normal Rust code, but handle it gracefully
> > + f.pad("(pK-error)")
>
> Why can't this happen in Rust code? Rust can run in IRQ context.
You're correct about the IRQ context - I had misunderstood the situation.
>
> > + }
> > + 0 => {
> > + // kptr_restrict == 0: hash the pointer (same as %p)
> > + format_hashed_ptr(self.0, f)
> > + }
> > + 1 => {
> > + // kptr_restrict == 1: print raw pointer if ptr_value is non-null,
> > + // otherwise print 0 (no permission)
> > + if ptr_value.is_null() {
> > + Pointer::fmt(&core::ptr::null::<c_void>(), f)
> > + } else {
> > + // Print the raw pointer directly (like %px)
> > + // This matches C behavior: pointer_string() prints the raw address
> > + Pointer::fmt(&ptr_value, f)
> > + }
> > + }
> > + _ => {
> > + // kptr_restrict >= 2: always print 0
> > + // ptr_value should already be NULL, but check to be safe
> > + Pointer::fmt(&core::ptr::null::<c_void>(), f)
> > + }
> > + }
> > + }
> > +}
>
> Alice
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v7 0/4] rust: Add safe pointer formatting support
2025-12-29 7:21 [PATCH v7 0/4] rust: Add safe pointer formatting support Ke Sun
` (3 preceding siblings ...)
2025-12-29 7:21 ` [PATCH v7 4/4] docs: rust: Add pointer formatting documentation Ke Sun
@ 2025-12-29 14:11 ` Andy Shevchenko
2025-12-30 2:03 ` Ke Sun
4 siblings, 1 reply; 18+ messages in thread
From: Andy Shevchenko @ 2025-12-29 14:11 UTC (permalink / raw)
To: Ke Sun
Cc: Dirk Behme, Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt,
Timur Tabi, Danilo Krummrich, Benno Lossin, John Ogness,
Rasmus Villemoes, Andrew Morton, Gary Guo, Björn Roy Baron,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Tamir Duberstein,
Ke Sun, rust-for-linux
On Mon, Dec 29, 2025 at 03:21:18PM +0800, Ke Sun wrote:
> This patch series adds safe pointer formatting support for Rust kernel code,
> providing three pointer wrapper types (HashedPtr, RawPtr, RestrictedPtr) that
> correspond to C kernel's printk format specifiers %p, %px, and %pK.
I didn't get the motivation behind %pK. Also what's about all the extensions
we (currently) have?
> The implementation ensures that raw pointers are automatically hashed when
> formatted with {:p}, providing safe default behavior that prevents information
> leaks about kernel memory layout. Users can also explicitly use wrapper types
> when they need specific formatting behavior.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v7 1/4] lib/vsprintf: Export functions for Rust pointer formatting support
2025-12-29 7:21 ` [PATCH v7 1/4] lib/vsprintf: Export functions for Rust " Ke Sun
2025-12-29 10:44 ` Dirk Behme
@ 2025-12-29 14:18 ` Andy Shevchenko
2025-12-29 15:00 ` Ke Sun
2025-12-31 10:04 ` Alice Ryhl
1 sibling, 2 replies; 18+ messages in thread
From: Andy Shevchenko @ 2025-12-29 14:18 UTC (permalink / raw)
To: Ke Sun
Cc: Dirk Behme, Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt,
Timur Tabi, Danilo Krummrich, Benno Lossin, John Ogness,
Rasmus Villemoes, Andrew Morton, Gary Guo, Björn Roy Baron,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Tamir Duberstein,
Ke Sun, rust-for-linux
On Mon, Dec 29, 2025 at 03:21:19PM +0800, Ke Sun wrote:
> Export ptr_to_hashval() and extract kptr_restrict_value() to enable
> Rust code to use kernel pointer formatting functionality.
>
> - Export ptr_to_hashval() with EXPORT_SYMBOL_GPL for pointer hashing.
> This function is used to hash kernel pointers before printing them,
> preventing information leaks about kernel memory layout.
>
> - Extract kptr_restrict handling logic from restricted_pointer() into
> a separate exported function kptr_restrict_value() that can be
> reused by both restricted_pointer() (for %pK format specifier) and
> Rust code.
>
> The kptr_restrict_value() function:
> - Returns 0, 1, or 2 to indicate the kptr_restrict sysctl value
> - Returns -1 for error case (IRQ context with kptr_restrict==1)
> - Modifies the pointer value through @pptr parameter when needed
> (sets to NULL when access should be restricted)
>
> These functions are needed for the HashedPtr and RestrictedPtr wrapper
> types in rust/kernel/ptr.rs to provide safe pointer formatting that
> matches C kernel patterns.
>
> This refactoring:
> - Allows restricted_pointer() to reuse the common logic while
> maintaining the same behavior
> - Enables Rust code to use the same kptr_restrict handling logic
> - Reduces code duplication
...
> +EXPORT_SYMBOL_GPL(ptr_to_hashval);
I do not like this. At bare minimum we should make sure it's namespaced, so the
author of the code deliberately needs to import it (I'm talking about C side).
Ideally we should have something which is Rust specific, like
EXPORT_SYMBOL_FOR_RUST_ONLY(foo);
Can we do that first?
...
> +/**
> + * kptr_restrict_value - Determine what pointer value should be used for %pK
> + * @pptr: Pointer to the pointer value (may be modified)
> + *
> + * This function determines what pointer value should be printed based on the
> + * kptr_restrict sysctl setting:
> + * - kptr_restrict == 0: Return 0 (use original pointer, will be hashed)
> + * - kptr_restrict == 1: Return 1 if current process has CAP_SYSLOG and same
> + * euid/egid, otherwise set *pptr to NULL and return 1
> + * - kptr_restrict >= 2: Set *pptr to NULL and return 2
It's the usual practice to give a enum with self-explained definitions and use
them. plain numbers are prone to mistakes during the evolution of the code.
Also it's hard to read inside the code their semantic.
> + * Returns:
> + * - 0, 1, or 2: The kptr_restrict value if pointer should be used
> + * - -1: Error case (IRQ context with kptr_restrict==1), *pptr unchanged
> + */
...
> + if (in_hardirq() || in_serving_softirq() || in_nmi())
> + return -1;
Give a meaningful Linux error code for this.
...
> +static noinline_for_stack
> +char *restricted_pointer(char *buf, char *end, const void *ptr,
> + struct printf_spec spec)
> +{
> + int ret = kptr_restrict_value(&ptr);
> +
> + if (ret < 0) {
> + if (spec.field_width == -1)
> + spec.field_width = 2 * sizeof(ptr);
> + return error_string(buf, end, "pK-error", spec);
> + }
This pattern is harder to maintain, decouple definition and assignment to make
it better.
int ret;
ret = kptr_restrict_value(&ptr);
if (ret < 0) {
> + if (ret == 0)
> + return default_pointer(buf, end, ptr, spec);
>
> return pointer_string(buf, end, ptr, spec);
> }
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v7 1/4] lib/vsprintf: Export functions for Rust pointer formatting support
2025-12-29 14:18 ` Andy Shevchenko
@ 2025-12-29 15:00 ` Ke Sun
2025-12-31 10:04 ` Alice Ryhl
1 sibling, 0 replies; 18+ messages in thread
From: Ke Sun @ 2025-12-29 15:00 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Dirk Behme, Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt,
Timur Tabi, Danilo Krummrich, Benno Lossin, John Ogness,
Rasmus Villemoes, Andrew Morton, Gary Guo, Björn Roy Baron,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Tamir Duberstein,
rust-for-linux
Thanks for the detailed review! I'll work on addressing all your suggestions.
Ke Sun
Andy Shevchenko <andriy.shevchenko@linux.intel.com> 于2025年12月29日周一 22:19写道:
>
> On Mon, Dec 29, 2025 at 03:21:19PM +0800, Ke Sun wrote:
> > Export ptr_to_hashval() and extract kptr_restrict_value() to enable
> > Rust code to use kernel pointer formatting functionality.
> >
> > - Export ptr_to_hashval() with EXPORT_SYMBOL_GPL for pointer hashing.
> > This function is used to hash kernel pointers before printing them,
> > preventing information leaks about kernel memory layout.
> >
> > - Extract kptr_restrict handling logic from restricted_pointer() into
> > a separate exported function kptr_restrict_value() that can be
> > reused by both restricted_pointer() (for %pK format specifier) and
> > Rust code.
> >
> > The kptr_restrict_value() function:
> > - Returns 0, 1, or 2 to indicate the kptr_restrict sysctl value
> > - Returns -1 for error case (IRQ context with kptr_restrict==1)
> > - Modifies the pointer value through @pptr parameter when needed
> > (sets to NULL when access should be restricted)
> >
> > These functions are needed for the HashedPtr and RestrictedPtr wrapper
> > types in rust/kernel/ptr.rs to provide safe pointer formatting that
> > matches C kernel patterns.
> >
> > This refactoring:
> > - Allows restricted_pointer() to reuse the common logic while
> > maintaining the same behavior
> > - Enables Rust code to use the same kptr_restrict handling logic
> > - Reduces code duplication
>
> ...
>
> > +EXPORT_SYMBOL_GPL(ptr_to_hashval);
>
> I do not like this. At bare minimum we should make sure it's namespaced, so the
> author of the code deliberately needs to import it (I'm talking about C side).
>
> Ideally we should have something which is Rust specific, like
>
> EXPORT_SYMBOL_FOR_RUST_ONLY(foo);
>
> Can we do that first?
>
> ...
>
> > +/**
> > + * kptr_restrict_value - Determine what pointer value should be used for %pK
> > + * @pptr: Pointer to the pointer value (may be modified)
> > + *
> > + * This function determines what pointer value should be printed based on the
> > + * kptr_restrict sysctl setting:
>
> > + * - kptr_restrict == 0: Return 0 (use original pointer, will be hashed)
> > + * - kptr_restrict == 1: Return 1 if current process has CAP_SYSLOG and same
> > + * euid/egid, otherwise set *pptr to NULL and return 1
> > + * - kptr_restrict >= 2: Set *pptr to NULL and return 2
>
> It's the usual practice to give a enum with self-explained definitions and use
> them. plain numbers are prone to mistakes during the evolution of the code.
> Also it's hard to read inside the code their semantic.
>
> > + * Returns:
> > + * - 0, 1, or 2: The kptr_restrict value if pointer should be used
> > + * - -1: Error case (IRQ context with kptr_restrict==1), *pptr unchanged
> > + */
>
> ...
>
> > + if (in_hardirq() || in_serving_softirq() || in_nmi())
> > + return -1;
>
> Give a meaningful Linux error code for this.
>
> ...
>
> > +static noinline_for_stack
> > +char *restricted_pointer(char *buf, char *end, const void *ptr,
> > + struct printf_spec spec)
> > +{
>
> > + int ret = kptr_restrict_value(&ptr);
> > +
> > + if (ret < 0) {
> > + if (spec.field_width == -1)
> > + spec.field_width = 2 * sizeof(ptr);
> > + return error_string(buf, end, "pK-error", spec);
> > + }
>
> This pattern is harder to maintain, decouple definition and assignment to make
> it better.
>
> int ret;
>
> ret = kptr_restrict_value(&ptr);
> if (ret < 0) {
>
> > + if (ret == 0)
> > + return default_pointer(buf, end, ptr, spec);
> >
> > return pointer_string(buf, end, ptr, spec);
> > }
>
> --
> With Best Regards,
> Andy Shevchenko
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v7 0/4] rust: Add safe pointer formatting support
2025-12-29 14:11 ` [PATCH v7 0/4] rust: Add safe pointer formatting support Andy Shevchenko
@ 2025-12-30 2:03 ` Ke Sun
2025-12-30 8:40 ` Andy Shevchenko
0 siblings, 1 reply; 18+ messages in thread
From: Ke Sun @ 2025-12-30 2:03 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Dirk Behme, Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt,
Timur Tabi, Danilo Krummrich, Benno Lossin, John Ogness,
Rasmus Villemoes, Andrew Morton, Gary Guo, Björn Roy Baron,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Tamir Duberstein,
rust-for-linux
On Mon, Dec 29, 2025 at 10:12 PM Andy Shevchenko
<andriy.shevchenko@linux.intel.com> wrote:
>
> On Mon, Dec 29, 2025 at 03:21:18PM +0800, Ke Sun wrote:
> > This patch series adds safe pointer formatting support for Rust kernel code,
> > providing three pointer wrapper types (HashedPtr, RawPtr, RestrictedPtr) that
> > correspond to C kernel's printk format specifiers %p, %px, and %pK.
>
> I didn't get the motivation behind %pK. Also what's about all the extensions
> we (currently) have?
I'm implementing a R4L wrapper for the RTC driver and currently only
need basic pointer printing. %pK is typically used in seqfile to
export information to userspace.
All extensions can be implemented by modifying and exporting the
corresponding functions in C, then adding wrapper types in Rust.
What's your recommendation on which extensions to prioritize, or
should we implement them all?
>
> > The implementation ensures that raw pointers are automatically hashed when
> > formatted with {:p}, providing safe default behavior that prevents information
> > leaks about kernel memory layout. Users can also explicitly use wrapper types
> > when they need specific formatting behavior.
>
>
> --
> With Best Regards,
> Andy Shevchenko
>
>
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v7 0/4] rust: Add safe pointer formatting support
2025-12-30 2:03 ` Ke Sun
@ 2025-12-30 8:40 ` Andy Shevchenko
0 siblings, 0 replies; 18+ messages in thread
From: Andy Shevchenko @ 2025-12-30 8:40 UTC (permalink / raw)
To: Ke Sun
Cc: Dirk Behme, Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt,
Timur Tabi, Danilo Krummrich, Benno Lossin, John Ogness,
Rasmus Villemoes, Andrew Morton, Gary Guo, Björn Roy Baron,
Andreas Hindborg, Alice Ryhl, Trevor Gross, Tamir Duberstein,
rust-for-linux
On Tue, Dec 30, 2025 at 10:03:17AM +0800, Ke Sun wrote:
> On Mon, Dec 29, 2025 at 10:12 PM Andy Shevchenko
> <andriy.shevchenko@linux.intel.com> wrote:
> >
> > On Mon, Dec 29, 2025 at 03:21:18PM +0800, Ke Sun wrote:
> > > This patch series adds safe pointer formatting support for Rust kernel code,
> > > providing three pointer wrapper types (HashedPtr, RawPtr, RestrictedPtr) that
> > > correspond to C kernel's printk format specifiers %p, %px, and %pK.
> >
> > I didn't get the motivation behind %pK. Also what's about all the extensions
> > we (currently) have?
>
> I'm implementing a R4L wrapper for the RTC driver and currently only
> need basic pointer printing. %pK is typically used in seqfile to
> export information to userspace.
>
> All extensions can be implemented by modifying and exporting the
> corresponding functions in C, then adding wrapper types in Rust.
> What's your recommendation on which extensions to prioritize, or
> should we implement them all?
I have no priority list, I just asked for clarification of your roadmap and %pK
case as the latter is quite rare (3 in Documentation, 8 in tools, and 25 otherwise)
and probably shouldn't have existed at all. So, I would rather not advertise it,
may be even mark as deprecated or so on Rust level.
> > > The implementation ensures that raw pointers are automatically hashed when
> > > formatted with {:p}, providing safe default behavior that prevents information
> > > leaks about kernel memory layout. Users can also explicitly use wrapper types
> > > when they need specific formatting behavior.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v7 1/4] lib/vsprintf: Export functions for Rust pointer formatting support
2025-12-29 10:44 ` Dirk Behme
@ 2025-12-31 2:46 ` Ke Sun
2025-12-31 11:07 ` Alice Ryhl
0 siblings, 1 reply; 18+ messages in thread
From: Ke Sun @ 2025-12-31 2:46 UTC (permalink / raw)
To: Dirk Behme, Andy Shevchenko
Cc: Boqun Feng, Miguel Ojeda, Petr Mladek, Steven Rostedt, Timur Tabi,
Danilo Krummrich, Benno Lossin, John Ogness, Rasmus Villemoes,
Andrew Morton, Gary Guo, Björn Roy Baron, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Tamir Duberstein, rust-for-linux
On Mon, Dec 29, 2025 at 6:44 PM Dirk Behme <dirk.behme@gmail.com> wrote:
>
> On 29.12.25 08:21, Ke Sun wrote:
> > Export ptr_to_hashval() and extract kptr_restrict_value() to enable
> > Rust code to use kernel pointer formatting functionality.
> >
> > - Export ptr_to_hashval() with EXPORT_SYMBOL_GPL for pointer hashing.
> > This function is used to hash kernel pointers before printing them,
> > preventing information leaks about kernel memory layout.
> >
> > - Extract kptr_restrict handling logic from restricted_pointer() into
> > a separate exported function kptr_restrict_value() that can be
> > reused by both restricted_pointer() (for %pK format specifier) and
> > Rust code.
> >
> > The kptr_restrict_value() function:
> > - Returns 0, 1, or 2 to indicate the kptr_restrict sysctl value
> > - Returns -1 for error case (IRQ context with kptr_restrict==1)
> > - Modifies the pointer value through @pptr parameter when needed
> > (sets to NULL when access should be restricted)
> >
> > These functions are needed for the HashedPtr and RestrictedPtr wrapper
> > types in rust/kernel/ptr.rs to provide safe pointer formatting that
> > matches C kernel patterns.
> >
> > This refactoring:
> > - Allows restricted_pointer() to reuse the common logic while
> > maintaining the same behavior
> > - Enables Rust code to use the same kptr_restrict handling logic
> > - Reduces code duplication
> >
> > Signed-off-by: Ke Sun <sunke@kylinos.cn>
> > Suggested-by: Boqun Feng <boqun.feng@gmail.com>
> > ---
> > include/linux/printk.h | 10 ++++++++
> > lib/vsprintf.c | 55 ++++++++++++++++++++++++++++++++----------
> > 2 files changed, 52 insertions(+), 13 deletions(-)
> >
> > diff --git a/include/linux/printk.h b/include/linux/printk.h
> > index 45c663124c9bd..91380b1eff1a1 100644
> > --- a/include/linux/printk.h
> > +++ b/include/linux/printk.h
> > @@ -385,6 +385,16 @@ extern void __printk_cpu_sync_put(void);
> >
> > extern int kptr_restrict;
> >
> > +/**
> > + * kptr_restrict_value - Determine what pointer value should be used for %pK
> > + * @pptr: Pointer to the pointer value (may be modified)
> > + *
> > + * Returns:
> > + * - 0, 1, or 2: The kptr_restrict value if pointer should be used
> > + * - -1: Error case (IRQ context with kptr_restrict==1), *pptr unchanged
> > + */
> > +int kptr_restrict_value(const void **pptr);
> > +
> > /**
> > * pr_fmt - used by the pr_*() macros to generate the printk format string
> > * @fmt: format string passed from a pr_*() macro
> > diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> > index a3790c43a0aba..29d2e681c6e73 100644
> > --- a/lib/vsprintf.c
> > +++ b/lib/vsprintf.c
> > @@ -811,6 +811,7 @@ int ptr_to_hashval(const void *ptr, unsigned long *hashval_out)
> > {
> > return __ptr_to_hashval(ptr, hashval_out);
> > }
> > +EXPORT_SYMBOL_GPL(ptr_to_hashval);
> >
> > static char *ptr_to_id(char *buf, char *end, const void *ptr,
> > struct printf_spec spec)
> > @@ -857,14 +858,28 @@ static char *default_pointer(char *buf, char *end, const void *ptr,
> >
> > int kptr_restrict __read_mostly;
> >
> > -static noinline_for_stack
> > -char *restricted_pointer(char *buf, char *end, const void *ptr,
> > - struct printf_spec spec)
> > +/**
> > + * kptr_restrict_value - Determine what pointer value should be used for %pK
> > + * @pptr: Pointer to the pointer value (may be modified)
> > + *
> > + * This function determines what pointer value should be printed based on the
> > + * kptr_restrict sysctl setting:
> > + *
> > + * - kptr_restrict == 0: Return 0 (use original pointer, will be hashed)
> > + * - kptr_restrict == 1: Return 1 if current process has CAP_SYSLOG and same
> > + * euid/egid, otherwise set *pptr to NULL and return 1
> > + * - kptr_restrict >= 2: Set *pptr to NULL and return 2
> > + *
> > + * Returns:
> > + * - 0, 1, or 2: The kptr_restrict value if pointer should be used
> > + * - -1: Error case (IRQ context with kptr_restrict==1), *pptr unchanged
> > + */
> > +int kptr_restrict_value(const void **pptr)
>
> Would it be an improvment to not modify the pptr itself? But instead
> to work with some kind of in ptr (not modified) and out_ptr (returned
> to the caller then)?
>
> kptr_restrict_value(const void *ptr, const void **out_ptr)
>
> And an enum for the result? With something like
>
> enum kptr_restict_result {
> KPTR_RESTICT_ERROR = -1,
> KPTR_RESTICT_NONE = 0,
> KPTR_RESTICT_PARTIAL = 1,
> KPTR_RESTICT_FULL = 2,
> }
>
> What would result in something like
>
> enum kptr_restict_result kptr_restrict_value(const void *ptr, const
> void **out_ptr)
>
> Opinions?
Given that fully implementing all %p format specifier extensions would
require substantial code changes, we're considering converting Rust's
Formatter to C format strings at the Rust layer and directly calling
snprintf. This would allow us to reuse the existing C implementations
without modifying vsprintf.c.
What do you think of this approach?
>
> Dirk
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v7 1/4] lib/vsprintf: Export functions for Rust pointer formatting support
2025-12-29 14:18 ` Andy Shevchenko
2025-12-29 15:00 ` Ke Sun
@ 2025-12-31 10:04 ` Alice Ryhl
2026-01-01 1:43 ` 孙科
1 sibling, 1 reply; 18+ messages in thread
From: Alice Ryhl @ 2025-12-31 10:04 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Ke Sun, Dirk Behme, Boqun Feng, Miguel Ojeda, Petr Mladek,
Steven Rostedt, Timur Tabi, Danilo Krummrich, Benno Lossin,
John Ogness, Rasmus Villemoes, Andrew Morton, Gary Guo,
Björn Roy Baron, Andreas Hindborg, Trevor Gross,
Tamir Duberstein, Ke Sun, rust-for-linux
On Mon, Dec 29, 2025 at 04:18:57PM +0200, Andy Shevchenko wrote:
> On Mon, Dec 29, 2025 at 03:21:19PM +0800, Ke Sun wrote:
> > Export ptr_to_hashval() and extract kptr_restrict_value() to enable
> > Rust code to use kernel pointer formatting functionality.
> >
> > - Export ptr_to_hashval() with EXPORT_SYMBOL_GPL for pointer hashing.
> > This function is used to hash kernel pointers before printing them,
> > preventing information leaks about kernel memory layout.
> >
> > - Extract kptr_restrict handling logic from restricted_pointer() into
> > a separate exported function kptr_restrict_value() that can be
> > reused by both restricted_pointer() (for %pK format specifier) and
> > Rust code.
> >
> > The kptr_restrict_value() function:
> > - Returns 0, 1, or 2 to indicate the kptr_restrict sysctl value
> > - Returns -1 for error case (IRQ context with kptr_restrict==1)
> > - Modifies the pointer value through @pptr parameter when needed
> > (sets to NULL when access should be restricted)
> >
> > These functions are needed for the HashedPtr and RestrictedPtr wrapper
> > types in rust/kernel/ptr.rs to provide safe pointer formatting that
> > matches C kernel patterns.
> >
> > This refactoring:
> > - Allows restricted_pointer() to reuse the common logic while
> > maintaining the same behavior
> > - Enables Rust code to use the same kptr_restrict handling logic
> > - Reduces code duplication
>
> ...
>
> > +EXPORT_SYMBOL_GPL(ptr_to_hashval);
>
> I do not like this. At bare minimum we should make sure it's namespaced, so the
> author of the code deliberately needs to import it (I'm talking about C side).
>
> Ideally we should have something which is Rust specific, like
>
> EXPORT_SYMBOL_FOR_RUST_ONLY(foo);
>
> Can we do that first?
We don't have an EXPORT_SYMBOL_FOR_RUST_ONLY(). The closest there is
would be to place it in rust/helpers/, since such symbols won't be
available to C modules once we land this:
https://lore.kernel.org/all/20251202-inline-helpers-v1-0-879dae33a66a@google.com/
But since the current file also needs to access this, I don't think it
will fly.
Alice
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v7 1/4] lib/vsprintf: Export functions for Rust pointer formatting support
2025-12-31 2:46 ` Ke Sun
@ 2025-12-31 11:07 ` Alice Ryhl
0 siblings, 0 replies; 18+ messages in thread
From: Alice Ryhl @ 2025-12-31 11:07 UTC (permalink / raw)
To: Ke Sun
Cc: Dirk Behme, Andy Shevchenko, Boqun Feng, Miguel Ojeda,
Petr Mladek, Steven Rostedt, Timur Tabi, Danilo Krummrich,
Benno Lossin, John Ogness, Rasmus Villemoes, Andrew Morton,
Gary Guo, Björn Roy Baron, Andreas Hindborg, Trevor Gross,
Tamir Duberstein, rust-for-linux
On Wed, Dec 31, 2025 at 10:46:37AM +0800, Ke Sun wrote:
> On Mon, Dec 29, 2025 at 6:44 PM Dirk Behme <dirk.behme@gmail.com> wrote:
> >
> > On 29.12.25 08:21, Ke Sun wrote:
> > > Export ptr_to_hashval() and extract kptr_restrict_value() to enable
> > > Rust code to use kernel pointer formatting functionality.
> > >
> > > - Export ptr_to_hashval() with EXPORT_SYMBOL_GPL for pointer hashing.
> > > This function is used to hash kernel pointers before printing them,
> > > preventing information leaks about kernel memory layout.
> > >
> > > - Extract kptr_restrict handling logic from restricted_pointer() into
> > > a separate exported function kptr_restrict_value() that can be
> > > reused by both restricted_pointer() (for %pK format specifier) and
> > > Rust code.
> > >
> > > The kptr_restrict_value() function:
> > > - Returns 0, 1, or 2 to indicate the kptr_restrict sysctl value
> > > - Returns -1 for error case (IRQ context with kptr_restrict==1)
> > > - Modifies the pointer value through @pptr parameter when needed
> > > (sets to NULL when access should be restricted)
> > >
> > > These functions are needed for the HashedPtr and RestrictedPtr wrapper
> > > types in rust/kernel/ptr.rs to provide safe pointer formatting that
> > > matches C kernel patterns.
> > >
> > > This refactoring:
> > > - Allows restricted_pointer() to reuse the common logic while
> > > maintaining the same behavior
> > > - Enables Rust code to use the same kptr_restrict handling logic
> > > - Reduces code duplication
> > >
> > > Signed-off-by: Ke Sun <sunke@kylinos.cn>
> > > Suggested-by: Boqun Feng <boqun.feng@gmail.com>
> > > ---
> > > include/linux/printk.h | 10 ++++++++
> > > lib/vsprintf.c | 55 ++++++++++++++++++++++++++++++++----------
> > > 2 files changed, 52 insertions(+), 13 deletions(-)
> > >
> > > diff --git a/include/linux/printk.h b/include/linux/printk.h
> > > index 45c663124c9bd..91380b1eff1a1 100644
> > > --- a/include/linux/printk.h
> > > +++ b/include/linux/printk.h
> > > @@ -385,6 +385,16 @@ extern void __printk_cpu_sync_put(void);
> > >
> > > extern int kptr_restrict;
> > >
> > > +/**
> > > + * kptr_restrict_value - Determine what pointer value should be used for %pK
> > > + * @pptr: Pointer to the pointer value (may be modified)
> > > + *
> > > + * Returns:
> > > + * - 0, 1, or 2: The kptr_restrict value if pointer should be used
> > > + * - -1: Error case (IRQ context with kptr_restrict==1), *pptr unchanged
> > > + */
> > > +int kptr_restrict_value(const void **pptr);
> > > +
> > > /**
> > > * pr_fmt - used by the pr_*() macros to generate the printk format string
> > > * @fmt: format string passed from a pr_*() macro
> > > diff --git a/lib/vsprintf.c b/lib/vsprintf.c
> > > index a3790c43a0aba..29d2e681c6e73 100644
> > > --- a/lib/vsprintf.c
> > > +++ b/lib/vsprintf.c
> > > @@ -811,6 +811,7 @@ int ptr_to_hashval(const void *ptr, unsigned long *hashval_out)
> > > {
> > > return __ptr_to_hashval(ptr, hashval_out);
> > > }
> > > +EXPORT_SYMBOL_GPL(ptr_to_hashval);
> > >
> > > static char *ptr_to_id(char *buf, char *end, const void *ptr,
> > > struct printf_spec spec)
> > > @@ -857,14 +858,28 @@ static char *default_pointer(char *buf, char *end, const void *ptr,
> > >
> > > int kptr_restrict __read_mostly;
> > >
> > > -static noinline_for_stack
> > > -char *restricted_pointer(char *buf, char *end, const void *ptr,
> > > - struct printf_spec spec)
> > > +/**
> > > + * kptr_restrict_value - Determine what pointer value should be used for %pK
> > > + * @pptr: Pointer to the pointer value (may be modified)
> > > + *
> > > + * This function determines what pointer value should be printed based on the
> > > + * kptr_restrict sysctl setting:
> > > + *
> > > + * - kptr_restrict == 0: Return 0 (use original pointer, will be hashed)
> > > + * - kptr_restrict == 1: Return 1 if current process has CAP_SYSLOG and same
> > > + * euid/egid, otherwise set *pptr to NULL and return 1
> > > + * - kptr_restrict >= 2: Set *pptr to NULL and return 2
> > > + *
> > > + * Returns:
> > > + * - 0, 1, or 2: The kptr_restrict value if pointer should be used
> > > + * - -1: Error case (IRQ context with kptr_restrict==1), *pptr unchanged
> > > + */
> > > +int kptr_restrict_value(const void **pptr)
> >
> > Would it be an improvment to not modify the pptr itself? But instead
> > to work with some kind of in ptr (not modified) and out_ptr (returned
> > to the caller then)?
> >
> > kptr_restrict_value(const void *ptr, const void **out_ptr)
> >
> > And an enum for the result? With something like
> >
> > enum kptr_restict_result {
> > KPTR_RESTICT_ERROR = -1,
> > KPTR_RESTICT_NONE = 0,
> > KPTR_RESTICT_PARTIAL = 1,
> > KPTR_RESTICT_FULL = 2,
> > }
> >
> > What would result in something like
> >
> > enum kptr_restict_result kptr_restrict_value(const void *ptr, const
> > void **out_ptr)
> >
> > Opinions?
>
> Given that fully implementing all %p format specifier extensions would
> require substantial code changes, we're considering converting Rust's
> Formatter to C format strings at the Rust layer and directly calling
> snprintf. This would allow us to reuse the existing C implementations
> without modifying vsprintf.c.
>
> What do you think of this approach?
That's never going to happen. It would be quite difficult to write a
safe API where you can't accidentally mix up the wrong type with the C
format string. You would probably have to write a proc macro parser for
format strings, which sounds like a nightmare. And you will never be
able to get error messages that are as good as the built-in formatting
machinery, because it relies on compiler internals and cannot be
reproduced in a custom proc macro.
I think Dirk's suggestion is reasonable. Or just do not support %pK.
Alice
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v7 1/4] lib/vsprintf: Export functions for Rust pointer formatting support
2025-12-31 10:04 ` Alice Ryhl
@ 2026-01-01 1:43 ` 孙科
2026-01-01 1:46 ` Alice Ryhl
0 siblings, 1 reply; 18+ messages in thread
From: 孙科 @ 2026-01-01 1:43 UTC (permalink / raw)
To: Alice Ryhl
Cc: Andy Shevchenko, Dirk Behme, Boqun Feng, Miguel Ojeda,
Petr Mladek, Steven Rostedt, Timur Tabi, Danilo Krummrich,
Benno Lossin, John Ogness, Rasmus Villemoes, Andrew Morton,
Gary Guo, Björn Roy Baron, Andreas Hindborg, Trevor Gross,
Tamir Duberstein, rust-for-linux
On Wed, Dec 31, 2025 at 6:04 PM Alice Ryhl <aliceryhl@google.com> wrote:
>
> On Mon, Dec 29, 2025 at 04:18:57PM +0200, Andy Shevchenko wrote:
> > On Mon, Dec 29, 2025 at 03:21:19PM +0800, Ke Sun wrote:
> > > Export ptr_to_hashval() and extract kptr_restrict_value() to enable
> > > Rust code to use kernel pointer formatting functionality.
> > >
> > > - Export ptr_to_hashval() with EXPORT_SYMBOL_GPL for pointer hashing.
> > > This function is used to hash kernel pointers before printing them,
> > > preventing information leaks about kernel memory layout.
> > >
> > > - Extract kptr_restrict handling logic from restricted_pointer() into
> > > a separate exported function kptr_restrict_value() that can be
> > > reused by both restricted_pointer() (for %pK format specifier) and
> > > Rust code.
> > >
> > > The kptr_restrict_value() function:
> > > - Returns 0, 1, or 2 to indicate the kptr_restrict sysctl value
> > > - Returns -1 for error case (IRQ context with kptr_restrict==1)
> > > - Modifies the pointer value through @pptr parameter when needed
> > > (sets to NULL when access should be restricted)
> > >
> > > These functions are needed for the HashedPtr and RestrictedPtr wrapper
> > > types in rust/kernel/ptr.rs to provide safe pointer formatting that
> > > matches C kernel patterns.
> > >
> > > This refactoring:
> > > - Allows restricted_pointer() to reuse the common logic while
> > > maintaining the same behavior
> > > - Enables Rust code to use the same kptr_restrict handling logic
> > > - Reduces code duplication
> >
> > ...
> >
> > > +EXPORT_SYMBOL_GPL(ptr_to_hashval);
> >
> > I do not like this. At bare minimum we should make sure it's namespaced, so the
> > author of the code deliberately needs to import it (I'm talking about C side).
> >
> > Ideally we should have something which is Rust specific, like
> >
> > EXPORT_SYMBOL_FOR_RUST_ONLY(foo);
> >
> > Can we do that first?
>
> We don't have an EXPORT_SYMBOL_FOR_RUST_ONLY(). The closest there is
> would be to place it in rust/helpers/, since such symbols won't be
> available to C modules once we land this:
>
> https://lore.kernel.org/all/20251202-inline-helpers-v1-0-879dae33a66a@google.com/
Does the inline helpers feature also support GCC builds, or is it
limited to Clang only?
>
> But since the current file also needs to access this, I don't think it
> will fly.
>
> Alice
^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v7 1/4] lib/vsprintf: Export functions for Rust pointer formatting support
2026-01-01 1:43 ` 孙科
@ 2026-01-01 1:46 ` Alice Ryhl
0 siblings, 0 replies; 18+ messages in thread
From: Alice Ryhl @ 2026-01-01 1:46 UTC (permalink / raw)
To: 孙科
Cc: Andy Shevchenko, Dirk Behme, Boqun Feng, Miguel Ojeda,
Petr Mladek, Steven Rostedt, Timur Tabi, Danilo Krummrich,
Benno Lossin, John Ogness, Rasmus Villemoes, Andrew Morton,
Gary Guo, Björn Roy Baron, Andreas Hindborg, Trevor Gross,
Tamir Duberstein, rust-for-linux
On Thu, Jan 1, 2026 at 2:43 AM 孙科 <sk.alvin.x@gmail.com> wrote:
>
> On Wed, Dec 31, 2025 at 6:04 PM Alice Ryhl <aliceryhl@google.com> wrote:
> >
> > On Mon, Dec 29, 2025 at 04:18:57PM +0200, Andy Shevchenko wrote:
> > > On Mon, Dec 29, 2025 at 03:21:19PM +0800, Ke Sun wrote:
> > > > Export ptr_to_hashval() and extract kptr_restrict_value() to enable
> > > > Rust code to use kernel pointer formatting functionality.
> > > >
> > > > - Export ptr_to_hashval() with EXPORT_SYMBOL_GPL for pointer hashing.
> > > > This function is used to hash kernel pointers before printing them,
> > > > preventing information leaks about kernel memory layout.
> > > >
> > > > - Extract kptr_restrict handling logic from restricted_pointer() into
> > > > a separate exported function kptr_restrict_value() that can be
> > > > reused by both restricted_pointer() (for %pK format specifier) and
> > > > Rust code.
> > > >
> > > > The kptr_restrict_value() function:
> > > > - Returns 0, 1, or 2 to indicate the kptr_restrict sysctl value
> > > > - Returns -1 for error case (IRQ context with kptr_restrict==1)
> > > > - Modifies the pointer value through @pptr parameter when needed
> > > > (sets to NULL when access should be restricted)
> > > >
> > > > These functions are needed for the HashedPtr and RestrictedPtr wrapper
> > > > types in rust/kernel/ptr.rs to provide safe pointer formatting that
> > > > matches C kernel patterns.
> > > >
> > > > This refactoring:
> > > > - Allows restricted_pointer() to reuse the common logic while
> > > > maintaining the same behavior
> > > > - Enables Rust code to use the same kptr_restrict handling logic
> > > > - Reduces code duplication
> > >
> > > ...
> > >
> > > > +EXPORT_SYMBOL_GPL(ptr_to_hashval);
> > >
> > > I do not like this. At bare minimum we should make sure it's namespaced, so the
> > > author of the code deliberately needs to import it (I'm talking about C side).
> > >
> > > Ideally we should have something which is Rust specific, like
> > >
> > > EXPORT_SYMBOL_FOR_RUST_ONLY(foo);
> > >
> > > Can we do that first?
> >
> > We don't have an EXPORT_SYMBOL_FOR_RUST_ONLY(). The closest there is
> > would be to place it in rust/helpers/, since such symbols won't be
> > available to C modules once we land this:
> >
> > https://lore.kernel.org/all/20251202-inline-helpers-v1-0-879dae33a66a@google.com/
>
> Does the inline helpers feature also support GCC builds, or is it
> limited to Clang only?
Clang only.
Alice
^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2026-01-01 1:46 UTC | newest]
Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-29 7:21 [PATCH v7 0/4] rust: Add safe pointer formatting support Ke Sun
2025-12-29 7:21 ` [PATCH v7 1/4] lib/vsprintf: Export functions for Rust " Ke Sun
2025-12-29 10:44 ` Dirk Behme
2025-12-31 2:46 ` Ke Sun
2025-12-31 11:07 ` Alice Ryhl
2025-12-29 14:18 ` Andy Shevchenko
2025-12-29 15:00 ` Ke Sun
2025-12-31 10:04 ` Alice Ryhl
2026-01-01 1:43 ` 孙科
2026-01-01 1:46 ` Alice Ryhl
2025-12-29 7:21 ` [PATCH v7 2/4] rust: kernel: Add pointer wrapper types for safe pointer formatting Ke Sun
2025-12-29 9:03 ` Alice Ryhl
2025-12-29 14:07 ` Ke Sun
2025-12-29 7:21 ` [PATCH v7 3/4] rust: fmt: Default raw pointer formatting to HashedPtr Ke Sun
2025-12-29 7:21 ` [PATCH v7 4/4] docs: rust: Add pointer formatting documentation Ke Sun
2025-12-29 14:11 ` [PATCH v7 0/4] rust: Add safe pointer formatting support Andy Shevchenko
2025-12-30 2:03 ` Ke Sun
2025-12-30 8:40 ` Andy Shevchenko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox