zalloc/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2#![cfg_attr(docsrs, feature(doc_auto_cfg))]
3#![cfg_attr(feature = "allocator", feature(allocator_api))]
4
5//! Implementation of a Zeroizing Allocator, enabling zeroizing memory on deallocation.
6//! This can either be used with Box (requires nightly and the "allocator" feature) to provide the
7//! functionality of zeroize on types which don't implement zeroize, or used as a wrapper around
8//! the global allocator to ensure *all* memory is zeroized.
9
10use core::{
11  slice,
12  alloc::{Layout, GlobalAlloc},
13};
14
15use zeroize::Zeroize;
16
17/// An allocator wrapper which zeroizes its memory on dealloc.
18pub struct ZeroizingAlloc<T>(pub T);
19
20#[cfg(feature = "allocator")]
21use core::{
22  ptr::NonNull,
23  alloc::{AllocError, Allocator},
24};
25#[cfg(feature = "allocator")]
26unsafe impl<T: Allocator> Allocator for ZeroizingAlloc<T> {
27  fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
28    self.0.allocate(layout)
29  }
30
31  unsafe fn deallocate(&self, mut ptr: NonNull<u8>, layout: Layout) {
32    slice::from_raw_parts_mut(ptr.as_mut(), layout.size()).zeroize();
33    self.0.deallocate(ptr, layout);
34  }
35}
36
37unsafe impl<T: GlobalAlloc> GlobalAlloc for ZeroizingAlloc<T> {
38  unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
39    self.0.alloc(layout)
40  }
41
42  unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
43    slice::from_raw_parts_mut(ptr, layout.size()).zeroize();
44    self.0.dealloc(ptr, layout);
45  }
46}