summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Object/MachOObjectFile.cpp
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2015-06-04 19:45:22 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2015-06-04 19:45:22 +0000
commit9f336636fec73f6e7439174fce5b41b3028ccb43 (patch)
tree9fd44026c3c505e16f9df816c6847a63950633e8 /llvm/lib/Object/MachOObjectFile.cpp
parent4fdbed38858b69c80fc18ea3743cca267b6c72ff (diff)
downloadbcm5719-llvm-9f336636fec73f6e7439174fce5b41b3028ccb43.tar.gz
bcm5719-llvm-9f336636fec73f6e7439174fce5b41b3028ccb43.zip
[Object, MachO] Don't crash on parsing invalid MachO header.
Summary: Instead, properly report this error from MachOObjectFile constructor. Test Plan: regression test suite Reviewers: rafael Subscribers: llvm-commits llvm-svn: 239078
Diffstat (limited to 'llvm/lib/Object/MachOObjectFile.cpp')
-rw-r--r--llvm/lib/Object/MachOObjectFile.cpp33
1 files changed, 29 insertions, 4 deletions
diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp
index 1620c1a6a91..c1d13838444 100644
--- a/llvm/lib/Object/MachOObjectFile.cpp
+++ b/llvm/lib/Object/MachOObjectFile.cpp
@@ -38,6 +38,7 @@ namespace {
};
}
+// FIXME: Replace all uses of this function with getStructOrErr.
template <typename T>
static T getStruct(const MachOObjectFile *O, const char *P) {
// Don't read before the beginning or past the end of the file
@@ -51,6 +52,19 @@ static T getStruct(const MachOObjectFile *O, const char *P) {
return Cmd;
}
+template <typename T>
+static ErrorOr<T> getStructOrErr(const MachOObjectFile *O, const char *P) {
+ // Don't read before the beginning or past the end of the file
+ if (P < O->getData().begin() || P + sizeof(T) > O->getData().end())
+ return object_error::parse_failed;
+
+ T Cmd;
+ memcpy(&Cmd, P, sizeof(T));
+ if (O->isLittleEndian() != sys::IsLittleEndianHost)
+ MachO::swapStruct(Cmd);
+ return Cmd;
+}
+
template <typename SegmentCmd>
static uint32_t getSegmentLoadCommandNumSections(const SegmentCmd &S,
uint32_t Cmdsize) {
@@ -203,6 +217,16 @@ getNextLoadCommandInfo(const MachOObjectFile *Obj,
return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize);
}
+template <typename T>
+static void parseHeader(const MachOObjectFile *Obj, T &Header,
+ std::error_code &EC) {
+ auto HeaderOrErr = getStructOrErr<T>(Obj, getPtr(Obj, 0));
+ if (HeaderOrErr)
+ Header = HeaderOrErr.get();
+ else
+ EC = HeaderOrErr.getError();
+}
+
MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
bool Is64bits, std::error_code &EC)
: ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object),
@@ -210,14 +234,15 @@ MachOObjectFile::MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian,
DataInCodeLoadCmd(nullptr), LinkOptHintsLoadCmd(nullptr),
DyldInfoLoadCmd(nullptr), UuidLoadCmd(nullptr),
HasPageZeroSegment(false) {
- // Parse header.
if (is64Bit())
- Header64 = getStruct<MachO::mach_header_64>(this, getPtr(this, 0));
+ parseHeader(this, Header64, EC);
else
// First fields of MachO::mach_header_64 are the same as
// in MachO::mach_header.
- *reinterpret_cast<MachO::mach_header *>(&this->Header64) =
- getStruct<MachO::mach_header>(this, getPtr(this, 0));
+ parseHeader(this, *reinterpret_cast<MachO::mach_header *>(&this->Header64),
+ EC);
+ if (EC)
+ return;
uint32_t LoadCommandCount = getHeader().ncmds;
if (LoadCommandCount == 0)
OpenPOWER on IntegriCloud