Skip to content

[ELF] Reject certain unknown section types #85173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lld/ELF/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ struct Config {
bool printGcSections;
bool printIcfSections;
bool printMemoryUsage;
bool rejectMismatch;
bool relax;
bool relaxGP;
bool relocatable;
Expand Down
1 change: 1 addition & 0 deletions lld/ELF/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1348,6 +1348,7 @@ static void readConfigs(opt::InputArgList &args) {
config->printArchiveStats = args.getLastArgValue(OPT_print_archive_stats);
config->printSymbolOrder =
args.getLastArgValue(OPT_print_symbol_order);
config->rejectMismatch = !args.hasArg(OPT_no_warn_mismatch);
config->relax = args.hasFlag(OPT_relax, OPT_no_relax, true);
config->relaxGP = args.hasFlag(OPT_relax_gp, OPT_no_relax_gp, false);
config->rpath = getRpath(args);
Expand Down
35 changes: 29 additions & 6 deletions lld/ELF/InputFiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,15 @@ template <class ELFT> void ObjFile<ELFT>::initializeJustSymbols() {
sections.resize(numELFShdrs);
}

static bool isKnownSpecificSectionType(uint32_t t, uint32_t flags) {
if (SHT_LOUSER <= t && t <= SHT_HIUSER && !(flags & SHF_ALLOC))
return true;
if (SHT_LOOS <= t && t <= SHT_HIOS && !(flags & SHF_OS_NONCONFORMING))
return true;
// Allow all processor-specific types. This is different from GNU ld.
return SHT_LOPROC <= t && t <= SHT_HIPROC;
}

template <class ELFT>
void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
const llvm::object::ELFFile<ELFT> &obj) {
Expand All @@ -752,14 +761,15 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
if (this->sections[i] == &InputSection::discarded)
continue;
const Elf_Shdr &sec = objSections[i];
const uint32_t type = sec.sh_type;

// SHF_EXCLUDE'ed sections are discarded by the linker. However,
// if -r is given, we'll let the final link discard such sections.
// This is compatible with GNU.
if ((sec.sh_flags & SHF_EXCLUDE) && !config->relocatable) {
if (sec.sh_type == SHT_LLVM_CALL_GRAPH_PROFILE)
if (type == SHT_LLVM_CALL_GRAPH_PROFILE)
cgProfileSectionIndex = i;
if (sec.sh_type == SHT_LLVM_ADDRSIG) {
if (type == SHT_LLVM_ADDRSIG) {
// We ignore the address-significance table if we know that the object
// file was created by objcopy or ld -r. This is because these tools
// will reorder the symbols in the symbol table, invalidating the data
Expand All @@ -778,7 +788,7 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
continue;
}

switch (sec.sh_type) {
switch (type) {
case SHT_GROUP: {
if (!config->relocatable)
sections[i] = &InputSection::discarded;
Expand All @@ -801,12 +811,25 @@ void ObjFile<ELFT>::initializeSections(bool ignoreComdats,
case SHT_RELA:
case SHT_NULL:
break;
case SHT_LLVM_SYMPART:
ctx.hasSympart.store(true, std::memory_order_relaxed);
[[fallthrough]];
case SHT_PROGBITS:
case SHT_NOTE:
case SHT_NOBITS:
case SHT_INIT_ARRAY:
case SHT_FINI_ARRAY:
case SHT_PREINIT_ARRAY:
this->sections[i] =
createInputSection(i, sec, check(obj.getSectionName(sec, shstrtab)));
break;
default:
this->sections[i] =
createInputSection(i, sec, check(obj.getSectionName(sec, shstrtab)));
if (type == SHT_LLVM_SYMPART)
ctx.hasSympart.store(true, std::memory_order_relaxed);
else if (config->rejectMismatch &&
!isKnownSpecificSectionType(type, sec.sh_flags))
errorOrWarn(toString(this->sections[i]) + ": unknown section type 0x" +
Twine::utohexstr(type));
break;
}
}

Expand Down
4 changes: 3 additions & 1 deletion lld/ELF/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,9 @@ def no_dynamic_linker: F<"no-dynamic-linker">,
def noinhibit_exec: F<"noinhibit-exec">,
HelpText<"Retain the executable output file whenever it is still usable">;

def no_warn_mismatch: F<"no-warn-mismatch">,
HelpText<"Suppress errors for certain unknown seciton types">;

def no_nmagic: F<"no-nmagic">, MetaVarName<"<magic>">,
HelpText<"Page align sections (default)">;

Expand Down Expand Up @@ -753,7 +756,6 @@ def: FF<"no-add-needed">;
def: F<"no-copy-dt-needed-entries">;
def: F<"no-ctors-in-init-array">;
def: F<"no-keep-memory">;
def: F<"no-warn-mismatch">;
def: Separate<["--", "-"], "rpath-link">;
def: J<"rpath-link=">;
def: F<"secure-plt">;
Expand Down
2 changes: 2 additions & 0 deletions lld/docs/ld.lld.1
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,8 @@ Do not put read-only non-executable sections in their own segment.
Do not report version scripts that refer to undefined symbols.
.It Fl -no-undefined
Report unresolved symbols even if the linker is creating a shared library.
.It Fl -no-warn-mismatch
Do not reject unknown section types.
.It Fl -no-warn-symbol-ordering
Do not warn about problems with the symbol ordering file or call graph profile.
.It Fl -no-warnings , Fl w
Expand Down
2 changes: 1 addition & 1 deletion lld/test/ELF/incompatible-section-types2.s
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
// CHECK-NEXT: >>> <internal>:(.shstrtab): SHT_STRTAB
// CHECK-NEXT: >>> output section .shstrtab: Unknown

.section .shstrtab,"",@12345
.section .shstrtab,"",@0x60000000
.short 20
2 changes: 1 addition & 1 deletion lld/test/ELF/linkerscript/custom-section-type.s
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ SECTIONS {
.section progbits,"a",@note
.byte 0

.section expr,"a",@12345
.section expr,"a",@0x60000000
.byte 0

#--- unknown1.lds
Expand Down
48 changes: 48 additions & 0 deletions lld/test/ELF/unknown-section.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# RUN: rm -rf %t && mkdir %t && cd %t
# RUN: yaml2obj %s -o a.o
# RUN: not ld.lld a.o -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:

# CHECK: error: a.o:(relr): unknown section type 0x13
# CHECK-NEXT: error: a.o:(regular): unknown section type 0x15
# CHECK-NEXT: error: a.o:(loos_nonconforming): unknown section type 0x60000000
# CHECK-NEXT: error: a.o:(hios_nonconforming): unknown section type 0x6fffffff
# CHECK-NEXT: error: a.o:(louser_alloc): unknown section type 0x80000000
# CHECK-NEXT: error: a.o:(hiuser_alloc): unknown section type 0xffffffff

--- !ELF
FileHeader:
Class: ELFCLASS64
Data: ELFDATA2LSB
Type: ET_REL
Machine: EM_X86_64
Sections:
- Name: relr
Type: 19
- Name: regular
Type: 21
- Name: loos
Type: 0x60000000
- Name: hios
Type: 0x6fffffff
- Name: loos_nonconforming
Type: 0x60000000
Flags: [ SHF_OS_NONCONFORMING ]
- Name: hios_nonconforming
Type: 0x6fffffff
Flags: [ SHF_OS_NONCONFORMING ]

- Name: loproc
Type: 0x70000000
- Name: hiproc
Type: 0x7fffffff

- Name: louser
Type: 0x80000000
- Name: hiuser
Type: 0xffffffff
- Name: louser_alloc
Type: 0x80000000
Flags: [ SHF_ALLOC ]
- Name: hiuser_alloc
Type: 0xffffffff
Flags: [ SHF_ALLOC ]