Skip to content

Commit 3eed847

Browse files
authored
[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.
1 parent e9fb0ad commit 3eed847

File tree

1 file changed

+14
-7
lines changed

1 file changed

+14
-7
lines changed

compiler-rt/lib/profile/InstrProfilingMerge.c

+14-7
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ getDistanceFromCounterToValueProf(const __llvm_profile_header *const Header) {
127127
PaddingBytesAfterVNamesSize;
128128
}
129129

130+
// Add offset to pointer without assuming that the addition does not overflow.
131+
// This allows performing bounds checks by checking the result of the addition.
132+
static const char *ptr_add_with_overflow(const char *p, size_t offset) {
133+
return (const char *)((uintptr_t)p + offset);
134+
}
135+
130136
COMPILER_RT_VISIBILITY
131137
int __llvm_profile_merge_from_buffer(const char *ProfileData,
132138
uint64_t ProfileSize) {
@@ -154,9 +160,10 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,
154160
SrcCountersStart = (char *)SrcDataEnd;
155161
SrcCountersEnd = SrcCountersStart +
156162
Header->NumCounters * __llvm_profile_counter_entry_size();
157-
SrcBitmapStart = SrcCountersEnd + __llvm_profile_get_num_padding_bytes(
158-
SrcCountersEnd - SrcCountersStart);
159-
SrcNameStart = SrcBitmapStart + Header->NumBitmapBytes;
163+
SrcBitmapStart = ptr_add_with_overflow(
164+
SrcCountersEnd,
165+
__llvm_profile_get_num_padding_bytes(SrcCountersEnd - SrcCountersStart));
166+
SrcNameStart = ptr_add_with_overflow(SrcBitmapStart, Header->NumBitmapBytes);
160167
SrcValueProfDataStart =
161168
SrcNameStart + getDistanceFromCounterToValueProf(Header);
162169
if (SrcNameStart < SrcCountersStart || SrcNameStart < SrcBitmapStart)
@@ -200,8 +207,8 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,
200207
// CountersDelta computes the offset into the in-buffer counter section.
201208
//
202209
// On WIN64, CountersDelta is truncated as well, so no need for signext.
203-
char *SrcCounters =
204-
SrcCountersStart + ((uintptr_t)SrcData->CounterPtr - CountersDelta);
210+
const char *SrcCounters = ptr_add_with_overflow(
211+
SrcCountersStart, (uintptr_t)SrcData->CounterPtr - CountersDelta);
205212
// CountersDelta needs to be decreased as we advance to the next data
206213
// record.
207214
CountersDelta -= sizeof(*SrcData);
@@ -220,8 +227,8 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,
220227
}
221228
}
222229

223-
const char *SrcBitmap =
224-
SrcBitmapStart + ((uintptr_t)SrcData->BitmapPtr - BitmapDelta);
230+
const char *SrcBitmap = ptr_add_with_overflow(
231+
SrcBitmapStart, (uintptr_t)SrcData->BitmapPtr - BitmapDelta);
225232
// BitmapDelta also needs to be decreased as we advance to the next data
226233
// record.
227234
BitmapDelta -= sizeof(*SrcData);

0 commit comments

Comments
 (0)