The gdv_fn_upper_utf8, gdv_fn_lower_utf8 and gdv_fn_initcap_utf8 stubs in cpp/src/gandiva/gdv_string_function_stubs.cc decode a multibyte glyph with arrow::util::UTF8Decode without first checking that the whole glyph fits inside data_len. When the input ends in a truncated multibyte sequence (for example a final 0xC3 or 0xE0 lead byte), UTF8Decode walks continuation bytes past data[data_len].
The functions back the SQL upper(), lower() and initcap() scalar functions, so the input comes straight from a string array value buffer. When the value buffer is packed and exactly sized (no trailing NUL), the read lands past the allocation.
ASAN on an exact-sized buffer:
heap-buffer-overflow READ of size 1 ... 0 bytes after 4-byte region
in arrow::util::UTF8Decode (utf8_internal.h:353)
in gdv_fn_upper_utf8 (gdv_string_function_stubs.cc:361)
Component(s)
C++, Gandiva
The
gdv_fn_upper_utf8,gdv_fn_lower_utf8andgdv_fn_initcap_utf8stubs incpp/src/gandiva/gdv_string_function_stubs.ccdecode a multibyte glyph witharrow::util::UTF8Decodewithout first checking that the whole glyph fits insidedata_len. When the input ends in a truncated multibyte sequence (for example a final0xC3or0xE0lead byte),UTF8Decodewalks continuation bytes pastdata[data_len].The functions back the SQL
upper(),lower()andinitcap()scalar functions, so the input comes straight from a string array value buffer. When the value buffer is packed and exactly sized (no trailing NUL), the read lands past the allocation.ASAN on an exact-sized buffer:
Component(s)
C++, Gandiva