30
30
//!
31
31
//! ## Minimum Supported Rust Version
32
32
//!
33
- //! Requires Rust **1.56 ** or newer.
33
+ //! Requires Rust **1.60 ** or newer.
34
34
//!
35
35
//! In the future, we reserve the right to change MSRV (i.e. MSRV is out-of-scope
36
36
//! for this crate's SemVer guarantees), however when we do it will be accompanied
@@ -263,10 +263,7 @@ use core::{
263
263
} ;
264
264
265
265
#[ cfg( feature = "alloc" ) ]
266
- use {
267
- alloc:: { boxed:: Box , string:: String , vec:: Vec } ,
268
- core:: slice,
269
- } ;
266
+ use alloc:: { boxed:: Box , string:: String , vec:: Vec } ;
270
267
271
268
#[ cfg( feature = "std" ) ]
272
269
use std:: ffi:: CString ;
@@ -315,18 +312,28 @@ macro_rules! impl_zeroize_with_default {
315
312
316
313
#[ rustfmt:: skip]
317
314
impl_zeroize_with_default ! {
318
- bool , char ,
315
+ PhantomPinned , ( ) , bool , char ,
319
316
f32 , f64 ,
320
317
i8 , i16 , i32 , i64 , i128 , isize ,
321
318
u8 , u16 , u32 , u64 , u128 , usize
322
319
}
323
320
321
+ /// `PhantomPinned` is zero sized so provide a ZeroizeOnDrop implementation.
322
+ impl ZeroizeOnDrop for PhantomPinned { }
323
+
324
+ /// `()` is zero sized so provide a ZeroizeOnDrop implementation.
325
+ impl ZeroizeOnDrop for ( ) { }
326
+
324
327
macro_rules! impl_zeroize_for_non_zero {
325
328
( $( $type: ty) ,+) => {
326
329
$(
327
330
impl Zeroize for $type {
328
331
fn zeroize( & mut self ) {
329
- volatile_write( self , unsafe { <$type>:: new_unchecked( 1 ) } ) ;
332
+ const ONE : $type = match <$type>:: new( 1 ) {
333
+ Some ( one) => one,
334
+ None => unreachable!( ) ,
335
+ } ;
336
+ volatile_write( self , ONE ) ;
330
337
atomic_fence( ) ;
331
338
}
332
339
}
@@ -371,7 +378,7 @@ where
371
378
/// Impl [`ZeroizeOnDrop`] on arrays of types that impl [`ZeroizeOnDrop`].
372
379
impl < Z , const N : usize > ZeroizeOnDrop for [ Z ; N ] where Z : ZeroizeOnDrop { }
373
380
374
- impl < ' a , Z > Zeroize for IterMut < ' a , Z >
381
+ impl < Z > Zeroize for IterMut < ' _ , Z >
375
382
where
376
383
Z : Zeroize ,
377
384
{
@@ -405,25 +412,39 @@ where
405
412
// The memory pointed to by `self` is valid for `mem::size_of::<Self>()` bytes.
406
413
// It is also properly aligned, because `u8` has an alignment of `1`.
407
414
unsafe {
408
- volatile_set ( self as * mut _ as * mut u8 , 0 , mem:: size_of :: < Self > ( ) ) ;
415
+ volatile_set ( ( self as * mut Self ) . cast :: < u8 > ( ) , 0 , mem:: size_of :: < Self > ( ) ) ;
409
416
}
410
417
411
- // Ensures self is overwritten with the default bit pattern. volatile_write can't be
418
+ // Ensures self is overwritten with the `None` bit pattern. volatile_write can't be
412
419
// used because Option<Z> is not copy.
413
420
//
414
421
// Safety:
415
422
//
416
- // self is safe to replace with the default , which the take() call above should have
423
+ // self is safe to replace with `None` , which the take() call above should have
417
424
// already done semantically. Any value which needed to be dropped will have been
418
425
// done so by take().
419
- unsafe { ptr:: write_volatile ( self , Option :: default ( ) ) }
426
+ unsafe { ptr:: write_volatile ( self , None ) }
420
427
421
428
atomic_fence ( ) ;
422
429
}
423
430
}
424
431
425
432
impl < Z > ZeroizeOnDrop for Option < Z > where Z : ZeroizeOnDrop { }
426
433
434
+ /// Impl [`Zeroize`] on [`MaybeUninit`] types.
435
+ ///
436
+ /// This fills the memory with zeroes.
437
+ /// Note that this ignore invariants that `Z` might have, because
438
+ /// [`MaybeUninit`] removes all invariants.
439
+ impl < Z > Zeroize for MaybeUninit < Z > {
440
+ fn zeroize ( & mut self ) {
441
+ // Safety:
442
+ // `MaybeUninit` is valid for any byte pattern, including zeros.
443
+ unsafe { ptr:: write_volatile ( self , MaybeUninit :: zeroed ( ) ) }
444
+ atomic_fence ( ) ;
445
+ }
446
+ }
447
+
427
448
/// Impl [`Zeroize`] on slices of [`MaybeUninit`] types.
428
449
///
429
450
/// This impl can eventually be optimized using an memset intrinsic,
@@ -435,7 +456,7 @@ impl<Z> ZeroizeOnDrop for Option<Z> where Z: ZeroizeOnDrop {}
435
456
/// [`MaybeUninit`] removes all invariants.
436
457
impl < Z > Zeroize for [ MaybeUninit < Z > ] {
437
458
fn zeroize ( & mut self ) {
438
- let ptr = self . as_mut_ptr ( ) as * mut MaybeUninit < u8 > ;
459
+ let ptr = self . as_mut_ptr ( ) . cast :: < MaybeUninit < u8 > > ( ) ;
439
460
let size = self . len ( ) . checked_mul ( mem:: size_of :: < Z > ( ) ) . unwrap ( ) ;
440
461
assert ! ( size <= isize :: MAX as usize ) ;
441
462
@@ -445,7 +466,7 @@ impl<Z> Zeroize for [MaybeUninit<Z>] {
445
466
// and it is backed by a single allocated object for at least `self.len() * size_pf::<Z>()` bytes.
446
467
// and 0 is a valid value for `MaybeUninit<Z>`
447
468
// The memory of the slice should not wrap around the address space.
448
- unsafe { volatile_set ( ptr, MaybeUninit :: new ( 0 ) , size) }
469
+ unsafe { volatile_set ( ptr, MaybeUninit :: zeroed ( ) , size) }
449
470
atomic_fence ( ) ;
450
471
}
451
472
}
@@ -492,47 +513,22 @@ impl<Z> Zeroize for PhantomData<Z> {
492
513
/// [`PhantomData` is always zero sized so provide a ZeroizeOnDrop implementation.
493
514
impl < Z > ZeroizeOnDrop for PhantomData < Z > { }
494
515
495
- /// `PhantomPinned` is zero sized so provide a Zeroize implementation.
496
- impl Zeroize for PhantomPinned {
497
- fn zeroize ( & mut self ) { }
498
- }
499
-
500
- /// `PhantomPinned` is zero sized so provide a ZeroizeOnDrop implementation.
501
- impl ZeroizeOnDrop for PhantomPinned { }
502
-
503
- /// `()` is zero sized so provide a Zeroize implementation.
504
- impl Zeroize for ( ) {
505
- fn zeroize ( & mut self ) { }
506
- }
507
-
508
- /// `()` is zero sized so provide a ZeroizeOnDrop implementation.
509
- impl ZeroizeOnDrop for ( ) { }
510
-
511
- /// Generic implementation of Zeroize for tuples up to 10 parameters.
512
- impl < A : Zeroize > Zeroize for ( A , ) {
513
- fn zeroize ( & mut self ) {
514
- self . 0 . zeroize ( ) ;
515
- }
516
- }
517
-
518
- /// Generic implementation of ZeroizeOnDrop for tuples up to 10 parameters.
519
- impl < A : ZeroizeOnDrop > ZeroizeOnDrop for ( A , ) { }
520
-
521
516
macro_rules! impl_zeroize_tuple {
522
517
( $( $type_name: ident ) ,+ ) => {
523
- impl <$( $type_name: Zeroize ) ,+> Zeroize for ( $( $type_name) , +) {
518
+ impl <$( $type_name: Zeroize ) ,+> Zeroize for ( $( $type_name, ) +) {
524
519
fn zeroize( & mut self ) {
525
520
#[ allow( non_snake_case) ]
526
- let ( $( $type_name) , +) = self ;
521
+ let ( $( $type_name, ) +) = self ;
527
522
$( $type_name. zeroize( ) ) ;+
528
523
}
529
524
}
530
525
531
- impl <$( $type_name: ZeroizeOnDrop ) ,+> ZeroizeOnDrop for ( $( $type_name) , +) { }
526
+ impl <$( $type_name: ZeroizeOnDrop ) ,+> ZeroizeOnDrop for ( $( $type_name, ) +) { }
532
527
}
533
528
}
534
529
535
530
// Generic implementations for tuples up to 10 parameters.
531
+ impl_zeroize_tuple ! ( A ) ;
536
532
impl_zeroize_tuple ! ( A , B ) ;
537
533
impl_zeroize_tuple ! ( A , B , C ) ;
538
534
impl_zeroize_tuple ! ( A , B , C , D ) ;
@@ -561,17 +557,7 @@ where
561
557
self . clear ( ) ;
562
558
563
559
// Zero the full capacity of `Vec`.
564
- // Safety:
565
- //
566
- // This is safe, because `Vec` never allocates more than `isize::MAX` bytes.
567
- // This exact use case is even mentioned in the documentation of `pointer::add`.
568
- // This is safe because MaybeUninit ignores all invariants,
569
- // so we can create a slice of MaybeUninit<Z> using the full capacity of the Vec
570
- let uninit_slice = unsafe {
571
- slice:: from_raw_parts_mut ( self . as_mut_ptr ( ) as * mut MaybeUninit < Z > , self . capacity ( ) )
572
- } ;
573
-
574
- uninit_slice. zeroize ( ) ;
560
+ self . spare_capacity_mut ( ) . zeroize ( ) ;
575
561
}
576
562
}
577
563
@@ -621,11 +607,11 @@ impl Zeroize for CString {
621
607
// contain a trailing zero byte
622
608
let this = mem:: take ( self ) ;
623
609
624
- // - CString::into_bytes calls ::into_vec which takes ownership of the heap pointer
610
+ // - CString::into_bytes_with_nul calls ::into_vec which takes ownership of the heap pointer
625
611
// as a Vec<u8>
626
612
// - Calling .zeroize() on the resulting vector clears out the bytes
627
613
// From: https://github.com/RustCrypto/utils/pull/759#issuecomment-1087976570
628
- let mut buf = this. into_bytes ( ) ;
614
+ let mut buf = this. into_bytes_with_nul ( ) ;
629
615
buf. zeroize ( ) ;
630
616
631
617
// expect() should never fail, because zeroize() truncates the Vec
0 commit comments