Describe the bug, including details regarding any error messages, version, and platform.
byte_substr_binary_int32_int32 (cpp/src/gandiva/precompiled/string_ops.cc) computes startPos from the offset argument but never checks that it lands inside the input. With a positive offset greater than text_len, startPos = offset - 1 >= text_len, and the length truncation
if (startPos + length > text_len) {
*out_len = text_len - startPos; // negative
}
memcpy(ret, text + startPos, *out_len);
produces a negative *out_len. memcpy reads that as a very large size_t, so it reads past the end of text and writes past the text_len-sized output buffer.
Reproduced with a verbatim copy of the function under AddressSanitizer using byte_substr("TestString", 10, offset=15, length=10):
ERROR: AddressSanitizer: negative-size-param: (size=-4)
#2 byte_substr_binary_int32_int32 string_ops.cc
0x... is located 4 bytes after 10-byte region
SUMMARY: AddressSanitizer: negative-size-param in byte_substr_binary_int32_int32
The offset comes from user SQL, so any byte_substr(col, n, m) with n beyond the row length triggers it.
Component(s)
C++, Gandiva
Describe the bug, including details regarding any error messages, version, and platform.
byte_substr_binary_int32_int32(cpp/src/gandiva/precompiled/string_ops.cc) computesstartPosfrom the offset argument but never checks that it lands inside the input. With a positiveoffsetgreater thantext_len,startPos = offset - 1 >= text_len, and the length truncationproduces a negative
*out_len.memcpyreads that as a very largesize_t, so it reads past the end oftextand writes past thetext_len-sized output buffer.Reproduced with a verbatim copy of the function under AddressSanitizer using
byte_substr("TestString", 10, offset=15, length=10):The offset comes from user SQL, so any
byte_substr(col, n, m)withnbeyond the row length triggers it.Component(s)
C++, Gandiva