llvm.org GIT mirror llvm / d12f22c
[asan] Add options -asan-detect-invalid-pointer-cmp and -asan-detect-invalid-pointer-sub options. This is in preparation to a driver patch to add gcc 8's -fsanitize=pointer-compare and -fsanitize=pointer-subtract. Disabled by default as this is still an experimental feature. Reviewed By: morehouse, vitalybuka Differential Revision: https://reviews.llvm.org/D59220 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@357157 91177308-0d34-0410-b5e6-96231b3b80d8 Pierre Gousseau 6 months ago
2 changed file(s) with 64 addition(s) and 6 deletion(s). Raw diff Collapse all Expand all
274274 cl::desc("Instrument <, <=, >, >=, - with pointer operands"), cl::Hidden,
275275 cl::init(false));
276276
277 static cl::opt ClInvalidPointerCmp(
278 "asan-detect-invalid-pointer-cmp",
279 cl::desc("Instrument <, <=, >, >= with pointer operands"), cl::Hidden,
280 cl::init(false));
281
282 static cl::opt ClInvalidPointerSub(
283 "asan-detect-invalid-pointer-sub",
284 cl::desc("Instrument - operations with pointer operands"), cl::Hidden,
285 cl::init(false));
286
277287 static cl::opt ClRealignStack(
278288 "asan-realign-stack",
279289 cl::desc("Realign stack to the value of this flag (power of two)"),
14071417 // This is a rough heuristic; it may cause both false positives and
14081418 // false negatives. The proper implementation requires cooperation with
14091419 // the frontend.
1410 static bool isInterestingPointerComparisonOrSubtraction(Instruction *I) {
1420 static bool isInterestingPointerComparison(Instruction *I) {
14111421 if (ICmpInst *Cmp = dyn_cast(I)) {
1412 if (!Cmp->isRelational()) return false;
1413 } else if (BinaryOperator *BO = dyn_cast(I)) {
1414 if (BO->getOpcode() != Instruction::Sub) return false;
1422 if (!Cmp->isRelational())
1423 return false;
1424 } else {
1425 return false;
1426 }
1427 return isPointerOperand(I->getOperand(0)) &&
1428 isPointerOperand(I->getOperand(1));
1429 }
1430
1431 // This is a rough heuristic; it may cause both false positives and
1432 // false negatives. The proper implementation requires cooperation with
1433 // the frontend.
1434 static bool isInterestingPointerSubtraction(Instruction *I) {
1435 if (BinaryOperator *BO = dyn_cast(I)) {
1436 if (BO->getOpcode() != Instruction::Sub)
1437 return false;
14151438 } else {
14161439 return false;
14171440 }
26182641 continue; // We've seen this temp in the current BB.
26192642 }
26202643 }
2621 } else if (ClInvalidPointerPairs &&
2622 isInterestingPointerComparisonOrSubtraction(&Inst)) {
2644 } else if (((ClInvalidPointerPairs || ClInvalidPointerCmp) &&
2645 isInterestingPointerComparison(&Inst)) ||
2646 ((ClInvalidPointerPairs || ClInvalidPointerSub) &&
2647 isInterestingPointerSubtraction(&Inst))) {
26232648 PointerComparisonsOrSubtracts.push_back(&Inst);
26242649 continue;
26252650 } else if (isa(Inst)) {
0 ; RUN: opt < %s -asan -asan-detect-invalid-pointer-cmp -S \
1 ; RUN: | FileCheck %s --check-prefixes=CMP,NOSUB,ALL
2 ; RUN: opt < %s -asan -asan-detect-invalid-pointer-sub -S \
3 ; RUN: | FileCheck %s --check-prefixes=SUB,NOCMP,ALL
4 ; RUN: opt < %s -asan -asan-detect-invalid-pointer-pair -S \
5 ; RUN: | FileCheck %s --check-prefixes=CMP,SUB,ALL
6 ; Support instrumentation of invalid pointer pair detection.
7
8 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
9
10 define i32 @mycmp(i8* %p, i8* %q) sanitize_address {
11 ; ALL-LABEL: @mycmp
12 ; NOCMP-NOT: call void @__sanitizer_ptr_cmp
13 ; CMP: [[P:%[0-9A-Za-z]+]] = ptrtoint i8* %p to i64
14 ; CMP: [[Q:%[0-9A-Za-z]+]] = ptrtoint i8* %q to i64
15 %x = icmp ule i8* %p, %q
16 ; CMP: call void @__sanitizer_ptr_cmp(i64 [[P]], i64 [[Q]])
17 %y = zext i1 %x to i32
18 ret i32 %y
19 }
20
21 define i32 @mysub(i8* %p, i8* %q) sanitize_address {
22 ; ALL-LABEL: @mysub
23 ; NOSUB-NOT: call void @__sanitizer_ptr_sub
24 ; SUB: [[P:%[0-9A-Za-z]+]] = ptrtoint i8* %p to i64
25 ; SUB: [[Q:%[0-9A-Za-z]+]] = ptrtoint i8* %q to i64
26 %x = ptrtoint i8* %p to i64
27 %y = ptrtoint i8* %q to i64
28 %z = sub i64 %x, %y
29 ; SUB: call void @__sanitizer_ptr_sub(i64 [[P]], i64 [[Q]])
30 %w = trunc i64 %z to i32
31 ret i32 %w
32 }