From 7b407c478fab53a6d9a091887c828c3f7b3f8b46 Mon Sep 17 00:00:00 2001 From: kettenis Date: Wed, 19 Apr 2023 16:04:33 +0000 Subject: [PATCH] Implement support for PT_OPENBSD_NOBTCFI in lld(1). This can be set using the -z nobtcfi option. ok deraadt@ --- gnu/llvm/lld/ELF/Config.h | 1 + gnu/llvm/lld/ELF/Driver.cpp | 4 +++- gnu/llvm/lld/ELF/Writer.cpp | 5 +++++ gnu/llvm/llvm/include/llvm/BinaryFormat/ELF.h | 1 + gnu/llvm/llvm/tools/llvm-objdump/ELFDump.cpp | 3 +++ gnu/llvm/llvm/tools/llvm-readobj/ELFDumper.cpp | 1 + 6 files changed, 14 insertions(+), 1 deletion(-) diff --git a/gnu/llvm/lld/ELF/Config.h b/gnu/llvm/lld/ELF/Config.h index e61c698e146..73d4c8bc156 100644 --- a/gnu/llvm/lld/ELF/Config.h +++ b/gnu/llvm/lld/ELF/Config.h @@ -236,6 +236,7 @@ struct Configuration { bool zInitfirst; bool zInterpose; bool zKeepTextSectionPrefix; + bool zNoBtCfi; bool zNodefaultlib; bool zNodelete; bool zNodlopen; diff --git a/gnu/llvm/lld/ELF/Driver.cpp b/gnu/llvm/lld/ELF/Driver.cpp index 24b8d780a2c..ee9867293cf 100644 --- a/gnu/llvm/lld/ELF/Driver.cpp +++ b/gnu/llvm/lld/ELF/Driver.cpp @@ -462,7 +462,8 @@ static bool isKnownZFlag(StringRef s) { s == "initfirst" || s == "interpose" || s == "keep-text-section-prefix" || s == "lazy" || s == "muldefs" || s == "separate-code" || s == "separate-loadable-segments" || - s == "start-stop-gc" || s == "nocombreloc" || s == "nocopyreloc" || + s == "start-stop-gc" || s == "nobtcfi" || + s == "nocombreloc" || s == "nocopyreloc" || s == "nodefaultlib" || s == "nodelete" || s == "nodlopen" || s == "noexecstack" || s == "nognustack" || s == "nokeep-text-section-prefix" || s == "norelro" || @@ -1197,6 +1198,7 @@ static void readConfigs(opt::InputArgList &args) { config->zInterpose = hasZOption(args, "interpose"); config->zKeepTextSectionPrefix = getZFlag( args, "keep-text-section-prefix", "nokeep-text-section-prefix", false); + config->zNoBtCfi = hasZOption(args, "nobtcfi"); config->zNodefaultlib = hasZOption(args, "nodefaultlib"); config->zNodelete = hasZOption(args, "nodelete"); config->zNodlopen = hasZOption(args, "nodlopen"); diff --git a/gnu/llvm/lld/ELF/Writer.cpp b/gnu/llvm/lld/ELF/Writer.cpp index 8b5e4e294e8..e8de5f0f2b6 100644 --- a/gnu/llvm/lld/ELF/Writer.cpp +++ b/gnu/llvm/lld/ELF/Writer.cpp @@ -2499,6 +2499,11 @@ std::vector Writer::createPhdrs(Partition &part) { if (config->zWxneeded) addHdr(PT_OPENBSD_WXNEEDED, PF_X); + // PT_OPENBSD_NOBTCFI is an OpenBSD-specific header to mark that the + // executable is expected to violate branch-target CFI checks. + if (config->zNoBtCfi) + addHdr(PT_OPENBSD_NOBTCFI, PF_X); + if (OutputSection *cmd = findSection(".note.gnu.property", partNo)) addHdr(PT_GNU_PROPERTY, PF_R)->add(cmd); diff --git a/gnu/llvm/llvm/include/llvm/BinaryFormat/ELF.h b/gnu/llvm/llvm/include/llvm/BinaryFormat/ELF.h index fa4139b88c2..71cf3a61448 100644 --- a/gnu/llvm/llvm/include/llvm/BinaryFormat/ELF.h +++ b/gnu/llvm/llvm/include/llvm/BinaryFormat/ELF.h @@ -1306,6 +1306,7 @@ enum { PT_OPENBSD_MUTABLE = 0x65a3dbe5, // Like bss, but not immutable. PT_OPENBSD_RANDOMIZE = 0x65a3dbe6, // Fill with random data. PT_OPENBSD_WXNEEDED = 0x65a3dbe7, // Program does W^X violations. + PT_OPENBSD_NOBTCFI = 0x65a3dbe8, // Do not enforce branch target CFI PT_OPENBSD_BOOTDATA = 0x65a41be6, // Section for boot arguments. // ARM program header types. diff --git a/gnu/llvm/llvm/tools/llvm-objdump/ELFDump.cpp b/gnu/llvm/llvm/tools/llvm-objdump/ELFDump.cpp index 5e87efa5a5d..952a417f820 100644 --- a/gnu/llvm/llvm/tools/llvm-objdump/ELFDump.cpp +++ b/gnu/llvm/llvm/tools/llvm-objdump/ELFDump.cpp @@ -249,6 +249,9 @@ static void printProgramHeaders(const ELFFile &Obj, StringRef FileName) { case ELF::PT_OPENBSD_MUTABLE: outs() << "OPENBSD_MUTABLE "; break; + case ELF::PT_OPENBSD_NOBTCFI: + outs() << "OPENBSD_NOBTCFI "; + break; case ELF::PT_OPENBSD_RANDOMIZE: outs() << "OPENBSD_RANDOMIZE "; break; diff --git a/gnu/llvm/llvm/tools/llvm-readobj/ELFDumper.cpp b/gnu/llvm/llvm/tools/llvm-readobj/ELFDumper.cpp index f0708a758dc..97e6e25841e 100644 --- a/gnu/llvm/llvm/tools/llvm-readobj/ELFDumper.cpp +++ b/gnu/llvm/llvm/tools/llvm-readobj/ELFDumper.cpp @@ -1372,6 +1372,7 @@ static StringRef segmentTypeToString(unsigned Arch, unsigned Type) { LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_MUTABLE); LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_RANDOMIZE); LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_WXNEEDED); + LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_NOBTCFI); LLVM_READOBJ_ENUM_CASE(ELF, PT_OPENBSD_BOOTDATA); default: return ""; -- 2.20.1