From b8654498ee7f06047a111213f5d33e55c5af74b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 14 Sep 2026 17:18:44 +0300 Subject: [PATCH 1/4] zeroize: tweak proxy allocator test --- zeroize/tests/alloc.rs | 53 ++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/zeroize/tests/alloc.rs b/zeroize/tests/alloc.rs index 5dbdd715..7f201a38 100644 --- a/zeroize/tests/alloc.rs +++ b/zeroize/tests/alloc.rs @@ -1,24 +1,32 @@ //! Tests for `Zeroize` impls on heap-allocated data structures -#![allow(clippy::std_instead_of_core, clippy::undocumented_unsafe_blocks)] - -use std::alloc::{GlobalAlloc, Layout, System}; +use core::{ + alloc::{GlobalAlloc, Layout}, + ptr, + sync::atomic::{AtomicPtr, Ordering::Relaxed}, +}; use zeroize::Zeroize; -// Allocator that ensures that deallocated data is zeroized. +use std::alloc::System; + +static REG_PTR: AtomicPtr = AtomicPtr::new(ptr::null_mut()); + +// Allocator that ensures that allocation registered in `REG_PTR` is zeroized. struct ProxyAllocator; +#[allow(clippy::undocumented_unsafe_blocks)] unsafe impl GlobalAlloc for ProxyAllocator { unsafe fn alloc(&self, layout: Layout) -> *mut u8 { unsafe { System.alloc(layout) } } unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { - if layout.size() == 160 { + if ptr == REG_PTR.load(Relaxed) { for i in 0..layout.size() { - let b = unsafe { core::ptr::read(ptr.add(i)) }; + let b = unsafe { ptr::read(ptr.add(i)) }; assert_eq!(b, 0); } + REG_PTR.store(ptr::null_mut(), Relaxed); } unsafe { System.dealloc(ptr, layout) } @@ -32,7 +40,10 @@ struct SecretBox(Box); impl SecretBox { fn new(val: S) -> Self { - Self(Box::new(val)) + let mut b = Box::new(val); + let p = &raw mut b; + REG_PTR.store(p.cast(), Relaxed); + Self(b) } } @@ -42,19 +53,14 @@ impl Drop for SecretBox { } } -#[test] -fn secret_box_alloc_test() { - let b1 = SecretBox::new([u128::MAX; 10]); - core::hint::black_box(&b1); - let b2 = SecretBox::new([u8::MAX; 160]); - core::hint::black_box(&b2); -} - struct ObserveSecretBox(Box); impl ObserveSecretBox { fn new(val: S) -> Self { - Self(Box::new(val)) + let mut b = Box::new(val); + let p = &raw mut b; + REG_PTR.store(p.cast(), Relaxed); + Self(b) } } @@ -66,9 +72,20 @@ impl Drop for ObserveSecretBox { } #[test] -fn observe_secret_box_alloc_test() { - let b1 = ObserveSecretBox::new([u128::MAX; 10]); +fn proxy_alloc_test() { + let b1 = SecretBox::new([u128::MAX; 10]); core::hint::black_box(&b1); + drop(b1); + let b2 = SecretBox::new([u8::MAX; 160]); core::hint::black_box(&b2); + drop(b2); + + let b3 = ObserveSecretBox::new([u128::MAX; 10]); + core::hint::black_box(&b3); + drop(b3); + + let b4 = SecretBox::new([u8::MAX; 160]); + core::hint::black_box(&b4); + drop(b4); } From 447ecc0aa59ffe36ff21e046492b4df067b304bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 14 Sep 2026 17:21:32 +0300 Subject: [PATCH 2/4] add changelog entry --- zeroize/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/zeroize/CHANGELOG.md b/zeroize/CHANGELOG.md index 0272a4c9..51e3b421 100644 --- a/zeroize/CHANGELOG.md +++ b/zeroize/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 1.9.1 (UNRELEASED) +### Fixed +- False positive failures in proxy allocator test ([#1538]) + +[#1538]: https://github.com/RustCrypto/utils/pull/1538 + ## 1.9.0 (2026-06-12) ### Added - `Zeroizing` is now `repr(transparent)` ([#1253]) From 67ba972cb64278a599ff4da7394ee30d9617a474 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 14 Sep 2026 18:43:31 +0300 Subject: [PATCH 3/4] fix box deref --- zeroize/tests/alloc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zeroize/tests/alloc.rs b/zeroize/tests/alloc.rs index 7f201a38..2695381c 100644 --- a/zeroize/tests/alloc.rs +++ b/zeroize/tests/alloc.rs @@ -41,7 +41,7 @@ struct SecretBox(Box); impl SecretBox { fn new(val: S) -> Self { let mut b = Box::new(val); - let p = &raw mut b; + let p: *mut S = &raw mut *b; REG_PTR.store(p.cast(), Relaxed); Self(b) } @@ -58,7 +58,7 @@ struct ObserveSecretBox(Box); impl ObserveSecretBox { fn new(val: S) -> Self { let mut b = Box::new(val); - let p = &raw mut b; + let p: *mut S = &raw mut *b; REG_PTR.store(p.cast(), Relaxed); Self(b) } From 2226323a394ec0311e0f827bfe1d599e0fcf0209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D1=80=D1=82=D1=91=D0=BC=20=D0=9F=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=BE=D0=B2=20=5BArtyom=20Pavlov=5D?= Date: Mon, 14 Sep 2026 19:03:48 +0300 Subject: [PATCH 4/4] Add TODO note --- zeroize/tests/alloc.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/zeroize/tests/alloc.rs b/zeroize/tests/alloc.rs index 2695381c..9a575d7d 100644 --- a/zeroize/tests/alloc.rs +++ b/zeroize/tests/alloc.rs @@ -41,6 +41,7 @@ struct SecretBox(Box); impl SecretBox { fn new(val: S) -> Self { let mut b = Box::new(val); + // TODO(MSRV-1.98): use `Box::as_mut_ptr` let p: *mut S = &raw mut *b; REG_PTR.store(p.cast(), Relaxed); Self(b) @@ -58,6 +59,7 @@ struct ObserveSecretBox(Box); impl ObserveSecretBox { fn new(val: S) -> Self { let mut b = Box::new(val); + // TODO(MSRV-1.98): use `Box::as_mut_ptr` let p: *mut S = &raw mut *b; REG_PTR.store(p.cast(), Relaxed); Self(b)