[lld] d060cc1 - [ELF] Fix out-of-bounds write in memset(&Out::first, ...)
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sun Nov 28 14:48:03 PST 2021
Author: Fangrui Song
Date: 2021-11-28T14:47:57-08:00
New Revision: d060cc1f9808dd5de524334fd695404a96e3175f
URL: https://github.com/llvm/llvm-project/commit/d060cc1f9808dd5de524334fd695404a96e3175f
DIFF: https://github.com/llvm/llvm-project/commit/d060cc1f9808dd5de524334fd695404a96e3175f.diff
LOG: [ELF] Fix out-of-bounds write in memset(&Out::first, ...)
Fix r285764: there is no guarantee that Out::first is placed before other
static data members of `struct Out`. After `bufferStart` was introduced, this
out-of-bounds write is destined in many compilers. It is likely benign, though.
And move `Out::elfHeader->size` assignment beside `Out::elfHeader->sectionIndex`
Added:
Modified:
lld/ELF/Driver.cpp
lld/ELF/OutputSections.cpp
lld/ELF/OutputSections.h
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 5d306eab022ef..6399a1f947a70 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -2281,7 +2281,6 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// Create elfHeader early. We need a dummy section in
// addReservedSymbols to mark the created symbols as not absolute.
Out::elfHeader = make<OutputSection>("", 0, SHF_ALLOC);
- Out::elfHeader->size = sizeof(typename ELFT::Ehdr);
std::vector<WrappedSymbol> wrapped = addWrappedSymbols(args);
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 7b9cdc736b96c..a17f713b742a8 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -33,7 +33,6 @@ using namespace lld;
using namespace lld::elf;
uint8_t *Out::bufferStart;
-uint8_t Out::first;
PhdrEntry *Out::tlsPhdr;
OutputSection *Out::elfHeader;
OutputSection *Out::programHeaders;
diff --git a/lld/ELF/OutputSections.h b/lld/ELF/OutputSections.h
index 316fc3311644a..a5b05cf28aa8d 100644
--- a/lld/ELF/OutputSections.h
+++ b/lld/ELF/OutputSections.h
@@ -128,7 +128,6 @@ std::vector<InputSection *> getInputSections(const OutputSection *os);
// until Writer is initialized.
struct Out {
static uint8_t *bufferStart;
- static uint8_t first;
static PhdrEntry *tlsPhdr;
static OutputSection *elfHeader;
static OutputSection *programHeaders;
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index fc18e4f45be98..adceb30224603 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -281,7 +281,10 @@ static OutputSection *findSection(StringRef name, unsigned partition = 1) {
template <class ELFT> void elf::createSyntheticSections() {
// Initialize all pointers with NULL. This is needed because
// you can call lld::elf::main more than once as a library.
- memset(&Out::first, 0, sizeof(Out));
+ Out::tlsPhdr = nullptr;
+ Out::preinitArray = nullptr;
+ Out::initArray = nullptr;
+ Out::finiArray = nullptr;
// Add the .interp section first because it is not a SyntheticSection.
// The removeUnusedSyntheticSections() function relies on the
@@ -2054,6 +2057,7 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// to 1 to make __ehdr_start defined. The section number is not
// particularly relevant.
Out::elfHeader->sectionIndex = 1;
+ Out::elfHeader->size = sizeof(typename ELFT::Ehdr);
for (size_t i = 0, e = outputSections.size(); i != e; ++i) {
OutputSection *sec = outputSections[i];
More information about the llvm-commits
mailing list