@@ -795,6 +795,74 @@ unsafe fn volatile_set<T: Copy + Sized>(dst: *mut T, src: T, count: usize) {
795
795
}
796
796
}
797
797
798
+ /// Zeroizes a flat type/struct. Only zeroizes the values that it owns, and it does not work on
799
+ /// dynamically sized values or trait objects. It would be inefficient to use this function on a
800
+ /// type that already implements `ZeroizeOnDrop`.
801
+ ///
802
+ /// # Safety
803
+ /// - The type must not contain references to outside data or dynamically sized data, such as Vec<X>
804
+ /// or String<X>.
805
+ /// - This function can invalidate the type if it is used after this function is called on it. It is
806
+ /// advisable to call this function in `impl Drop`.
807
+ /// - The bit pattern of all zeroes must be valid for the data being zeroized. This may not be true for
808
+ /// enums and pointers.
809
+ ///
810
+ /// # Incompatible data types
811
+ /// Some data types that cannot be safely zeroized using `zeroize_flat_type` include, but are not
812
+ /// limited to:
813
+ /// - pointers such as
814
+ /// - *const u8
815
+ /// - *mut u8
816
+ /// - references such as
817
+ /// - &T
818
+ /// - &mut T
819
+ /// - smart pointers and collections
820
+ /// - Arc<T>
821
+ /// - Box<T>
822
+ /// - Vec<T>
823
+ /// - HashMap<T1, T2>
824
+ /// - String
825
+ ///
826
+ /// Some data types that may be invalid after calling `zeroize_flat_type`:
827
+ /// - enums
828
+ ///
829
+ /// # Examples
830
+ /// Safe usage for a struct containing strictly flat data:
831
+ /// ```
832
+ /// use zeroize::{ZeroizeOnDrop, zeroize_flat_type};
833
+ ///
834
+ /// struct DataToZeroize {
835
+ /// flat_data_1: [u8; 32],
836
+ /// flat_data_2: SomeMoreFlatData,
837
+ /// }
838
+ ///
839
+ /// struct SomeMoreFlatData(u64);
840
+ ///
841
+ /// impl Drop for DataToZeroize {
842
+ /// fn drop(&mut self) {
843
+ /// unsafe { zeroize_flat_type(self as *mut Self) }
844
+ /// }
845
+ /// }
846
+ /// impl ZeroizeOnDrop for DataToZeroize {}
847
+ ///
848
+ /// let mut data = DataToZeroize {
849
+ /// flat_data_1: [3u8; 32],
850
+ /// flat_data_2: SomeMoreFlatData(123u64)
851
+ /// };
852
+ ///
853
+ /// // data gets zeroized when dropped
854
+ /// ```
855
+ #[ inline( always) ]
856
+ pub unsafe fn zeroize_flat_type < F : Sized > ( data : * mut F ) {
857
+ let size = mem:: size_of :: < F > ( ) ;
858
+ // Safety:
859
+ //
860
+ // This is safe because `mem::size_of<T>()` returns the exact size of the object in memory, and
861
+ // `data_ptr` points directly to the first byte of the data.
862
+ volatile_set ( data as * mut u8 , 0 , size) ;
863
+ atomic_fence ( )
864
+ }
865
+
798
866
/// Internal module used as support for `AssertZeroizeOnDrop`.
799
867
#[ doc( hidden) ]
800
868
pub mod __internal {
0 commit comments