@@ -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+
130136COMPILER_RT_VISIBILITY
131137int __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