Skip to content

[C++][Gandiva] Out-of-bounds read in round(int, precision) for the most negative precision #50544

Description

@Arawoof06

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

round_int32_int32 and round_int64_int32 in cpp/src/gandiva/precompiled/extended_math_ops.cc negate the caller-supplied precision into abs_precision and only then apply the range check (abs_precision > 9 and abs_precision > 18 respectively).

For precision == INT32_MIN the negation leaves the value unchanged and still negative, so both range checks evaluate false. The negative value is then passed to get_power_of_10, which indexes a 19-element static table guarded only by DCHECK_GE/DCHECK_LE. Those compile out in release builds, so the read lands far outside the table.

Reachable from SQL as round(int_col, -2147483648); both overloads are registered in function_registry_arithmetic.cc.

In a debug build the DCHECK fires:

extended_math_ops.cc:372:  Check failed: (exp) >= (0)

In a release build there is no check and the indexed load faults or yields arbitrary memory as the rounding multiplier.

truncate_int64_int32 in the same file already compares the signed scale directly (out_scale < -38) and is not affected.

Component(s)

C++ - Gandiva

Metadata

Metadata

Assignees

Labels

No labels
No labels

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