include/inline_memory: out-of-bounds read on unaligned memory

When checking if a >=16 byte unaligned buffer is zeroed, the 32bit
check will read outside the buffer memory range.

Fixes: #13082
Signed-off-by: Jason Dillaman <dillaman@redhat.com>
This commit is contained in:
Jason Dillaman 2015-09-14 11:23:31 -04:00
parent 27d1e4d41e
commit adb8478b61

View File

@ -77,13 +77,9 @@ static inline bool mem_is_zero(const char *data, size_t len)
bool mem_is_zero(const char *data, size_t len)
{
const char *max = data + len;
const char* max32 = data + (len / sizeof(uint32_t))*sizeof(uint32_t);
#if defined(__GNUC__) && defined(__x86_64__)
// we do have XMM registers in x86-64, so if we need to check at least
// 16 bytes, make use of them
int left = len;
if (left / sizeof(uint128_t) > 0) {
// 16 bytes, make use of them
if (len / sizeof(uint128_t) > 0) {
// align data pointer to 16 bytes, otherwise it'll segfault due to bug
// in (at least some) GCC versions (using MOVAPS instead of MOVUPS).
// check up to 15 first bytes while at it.
@ -92,10 +88,11 @@ bool mem_is_zero(const char *data, size_t len)
return false;
}
data += sizeof(uint8_t);
left--;
--len;
}
const char* max128 = data + (left / sizeof(uint128_t))*sizeof(uint128_t);
const char* data_start = data;
const char* max128 = data + (len / sizeof(uint128_t))*sizeof(uint128_t);
while (data < max128) {
if (*(uint128_t*)data != 0) {
@ -103,8 +100,11 @@ bool mem_is_zero(const char *data, size_t len)
}
data += sizeof(uint128_t);
}
len -= (data - data_start);
}
#endif
const char* max = data + len;
const char* max32 = data + (len / sizeof(uint32_t))*sizeof(uint32_t);
while (data < max32) {
if (*(uint32_t*)data != 0) {
return false;