mirror of
https://github.com/ceph/ceph
synced 2024-12-25 21:03:31 +00:00
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:
parent
27d1e4d41e
commit
adb8478b61
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user