[PATCH] D138830: [llvm] Check for overflows when computing load-command's addresses.

Vy Nguyen via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 28 09:15:57 PST 2022


oontvoo created this revision.
oontvoo added a reviewer: jyknight.
Herald added a subscriber: hiraditya.
Herald added a project: All.
oontvoo requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

PR/56746


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D138830

Files:
  llvm/lib/Object/MachOObjectFile.cpp


Index: llvm/lib/Object/MachOObjectFile.cpp
===================================================================
--- llvm/lib/Object/MachOObjectFile.cpp
+++ llvm/lib/Object/MachOObjectFile.cpp
@@ -35,6 +35,7 @@
 #include "llvm/Support/Format.h"
 #include "llvm/Support/Host.h"
 #include "llvm/Support/LEB128.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/Support/MemoryBufferRef.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/SwapByteOrder.h"
@@ -84,7 +85,9 @@
 template <typename T>
 static Expected<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())
+  bool Overflowed = false;
+  uintptr_t Ret = llvm::SaturatingAdd<uintptr_t>(P, sizeof(T), &Overflowed);
+  if (P < O.getData().begin() || Overflowed || Ret > O.getData().end())
     return malformedError("Structure read out-of-range");
 
   T Cmd;
@@ -191,7 +194,12 @@
 getLoadCommandInfo(const MachOObjectFile &Obj, const char *Ptr,
                    uint32_t LoadCommandIndex) {
   if (auto CmdOrErr = getStructOrErr<MachO::load_command>(Obj, Ptr)) {
-    if (CmdOrErr->cmdsize + Ptr > Obj.getData().end())
+    bool Overflowed = false;
+    uintptr_t Ret = llvm::SaturatingAdd<uintptr_t>(
+        CmdOrErr->cmdsize, reinterpret_cast<uintptr_t>(Ptr), &Overflowed);
+
+    if (Overflowed ||
+        Ret > reinterpret_cast<long unsigned int>(Obj.getData().end()))
       return malformedError("load command " + Twine(LoadCommandIndex) +
                             " extends past end of file");
     if (CmdOrErr->cmdsize < 8)
@@ -217,8 +225,28 @@
                        const MachOObjectFile::LoadCommandInfo &L) {
   unsigned HeaderSize = Obj.is64Bit() ? sizeof(MachO::mach_header_64)
                                       : sizeof(MachO::mach_header);
-  if (L.Ptr + L.C.cmdsize + sizeof(MachO::load_command) >
-      Obj.getData().data() + HeaderSize + Obj.getHeader().sizeofcmds)
+
+  bool Overflowed = false;
+  // FIXME: Perhaps this validation on the Obj file should have been
+  // done somewhere else (earlier).
+  uint32_t LoadCmdsEnd = llvm::SaturatingAdd<uintptr_t>(
+      reinterpret_cast<uintptr_t>(Obj.getData().data()), HeaderSize,
+      &Overflowed);
+  assert(!Overflowed && "Load commands range extends past uint32_t type limit");
+  LoadCmdsEnd = llvm::SaturatingAdd<uintptr_t>(
+      LoadCmdsEnd, Obj.getHeader().sizeofcmds, &Overflowed);
+  assert(!Overflowed && "Load commands range extends past uint32_t type limit");
+
+  uint32_t PtrEnd = llvm::SaturatingAdd<uintptr_t>(
+      reinterpret_cast<uintptr_t>(L.Ptr), L.C.cmdsize, &Overflowed);
+  if (!Overflowed)
+    PtrEnd = llvm::SaturatingAdd<uintptr_t>(PtrEnd, sizeof(MachO::load_command),
+                                            &Overflowed);
+  if (Overflowed)
+    return malformedError("load command " + Twine(LoadCommandIndex + 1) +
+                          " extends past uint32_t type limit.");
+
+  if (PtrEnd > LoadCmdsEnd)
     return malformedError("load command " + Twine(LoadCommandIndex + 1) +
                           " extends past the end all load commands in the file");
   return getLoadCommandInfo(Obj, L.Ptr + L.C.cmdsize, LoadCommandIndex + 1);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D138830.478266.patch
Type: text/x-patch
Size: 3285 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20221128/4567a7eb/attachment.bin>


More information about the llvm-commits mailing list