mirror of
https://github.com/intel/llvm.git
synced 2026-01-21 20:53:29 +08:00
[ELF] Correctly compute .gdb_index size when symbol's name offset overflows
if `nameOff` overflows, `size` may be underestimated. In writeTo, `memcpy(buf + sym.nameOff, sym.name.data(), sym.name.size());` may cause an out-of-bounds write, leading to a SIGSEGV.
This commit is contained in:
@@ -2692,20 +2692,6 @@ size_t GdbIndexSection::computeSymtabSize() const {
|
||||
return std::max<size_t>(NextPowerOf2(symbols.size() * 4 / 3), 1024);
|
||||
}
|
||||
|
||||
// Compute the output section size.
|
||||
void GdbIndexSection::initOutputSize() {
|
||||
size = sizeof(GdbIndexHeader) + computeSymtabSize() * 8;
|
||||
|
||||
for (GdbChunk &chunk : chunks)
|
||||
size += chunk.compilationUnits.size() * 16 + chunk.addressAreas.size() * 20;
|
||||
|
||||
// Add the constant pool size if exists.
|
||||
if (!symbols.empty()) {
|
||||
GdbSymbol &sym = symbols.back();
|
||||
size += sym.nameOff + sym.name.size() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
static SmallVector<GdbIndexSection::CuEntry, 0>
|
||||
readCuList(DWARFContext &dwarf) {
|
||||
SmallVector<GdbIndexSection::CuEntry, 0> ret;
|
||||
@@ -2780,7 +2766,8 @@ readPubNamesAndTypes(const LLDDwarfObj<ELFT> &obj,
|
||||
|
||||
// Create a list of symbols from a given list of symbol names and types
|
||||
// by uniquifying them by name.
|
||||
static SmallVector<GdbIndexSection::GdbSymbol, 0> createSymbols(
|
||||
static std::pair<SmallVector<GdbIndexSection::GdbSymbol, 0>, size_t>
|
||||
createSymbols(
|
||||
ArrayRef<SmallVector<GdbIndexSection::NameAttrEntry, 0>> nameAttrs,
|
||||
const SmallVector<GdbIndexSection::GdbChunk, 0> &chunks) {
|
||||
using GdbSymbol = GdbIndexSection::GdbSymbol;
|
||||
@@ -2858,7 +2845,7 @@ static SmallVector<GdbIndexSection::GdbSymbol, 0> createSymbols(
|
||||
off += sym.name.size() + 1;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return {ret, off};
|
||||
}
|
||||
|
||||
// Returns a newly-created .gdb_index section.
|
||||
@@ -2908,8 +2895,14 @@ template <class ELFT> GdbIndexSection *GdbIndexSection::create() {
|
||||
|
||||
auto *ret = make<GdbIndexSection>();
|
||||
ret->chunks = std::move(chunks);
|
||||
ret->symbols = createSymbols(nameAttrs, ret->chunks);
|
||||
ret->initOutputSize();
|
||||
std::tie(ret->symbols, ret->size) = createSymbols(nameAttrs, ret->chunks);
|
||||
|
||||
// Count the areas other than the constant pool.
|
||||
ret->size += sizeof(GdbIndexHeader) + ret->computeSymtabSize() * 8;
|
||||
for (GdbChunk &chunk : ret->chunks)
|
||||
ret->size +=
|
||||
chunk.compilationUnits.size() * 16 + chunk.addressAreas.size() * 20;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -787,7 +787,6 @@ private:
|
||||
llvm::support::ulittle32_t constantPoolOff;
|
||||
};
|
||||
|
||||
void initOutputSize();
|
||||
size_t computeSymtabSize() const;
|
||||
|
||||
// Each chunk contains information gathered from debug sections of a
|
||||
|
||||
Reference in New Issue
Block a user