From: Jason Dillaman Date: Mon, 14 Sep 2015 15:23:31 +0000 (-0400) Subject: include/inline_memory: out-of-bounds read on unaligned memory X-Git-Tag: v9.1.0~123^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F5926%2Fhead;p=ceph.git 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 --- diff --git a/src/include/inline_memory.h b/src/include/inline_memory.h index 33c6bc0ea0dc..f2166826b76d 100644 --- a/src/include/inline_memory.h +++ b/src/include/inline_memory.h @@ -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;