-
Notifications
You must be signed in to change notification settings - Fork 778
Closed
Labels
bugSomething isn't workingSomething isn't working
Description
Description
A null pointer dereference occurs in ImportBlackboardFromJSON when attempting to use an entry pointer without verifying that the entry was successfully created. This happens because the code assumes createEntry followed by getEntry will always return a valid entry.
BehaviorTree.CPP/src/blackboard.cpp
Lines 280 to 295 in 48f6c5b
| void ImportBlackboardFromJSON(const nlohmann::json& json, Blackboard& blackboard) | |
| { | |
| for(auto it = json.begin(); it != json.end(); ++it) | |
| { | |
| if(auto res = JsonExporter::get().fromJson(it.value())) | |
| { | |
| auto entry = blackboard.getEntry(it.key()); | |
| if(!entry) | |
| { | |
| blackboard.createEntry(it.key(), res->second); | |
| entry = blackboard.getEntry(it.key()); | |
| } | |
| entry->value = res->first; | |
| } | |
| } | |
| } |
Found in commit: 48f6c5b
Bug Class
Memory Safety - Null Pointer Dereference
Root Cause
void ImportBlackboardFromJSON(const nlohmann::json& json, Blackboard& blackboard)
{
for(auto it = json.begin(); it != json.end(); ++it)
{
if(auto res = JsonExporter::get().fromJson(it.value()))
{
auto entry = blackboard.getEntry(it.key());
if(!entry)
{
blackboard.createEntry(it.key(), res->second);
entry = blackboard.getEntry(it.key()); // Could still return nullptr
}
entry->value = res->first; // CRASH: Null pointer dereference
}
}
}The issue occurs because:
- Code checks if initial
getEntryreturnsnullptr - Attempts to create
entryif it doesn't exist - Gets
entryagain but doesn't verify it's valid - Dereferences the
entrypointer without checking
GDB
pwndbg> p entry->value
Cannot access memory at address 0x0
pwndbg> p entry
$1 = std::shared_ptr<BT::Blackboard::Entry> (empty) = {
get() = 0x0
}
pwndbg> p res->first
$2 = {
_any = {
storage = {
dynamic = 0xffffffffe010006e,
stack = {
__data = "n\000\020\340\377\377\377\377\000\000\000\000\000\000\000",
__align = {<No data fields>}
}
},
vtable = 0x555556412f40 <linb::any::vtable_for_type<long>()::table>
},
_original_type = {
_M_target = 0x7ffff7c6e610 <typeinfo for long>
}
}
pwndbg> p json
$1 = (const nlohmann::json_abi_v3_11_3::json &) @0x7ffff550dc20: {
<nlohmann::json_abi_v3_11_3::detail::json_default_base> = {<No data fields>},
members of nlohmann::json_abi_v3_11_3::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::json_abi_v3_11_3::adl_serializer, std::vector<unsigned char, std::allocator<unsigned char> >, void>:
m_data = {
m_type = nlohmann::json_abi_v3_11_3::detail::value_t::object,
m_value = {
object = 0x504000000250,
array = 0x504000000250,
string = 0x504000000250,
binary = 0x504000000250,
boolean = 80,
number_integer = 88235808129616,
number_unsigned = 88235808129616,
number_float = 4.3594281529883041e-310
}
}
}
Stack trace
#0 0x00005555558f5d1e in BT::ImportBlackboardFromJSON (json=..., blackboard=...)
Proposed Fix
void ImportBlackboardFromJSON(const nlohmann::json& json, Blackboard& blackboard)
{
for(auto it = json.begin(); it != json.end(); ++it)
{
if(auto res = JsonExporter::get().fromJson(it.value()))
{
auto entry = blackboard.getEntry(it.key());
if(!entry)
{
blackboard.createEntry(it.key(), res->second);
entry = blackboard.getEntry(it.key());
if(!entry) {
// Either throw or continue to next entry
continue;
}
}
entry->value = res->first;
}
}
}Impact
Impact
- Program crash on malformed input
- Potential security vulnerability if JSON input is untrusted
- Could be used for denial of service attacks
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working