summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib
diff options
context:
space:
mode:
authorRoman Lebedev <lebedev.ri@gmail.com>2019-01-15 09:44:27 +0000
committerRoman Lebedev <lebedev.ri@gmail.com>2019-01-15 09:44:27 +0000
commita06ad18669f85b21df9ce9e4847c4b899692fb9b (patch)
treed2127fee7afa9d728cac2b5a8373b7ccb00200c0 /compiler-rt/lib
parentbd1c0870198e025f92d31eead0fb2019c4057a4a (diff)
downloadbcm5719-llvm-a06ad18669f85b21df9ce9e4847c4b899692fb9b.tar.gz
bcm5719-llvm-a06ad18669f85b21df9ce9e4847c4b899692fb9b.zip
[compiler-rt][UBSan] Sanitization for alignment assumptions.
Summary: This is the compiler-rt part. The clang part is D54589. This is a second commit, the original one was r351106, which was mass-reverted in r351159 because 2 compiler-rt tests were failing. Now, i have fundamentally changed the testing approach: i malloc a few bytes, intentionally mis-align the pointer (increment it by one), and check that. Also, i have decreased the expected alignment. This hopefully should be enough to pacify all the bots. If not, i guess i might just drop the two 'bad' tests. Reviewers: filcab, vsk, #sanitizers, vitalybuka, rsmith, morehouse Reviewed By: morehouse Subscribers: rjmccall, krytarowski, rsmith, kcc, srhines, kubamracek, dberris, llvm-commits Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D54590 llvm-svn: 351178
Diffstat (limited to 'compiler-rt/lib')
-rw-r--r--compiler-rt/lib/ubsan/ubsan_checks.inc1
-rw-r--r--compiler-rt/lib/ubsan/ubsan_handlers.cc56
-rw-r--r--compiler-rt/lib/ubsan/ubsan_handlers.h11
-rw-r--r--compiler-rt/lib/ubsan/ubsan_interface.inc2
-rw-r--r--compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cc1
5 files changed, 71 insertions, 0 deletions
diff --git a/compiler-rt/lib/ubsan/ubsan_checks.inc b/compiler-rt/lib/ubsan/ubsan_checks.inc
index e976ea4f6ab..ea82f89e129 100644
--- a/compiler-rt/lib/ubsan/ubsan_checks.inc
+++ b/compiler-rt/lib/ubsan/ubsan_checks.inc
@@ -21,6 +21,7 @@ UBSAN_CHECK(GenericUB, "undefined-behavior", "undefined")
UBSAN_CHECK(NullPointerUse, "null-pointer-use", "null")
UBSAN_CHECK(PointerOverflow, "pointer-overflow", "pointer-overflow")
UBSAN_CHECK(MisalignedPointerUse, "misaligned-pointer-use", "alignment")
+UBSAN_CHECK(AlignmentAssumption, "alignment-assumption", "alignment")
UBSAN_CHECK(InsufficientObjectSize, "insufficient-object-size", "object-size")
UBSAN_CHECK(SignedIntegerOverflow, "signed-integer-overflow",
"signed-integer-overflow")
diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.cc b/compiler-rt/lib/ubsan/ubsan_handlers.cc
index 53430a6076a..11e09b0ff0f 100644
--- a/compiler-rt/lib/ubsan/ubsan_handlers.cc
+++ b/compiler-rt/lib/ubsan/ubsan_handlers.cc
@@ -106,6 +106,62 @@ void __ubsan::__ubsan_handle_type_mismatch_v1_abort(TypeMismatchData *Data,
Die();
}
+static void handleAlignmentAssumptionImpl(AlignmentAssumptionData *Data,
+ ValueHandle Pointer,
+ ValueHandle Alignment,
+ ValueHandle Offset,
+ ReportOptions Opts) {
+ Location Loc = Data->Loc.acquire();
+ SourceLocation AssumptionLoc = Data->AssumptionLoc.acquire();
+
+ ErrorType ET = ErrorType::AlignmentAssumption;
+
+ if (ignoreReport(Loc.getSourceLocation(), Opts, ET))
+ return;
+
+ ScopedReport R(Opts, Loc, ET);
+
+ uptr RealPointer = Pointer - Offset;
+ uptr LSB = LeastSignificantSetBitIndex(RealPointer);
+ uptr ActualAlignment = uptr(1) << LSB;
+
+ uptr Mask = Alignment - 1;
+ uptr MisAlignmentOffset = RealPointer & Mask;
+
+ if (!Offset) {
+ Diag(Loc, DL_Error, ET,
+ "assumption of %0 byte alignment for pointer of type %1 failed")
+ << Alignment << Data->Type;
+ } else {
+ Diag(Loc, DL_Error, ET,
+ "assumption of %0 byte alignment (with offset of %1 byte) for pointer "
+ "of type %2 failed")
+ << Alignment << Offset << Data->Type;
+ }
+
+ if (!AssumptionLoc.isInvalid())
+ Diag(AssumptionLoc, DL_Note, ET, "alignment assumption was specified here");
+
+ Diag(RealPointer, DL_Note, ET,
+ "%0address is %1 aligned, misalignment offset is %2 bytes")
+ << (Offset ? "offset " : "") << ActualAlignment << MisAlignmentOffset;
+}
+
+void __ubsan::__ubsan_handle_alignment_assumption(AlignmentAssumptionData *Data,
+ ValueHandle Pointer,
+ ValueHandle Alignment,
+ ValueHandle Offset) {
+ GET_REPORT_OPTIONS(false);
+ handleAlignmentAssumptionImpl(Data, Pointer, Alignment, Offset, Opts);
+}
+void __ubsan::__ubsan_handle_alignment_assumption_abort(
+ AlignmentAssumptionData *Data, ValueHandle Pointer, ValueHandle Alignment,
+ ValueHandle Offset) {
+ GET_REPORT_OPTIONS(true);
+ handleAlignmentAssumptionImpl(Data, Pointer, Alignment, Offset, Opts);
+ Die();
+}
+
/// \brief Common diagnostic emission for various forms of integer overflow.
template <typename T>
static void handleIntegerOverflowImpl(OverflowData *Data, ValueHandle LHS,
diff --git a/compiler-rt/lib/ubsan/ubsan_handlers.h b/compiler-rt/lib/ubsan/ubsan_handlers.h
index 04405770e58..2bf9ff4320e 100644
--- a/compiler-rt/lib/ubsan/ubsan_handlers.h
+++ b/compiler-rt/lib/ubsan/ubsan_handlers.h
@@ -39,6 +39,17 @@ struct TypeMismatchData {
/// type.
RECOVERABLE(type_mismatch_v1, TypeMismatchData *Data, ValueHandle Pointer)
+struct AlignmentAssumptionData {
+ SourceLocation Loc;
+ SourceLocation AssumptionLoc;
+ const TypeDescriptor &Type;
+};
+
+/// \brief Handle a runtime alignment assumption check failure,
+/// caused by a misaligned pointer.
+RECOVERABLE(alignment_assumption, AlignmentAssumptionData *Data,
+ ValueHandle Pointer, ValueHandle Alignment, ValueHandle Offset)
+
struct OverflowData {
SourceLocation Loc;
const TypeDescriptor &Type;
diff --git a/compiler-rt/lib/ubsan/ubsan_interface.inc b/compiler-rt/lib/ubsan/ubsan_interface.inc
index 0be6010ad27..81e06345dcf 100644
--- a/compiler-rt/lib/ubsan/ubsan_interface.inc
+++ b/compiler-rt/lib/ubsan/ubsan_interface.inc
@@ -10,6 +10,8 @@
//===----------------------------------------------------------------------===//
INTERFACE_FUNCTION(__ubsan_handle_add_overflow)
INTERFACE_FUNCTION(__ubsan_handle_add_overflow_abort)
+INTERFACE_FUNCTION(__ubsan_handle_alignment_assumption)
+INTERFACE_FUNCTION(__ubsan_handle_alignment_assumption_abort)
INTERFACE_FUNCTION(__ubsan_handle_builtin_unreachable)
INTERFACE_FUNCTION(__ubsan_handle_cfi_bad_type)
INTERFACE_FUNCTION(__ubsan_handle_cfi_check_fail)
diff --git a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cc b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cc
index e8fc3a8499b..ed62ddd0fa3 100644
--- a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cc
+++ b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cc
@@ -95,6 +95,7 @@ void NORETURN CheckFailed(const char *file, int, const char *cond, u64, u64) {
HANDLER_NORECOVER(name, msg)
HANDLER(type_mismatch, "type-mismatch")
+HANDLER(alignment_assumption, "alignment-assumption")
HANDLER(add_overflow, "add-overflow")
HANDLER(sub_overflow, "sub-overflow")
HANDLER(mul_overflow, "mul-overflow")
OpenPOWER on IntegriCloud