Skip to content

[C++][Gandiva] Integer overflow in mask output buffer size causes heap overflow #50472

Description

@Arawoof06

Describe the bug, including details regarding any error messages, version, and platform.

mask_utf8_utf8_utf8_utf8 in cpp/src/gandiva/gdv_function_stubs.cc computes the size of its output buffer as:

int32_t max_length =
    std::max(upper_length, std::max(lower_length, num_length)) * data_len;

Both the replacement length and data_len come from the SQL mask(str, upper, lower, num) arguments. The multiplication is done in int32_t, so a large replacement string combined with a large input wraps around and produces a small (or negative) max_length. The arena allocation is then far smaller than the masking loop needs, and the subsequent memcpy of each replacement writes past the buffer.

Example: data_len = 65536 with a 65537-byte replacement gives a true size of 4,295,032,832 which truncates to 65536, so the very first masked character already writes 65537 bytes into a 65536-byte allocation. Running the masking function on such inputs crashes with SIGSEGV (heap buffer overflow).

Sibling functions (repeat_utf8_int32, to_hex_binary, the multibyte translate path) already guard these size multiplications with arrow::internal::MultiplyWithOverflow; mask is missing that guard.

Component(s)

C++, Gandiva

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions