Skip to content

Commit 41dfc4f

Browse files
committedJun 1, 2017
[ubsan] Runtime support for pointer overflow checking
Patch by John Regehr and Will Dietz! Differential Revision: https://reviews.llvm.org/D20323 llvm-svn: 304461
1 parent 4952871 commit 41dfc4f

File tree

5 files changed

+60
-0
lines changed

5 files changed

+60
-0
lines changed
 

‎compiler-rt/lib/ubsan/ubsan_checks.inc

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
UBSAN_CHECK(GenericUB, "undefined-behavior", "undefined")
2121
UBSAN_CHECK(NullPointerUse, "null-pointer-use", "null")
22+
UBSAN_CHECK(PointerOverflow, "pointer-overflow", "pointer-overflow")
2223
UBSAN_CHECK(MisalignedPointerUse, "misaligned-pointer-use", "alignment")
2324
UBSAN_CHECK(InsufficientObjectSize, "insufficient-object-size", "object-size")
2425
UBSAN_CHECK(SignedIntegerOverflow, "signed-integer-overflow",

‎compiler-rt/lib/ubsan/ubsan_handlers.cc

+31
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,37 @@ void __ubsan::__ubsan_handle_nullability_arg_abort(NonNullArgData *Data) {
554554
Die();
555555
}
556556

557+
static void handlePointerOverflowImpl(PointerOverflowData *Data,
558+
ValueHandle Base,
559+
ValueHandle Result,
560+
ReportOptions Opts) {
561+
SourceLocation Loc = Data->Loc.acquire();
562+
ErrorType ET = ErrorType::PointerOverflow;
563+
564+
if (ignoreReport(Loc, Opts, ET))
565+
return;
566+
567+
ScopedReport R(Opts, Loc, ET);
568+
569+
Diag(Loc, DL_Error, "pointer index expression with base %0 overflowed to %1")
570+
<< (void *)Base << (void*)Result;
571+
}
572+
573+
void __ubsan::__ubsan_handle_pointer_overflow(PointerOverflowData *Data,
574+
ValueHandle Base,
575+
ValueHandle Result) {
576+
GET_REPORT_OPTIONS(false);
577+
handlePointerOverflowImpl(Data, Base, Result, Opts);
578+
}
579+
580+
void __ubsan::__ubsan_handle_pointer_overflow_abort(PointerOverflowData *Data,
581+
ValueHandle Base,
582+
ValueHandle Result) {
583+
GET_REPORT_OPTIONS(true);
584+
handlePointerOverflowImpl(Data, Base, Result, Opts);
585+
Die();
586+
}
587+
557588
static void handleCFIBadIcall(CFICheckFailData *Data, ValueHandle Function,
558589
ReportOptions Opts) {
559590
if (Data->CheckKind != CFITCK_ICall)

‎compiler-rt/lib/ubsan/ubsan_handlers.h

+7
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,13 @@ struct NonNullArgData {
152152
RECOVERABLE(nonnull_arg, NonNullArgData *Data)
153153
RECOVERABLE(nullability_arg, NonNullArgData *Data)
154154

155+
struct PointerOverflowData {
156+
SourceLocation Loc;
157+
};
158+
159+
RECOVERABLE(pointer_overflow, PointerOverflowData *Data, ValueHandle Base,
160+
ValueHandle Result)
161+
155162
/// \brief Known CFI check kinds.
156163
/// Keep in sync with the enum of the same name in CodeGenFunction.h
157164
enum CFITypeCheckKind : unsigned char {

‎compiler-rt/lib/ubsan/ubsan_interface.inc

+2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ INTERFACE_FUNCTION(__ubsan_handle_nullability_return)
3636
INTERFACE_FUNCTION(__ubsan_handle_nullability_return_abort)
3737
INTERFACE_FUNCTION(__ubsan_handle_out_of_bounds)
3838
INTERFACE_FUNCTION(__ubsan_handle_out_of_bounds_abort)
39+
INTERFACE_FUNCTION(__ubsan_handle_pointer_overflow)
40+
INTERFACE_FUNCTION(__ubsan_handle_pointer_overflow_abort)
3941
INTERFACE_FUNCTION(__ubsan_handle_shift_out_of_bounds)
4042
INTERFACE_FUNCTION(__ubsan_handle_shift_out_of_bounds_abort)
4143
INTERFACE_FUNCTION(__ubsan_handle_sub_overflow)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %clangxx -fsanitize=pointer-overflow %s -o %t
2+
// RUN: %t 1 2>&1 | FileCheck %s --check-prefix=ERR
3+
// RUN: %t 0 2>&1 | FileCheck %s --check-prefix=SAFE
4+
// RUN: %t -1 2>&1 | FileCheck %s --check-prefix=SAFE
5+
6+
#include <stdio.h>
7+
#include <stdint.h>
8+
#include <stdlib.h>
9+
10+
int main(int argc, char *argv[]) {
11+
// SAFE-NOT: runtime error
12+
// ERR: runtime error: pointer index expression with base {{.*}} overflowed to
13+
14+
char *p = (char *)(UINTPTR_MAX);
15+
16+
printf("%p\n", p + atoi(argv[1]));
17+
18+
return 0;
19+
}

0 commit comments

Comments
 (0)
Please sign in to comment.