aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2015-12-25 18:02:50 -0500
committerJack Lloyd <[email protected]>2015-12-25 18:02:50 -0500
commit8d6fb90007ae67767936780e5e6cdb21ab5c8686 (patch)
tree9de4fbd27a40fc970a9c272a7bc66f804950edc9 /src
parent84eaa5cdd5c966d62475e223d26fce5946d261ef (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.
Diffstat (limited to 'src')
-rw-r--r--src/lib/utils/loadstor.h42
-rw-r--r--src/lib/utils/mem_ops.h15
2 files changed, 36 insertions, 21 deletions
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);
+ }
}
/**