[Lldb-commits] [lldb] 6baa9c9 - [lldb][Mach-O] Fix null __LINKEDIT deref in ParseSymtab for shared cache images (#207448)
via lldb-commits
lldb-commits at lists.llvm.org
Mon Jul 27 08:20:28 PDT 2026
Author: Yao Qi
Date: 2026-07-27T16:20:24+01:00
New Revision: 6baa9c9ac22c60e00471c6412387b5a48aa12e3e
URL: https://github.com/llvm/llvm-project/commit/6baa9c9ac22c60e00471c6412387b5a48aa12e3e
DIFF: https://github.com/llvm/llvm-project/commit/6baa9c9ac22c60e00471c6412387b5a48aa12e3e.diff
LOG: [lldb][Mach-O] Fix null __LINKEDIT deref in ParseSymtab for shared cache images (#207448)
`ObjectFileMachO::ParseSymtab`, when handling a local shared cache image
(`MH_DYLIB_IN_CACHE` set and not read from memory), unconditionally
called
`linkedit_section_sp->GetFileOffset()` to slide the load command
offsets.
If the Mach-O has no `__LINKEDIT` segment, `FindSectionByName` returns a
`null` SectionSP, and this is a member call on a null pointer (caught by
UBSan;
crashes in release builds).
```
* thread #1, queue = 'com.apple.main-thread', stop reason =
EXC_BAD_ACCESS (code=1, address=0x68)
* frame #0: 0x0000000100121ff0 ObjectFileMachOTests`lldb_private::Section::GetFileOffset(this=0x0000000000000000) const at Section.h:181:49 [opt] [inlined]
frame #1: 0x0000000100121ff0 ObjectFileMachOTests`ObjectFileMachO::ParseSymtab(this=0x00000001055616b0, symtab=
0x000000016fdfe988) at ObjectFileMachO.cpp:2353:59 [opt]
```
Guard the shared-cache slide branch with a null check on
`linkedit_section_sp`, matching the existing guard used on the in-memory
path.
Found by lldb-target-fuzzer.
---------
Co-authored-by: Jonas Devlieghere <jonas at devlieghere.com>
Added:
Modified:
lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp
Removed:
################################################################################
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index bfe88256adc67..9eab45f57f422 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -2338,7 +2338,7 @@ void ObjectFileMachO::ParseSymtab(Symtab &symtab) {
}
}
} else {
- if (is_local_shared_cache_image) {
+ if (is_local_shared_cache_image && linkedit_section_sp) {
// The load commands in shared cache images are relative to the
// beginning of the shared cache, not the library image. The
// data we get handed when creating the ObjectFileMachO starts
diff --git a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp
index 147ea55e85efa..b3a238022aa57 100644
--- a/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp
+++ b/lldb/unittests/ObjectFile/MachO/TestObjectFileMachO.cpp
@@ -15,8 +15,12 @@
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
+#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/Symtab.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/lldb-defines.h"
+#include "llvm/Testing/Support/Error.h"
+#include "gmock/gmock.h"
#include "gtest/gtest.h"
#ifdef __APPLE__
@@ -107,3 +111,49 @@ TEST_F(ObjectFileMachOTest, IndirectSymbolsInTheSharedCache) {
OF->ParseSymtab(symtab);
}
#endif
+
+// A Mach-O whose MH_DYLIB_IN_CACHE flag is set but which has no __LINKEDIT
+// segment.
+TEST_F(ObjectFileMachOTest, ParseSymtabSharedCacheMissingLinkedit) {
+ const char *yamldata = R"(
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x01000007
+ cpusubtype: 0x00000003
+ filetype: 0x00000006
+ ncmds: 2
+ sizeofcmds: 96
+ flags: 0x80000000
+ reserved: 0x00000000
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 4096
+ fileoff: 0
+ filesize: 0
+ maxprot: 7
+ initprot: 5
+ nsects: 0
+ flags: 0
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 0
+ nsyms: 0
+ stroff: 0
+ strsize: 0
+...
+)";
+
+ llvm::Expected<TestFile> file = TestFile::fromYaml(yamldata);
+ ASSERT_THAT_EXPECTED(file, llvm::Succeeded());
+ lldb::ModuleSP module = std::make_shared<Module>(file->moduleSpec());
+ ObjectFile *OF = module->GetObjectFile();
+ ASSERT_TRUE(llvm::isa<ObjectFileMachO>(OF));
+
+ // Simply no crashing is the regression check.
+ Symtab symtab(OF);
+ OF->ParseSymtab(symtab);
+}
More information about the lldb-commits
mailing list