Skip to content

Commit a1df41e

Browse files
JDevliegheregithub-actions[bot]
authored andcommitted
Automerge: [lldb] Fix a use-after-free in SymbolFileCTF (#151586)
This fixes a use-after-free in SymbolFileCTF. Previously, we would remove the underlying CTF type as soon as we resolved it. However, it's possible that we're still holding onto the CTF type while we're parsing a dependent type, like a modifier, resulting in a use-after-free. This patch addresses the issue by delaying the removal of the CTF type until the type is fully resolved. I have a XNU kernel binary that reproduces the issue and confirmed that this solves the memory issue using ASan. However I haven't been able to craft types by hand that reproduce this issue for a test case. rdar://156660866
2 parents 4ed4cfa + e1d45b1 commit a1df41e

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

lldb/source/Plugins/SymbolFile/CTF/SymbolFileCTF.cpp

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -738,9 +738,29 @@ size_t SymbolFileCTF::ParseTypes(CompileUnit &cu) {
738738

739739
LLDB_LOG(log, "Parsed {0} CTF types", m_ctf_types.size());
740740

741-
for (lldb::user_id_t uid = 1; uid < type_uid; ++uid)
741+
for (lldb::user_id_t uid = 1; uid < type_uid; ++uid) {
742742
ResolveTypeUID(uid);
743743

744+
// Remove the CTF type because we don't need it anymore, except for record
745+
// types which we may need to complete later.
746+
auto ctf_type_it = m_ctf_types.find(uid);
747+
if (ctf_type_it != m_ctf_types.end()) {
748+
CTFType *ctf_type = ctf_type_it->second.get();
749+
if (!llvm::isa<CTFRecord>(ctf_type))
750+
m_ctf_types.erase(uid);
751+
}
752+
}
753+
754+
#ifndef NDEBUG
755+
// Verify that the only CTF types left at this point are record types.
756+
for (auto &t : m_ctf_types) {
757+
CTFType *ctf_type = t.second.get();
758+
assert(ctf_type && "invalid type in m_ctf_types");
759+
assert(llvm::isa<CTFRecord>(ctf_type) && "leaking non record type");
760+
}
761+
762+
#endif
763+
744764
LLDB_LOG(log, "Created {0} CTF types", m_types.size());
745765

746766
return m_types.size();
@@ -994,6 +1014,8 @@ lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) {
9941014

9951015
CTFType *ctf_type = ctf_type_it->second.get();
9961016
assert(ctf_type && "m_ctf_types should only contain valid CTF types");
1017+
assert(ctf_type->uid == type_uid &&
1018+
"CTF type UID doesn't match UID in m_ctf_types");
9971019

9981020
Log *log = GetLog(LLDBLog::Symbols);
9991021

@@ -1015,11 +1037,6 @@ lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) {
10151037

10161038
m_types[type_uid] = type_sp;
10171039

1018-
// Except for record types which we'll need to complete later, we don't need
1019-
// the CTF type anymore.
1020-
if (!isa<CTFRecord>(ctf_type))
1021-
m_ctf_types.erase(type_uid);
1022-
10231040
return type_sp.get();
10241041
}
10251042

0 commit comments

Comments
 (0)