From nobody Mon Jun 8 22:53:11 2026 Received: from mail-pg1-f179.google.com (mail-pg1-f179.google.com [209.85.215.179]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 14B4630BB8C for ; Tue, 26 May 2026 02:43:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.215.179 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779763404; cv=none; b=dcaeqIYT6t4DlPmF5BJPU9TPKtp/k07lK09Zsf7zCShLmGvzIP1VUTvXRfO213o+ynlivuGrgV0kC1t21TzUVAP5+lXl8a/32abTk2Mw4+hD/5f3r5eRYQrlqAdzbsGvRMNV4H+umep9Z8tA6Ak0Hq7xS3IX2GzFkscglbthutc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779763404; c=relaxed/simple; bh=2TV7ebtbvkj1szJHQaiHLbPPgbAjz9bEw83GICTxwwE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=iu79jLs0m7xmeYoZ/L1UoT+a8ULLhWzUWKzrdW+zoUEASD+1+LLHG3OdT7J9ZpED37HAKlrk1WX6hzJUywdhu6oazWZbeuYSsAzdbWr9UpzjyRlOQw/oGXkQPjAUpPNlSBwTlluGaK12HtoVKygaUjYFf/JSnzIErCswaIn1vXY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.215.179 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pg1-f179.google.com with SMTP id 41be03b00d2f7-c82de129a40so4217313a12.1 for ; Mon, 25 May 2026 19:43:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779763401; x=1780368201; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=SG3tL/12wgrOEhpyoLjgZFw1i9B1GNATu65IvCzKwy8=; b=VGKvP/xW21vjUdwUkgdA18ix46oB9bM1Egoni5EU41Cm25RkpMLOTh9FzPyeCfp3jo SuoJjA0BKm9N4qEhD3dErRUKobGOGBrtj1PaKcsakBX9yJ5kgI+va5annNH05DSmC5wc MeBcA3jzha2MgVqM+w11IRXsFPKiGVwAvDjBHSFJS2Ys9UNSIcc8h2wlBTb08OyERbb+ HdytaAoNxKHuB9yn2ws2XHfqmzCuEYbtiXQvNUQ4wZrHEYbEZ0yfxsB2yO3ABqW574xb ICfCxMzytiuuq6vq94lzp97Si1epWPaeTTIpWLM7fDj8J/m/WDu24Mlklgv85rij9zLz k18A== X-Forwarded-Encrypted: i=1; AFNElJ//1xYo7mGkNKb0FoBpRGiQNR8PlWnl49MeVUGLeu0kXuf7k//HG94/VCGism9Qa7UK+lUXz6BJk2+MNNM=@vger.kernel.org X-Gm-Message-State: AOJu0YxaXtIVTVJawEiaOjQo94vNWJ4Rxx4F7UlIprx3LDzVAfj4CeJw eI0tLTa51szOtXb0JyNPqKG7guoilMCELZXTSuFMj6bCmvXb8dKa0c9ibX6hCxiI X-Gm-Gg: Acq92OEwKmeZwlaqKls4TEVBtvQYOH2peh/Hu9kLtTAQoYaVjOVQleH42lzq7Av6YV4 5CMiMA5HbrVIjyuotj1m+WFdHIWjI4XWPwc1nOkyRRPn0b5HDHuObwa/vEVbPETQOdh0KPlBZHU Q5QJ8JMTQhKUFgoWR0o7KEla+yyfpM/uVPKxElvQ5Ek1CNSnhbDcYQhEE8Dlo/MVU5rQpF4D8jV JAepj77MdxaUxCswhH/Fo2W1Ft6XL3JYWDV8KhVpzE7cLI3AA7/l3Cro8itq6w3Wj6ZgHWYaN15 ATCgFghBBsM+D5QmCah511049VlZizN25NYK2bj29Hbz1fP9De0Nc/D42R58Ns052d3qDJtG723 Y6kndHQvLPfW2teIR8S25v6ZLbUD8wHe3Rsa2q0WDQ+gyyLrmG9GsSTYgYh5H7pT0Rxo= X-Received: by 2002:a17:902:e74f:b0:2b2:58c7:2ce1 with SMTP id d9443c01a7336-2beb07da2dcmr167887845ad.36.1779763401302; Mon, 25 May 2026 19:43:21 -0700 (PDT) Received: from [127.0.1.1] ([2a11:3:200::10a9]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2beb5695a40sm99551665ad.17.2026.05.25.19.43.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 May 2026 19:43:20 -0700 (PDT) From: Ke Sun Date: Tue, 26 May 2026 10:42:48 +0800 Subject: [PATCH v13 1/2] rust: fmt: fix {:p} printing stack addresses Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260526-hashedptr-v13-1-324352716eb9@kylinos.cn> References: <20260526-hashedptr-v13-0-324352716eb9@kylinos.cn> In-Reply-To: <20260526-hashedptr-v13-0-324352716eb9@kylinos.cn> To: Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Ke Sun X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1779763387; l=1203; i=sunke@kylinos.cn; s=20260317; h=from:subject:message-id; bh=2TV7ebtbvkj1szJHQaiHLbPPgbAjz9bEw83GICTxwwE=; b=qgJF+WCDZqH7A01c5o2qNMx/eN9/dju+G7cYpMV+avZWSyr+KuFCGLcjI68wbpwt8wIExUVVi YWqSOvauoArCUdW2VhPdvA1BwC4yul4XJvcPvf+83Y1p3z7iy69MER9 X-Developer-Key: i=sunke@kylinos.cn; a=ed25519; pk=CHcwQp8GSoj25V/L1ZWNSQjWp9eSIb0s9LKr0Nm3WuE= The `impl_fmt_adapter_forward!` macro forwards `Pointer` for `Adapter` by destructuring `self` into a local `t`, causing `{:p}` to print the address of that temporary stack variable rather than the actual pointer. Remove `Pointer` from the macro and provide a manual impl for `Adapter<&T>` that passes `self.0` directly. Signed-off-by: Ke Sun --- rust/kernel/fmt.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/rust/kernel/fmt.rs b/rust/kernel/fmt.rs index 73afbc51ba33a..cd7d9664ff5b9 100644 --- a/rust/kernel/fmt.rs +++ b/rust/kernel/fmt.rs @@ -43,7 +43,14 @@ fn fmt(&self, f: &mut Formatter<'_>) -> Result { UpperExp, UpperHex, // }; -impl_fmt_adapter_forward!(Debug, LowerHex, UpperHex, Octal, Binary, Pointe= r, LowerExp, UpperExp); +impl_fmt_adapter_forward!(Debug, LowerHex, UpperHex, Octal, Binary, LowerE= xp, UpperExp); + +impl Pointer for Adapter<&T> { + #[inline] + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + Pointer::fmt(self.0, f) + } +} =20 /// A copy of [`core::fmt::Display`] that allows us to implement it for fo= reign types. /// --=20 2.43.0 From nobody Mon Jun 8 22:53:11 2026 Received: from mail-pj1-f52.google.com (mail-pj1-f52.google.com [209.85.216.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4149930BF67 for ; Tue, 26 May 2026 02:43:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779763411; cv=none; b=Lspc6/JWxMEIHtFoKDendrNFRxoSsRaOcDnSZXvK2aoXximlnBJ5s97qjeSGt38pgo4uNZmaQNGJYDi1G3M/PDZF1BGrK76yQQ/zikromhimYpIsGpe7A/70UyJWSL1qxJY1KDTp+1u1dPxDLnxhioQ3ISyjLz83GfifZFmGbBw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779763411; c=relaxed/simple; bh=3Bz1W83pyaisYQLkTiiVDMpcQpVcYcsFqTaZmc/GLPo=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mg+Rwx/Sf043TxUqHv1uot/L+u9fK1LhHmafG0BxV75xwcdIMHTN77lvmg2mcQjodORJmXxySbPM2GGJ4I+mhU5d3+yFaJxk2m/vob1ZfP5uTA9YXAy1SAkbUi6Sz+GnapUghkfUgIIOz9AuoUamFu779BSDKbZZ406AAukcdBY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn; spf=pass smtp.mailfrom=gmail.com; arc=none smtp.client-ip=209.85.216.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pj1-f52.google.com with SMTP id 98e67ed59e1d1-36b0c968fe8so116641a91.3 for ; Mon, 25 May 2026 19:43:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1779763408; x=1780368208; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=Ihr6pecjt6XrybXMPyshAo9jLguaTZlFe4uVWsyidKc=; b=i7whdbz6x2vTqrehqNFejtIPGWvymeYJdKiJsjLVoQ8o9Oi0bai8tLmAPo4xCkRyFT fx+SC9zjYiTFKJE0Ymrofib4cLYNgs8gqtM+59h9KmH9NAUDYzZhPYEYlC2rXdQ2MVC+ L1RJx4gTHEylM95Rs8S/QJoBgbQ7KUyXvE+dtSCFuVZfj4DyWur+OWxktS2PavKUoB+i OU0YrpfTAWmfvyJNEQEmCxDdu5D/REbjrF7umZDhrUyIKmwCS0JEOfCAczOA1Osc8/2M K6C5StFU1Xe9QwyUnt77db4tokn9xrdaKsD1RgLoWdBJfLDNAEK/UjDnbU6hquj4YE35 aujg== X-Forwarded-Encrypted: i=1; AFNElJ/ZKTrLLwBmRseXGME3SCuGz6zS2rzkEf/1d/k2F+DdFtyos4kzZ2rrkx14mBs6Xs0ChVfLH4QUIKnk1ts=@vger.kernel.org X-Gm-Message-State: AOJu0Yz5u7VixhKiHXgK0mcTJ5nWDA7H2y0x4NPOp5dZM/O0NqaeE93i h2qqS9h2fhhvWv1znTp0UsoDUM+9hFBCTTkudwY0yGMGYyJIxwiFY1Ue X-Gm-Gg: Acq92OG4kxbcOb1GFRAcYIuyJxua7ClKPoeJVGAD6dtPmb6Q4Slg4go9CEkqT7GDu/W OW+bIyHqzuLoxN38jxaLPrV1MBJk3bwbS4RcrWoSTliKBYwwLM3Hc8wTxCKoG6Fsk3tl4Dwl63m W93akiS8BrM5NxQzcRRccT/G48fvcVSbBe6xeZTwHGB/wQ99d4aMQ7E0kxIXzt8N6Z9kIXVAjoi HS1RNYoTXGUoEQKUN82KWBsqlmKQPtyK5alBB0T5+5JkyBd9/e6sv2gRNlh6Cf/ouXAOp4dYbSs A95eBKGMIJEAQq+XCYTWX6gPl7Rghl1EdzrN26wj9PjU2aKzGnBQlyi/xbxFa0kuEwcRHByCbGq Z7IWR3AhhUOAeD439vpFf274a+QckcfcgtwhRzcbRNq31641Z4DMVU0i/wVYKEuoc8M4= X-Received: by 2002:a17:903:2ece:b0:2bd:eeb6:ff22 with SMTP id d9443c01a7336-2beb0390b36mr201048235ad.7.1779763408229; Mon, 25 May 2026 19:43:28 -0700 (PDT) Received: from [127.0.1.1] ([2a11:3:200::10a9]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2beb5695a40sm99551665ad.17.2026.05.25.19.43.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 May 2026 19:43:27 -0700 (PDT) From: Ke Sun Date: Tue, 26 May 2026 10:42:49 +0800 Subject: [PATCH v13 2/2] rust: fmt: route {:p} through HashedPtr to prevent address leaks Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260526-hashedptr-v13-2-324352716eb9@kylinos.cn> References: <20260526-hashedptr-v13-0-324352716eb9@kylinos.cn> In-Reply-To: <20260526-hashedptr-v13-0-324352716eb9@kylinos.cn> To: Miguel Ojeda , Boqun Feng , Gary Guo , =?utf-8?q?Bj=C3=B6rn_Roy_Baron?= , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Ke Sun X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1779763387; l=7686; i=sunke@kylinos.cn; s=20260317; h=from:subject:message-id; bh=3Bz1W83pyaisYQLkTiiVDMpcQpVcYcsFqTaZmc/GLPo=; b=isIdJUrRam+JF2yWlVem9AYutkgYGafJoaBPSHYf8bKeIRCDRy5HjFl0NLaDZ7uwUdJ/0hpGA HPDVkf/EBYJCW5Y9RSjpuRbWWByA3iOUvPoGycLW9OsaADX8d386P/J X-Developer-Key: i=sunke@kylinos.cn; a=ed25519; pk=CHcwQp8GSoj25V/L1ZWNSQjWp9eSIb0s9LKr0Nm3WuE= Define a custom `kernel::fmt::Pointer` trait and `HashedPtr` wrapper so that `{:p}` formatting uses the kernel's `%p` hashed format instead of printing raw pointer values, preventing kernel address space leaks. Signed-off-by: Ke Sun --- rust/kernel/fmt.rs | 166 +++++++++++++++++++++++++++++++++++++++++++++++++= +++- 1 file changed, 164 insertions(+), 2 deletions(-) diff --git a/rust/kernel/fmt.rs b/rust/kernel/fmt.rs index cd7d9664ff5b9..3d154dad06f64 100644 --- a/rust/kernel/fmt.rs +++ b/rust/kernel/fmt.rs @@ -39,13 +39,106 @@ fn fmt(&self, f: &mut Formatter<'_>) -> Result { LowerExp, LowerHex, Octal, - Pointer, UpperExp, UpperHex, // }; +use core::ptr::NonNull; impl_fmt_adapter_forward!(Debug, LowerHex, UpperHex, Octal, Binary, LowerE= xp, UpperExp); =20 -impl Pointer for Adapter<&T> { +/// A copy of [`core::fmt::Pointer`] that allows implementing pointer form= atting for foreign types. +/// +/// Together with the [`Adapter`] type and [`fmt!`] macro, it enables raw = pointer formatting to be +/// intercepted and routed to [`HashedPtr`] (kernel's `%p` hashed format),= preventing kernel address +/// leaks. +/// +/// [`fmt!`]: crate::prelude::fmt! +pub trait Pointer { + /// Same as [`core::fmt::Pointer::fmt`]. + fn fmt(&self, f: &mut Formatter<'_>) -> Result; +} + +/// A wrapper for pointers that formats them using kernel's `%p` format sp= ecifier. +/// +/// By default, `%p` prints a hashed representation of the pointer address= to prevent kernel address +/// leaks. When the `no_hash_pointers` kernel command-line parameter is en= abled, the real address is +/// printed instead (for debugging purposes). +pub struct HashedPtr(pub *const T); + +impl Pointer for HashedPtr { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + use crate::str::CStrExt as _; + + let mut buf =3D [0u8; 32]; + + // SAFETY: `buf` is a valid, writable buffer of 32 bytes, sufficie= nt for all architectures + // (max 19 bytes for 64-bit). The format string `c"0x%p"` is null-= terminated and `%p` + // matches the pointer argument. + let len =3D unsafe { + crate::bindings::scnprintf( + buf.as_mut_ptr().cast(), + buf.len(), + // Rust's `{:p}` includes a "0x" prefix, the kernel's `%p`= does not. + c"0x%p".as_char_ptr(), + self.0.cast::(), + ) + }; + + // SAFETY: "0x%p" produces only ASCII, which is valid UTF-8. + let hashed_str =3D unsafe { core::str::from_utf8_unchecked(&buf[..= len as usize]) }; + + // Handle `{:0width$p}`: insert zeros after "0x" prefix. + if f.sign_aware_zero_pad() { + if let Some(width) =3D f.width() { + if hashed_str.len() < width && hashed_str.starts_with("0x"= ) { + return write!(f, "0x{:0>width$}", &hashed_str[2..], wi= dth =3D width - 2); + } + } + } + + // Use `f.pad` to handle width/alignment formatting. + f.pad(hashed_str) + } +} + +// Raw pointers are formatted via `HashedPtr` (kernel `%p`: hashed by defa= ult, plain with +// `no_hash_pointers`). +impl Pointer for *const T { + #[inline] + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + Pointer::fmt(&HashedPtr(*self), f) + } +} + +impl Pointer for *mut T { + #[inline] + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + <*const T as Pointer>::fmt(&(*self).cast_const(), f) + } +} + +impl Pointer for &T { + #[inline] + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + <*const T as Pointer>::fmt(&core::ptr::from_ref(*self), f) + } +} + +impl Pointer for &mut T { + #[inline] + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + <*const T as Pointer>::fmt(&core::ptr::from_ref(*self), f) + } +} + +impl Pointer for NonNull { + #[inline] + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + <*const T as Pointer>::fmt(&self.as_ptr().cast_const(), f) + } +} + +// `Adapter<&T>` bridges our `Pointer` trait to `core::fmt::Pointer` +impl core::fmt::Pointer for Adapter<&T> { #[inline] fn fmt(&self, f: &mut Formatter<'_>) -> Result { Pointer::fmt(self.0, f) @@ -112,3 +205,72 @@ fn fmt(&self, f: &mut Formatter<'_>) -> Result { {} crate::sync::Arc {where crate::sync::Arc: core::fm= t::Display}, {} crate::sync::UniqueArc {where crate::sync::UniqueArc<= T>: core::fmt::Display}, ); + +#[macros::kunit_tests(rust_kernel_fmt)] +mod tests { + use crate::{ + bindings, + prelude::fmt, + str::CString, // + }; + + #[cfg(CONFIG_64BIT)] + mod expected { + pub(super) const PTR_VALUE: usize =3D 0xffffffffdeadbeef; + pub(super) const HASHED_PREFIX: &str =3D "0x00000000"; + pub(super) const RAW_POINTER: &str =3D "0xffffffffdeadbeef"; + pub(super) const PADDED_RIGHT: &str =3D " 0xffffffffdeadbeef"; + pub(super) const ZERO_PADDED: &str =3D "0x000000ffffffffdeadbeef"; + pub(super) const HASHED_PADDED_RIGHT_PREFIX: &str =3D " "; + pub(super) const HASHED_ZERO_PADDED_PREFIX: &str =3D "0x0000000000= 0000"; + } + + #[cfg(not(CONFIG_64BIT))] + mod expected { + pub(super) const PTR_VALUE: usize =3D 0xdeadbeef; + pub(super) const HASHED_PREFIX: &str =3D "0x"; + pub(super) const RAW_POINTER: &str =3D "0xdeadbeef"; + pub(super) const PADDED_RIGHT: &str =3D " 0xdeadbeef"; + pub(super) const ZERO_PADDED: &str =3D "0x00000000000000deadbeef"; + pub(super) const HASHED_PADDED_RIGHT_PREFIX: &str =3D " = "; + pub(super) const HASHED_ZERO_PADDED_PREFIX: &str =3D "0x0000000000= 0000"; + } + + #[test] + fn test_ptr_formatting() -> core::result::Result<(), crate::error::Err= or> { + let ptr =3D expected::PTR_VALUE as *const u8; + + // SAFETY: `no_hash_pointers` is a global variable that is never c= oncurrently modified =E2=80=94 + // KUnit tests may run at boot (before `mark_readonly()`) or manua= lly afterwards (when the + // variable is read-only). Reading is always safe. + let no_hash =3D unsafe { bindings::no_hash_pointers }; + + if no_hash { + let cstr =3D CString::try_from_fmt(fmt!("{:p}", ptr))?; + assert_eq!(cstr.to_str()?, expected::RAW_POINTER); + + let cstr =3D CString::try_from_fmt(fmt!("{:>24p}", ptr))?; + assert_eq!(cstr.to_str()?, expected::PADDED_RIGHT); + + let cstr =3D CString::try_from_fmt(fmt!("{:024p}", ptr))?; + assert_eq!(cstr.to_str()?, expected::ZERO_PADDED); + } else { + let cstr =3D CString::try_from_fmt(fmt!("{:p}", ptr))?; + let formatted =3D cstr.to_str()?; + assert!(formatted.starts_with(expected::HASHED_PREFIX)); + assert_ne!(formatted, expected::RAW_POINTER); + + let cstr =3D CString::try_from_fmt(fmt!("{:>24p}", ptr))?; + assert!(cstr + .to_str()? + .starts_with(expected::HASHED_PADDED_RIGHT_PREFIX)); + + let cstr =3D CString::try_from_fmt(fmt!("{:024p}", ptr))?; + assert!(cstr + .to_str()? + .starts_with(expected::HASHED_ZERO_PADDED_PREFIX)); + } + + Ok(()) + } +} --=20 2.43.0