Skip to content

Commit

Permalink
[Binary] Further improve malformed input handling for the OffloadBinary
Browse files Browse the repository at this point in the history
Summary:
This patch adds some new sanity checks to make sure that the sizes of
the offsets are within the bounds of the file or what is expected by the
binary. This also improves the error handling of the version structure
to be built into the binary itself so we can change it easier.
  • Loading branch information
jhuber6 committed Jun 24, 2022
1 parent acc22ae commit 1dcbe03
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 8 deletions.
4 changes: 0 additions & 4 deletions clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,6 @@ Error extractOffloadFiles(MemoryBufferRef Contents,
return BinaryOrErr.takeError();
OffloadBinary &Binary = **BinaryOrErr;

if (Binary.getVersion() != 1)
return createStringError(inconvertibleErrorCode(),
"Incompatible device image version");

// Create a new owned binary with a copy of the original memory.
std::unique_ptr<MemoryBuffer> BufferCopy = MemoryBuffer::getMemBufferCopy(
Binary.getData().take_front(Binary.getSize()),
Expand Down
5 changes: 4 additions & 1 deletion llvm/include/llvm/Object/OffloadBinary.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class OffloadBinary : public Binary {
using string_iterator = StringMap<StringRef>::const_iterator;
using string_iterator_range = iterator_range<string_iterator>;

/// The current version of the binary used for backwards compatibility.
static const uint32_t Version = 1;

/// The offloading metadata that will be serialized to a memory buffer.
struct OffloadingImage {
ImageKind TheImageKind;
Expand Down Expand Up @@ -103,7 +106,7 @@ class OffloadBinary : public Binary {
private:
struct Header {
uint8_t Magic[4] = {0x10, 0xFF, 0x10, 0xAD}; // 0x10FF10AD magic bytes.
uint32_t Version = 1; // Version identifier.
uint32_t Version = OffloadBinary::Version; // Version identifier.
uint64_t Size; // Size in bytes of this entire binary.
uint64_t EntryOffset; // Offset of the metadata entry in bytes.
uint64_t EntrySize; // Size of the metadata entry in bytes.
Expand Down
12 changes: 9 additions & 3 deletions llvm/lib/Object/OffloadBinary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,18 @@ OffloadBinary::create(MemoryBufferRef Buf) {

const char *Start = Buf.getBufferStart();
const Header *TheHeader = reinterpret_cast<const Header *>(Start);
if (TheHeader->Version != OffloadBinary::Version)
return errorCodeToError(object_error::parse_failed);

if (TheHeader->Size > Buf.getBufferSize() ||
TheHeader->EntryOffset > TheHeader->Size - sizeof(Entry) ||
TheHeader->EntrySize > TheHeader->Size - sizeof(Header))
return errorCodeToError(object_error::unexpected_eof);

const Entry *TheEntry =
reinterpret_cast<const Entry *>(&Start[TheHeader->EntryOffset]);

// Make sure the offsets are inside the file.
if (TheHeader->EntryOffset > Buf.getBufferSize() ||
TheEntry->ImageOffset > Buf.getBufferSize() ||
if (TheEntry->ImageOffset > Buf.getBufferSize() ||
TheEntry->StringOffset > Buf.getBufferSize())
return errorCodeToError(object_error::unexpected_eof);

Expand Down

0 comments on commit 1dcbe03

Please sign in to comment.