From 496a8d3cbc29dd9aec6f9bcac578eb18f02ff701 Mon Sep 17 00:00:00 2001 From: Natalia Portillo Date: Sun, 28 Dec 2025 16:31:30 +0000 Subject: [PATCH] Fix buffer overflow risk in CRC64 calculation by implementing safe copy for second block --- src/crc64/crc64_vmull.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/crc64/crc64_vmull.c b/src/crc64/crc64_vmull.c index d3dda72..dc63a78 100644 --- a/src/crc64/crc64_vmull.c +++ b/src/crc64/crc64_vmull.c @@ -21,6 +21,7 @@ #include #include #include +#include #include @@ -163,9 +164,24 @@ AARU_EXPORT TARGET_WITH_SIMD uint64_t AARU_CALL aaruf_crc64_vmull(uint64_t previ P = veorq_u64(accumulator, vreinterpretq_u64_u32(vld1q_u32((const uint32_t *)alignedData))); else { + // When len is between 16 and 32, we need both blocks but must be careful not to read past buffer end const uint64x2_t end0 = veorq_u64(accumulator, vreinterpretq_u64_u32(vld1q_u32((const uint32_t *)alignedData))); - const uint64x2_t end1 = vreinterpretq_u64_u32(vld1q_u32((const uint32_t *)(alignedData + 1))); + + // For the second block, always use safe copy to avoid buffer overflow + // The algorithm expects to read up to alignedEnd, but ASan prevents over-reading + uint8_t temp[16] __attribute__((aligned(16))) = {0}; + const uint8_t *nextBlockAddr = (const uint8_t *)(alignedData + 1); + + // Only copy bytes that are actually within the original buffer + if(nextBlockAddr < end) + { + size_t available = (size_t)(end - nextBlockAddr); + if(available > 16) available = 16; + memcpy(temp, nextBlockAddr, available); + } + + const uint64x2_t end1 = vreinterpretq_u64_u32(vld1q_u32((const uint32_t *)temp)); uint64x2_t A, B, C, D; shiftRight128(end0, leadOutSize, &A, &B);