Fix more cases of UB from allocating 0 sized data. NFC.

The size of a section can be zero, even when it contains atoms, so
long as all of the atoms are also size 0.  In this case we were
allocating space for a 0 sized buffer.

Changed this to only allocate when we need the space, but also cleaned
up all the code to use MutableArrayRef instead of uint8_t* so its much much
safer as we get bounds checking on all of our section creation logic.

llvm-svn: 264204
This commit is contained in:
Pete Cooper 2016-03-23 22:19:16 +00:00
parent 08087c52eb
commit 47e5399cd3
6 changed files with 25 additions and 17 deletions

View File

@ -178,7 +178,7 @@ public:
FindAddressForAtom findAddress,
FindAddressForAtom findSectionAddress,
uint64_t imageBaseAddress,
uint8_t *atomContentBuffer) = 0;
llvm::MutableArrayRef<uint8_t> atomContentBuffer) = 0;
/// Used in -r mode to convert a Reference to a mach-o relocation.
virtual void appendSectionRelocations(const DefinedAtom &atom,

View File

@ -101,7 +101,7 @@ public:
FindAddressForAtom findAddress,
FindAddressForAtom findSectionAddress,
uint64_t imageBaseAddress,
uint8_t *atomContentBuffer) override;
llvm::MutableArrayRef<uint8_t> atomContentBuffer) override;
void appendSectionRelocations(const DefinedAtom &atom,
uint64_t atomSectionOffset,
@ -1019,9 +1019,10 @@ void ArchHandler_arm::generateAtomContent(const DefinedAtom &atom,
FindAddressForAtom findAddress,
FindAddressForAtom findSectionAddress,
uint64_t imageBaseAddress,
uint8_t *atomContentBuffer) {
llvm::MutableArrayRef<uint8_t> atomContentBuffer) {
// Copy raw bytes.
memcpy(atomContentBuffer, atom.rawContent().data(), atom.size());
std::copy(atom.rawContent().begin(), atom.rawContent().end(),
atomContentBuffer.begin());
// Apply fix-ups.
bool thumbMode = false;
for (const Reference *ref : atom) {

View File

@ -164,7 +164,7 @@ public:
FindAddressForAtom findAddress,
FindAddressForAtom findSectionAddress,
uint64_t imageBaseAddress,
uint8_t *atomContentBuffer) override;
llvm::MutableArrayRef<uint8_t> atomContentBuffer) override;
void appendSectionRelocations(const DefinedAtom &atom,
uint64_t atomSectionOffset,
@ -537,9 +537,10 @@ std::error_code ArchHandler_arm64::getPairReferenceInfo(
void ArchHandler_arm64::generateAtomContent(
const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress,
FindAddressForAtom findSectionAddress, uint64_t imageBaseAddress,
uint8_t *atomContentBuffer) {
llvm::MutableArrayRef<uint8_t> atomContentBuffer) {
// Copy raw bytes.
memcpy(atomContentBuffer, atom.rawContent().data(), atom.size());
std::copy(atom.rawContent().begin(), atom.rawContent().end(),
atomContentBuffer.begin());
// Apply fix-ups.
#ifndef NDEBUG
if (atom.begin() != atom.end()) {

View File

@ -107,7 +107,7 @@ public:
FindAddressForAtom findAddress,
FindAddressForAtom findSectionAddress,
uint64_t imageBaseAddress,
uint8_t *atomContentBuffer) override;
llvm::MutableArrayRef<uint8_t> atomContentBuffer) override;
void appendSectionRelocations(const DefinedAtom &atom,
uint64_t atomSectionOffset,
@ -419,9 +419,10 @@ void ArchHandler_x86::generateAtomContent(const DefinedAtom &atom,
FindAddressForAtom findAddress,
FindAddressForAtom findSectionAddress,
uint64_t imageBaseAddress,
uint8_t *atomContentBuffer) {
llvm::MutableArrayRef<uint8_t> atomContentBuffer) {
// Copy raw bytes.
memcpy(atomContentBuffer, atom.rawContent().data(), atom.size());
std::copy(atom.rawContent().begin(), atom.rawContent().end(),
atomContentBuffer.begin());
// Apply fix-ups.
for (const Reference *ref : atom) {
uint32_t offset = ref->offsetInAtom();

View File

@ -167,7 +167,7 @@ public:
FindAddressForAtom findAddress,
FindAddressForAtom findSectionAddress,
uint64_t imageBase,
uint8_t *atomContentBuffer) override;
llvm::MutableArrayRef<uint8_t> atomContentBuffer) override;
void appendSectionRelocations(const DefinedAtom &atom,
uint64_t atomSectionOffset,
@ -508,9 +508,10 @@ ArchHandler_x86_64::getPairReferenceInfo(const normalized::Relocation &reloc1,
void ArchHandler_x86_64::generateAtomContent(
const DefinedAtom &atom, bool relocatable, FindAddressForAtom findAddress,
FindAddressForAtom findSectionAddress, uint64_t imageBaseAddress,
uint8_t *atomContentBuffer) {
llvm::MutableArrayRef<uint8_t> atomContentBuffer) {
// Copy raw bytes.
memcpy(atomContentBuffer, atom.rawContent().data(), atom.size());
std::copy(atom.rawContent().begin(), atom.rawContent().end(),
atomContentBuffer.begin());
// Apply fix-ups.
for (const Reference *ref : atom) {
uint32_t offset = ref->offsetInAtom();

View File

@ -669,16 +669,20 @@ void Util::copySectionContent(NormalizedFile &file) {
continue;
}
// Copy content from atoms to content buffer for section.
uint8_t *sectionContent = file.ownedAllocations.Allocate<uint8_t>(si->size);
normSect->content = llvm::makeArrayRef(sectionContent, si->size);
llvm::MutableArrayRef<uint8_t> sectionContent;
if (si->size) {
uint8_t *sectContent = file.ownedAllocations.Allocate<uint8_t>(si->size);
sectionContent = llvm::MutableArrayRef<uint8_t>(sectContent, si->size);
normSect->content = sectionContent;
}
for (AtomInfo &ai : si->atomsAndOffsets) {
if (!ai.atom->size()) {
assert(ai.atom->begin() == ai.atom->end() &&
"Cannot have references without content");
continue;
}
uint8_t *atomContent = reinterpret_cast<uint8_t*>
(&sectionContent[ai.offsetInSection]);
auto atomContent = sectionContent.slice(ai.offsetInSection,
ai.atom->size());
_archHandler.generateAtomContent(*ai.atom, r, addrForAtom,
sectionAddrForAtom, _ctx.baseAddress(),
atomContent);