1 // Copyright 2017 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <zircon/compiler.h> 8 #include <stddef.h> 9 10 __BEGIN_CDECLS 11 12 // See memcpy(). Invocations of this implementation are guaranteed to not be optimized 13 // away. I.e. if you invoke mandatory_memcpy(dst, src, n), and then access 14 // |dst|, the compiler will not issue an access to |src|. The intention is that 15 // this is suitable for copying shared data from an untrusted source. The 16 // untrusted source should not be able to modify |dst| after the 17 // mandatory_memcpy() completes. 18 void* mandatory_memcpy(void* dst, const void* src, size_t n); 19 20 // See memset(). Invocations of this implementation are guaranteed to not be optimized 21 // away. I.e. if you invoke mandatory_memset(dst, c, n), |dst| will be 22 // written to, even if |dst| will not be read from again for the rest of its 23 // lifetime. The intention is that this is suitable for zeroing a buffer 24 // containing sensitive data. 25 void* mandatory_memset(void* dst, int c, size_t n); 26 27 __END_CDECLS 28 29 #ifdef __cplusplus 30 31 #include <fbl/macros.h> 32 #include <type_traits> 33 34 namespace explicit_memory { 35 36 // This class guarantees that the wrapped array will be filled with zeroes when 37 // the wrapping ZeroDtor object goes out of scope. See mandatory_memset() for 38 // discussion on what this guarantee entails. 39 template <typename T, typename = typename std::enable_if<std::is_pod<T>::value>::type> 40 class ZeroDtor { 41 public: ZeroDtor(T * array,size_t len)42 ZeroDtor(T* array, size_t len) : array_(array), len_(len) { } ~ZeroDtor()43 ~ZeroDtor() { 44 mandatory_memset(static_cast<void*>(array_), 0, sizeof(T) * len_); 45 } 46 DISALLOW_COPY_ASSIGN_AND_MOVE(ZeroDtor); 47 private: 48 T* const array_; 49 const size_t len_; 50 }; 51 52 } // namespace explicit_memory 53 54 #endif 55