[llvm] [BOLT] Fix 32-bit overflow in checkOffsets/checkVMA (PR #68274)

Amir Ayupov via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 4 16:51:54 PDT 2023


https://github.com/aaupov created https://github.com/llvm/llvm-project/pull/68274

None

>From ac1af7cc7b3a5f13fdbbcb006a250d856b7fd148 Mon Sep 17 00:00:00 2001
From: Amir Ayupov <aaupov at fb.com>
Date: Wed, 4 Oct 2023 15:41:58 -0700
Subject: [PATCH] [BOLT] Fix 32-bit overflow in checkOffsets/checkVMA

---
 bolt/lib/Rewrite/RewriteInstance.cpp  | 10 +++++---
 bolt/test/checkvma-large-section.test | 35 +++++++++++++++++++++++++++
 2 files changed, 41 insertions(+), 4 deletions(-)
 create mode 100644 bolt/test/checkvma-large-section.test

diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index 5cbbd1a5a8acaa8..29a1bd3f113eb01 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -408,8 +408,9 @@ static bool checkOffsets(const typename ELFT::Phdr &Phdr,
     return true;
 
   // Only non-empty sections can be at the end of a segment.
-  uint64_t SectionSize = Sec.sh_size ? Sec.sh_size : 1;
-  AddressRange SectionAddressRange(Sec.sh_offset, Sec.sh_offset + SectionSize);
+  uint64_t SectionSize = Sec.sh_size ? Sec.sh_size : 1ull;
+  AddressRange SectionAddressRange((uint64_t)Sec.sh_offset,
+                                   Sec.sh_offset + SectionSize);
   AddressRange SegmentAddressRange(Phdr.p_offset,
                                    Phdr.p_offset + Phdr.p_filesz);
   if (SegmentAddressRange.contains(SectionAddressRange))
@@ -425,8 +426,9 @@ template <class ELFT>
 static bool checkVMA(const typename ELFT::Phdr &Phdr,
                      const typename ELFT::Shdr &Sec, bool &Overlap) {
   // Only non-empty sections can be at the end of a segment.
-  uint64_t SectionSize = Sec.sh_size ? Sec.sh_size : 1;
-  AddressRange SectionAddressRange(Sec.sh_addr, Sec.sh_addr + SectionSize);
+  uint64_t SectionSize = Sec.sh_size ? Sec.sh_size : 1ull;
+  AddressRange SectionAddressRange((uint64_t)Sec.sh_addr,
+                                   Sec.sh_addr + SectionSize);
   AddressRange SegmentAddressRange(Phdr.p_vaddr, Phdr.p_vaddr + Phdr.p_memsz);
 
   if (SegmentAddressRange.contains(SectionAddressRange))
diff --git a/bolt/test/checkvma-large-section.test b/bolt/test/checkvma-large-section.test
new file mode 100644
index 000000000000000..36a915951115e10
--- /dev/null
+++ b/bolt/test/checkvma-large-section.test
@@ -0,0 +1,35 @@
+# This test reproduces the issue with a section which ends at >4G address
+REQUIRES: asserts
+RUN: split-file %s %t
+RUN: yaml2obj %t/yaml -o %t.exe --max-size=0
+RUN: llvm-bolt %t.exe -o /dev/null --allow-stripped
+#--- yaml
+--- !ELF
+FileHeader:
+  Class: ELFCLASS64
+  Data: ELFDATA2LSB
+  Type: ET_EXEC
+  Machine: EM_X86_64
+ProgramHeaders:
+  - Type: PT_LOAD
+    FirstSec: .a
+    LastSec: .a
+    Align: 0x1000
+  - Type: PT_LOAD
+    Flags: [ PF_R, PF_W ]
+    FirstSec: .large_sec
+    LastSec: .large_sec
+    VAddr: 0x4a0279a8
+  - Type: PT_GNU_RELRO
+    Flags: [ PF_R ]
+Sections:
+  - Name: .a
+    Type: SHT_PROGBITS
+    Content: 00
+    AddressAlign: 0x1
+  - Name: .large_sec
+    Type: SHT_PROGBITS
+    Flags: [ SHF_WRITE, SHF_ALLOC ]
+    Address: 0x4a0279a8
+    Size: 0xdf8bb1a0
+...



More information about the llvm-commits mailing list