[llvm-branch-commits] [llvm] release/23.x: [llvm-objcopy][MachO] Fix use-after-free when stripping (#228607) (PR #228733)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sat Oct 3 09:06:46 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-binary-utilities
Author: llvmbot
<details>
<summary>Changes</summary>
Backport feb8b100771af6b617efd3ef5b6ebcf51d858b9b
Requested by: @<!-- -->mstorsjo
---
Full diff: https://github.com/llvm/llvm-project/pull/228733.diff
4 Files Affected:
- (modified) llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp (+12-3)
- (modified) llvm/lib/ObjCopy/MachO/MachOObject.h (+1-1)
- (added) llvm/test/tools/llvm-objcopy/MachO/discard-all-relocations.test (+186)
- (modified) llvm/test/tools/llvm-objcopy/MachO/indirect-symbol-table-copy.s (+21)
``````````diff
diff --git a/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
index 7f862595449b53..1bca325198e0d8 100644
--- a/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOObjcopy.cpp
@@ -83,11 +83,21 @@ static Error removeSections(const CommonConfig &Config, Object &Obj) {
return Obj.removeSections(RemovePred);
}
-static void markSymbols(const CommonConfig &, Object &Obj) {
+static void markSymbols(const CommonConfig &Config, Object &Obj) {
// Symbols referenced from the indirect symbol table must not be removed.
for (IndirectSymbolEntry &ISE : Obj.IndirectSymTable.Symbols)
if (ISE.Symbol)
(*ISE.Symbol)->Referenced = true;
+
+ // --strip-all removes relocations, so their symbols need not be preserved.
+ if (Config.StripAll)
+ return;
+
+ for (const LoadCommand &LC : Obj.LoadCommands)
+ for (const std::unique_ptr<Section> &Sec : LC.Sections)
+ for (const RelocationInfo &R : Sec->Relocations)
+ if (R.Symbol && *R.Symbol)
+ (*R.Symbol)->Referenced = true;
}
static void updateAndRemoveSymbols(const CommonConfig &Config,
@@ -454,8 +464,7 @@ static Error handleArgs(const CommonConfig &Config,
return createFileError(Config.InputFilename, std::move(E));
// Mark symbols to determine which symbols are still needed.
- if (Config.StripAll)
- markSymbols(Config, Obj);
+ markSymbols(Config, Obj);
updateAndRemoveSymbols(Config, MachOConfig, Obj);
diff --git a/llvm/lib/ObjCopy/MachO/MachOObject.h b/llvm/lib/ObjCopy/MachO/MachOObject.h
index 86c6b120fa6c3e..9895585fcab143 100644
--- a/llvm/lib/ObjCopy/MachO/MachOObject.h
+++ b/llvm/lib/ObjCopy/MachO/MachOObject.h
@@ -172,7 +172,7 @@ struct StringTable {
struct RelocationInfo {
// The referenced symbol entry. Set if !Scattered && Extern.
- std::optional<const SymbolEntry *> Symbol;
+ std::optional<SymbolEntry *> Symbol;
// The referenced section. Set if !Scattered && !Extern.
std::optional<const Section *> Sec;
// True if Info is a scattered_relocation_info.
diff --git a/llvm/test/tools/llvm-objcopy/MachO/discard-all-relocations.test b/llvm/test/tools/llvm-objcopy/MachO/discard-all-relocations.test
new file mode 100644
index 00000000000000..7d947af42c62c2
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/discard-all-relocations.test
@@ -0,0 +1,186 @@
+## Local symbols referenced by relocations must survive --discard-all. Removing
+## an unreferenced symbol must also update the remaining relocation indices.
+# RUN: yaml2obj %s -o %t
+# RUN: llvm-objcopy --discard-all %t %t.copy
+# RUN: llvm-readobj --relocations --expand-relocs --symbols %t.copy | FileCheck %s
+# RUN: llvm-strip -x %t -o %t.strip
+# RUN: cmp %t.copy %t.strip
+
+## --strip-all removes relocations, so their symbols can be removed too.
+# RUN: llvm-objcopy --strip-all %t %t.all
+# RUN: llvm-readobj --relocations --symbols %t.all | FileCheck %s --check-prefix=ALL
+
+## Symbols referenced only by relocations in removed sections can be discarded.
+# RUN: llvm-objcopy -x --remove-section=__TEXT,__text %t %t.remove
+# RUN: llvm-readobj --relocations --symbols %t.remove | FileCheck %s --check-prefix=REMOVE
+
+# CHECK: Relocations [
+# CHECK-NEXT: Section __text {
+# CHECK-NEXT: Relocation {
+# CHECK-NEXT: Offset: 0x10
+# CHECK-NEXT: PCRel: 0
+# CHECK-NEXT: Length: 3
+# CHECK-NEXT: Type: X86_64_RELOC_UNSIGNED (0)
+# CHECK-NEXT: Symbol: _undefined (1)
+# CHECK-NEXT: }
+# CHECK-NEXT: Relocation {
+# CHECK-NEXT: Offset: 0x8
+# CHECK-NEXT: PCRel: 0
+# CHECK-NEXT: Length: 3
+# CHECK-NEXT: Type: X86_64_RELOC_UNSIGNED (0)
+# CHECK-NEXT: Section: __data (2)
+# CHECK-NEXT: }
+# CHECK-NEXT: Relocation {
+# CHECK-NEXT: Offset: 0x0
+# CHECK-NEXT: PCRel: 0
+# CHECK-NEXT: Length: 3
+# CHECK-NEXT: Type: X86_64_RELOC_UNSIGNED (0)
+# CHECK-NEXT: Symbol: _referenced (0)
+# CHECK-NEXT: }
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+# CHECK-NEXT: Symbols [
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: _referenced
+# CHECK-NEXT: Type: Section (0xE)
+# CHECK-NEXT: Section: __data (0x2)
+# CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
+# CHECK-NEXT: Flags [ (0x0)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Value: 0x1C
+# CHECK-NEXT: }
+# CHECK-NEXT: Symbol {
+# CHECK-NEXT: Name: _undefined
+# CHECK-NEXT: Extern
+# CHECK-NEXT: Type: Undef (0x0)
+# CHECK-NEXT: Section: (0x0)
+# CHECK-NEXT: RefType: UndefinedNonLazy (0x0)
+# CHECK-NEXT: Flags [ (0x0)
+# CHECK-NEXT: ]
+# CHECK-NEXT: Value: 0x0
+# CHECK-NEXT: }
+# CHECK-NEXT: ]
+
+# ALL: Relocations [
+# ALL-NEXT: ]
+# ALL-NEXT: Symbols [
+# ALL-NEXT: ]
+
+# REMOVE: Relocations [
+# REMOVE-NEXT: ]
+# REMOVE-NEXT: Symbols [
+# REMOVE-NEXT: Symbol {
+# REMOVE-NEXT: Name: _undefined
+# REMOVE-NEXT: Extern
+# REMOVE-NEXT: Type: Undef (0x0)
+# REMOVE-NEXT: Section: (0x0)
+# REMOVE-NEXT: RefType: UndefinedNonLazy (0x0)
+# REMOVE-NEXT: Flags [ (0x0)
+# REMOVE-NEXT: ]
+# REMOVE-NEXT: Value: 0x0
+# REMOVE-NEXT: }
+# REMOVE-NEXT: ]
+
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x01000007
+ cpusubtype: 3
+ filetype: 1
+ ncmds: 2
+ sizeofcmds: 256
+ flags: 0
+ reserved: 0
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 232
+ segname: ''
+ vmaddr: 0
+ vmsize: 32
+ fileoff: 288
+ filesize: 32
+ maxprot: 7
+ initprot: 7
+ nsects: 2
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0
+ size: 24
+ offset: 288
+ align: 3
+ reloff: 320
+ nreloc: 3
+ flags: 0
+ reserved1: 0
+ reserved2: 0
+ reserved3: 0
+ content: '000000000000000018000000000000000000000000000000'
+ relocations:
+ - address: 16
+ symbolnum: 2
+ pcrel: false
+ length: 3
+ extern: true
+ type: 0
+ scattered: false
+ value: 0
+ - address: 8
+ symbolnum: 2
+ pcrel: false
+ length: 3
+ extern: false
+ type: 0
+ scattered: false
+ value: 0
+ - address: 0
+ symbolnum: 1
+ pcrel: false
+ length: 3
+ extern: true
+ type: 0
+ scattered: false
+ value: 0
+ - sectname: __data
+ segname: __DATA
+ addr: 24
+ size: 8
+ offset: 312
+ align: 2
+ reloff: 0
+ nreloc: 0
+ flags: 0
+ reserved1: 0
+ reserved2: 0
+ reserved3: 0
+ content: '0000000000000000'
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 344
+ nsyms: 3
+ stroff: 392
+ strsize: 39
+LinkEditData:
+ NameList:
+ - n_strx: 1
+ n_type: 0x0E
+ n_sect: 2
+ n_desc: 0
+ n_value: 24
+ - n_strx: 15
+ n_type: 0x0E
+ n_sect: 2
+ n_desc: 0
+ n_value: 28
+ - n_strx: 27
+ n_type: 0x01
+ n_sect: 0
+ n_desc: 0
+ n_value: 0
+ StringTable:
+ - ''
+ - _unreferenced
+ - _referenced
+ - _undefined
+ - ''
diff --git a/llvm/test/tools/llvm-objcopy/MachO/indirect-symbol-table-copy.s b/llvm/test/tools/llvm-objcopy/MachO/indirect-symbol-table-copy.s
index 6b03f2e31471d1..e95136dd97d23f 100644
--- a/llvm/test/tools/llvm-objcopy/MachO/indirect-symbol-table-copy.s
+++ b/llvm/test/tools/llvm-objcopy/MachO/indirect-symbol-table-copy.s
@@ -6,6 +6,13 @@
# RUN: llvm-readobj --symbols --macho-indirect-symbols %t.copy \
# RUN: | FileCheck %s
+## Local symbols referenced by the indirect symbol table must be preserved.
+# RUN: llvm-objcopy -x %t %t.discard
+# RUN: llvm-readobj --symbols --macho-indirect-symbols %t.discard \
+# RUN: | FileCheck %s --check-prefix=DISCARD
+# RUN: llvm-strip -x %t -o %t.strip
+# RUN: cmp %t.discard %t.strip
+
# __DATA,__nl_symbol_ptr
.non_lazy_symbol_pointer
bar:
@@ -64,3 +71,17 @@ foo:
# CHECK-NEXT: }
# CHECK-NEXT: ]
# CHECK-NEXT: }
+
+# DISCARD: Symbols [
+# DISCARD-NEXT: Symbol {
+# DISCARD-NEXT: Name: foo
+# DISCARD-NEXT: Type: Section (0xE)
+# DISCARD-NEXT: Section: __la_symbol_ptr (0x3)
+# DISCARD-NEXT: RefType: UndefinedNonLazy (0x0)
+# DISCARD-NEXT: Flags [ (0x0)
+# DISCARD-NEXT: ]
+# DISCARD-NEXT: Value: 0x8
+# DISCARD-NEXT: }
+# DISCARD-NEXT: ]
+# DISCARD: Symbol Index: 0x80000000
+# DISCARD: Symbol Index: 0x0
``````````
</details>
https://github.com/llvm/llvm-project/pull/228733
More information about the llvm-branch-commits
mailing list