From e1ced6fbe18191dc2ac70ec1e9e3387a09140dac Mon Sep 17 00:00:00 2001 From: prabhukr Date: Fri, 7 Nov 2025 13:46:44 -0800 Subject: [PATCH 1/6] [lld][macho] Fix segfault while processing malformed object file. --- lld/MachO/InputFiles.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index 20e4a1d755229..add59272d9f67 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -808,6 +808,11 @@ void ObjFile::parseSymbols(ArrayRef sectionHeaders, continue; if ((sym.n_type & N_TYPE) == N_SECT) { + if (sym.n_sect == 0) { + error("Section symbol " + StringRef(strtab + sym.n_strx) + " in " + + toString(this) + " has an invalid section index of 0"); + llvm_unreachable("Section symbol without an associated section."); + } Subsections &subsections = sections[sym.n_sect - 1]->subsections; // parseSections() may have chosen not to parse this section. if (subsections.empty()) From 5e2c87b42bc5b0d0eefb1ac5a1476ff80aef59e8 Mon Sep 17 00:00:00 2001 From: Prabhu Rajasekaran Date: Mon, 10 Nov 2025 08:28:19 -0800 Subject: [PATCH 2/6] Emit fatal error instead of using error llvm_unreachable. Co-authored-by: Ellis Hoag --- lld/MachO/InputFiles.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index add59272d9f67..a3e5f72724009 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -809,9 +809,8 @@ void ObjFile::parseSymbols(ArrayRef sectionHeaders, if ((sym.n_type & N_TYPE) == N_SECT) { if (sym.n_sect == 0) { - error("Section symbol " + StringRef(strtab + sym.n_strx) + " in " + + fatal("Section symbol " + StringRef(strtab + sym.n_strx) + " in " + toString(this) + " has an invalid section index of 0"); - llvm_unreachable("Section symbol without an associated section."); } Subsections &subsections = sections[sym.n_sect - 1]->subsections; // parseSections() may have chosen not to parse this section. From d077666c30bb98398c2a63c0f6eb1bfbc3c43195 Mon Sep 17 00:00:00 2001 From: prabhukr Date: Mon, 10 Nov 2025 15:43:13 -0800 Subject: [PATCH 3/6] Add regression test. --- .../handle-invalid-section-reference.test | 128 ++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 lld/test/MachO/handle-invalid-section-reference.test diff --git a/lld/test/MachO/handle-invalid-section-reference.test b/lld/test/MachO/handle-invalid-section-reference.test new file mode 100644 index 0000000000000..e0dabbf6c1711 --- /dev/null +++ b/lld/test/MachO/handle-invalid-section-reference.test @@ -0,0 +1,128 @@ +# REQUIRES: aarch64 + +## This is a regression test which makes sure that when there is an invalid section index +## associated with a section symbol, the linker does not segfault. + +## Test YAML content was created using the following steps +## 1. Create an object file from the following assembly +## `llvm-mc -filetype=obj -triple=arm64-apple-darwin symbol.s -o symbol.o` +## +## .text +## .section __TEST,__mystuff +## .globl _mysec +## _mysec: +## .byte 0xC3 +## +## 2. Use obj2yaml to convert object file to yaml +## `obj2yaml symbol.o -o symbol.yaml` +## +## 3. Manually set n_sect value of ltmp1 symbol to 0 instead of 1. +## + +# RUN: yaml2obj %s -o %t +# RUN: not %lld -platform_version macos 10.14 11.0 -arch arm64 %t 2>&1 | FileCheck %s --check-prefix=FATAL + +# FATAL: error: Section symbol ltmp0 in {{.*}} has an invalid section index [0] + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x0 + filetype: 0x1 + ncmds: 3 + sizeofcmds: 336 + flags: 0x0 + reserved: 0x0 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: '' + vmaddr: 0 + vmsize: 1 + fileoff: 368 + filesize: 1 + maxprot: 7 + initprot: 7 + nsects: 2 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0 + size: 0 + offset: 0x170 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x80000000 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: '' + - sectname: __mystuff + segname: __TEST + addr: 0x0 + size: 1 + offset: 0x170 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: C3 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 376 + nsyms: 3 + stroff: 424 + strsize: 24 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 2 + iextdefsym: 2 + nextdefsym: 1 + iundefsym: 3 + nundefsym: 0 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 0 + nindirectsyms: 0 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 +LinkEditData: + NameList: + - n_strx: 14 + n_type: 0xE + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 8 + n_type: 0xE + n_sect: 2 + n_desc: 0 + n_value: 0 + - n_strx: 1 + n_type: 0xF + n_sect: 2 + n_desc: 0 + n_value: 0 + StringTable: + - '' + - _mysec + - ltmp1 + - ltmp0 + - '' + - '' + - '' + - '' +... From 309e01cb5daf40c875d7ba6851235b6567a20082 Mon Sep 17 00:00:00 2001 From: prabhukr Date: Mon, 10 Nov 2025 15:44:44 -0800 Subject: [PATCH 4/6] Nit: Improve error message. --- lld/MachO/InputFiles.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index a3e5f72724009..b32f780af6972 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -810,7 +810,7 @@ void ObjFile::parseSymbols(ArrayRef sectionHeaders, if ((sym.n_type & N_TYPE) == N_SECT) { if (sym.n_sect == 0) { fatal("Section symbol " + StringRef(strtab + sym.n_strx) + " in " + - toString(this) + " has an invalid section index of 0"); + toString(this) + " has an invalid section index [0]"); } Subsections &subsections = sections[sym.n_sect - 1]->subsections; // parseSections() may have chosen not to parse this section. From a9e11491a8e96e2efc2b14ec858089278ad59ed1 Mon Sep 17 00:00:00 2001 From: prabhukr Date: Mon, 10 Nov 2025 16:09:36 -0800 Subject: [PATCH 5/6] Test for section index larger than section size. --- lld/MachO/InputFiles.cpp | 7 + ...dle-invalid-section-reference-too-big.test | 128 ++++++++++++++++++ ...andle-invalid-section-reference-zero.test} | 0 3 files changed, 135 insertions(+) create mode 100644 lld/test/MachO/handle-invalid-section-reference-too-big.test rename lld/test/MachO/{handle-invalid-section-reference.test => handle-invalid-section-reference-zero.test} (100%) diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index b32f780af6972..f5f3af038badd 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -812,6 +812,13 @@ void ObjFile::parseSymbols(ArrayRef sectionHeaders, fatal("Section symbol " + StringRef(strtab + sym.n_strx) + " in " + toString(this) + " has an invalid section index [0]"); } + if (sym.n_sect > sections.size()) { + fatal("Section symbol " + StringRef(strtab + sym.n_strx) + " in " + + toString(this) + " has an invalid section index [" + + Twine(static_cast(sym.n_sect)) + + "] greater than the total number of sections [" + + Twine(sections.size()) + "]."); + } Subsections &subsections = sections[sym.n_sect - 1]->subsections; // parseSections() may have chosen not to parse this section. if (subsections.empty()) diff --git a/lld/test/MachO/handle-invalid-section-reference-too-big.test b/lld/test/MachO/handle-invalid-section-reference-too-big.test new file mode 100644 index 0000000000000..da7b93a7753f2 --- /dev/null +++ b/lld/test/MachO/handle-invalid-section-reference-too-big.test @@ -0,0 +1,128 @@ +# REQUIRES: aarch64 + +## This is a regression test which makes sure that when there is an invalid section index +## associated with a section symbol, the linker does not segfault. + +## Test YAML content was created using the following steps +## 1. Create an object file from the following assembly +## `llvm-mc -filetype=obj -triple=arm64-apple-darwin symbol.s -o symbol.o` +## +## .text +## .section __TEST,__mystuff +## .globl _mysec +## _mysec: +## .byte 0xC3 +## +## 2. Use obj2yaml to convert object file to yaml +## `obj2yaml symbol.o -o symbol.yaml` +## +## 3. Manually set n_sect value of ltmp1 symbol to 10 which is greater than the number of sections 2. +## + +# RUN: yaml2obj %s -o %t +# RUN: not %lld -platform_version macos 10.14 11.0 -arch arm64 %t 2>&1 | FileCheck %s --check-prefix=FATAL + +# FATAL: error: Section symbol ltmp0 in {{.*}} has an invalid section index [10] greater than the total number of sections [2]. + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x0 + filetype: 0x1 + ncmds: 3 + sizeofcmds: 336 + flags: 0x0 + reserved: 0x0 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: '' + vmaddr: 0 + vmsize: 1 + fileoff: 368 + filesize: 1 + maxprot: 7 + initprot: 7 + nsects: 2 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0 + size: 0 + offset: 0x170 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x80000000 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: '' + - sectname: __mystuff + segname: __TEST + addr: 0x0 + size: 1 + offset: 0x170 + align: 0 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: C3 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 376 + nsyms: 3 + stroff: 424 + strsize: 24 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 2 + iextdefsym: 2 + nextdefsym: 1 + iundefsym: 3 + nundefsym: 0 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 0 + nindirectsyms: 0 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 +LinkEditData: + NameList: + - n_strx: 14 + n_type: 0xE + n_sect: 10 + n_desc: 0 + n_value: 0 + - n_strx: 8 + n_type: 0xE + n_sect: 2 + n_desc: 0 + n_value: 0 + - n_strx: 1 + n_type: 0xF + n_sect: 2 + n_desc: 0 + n_value: 0 + StringTable: + - '' + - _mysec + - ltmp1 + - ltmp0 + - '' + - '' + - '' + - '' +... diff --git a/lld/test/MachO/handle-invalid-section-reference.test b/lld/test/MachO/handle-invalid-section-reference-zero.test similarity index 100% rename from lld/test/MachO/handle-invalid-section-reference.test rename to lld/test/MachO/handle-invalid-section-reference-zero.test From 6ec35a9bd309e6a9d0b329c3e2fb481584cf9a5d Mon Sep 17 00:00:00 2001 From: prabhukr Date: Tue, 11 Nov 2025 11:59:19 -0800 Subject: [PATCH 6/6] Fix the error messages as suggested. --- lld/MachO/InputFiles.cpp | 6 +++--- .../MachO/handle-invalid-section-reference-too-big.test | 2 +- lld/test/MachO/handle-invalid-section-reference-zero.test | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp index f5f3af038badd..d0128d03a9eab 100644 --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -809,15 +809,15 @@ void ObjFile::parseSymbols(ArrayRef sectionHeaders, if ((sym.n_type & N_TYPE) == N_SECT) { if (sym.n_sect == 0) { - fatal("Section symbol " + StringRef(strtab + sym.n_strx) + " in " + + fatal("section symbol " + StringRef(strtab + sym.n_strx) + " in " + toString(this) + " has an invalid section index [0]"); } if (sym.n_sect > sections.size()) { - fatal("Section symbol " + StringRef(strtab + sym.n_strx) + " in " + + fatal("section symbol " + StringRef(strtab + sym.n_strx) + " in " + toString(this) + " has an invalid section index [" + Twine(static_cast(sym.n_sect)) + "] greater than the total number of sections [" + - Twine(sections.size()) + "]."); + Twine(sections.size()) + "]"); } Subsections &subsections = sections[sym.n_sect - 1]->subsections; // parseSections() may have chosen not to parse this section. diff --git a/lld/test/MachO/handle-invalid-section-reference-too-big.test b/lld/test/MachO/handle-invalid-section-reference-too-big.test index da7b93a7753f2..1642d63e50af4 100644 --- a/lld/test/MachO/handle-invalid-section-reference-too-big.test +++ b/lld/test/MachO/handle-invalid-section-reference-too-big.test @@ -22,7 +22,7 @@ # RUN: yaml2obj %s -o %t # RUN: not %lld -platform_version macos 10.14 11.0 -arch arm64 %t 2>&1 | FileCheck %s --check-prefix=FATAL -# FATAL: error: Section symbol ltmp0 in {{.*}} has an invalid section index [10] greater than the total number of sections [2]. +# FATAL: error: section symbol ltmp0 in {{.*}} has an invalid section index [10] greater than the total number of sections [2] --- !mach-o FileHeader: diff --git a/lld/test/MachO/handle-invalid-section-reference-zero.test b/lld/test/MachO/handle-invalid-section-reference-zero.test index e0dabbf6c1711..ab636705198e5 100644 --- a/lld/test/MachO/handle-invalid-section-reference-zero.test +++ b/lld/test/MachO/handle-invalid-section-reference-zero.test @@ -22,7 +22,7 @@ # RUN: yaml2obj %s -o %t # RUN: not %lld -platform_version macos 10.14 11.0 -arch arm64 %t 2>&1 | FileCheck %s --check-prefix=FATAL -# FATAL: error: Section symbol ltmp0 in {{.*}} has an invalid section index [0] +# FATAL: error: section symbol ltmp0 in {{.*}} has an invalid section index [0] --- !mach-o FileHeader: