Skip to content

Commit 95fb23a

Browse files
committedSep 3, 2019
[InstrProf] Tighten a check for malformed data records in raw profiles
The check needs to validate a counter offset before performing pointer arithmetic with the (potentially corrupt) offset. Found by UBSan's pointer overflow check. rdar://54843625 Differential Revision: https://reviews.llvm.org/D66979 llvm-svn: 370826
1 parent a6fcadd commit 95fb23a

File tree

4 files changed

+23
-6
lines changed

4 files changed

+23
-6
lines changed
 

‎llvm/include/llvm/ProfileData/InstrProfReader.h

+8-2
Original file line numberDiff line numberDiff line change
@@ -268,8 +268,14 @@ class RawInstrProfReader : public InstrProfReader {
268268
return (const char *)ValueDataStart;
269269
}
270270

271-
const uint64_t *getCounter(IntPtrT CounterPtr) const {
272-
ptrdiff_t Offset = (swap(CounterPtr) - CountersDelta) / sizeof(uint64_t);
271+
/// Get the offset of \p CounterPtr from the start of the counters section of
272+
/// the profile. The offset has units of "number of counters", i.e. increasing
273+
/// the offset by 1 corresponds to an increase in the *byte offset* by 8.
274+
ptrdiff_t getCounterOffset(IntPtrT CounterPtr) const {
275+
return (swap(CounterPtr) - CountersDelta) / sizeof(uint64_t);
276+
}
277+
278+
const uint64_t *getCounter(ptrdiff_t Offset) const {
273279
return CountersStart + Offset;
274280
}
275281

‎llvm/lib/ProfileData/InstrProfReader.cpp

+10-4
Original file line numberDiff line numberDiff line change
@@ -413,13 +413,19 @@ Error RawInstrProfReader<IntPtrT>::readRawCounts(
413413
if (NumCounters == 0)
414414
return error(instrprof_error::malformed);
415415

416-
auto RawCounts = makeArrayRef(getCounter(CounterPtr), NumCounters);
417416
auto *NamesStartAsCounter = reinterpret_cast<const uint64_t *>(NamesStart);
417+
ptrdiff_t MaxNumCounters = NamesStartAsCounter - CountersStart;
418418

419-
// Check bounds.
420-
if (RawCounts.data() < CountersStart ||
421-
RawCounts.data() + RawCounts.size() > NamesStartAsCounter)
419+
// Check bounds. Note that the counter pointer embedded in the data record
420+
// may itself be corrupt.
421+
if (NumCounters > MaxNumCounters)
422422
return error(instrprof_error::malformed);
423+
ptrdiff_t CounterOffset = getCounterOffset(CounterPtr);
424+
if (CounterOffset < 0 || CounterOffset > MaxNumCounters ||
425+
(CounterOffset + NumCounters) > MaxNumCounters)
426+
return error(instrprof_error::malformed);
427+
428+
auto RawCounts = makeArrayRef(getCounter(CounterOffset), NumCounters);
423429

424430
if (ShouldSwapBytes) {
425431
Record.Counts.clear();
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
REQUIRES: zlib
2+
3+
RUN: not llvm-profdata merge -o /dev/null %p/Inputs/malformed-ptr-to-counter-array.profraw 2>&1 | FileCheck %s
4+
5+
CHECK: Malformed instrumentation profile data

0 commit comments

Comments
 (0)
Please sign in to comment.