Skip to content

Commit ee50633

Browse files
committed
Fix leaking BNDataVariableAndName when calling BNGetDebugDataVariableBy functions
1 parent 1014cb1 commit ee50633

File tree

5 files changed

+49
-60
lines changed

5 files changed

+49
-60
lines changed

binaryninjacore.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@
3737
// Current ABI version for linking to the core. This is incremented any time
3838
// there are changes to the API that affect linking, including new functions,
3939
// new types, or modifications to existing functions or types.
40-
#define BN_CURRENT_CORE_ABI_VERSION 93
40+
#define BN_CURRENT_CORE_ABI_VERSION 94
4141

4242
// Minimum ABI version that is supported for loading of plugins. Plugins that
4343
// are linked to an ABI version less than this will not be able to load and
4444
// will require rebuilding. The minimum version is increased when there are
4545
// incompatible changes that break binary compatibility, such as changes to
4646
// existing types or functions.
47-
#define BN_MINIMUM_CORE_ABI_VERSION 92
47+
#define BN_MINIMUM_CORE_ABI_VERSION 94
4848

4949
#ifdef __GNUC__
5050
#ifdef BINARYNINJACORE_LIBRARY
@@ -7555,10 +7555,10 @@ extern "C"
75557555
BNDebugInfo* const debugInfo, const BNDataVariableAndName* var);
75567556
BINARYNINJACOREAPI BNDataVariableAndName* BNGetDebugDataVariables(
75577557
BNDebugInfo* const debugInfo, const char* const name, size_t* count);
7558-
BINARYNINJACOREAPI BNDataVariableAndName* BNGetDebugDataVariableByName(
7559-
BNDebugInfo* const debugInfo, const char* const parserName, const char* const variableName);
7560-
BINARYNINJACOREAPI BNDataVariableAndName* BNGetDebugDataVariableByAddress(
7561-
BNDebugInfo* const debugInfo, const char* const parserName, const uint64_t address);
7558+
BINARYNINJACOREAPI bool BNGetDebugDataVariableByName(
7559+
BNDebugInfo* const debugInfo, const char* const parserName, const char* const variableName, BNDataVariableAndName* var);
7560+
BINARYNINJACOREAPI bool BNGetDebugDataVariableByAddress(
7561+
BNDebugInfo* const debugInfo, const char* const parserName, const uint64_t address, BNDataVariableAndName* var);
75627562
BINARYNINJACOREAPI BNDataVariableAndName* BNGetDebugDataVariablesByName(
75637563
BNDebugInfo* const debugInfo, const char* const variableName, size_t* count);
75647564
BINARYNINJACOREAPI BNDataVariableAndNameAndDebugParser* BNGetDebugDataVariablesByAddress(

debuginfo.cpp

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -158,27 +158,25 @@ Ref<Type> DebugInfo::GetTypeByName(const string& parserName, const string& name)
158158
optional<tuple<uint64_t, Ref<Type>>> DebugInfo::GetDataVariableByName(
159159
const string& parserName, const string& name) const
160160
{
161-
BNDataVariableAndName* result = BNGetDebugDataVariableByName(m_object, parserName.c_str(), name.c_str());
162-
if (result)
163-
{
164-
BNFreeString(result->name);
165-
return {{result->address, Ref<Type>(new Type(result->type))}};
166-
}
167-
return {};
161+
BNDataVariableAndName result;
162+
if (!BNGetDebugDataVariableByName(m_object, parserName.c_str(), name.c_str(), &result))
163+
return std::nullopt;
164+
Ref<Type> type = new Type(BNNewTypeReference(result.type));
165+
BNFreeDataVariableAndName(&result);
166+
return {{result.address, type}};
168167
}
169168

170169

171170
optional<tuple<string, Ref<Type>>> DebugInfo::GetDataVariableByAddress(
172171
const string& parserName, const uint64_t address) const
173172
{
174-
BNDataVariableAndName* nameAndVar = BNGetDebugDataVariableByAddress(m_object, parserName.c_str(), address);
175-
if (nameAndVar)
176-
{
177-
const tuple<string, Ref<Type>> result = {nameAndVar->name, Ref<Type>(new Type(nameAndVar->type))};
178-
BNFreeString(nameAndVar->name);
179-
return {result};
180-
}
181-
return {};
173+
BNDataVariableAndName result;
174+
if (!BNGetDebugDataVariableByAddress(m_object, parserName.c_str(), address, &result))
175+
return std::nullopt;
176+
string name = result.name;
177+
Ref<Type> type = new Type(BNNewTypeReference(result.type));
178+
BNFreeDataVariableAndName(&result);
179+
return {{name, type}};
182180
}
183181

184182

python/debuginfo.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -399,19 +399,20 @@ def get_type_by_name(self, parser_name: str, name: str) -> Optional[_types.Type]
399399
return None
400400

401401
def get_data_variable_by_name(self, parser_name: str, name: str) -> Optional[Tuple[int, _types.Type]]:
402-
result = core.BNGetDebugDataVariableByName(self.handle, parser_name, name)
403-
if result is not None:
404-
core.BNFreeString(result.name)
405-
return (result.address, _types.Type.create(result.type))
406-
return None
402+
name_and_var = core.BNDataVariableAndName()
403+
if not core.BNGetDebugDataVariableByName(self.handle, parser_name, name, name_and_var):
404+
return None
405+
result = (name_and_var.address, _types.Type.create(core.BNNewTypeReference(name_and_var.type)))
406+
core.BNFreeDataVariableAndName(name_and_var)
407+
return result
407408

408409
def get_data_variable_by_address(self, parser_name: str, address: int) -> Optional[Tuple[str, _types.Type]]:
409-
name_and_var = core.BNGetDebugDataVariableByAddress(self.handle, parser_name, address)
410-
if name_and_var is not None:
411-
result = (str(name_and_var.name), _types.Type.create(name_and_var.type))
412-
core.BNFreeString(name_and_var.name)
413-
return result
414-
return None
410+
name_and_var = core.BNDataVariableAndName()
411+
if not core.BNGetDebugDataVariableByAddress(self.handle, parser_name, address, name_and_var):
412+
return None
413+
result = (str(name_and_var.name), _types.Type.create(core.BNNewTypeReference(name_and_var.type)))
414+
core.BNFreeDataVariableAndName(name_and_var)
415+
return result
415416

416417
def get_types_by_name(self, name: str) -> List[Tuple[str, _types.Type]]:
417418
""" The first element in the Tuple returned in the list is the name of the debug info parser the type came from """

rust/src/debuginfo.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -562,18 +562,18 @@ impl DebugInfo {
562562
) -> Option<NamedDataVariableWithType> {
563563
let parser_name = parser_name.into_bytes_with_nul();
564564
let name = name.into_bytes_with_nul();
565-
let raw_named_var = unsafe {
566-
BNGetDebugDataVariableByName(
565+
let mut dv = BNDataVariableAndName::default();
566+
unsafe {
567+
if BNGetDebugDataVariableByName(
567568
self.handle,
568569
parser_name.as_ref().as_ptr() as *mut _,
569570
name.as_ref().as_ptr() as *mut _,
570-
)
571-
};
572-
573-
if !raw_named_var.is_null() {
574-
Some(unsafe { NamedDataVariableWithType::from_ref_raw(raw_named_var) })
575-
} else {
576-
None
571+
&mut dv,
572+
) {
573+
Some(NamedDataVariableWithType::from_owned_raw(dv))
574+
} else {
575+
None
576+
}
577577
}
578578
}
579579

@@ -583,18 +583,18 @@ impl DebugInfo {
583583
address: u64,
584584
) -> Option<NamedDataVariableWithType> {
585585
let parser_name = parser_name.into_bytes_with_nul();
586-
let raw_named_var = unsafe {
587-
BNGetDebugDataVariableByAddress(
586+
let mut dv = BNDataVariableAndName::default();
587+
unsafe {
588+
if BNGetDebugDataVariableByAddress(
588589
self.handle,
589590
parser_name.as_ref().as_ptr() as *mut _,
590591
address,
591-
)
592-
};
593-
594-
if !raw_named_var.is_null() {
595-
Some(unsafe { NamedDataVariableWithType::from_ref_raw(raw_named_var) })
596-
} else {
597-
None
592+
&mut dv,
593+
) {
594+
Some(NamedDataVariableWithType::from_owned_raw(dv))
595+
} else {
596+
None
597+
}
598598
}
599599
}
600600

rust/src/variable.rs

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,6 @@ impl NamedDataVariableWithType {
119119
owned
120120
}
121121

122-
pub(crate) unsafe fn from_ref_raw(value: *mut BNDataVariableAndName) -> Self {
123-
let owned = Self::from_raw(&*value);
124-
Self::free_ref_raw(value);
125-
owned
126-
}
127-
128122
pub(crate) fn into_raw(value: Self) -> BNDataVariableAndName {
129123
let bn_name = BnString::new(value.name);
130124
BNDataVariableAndName {
@@ -136,10 +130,6 @@ impl NamedDataVariableWithType {
136130
}
137131
}
138132

139-
pub(crate) fn free_ref_raw(value: *mut BNDataVariableAndName) {
140-
unsafe { BNFreeDataVariableAndName(value) }
141-
}
142-
143133
pub(crate) fn free_raw(value: BNDataVariableAndName) {
144134
let _ = unsafe { Type::ref_from_raw(value.type_) };
145135
let _ = unsafe { BnString::from_raw(value.name) };

0 commit comments

Comments
 (0)