[PATCH] D40940: [ubsan] Use pass_object_size info in bounds checks
Vedant Kumar via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Dec 6 19:45:26 PST 2017
vsk created this revision.
Herald added a reviewer: george.burgess.iv.
Teach UBSan's bounds check to opportunistically use pass_object_size
information to check array accesses.
rdar://33272922
https://reviews.llvm.org/D40940
Files:
lib/CodeGen/CGExpr.cpp
lib/CodeGen/CodeGenFunction.h
test/CodeGen/ubsan-pass-object-size.c
Index: test/CodeGen/ubsan-pass-object-size.c
===================================================================
--- /dev/null
+++ test/CodeGen/ubsan-pass-object-size.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-apple-darwin10 -fsanitize=array-bounds -o - | FileCheck %s
+
+// CHECK-LABEL: define i32 @foo(
+int foo(int *const p __attribute__((pass_object_size(0))), int n) {
+ int x = p[n];
+
+ // CHECK: [[SIZE_ALLOCA:%.*]] = alloca i64, align 8
+ // CHECK: store i64 %{{.*}}, i64* [[SIZE_ALLOCA]], align 8
+ // CHECK: [[LOAD_SIZE:%.*]] = load i64, i64* [[SIZE_ALLOCA]], align 8, !nosanitize
+ // CHECK-NEXT: [[SCALED_SIZE:%.*]] = udiv i64 [[LOAD_SIZE]], 4, !nosanitize
+ // CHECK-NEXT: [[SEXT_N:%.*]] = sext i32 %{{.*}} to i64, !nosanitize
+ // CHECK-NEXT: [[ICMP:%.*]] = icmp ult i64 [[SEXT_N]], [[SCALED_SIZE]], !nosanitize
+ // CHECK-NEXT: br i1 [[ICMP]], {{.*}} !nosanitize
+ // CHECK: __ubsan_handle_out_of_bounds
+
+ {
+ int *p = &n; // Shadow the parameter.
+ // CHECK-NOT: __ubsan_handle_out_of_bounds
+ x = p[n];
+ }
+
+ // CHECK: ret i32
+ return x;
+}
Index: lib/CodeGen/CodeGenFunction.h
===================================================================
--- lib/CodeGen/CodeGenFunction.h
+++ lib/CodeGen/CodeGenFunction.h
@@ -3932,6 +3932,10 @@
LValueBaseInfo *BaseInfo = nullptr,
TBAAAccessInfo *TBAAInfo = nullptr);
+ /// If \p E references a parameter with pass_object_size info, load the
+ /// object size and divide by the size of \p EltTy. Otherwise return null.
+ llvm::Value *LoadPassedObjectSize(const Expr *E, QualType EltTy);
+
void EmitSanitizerStatReport(llvm::SanitizerStatKind SSK);
private:
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -814,6 +814,32 @@
return false;
}
+llvm::Value *CodeGenFunction::LoadPassedObjectSize(const Expr *E,
+ QualType EltTy) {
+ auto *DRE = dyn_cast<DeclRefExpr>(E->IgnoreImpCasts());
+ if (!DRE)
+ return nullptr;
+
+ auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl());
+ if (!PVD)
+ return nullptr;
+
+ // Find the implicit size parameter.
+ auto SizeDeclIt = SizeArguments.find(PVD);
+ if (SizeDeclIt == SizeArguments.end())
+ return nullptr;
+
+ ASTContext &C = getContext();
+ const ImplicitParamDecl *IPD = SizeDeclIt->second;
+ assert(LocalDeclMap.count(IPD) && "Passed object size not loadable");
+ Address AddrOfSize = LocalDeclMap.find(IPD)->second;
+ llvm::Value *SizeInBytes = EmitLoadOfScalar(AddrOfSize, /*Volatile=*/false,
+ C.getSizeType(), E->getExprLoc());
+ llvm::Value *SizeOfElement = llvm::ConstantInt::get(
+ SizeInBytes->getType(), C.getTypeSizeInChars(EltTy).getQuantity());
+ return Builder.CreateUDiv(SizeInBytes, SizeOfElement);
+}
+
/// If Base is known to point to the start of an array, return the length of
/// that array. Return 0 if the length cannot be determined.
static llvm::Value *getArrayIndexingBound(
@@ -835,9 +861,16 @@
return CGF.Builder.getInt(CAT->getSize());
else if (const auto *VAT = dyn_cast<VariableArrayType>(AT))
return CGF.getVLASize(VAT).first;
+ // Ignore pass_object_size here. It's not applicable on decayed pointers.
}
}
+ QualType EltTy{Base->getType()->getPointeeOrArrayElementType(), 0};
+ if (llvm::Value *POS = CGF.LoadPassedObjectSize(Base, EltTy)) {
+ IndexedType = Base->getType();
+ return POS;
+ }
+
return nullptr;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D40940.125880.patch
Type: text/x-patch
Size: 3675 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20171207/a1689f4a/attachment.bin>
More information about the cfe-commits
mailing list