[compiler-rt] 3eed847 - [profile] Fix bounds checks in profile merging (#118782)

via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 6 01:09:34 PST 2024


Author: Nikita Popov
Date: 2024-12-06T10:09:30+01:00
New Revision: 3eed8479a895253307c6d87a38bb5acf314c6505

URL: https://github.com/llvm/llvm-project/commit/3eed8479a895253307c6d87a38bb5acf314c6505
DIFF: https://github.com/llvm/llvm-project/commit/3eed8479a895253307c6d87a38bb5acf314c6505.diff

LOG: [profile] Fix bounds checks in profile merging (#118782)

These bounds checks work on the result of the pointer addition -- but
the pointer addition already asserts that no overflow may occur, so the
checks are optimized away after #118472. Avoid this by performing the
addition in a way that permits overflow.

Added: 
    

Modified: 
    compiler-rt/lib/profile/InstrProfilingMerge.c

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/profile/InstrProfilingMerge.c b/compiler-rt/lib/profile/InstrProfilingMerge.c
index 7cf1679811eb07..a42fa74d1788eb 100644
--- a/compiler-rt/lib/profile/InstrProfilingMerge.c
+++ b/compiler-rt/lib/profile/InstrProfilingMerge.c
@@ -127,6 +127,12 @@ getDistanceFromCounterToValueProf(const __llvm_profile_header *const Header) {
          PaddingBytesAfterVNamesSize;
 }
 
+// Add offset to pointer without assuming that the addition does not overflow.
+// This allows performing bounds checks by checking the result of the addition.
+static const char *ptr_add_with_overflow(const char *p, size_t offset) {
+  return (const char *)((uintptr_t)p + offset);
+}
+
 COMPILER_RT_VISIBILITY
 int __llvm_profile_merge_from_buffer(const char *ProfileData,
                                      uint64_t ProfileSize) {
@@ -154,9 +160,10 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,
   SrcCountersStart = (char *)SrcDataEnd;
   SrcCountersEnd = SrcCountersStart +
                    Header->NumCounters * __llvm_profile_counter_entry_size();
-  SrcBitmapStart = SrcCountersEnd + __llvm_profile_get_num_padding_bytes(
-                                        SrcCountersEnd - SrcCountersStart);
-  SrcNameStart = SrcBitmapStart + Header->NumBitmapBytes;
+  SrcBitmapStart = ptr_add_with_overflow(
+      SrcCountersEnd,
+      __llvm_profile_get_num_padding_bytes(SrcCountersEnd - SrcCountersStart));
+  SrcNameStart = ptr_add_with_overflow(SrcBitmapStart, Header->NumBitmapBytes);
   SrcValueProfDataStart =
       SrcNameStart + getDistanceFromCounterToValueProf(Header);
   if (SrcNameStart < SrcCountersStart || SrcNameStart < SrcBitmapStart)
@@ -200,8 +207,8 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,
     // CountersDelta computes the offset into the in-buffer counter section.
     //
     // On WIN64, CountersDelta is truncated as well, so no need for signext.
-    char *SrcCounters =
-        SrcCountersStart + ((uintptr_t)SrcData->CounterPtr - CountersDelta);
+    const char *SrcCounters = ptr_add_with_overflow(
+        SrcCountersStart, (uintptr_t)SrcData->CounterPtr - CountersDelta);
     // CountersDelta needs to be decreased as we advance to the next data
     // record.
     CountersDelta -= sizeof(*SrcData);
@@ -220,8 +227,8 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,
       }
     }
 
-    const char *SrcBitmap =
-        SrcBitmapStart + ((uintptr_t)SrcData->BitmapPtr - BitmapDelta);
+    const char *SrcBitmap = ptr_add_with_overflow(
+        SrcBitmapStart, (uintptr_t)SrcData->BitmapPtr - BitmapDelta);
     // BitmapDelta also needs to be decreased as we advance to the next data
     // record.
     BitmapDelta -= sizeof(*SrcData);


        


More information about the llvm-commits mailing list