@@ -127,6 +127,12 @@ getDistanceFromCounterToValueProf(const __llvm_profile_header *const Header) {
127
127
PaddingBytesAfterVNamesSize ;
128
128
}
129
129
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
+
130
136
COMPILER_RT_VISIBILITY
131
137
int __llvm_profile_merge_from_buffer (const char * ProfileData ,
132
138
uint64_t ProfileSize ) {
@@ -154,9 +160,10 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,
154
160
SrcCountersStart = (char * )SrcDataEnd ;
155
161
SrcCountersEnd = SrcCountersStart +
156
162
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 );
160
167
SrcValueProfDataStart =
161
168
SrcNameStart + getDistanceFromCounterToValueProf (Header );
162
169
if (SrcNameStart < SrcCountersStart || SrcNameStart < SrcBitmapStart )
@@ -200,8 +207,8 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,
200
207
// CountersDelta computes the offset into the in-buffer counter section.
201
208
//
202
209
// 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 );
205
212
// CountersDelta needs to be decreased as we advance to the next data
206
213
// record.
207
214
CountersDelta -= sizeof (* SrcData );
@@ -220,8 +227,8 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,
220
227
}
221
228
}
222
229
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 );
225
232
// BitmapDelta also needs to be decreased as we advance to the next data
226
233
// record.
227
234
BitmapDelta -= sizeof (* SrcData );
0 commit comments