From e1655a3ddca303a10d1fc9453c321f3cb84f2d2d Mon Sep 17 00:00:00 2001 From: Prathamesh Hukkeri Date: Tue, 11 Aug 2026 10:44:31 +0530 Subject: [PATCH] MDEV-40454 UBSAN: shift exponent 64 is too large in aria_pack flush_bits() shifts a 64-bit value by BITS_SAVED (=64) when no whole bytes are pending (file_buffer.bits is a multiple of 8), which is undefined behavior. On x86 the shift count is masked, silently writing garbage bits into the compressed output; on other platforms and under UBSAN with halt_on_error it aborts aria_pack. Return early from flush_bits() when there is nothing to flush. The existing test maria.aria_pack_mdev14183 reproduces the problem under a UBSAN build (runtime error: shift exponent 64 is too large for 64-bit type 'ulonglong'). --- storage/maria/aria_pack.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/storage/maria/aria_pack.c b/storage/maria/aria_pack.c index 62926ec64ef16..aa39b17bc5d39 100644 --- a/storage/maria/aria_pack.c +++ b/storage/maria/aria_pack.c @@ -3032,16 +3032,19 @@ static void flush_bits(void) ulonglong bit_buffer; bits= file_buffer.bits & ~7; - bit_buffer= file_buffer.bitbucket >> bits; - bits= BITS_SAVED - bits; - while (bits > 0) + if (bits != BITS_SAVED) { - bits-= 8; - *file_buffer.pos++= (uchar) (bit_buffer >> bits); + bit_buffer= file_buffer.bitbucket >> bits; + bits= BITS_SAVED - bits; + while (bits > 0) + { + bits-= 8; + *file_buffer.pos++= (uchar) (bit_buffer >> bits); + } + if (file_buffer.pos >= file_buffer.end) + flush_buffer(~ (ulong) 0); + file_buffer.bits= BITS_SAVED; } - if (file_buffer.pos >= file_buffer.end) - flush_buffer(~ (ulong) 0); - file_buffer.bits= BITS_SAVED; file_buffer.bitbucket= 0; }