Closed
Description
Description
Undefined behavior in BT::Ast::ExprUnaryArithmetic::evaluate()
when performing bitwise complement operations on floating-point numbers. The function attempts to convert large floating-point values to int64_t
without range checking, leading to illegal instructions (SIGILL) when handling extreme values.
BehaviorTree.CPP/include/behaviortree_cpp/scripting/operators.hpp
Lines 121 to 132 in b4bbef6
Bug Class
Type Conversion Vulnerability - Undefined Behavior
Impact
- Program crashes (SIGILL) during script evaluation
- Affects all bitwise complement operations in scripting expressions
- Can be triggered through normal script execution
- Potential security implications when processing untrusted scripts
Types Affected
Found crashes in the following operations:
- Bitwise complement (
~
) on floating-point numbers - Specifically in the conversion path:
double -> int64_t -> ~int64_t -> double
Root Cause
In operators.hpp:132
:
case complement:
return Any(static_cast<double>(~static_cast<int64_t>(rv))); // UB here
The issue occurs because:
- Large floating-point values are converted to int64_t without range checking
- Values outside
int64_t
range cause undefined behavior during conversion - The subsequent bitwise operation is performed on potentially invalid values
GDB
Right before the call to return Any(static_cast<double>(~static_cast<int64_t>(rv)));
, this is the state that causes the crash:
pwndbg> p rv
$1 = 2.6666666000000001e+24
pwndbg> p op
$2 = BT::Ast::ExprUnaryArithmetic::complement
pwndbg> p e
$3 = {
i = {0, 1127522290},
x = 5805361265115136,
d = 5805361265115136
}
pwndbg> p env
$4 = (BT::Ast::Environment &) @0x7ffff5909040: {
vars = std::shared_ptr<BT::Blackboard> (use count 1, weak count 0) = {
get() = 0x511000000040
},
enums = std::shared_ptr<std::unordered_map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, int> > >> (use count 1, weak count 0) = {
get() = 0x507000000030
}
}
pwndbg>
Stack trace
Program received signal SIGILL, Illegal instruction.
0x0000555555a0f778 in BT::Ast::ExprUnaryArithmetic::evaluate (this=0x5030000001c0, env=...)
at /home/user/BehaviorTree.CPP/include/behaviortree_cpp/scripting/operators.hpp:132
132 return Any(static_cast<double>(~static_cast<int64_t>(rv)));
With rv = 2.6666666000000001e+24
Proposed Fix
case complement:
{
if (rv > static_cast<double>(std::numeric_limits<int64_t>::max()) ||
rv < static_cast<double>(std::numeric_limits<int64_t>::min())) {
throw RuntimeError("Number out of range for bitwise operation");
}
return Any(static_cast<double>(~static_cast<int64_t>(rv)));
}
Additional Notes:
This bug is related to #920.
Metadata
Metadata
Assignees
Labels
No labels