diff options
author | Jack Lloyd <[email protected]> | 2015-12-25 18:02:50 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2015-12-25 18:02:50 -0500 |
commit | 8d6fb90007ae67767936780e5e6cdb21ab5c8686 (patch) | |
tree | 9de4fbd27a40fc970a9c272a7bc66f804950edc9 | |
parent | 84eaa5cdd5c966d62475e223d26fce5946d261ef (diff) |
Guard all std::mem* ops against any call with zero length.
Calling memset, memmove, memcpy with an undefined or null pointer,
even with length zero, causes undefined behavior. Prevent that from
happening within the functions that call these dangerous things
since allowing a caller to pass length == 0 with null or just
past the end and not have things explode is nice.
Oh C, you so crazy.
-rw-r--r-- | doc/news.rst | 11 | ||||
-rw-r--r-- | src/lib/utils/loadstor.h | 42 | ||||
-rw-r--r-- | src/lib/utils/mem_ops.h | 15 |
3 files changed, 47 insertions, 21 deletions
diff --git a/doc/news.rst b/doc/news.rst index 39753a752..d3533d170 100644 --- a/doc/news.rst +++ b/doc/news.rst @@ -4,6 +4,11 @@ Release Notes Version 1.11.26, Not Yet Released ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* Deprecation warning: Nyberg-Rueppel signatures, MARS, RC2, RC5, RC6, + SAFER, HAS-160, RIPEMD-128, and MD2 are being considered for removal + in a future release. If there is a compelling use case for keeping + any of them in the library, please open a discussion ticket on GitHub. + * Root all exceptions thrown by the library in the `Botan::Exception` class. Previously the library would in many cases throw `std::runtime_error` or `std::invalid_argument` exceptions which would make it hard to determine @@ -21,6 +26,12 @@ Version 1.11.26, Not Yet Released random number generation, RSA key generation, and signing are supported. Tested using Trousers and an ST TPM +* Avoid calling memcpy, memset, or memmove with a length of zero to + avoid undefined behavior, as calling these functions with an invalid + or null pointer, even with a length of zero, is invalid. Often there + are corner cases where this can occur, such as pointing to the very + end of a buffer. + Version 1.11.25, 2015-12-07 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/lib/utils/loadstor.h b/src/lib/utils/loadstor.h index 53700fc86..8d33c2eef 100644 --- a/src/lib/utils/loadstor.h +++ b/src/lib/utils/loadstor.h @@ -308,24 +308,27 @@ inline void load_le(T out[], const byte in[], size_t count) { + if(count > 0) + { #if defined(BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS) - std::memcpy(out, in, sizeof(T)*count); + std::memcpy(out, in, sizeof(T)*count); #if defined(BOTAN_TARGET_CPU_IS_BIG_ENDIAN) - const size_t blocks = count - (count % 4); - const size_t left = count - blocks; + const size_t blocks = count - (count % 4); + const size_t left = count - blocks; - for(size_t i = 0; i != blocks; i += 4) - bswap_4(out + i); + for(size_t i = 0; i != blocks; i += 4) + bswap_4(out + i); - for(size_t i = 0; i != left; ++i) - out[blocks+i] = reverse_bytes(out[blocks+i]); + for(size_t i = 0; i != left; ++i) + out[blocks+i] = reverse_bytes(out[blocks+i]); #endif #else - for(size_t i = 0; i != count; ++i) - out[i] = load_le<T>(in, i); + for(size_t i = 0; i != count; ++i) + out[i] = load_le<T>(in, i); #endif + } } /** @@ -397,24 +400,27 @@ inline void load_be(T out[], const byte in[], size_t count) { + if(count > 0) + { #if defined(BOTAN_TARGET_CPU_HAS_KNOWN_ENDIANNESS) - std::memcpy(out, in, sizeof(T)*count); + std::memcpy(out, in, sizeof(T)*count); #if defined(BOTAN_TARGET_CPU_IS_LITTLE_ENDIAN) - const size_t blocks = count - (count % 4); - const size_t left = count - blocks; + const size_t blocks = count - (count % 4); + const size_t left = count - blocks; - for(size_t i = 0; i != blocks; i += 4) - bswap_4(out + i); + for(size_t i = 0; i != blocks; i += 4) + bswap_4(out + i); - for(size_t i = 0; i != left; ++i) - out[blocks+i] = reverse_bytes(out[blocks+i]); + for(size_t i = 0; i != left; ++i) + out[blocks+i] = reverse_bytes(out[blocks+i]); #endif #else - for(size_t i = 0; i != count; ++i) - out[i] = load_be<T>(in, i); + for(size_t i = 0; i != count; ++i) + out[i] = load_be<T>(in, i); #endif + } } /** diff --git a/src/lib/utils/mem_ops.h b/src/lib/utils/mem_ops.h index 6ea7bdafe..d11e3368c 100644 --- a/src/lib/utils/mem_ops.h +++ b/src/lib/utils/mem_ops.h @@ -28,7 +28,10 @@ BOTAN_DLL void zero_mem(void* ptr, size_t n); */ template<typename T> inline void clear_mem(T* ptr, size_t n) { - std::memset(ptr, 0, sizeof(T)*n); + if(n > 0) + { + std::memset(ptr, 0, sizeof(T)*n); + } } /** @@ -39,7 +42,10 @@ template<typename T> inline void clear_mem(T* ptr, size_t n) */ template<typename T> inline void copy_mem(T* out, const T* in, size_t n) { - std::memmove(out, in, sizeof(T)*n); + if(n > 0) + { + std::memmove(out, in, sizeof(T)*n); + } } /** @@ -51,7 +57,10 @@ template<typename T> inline void copy_mem(T* out, const T* in, size_t n) template<typename T> inline void set_mem(T* ptr, size_t n, byte val) { - std::memset(ptr, val, sizeof(T)*n); + if(n > 0) + { + std::memset(ptr, val, sizeof(T)*n); + } } /** |