diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2019-01-14 19:09:29 +0000 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2019-01-14 19:09:29 +0000 |
commit | 07d40687af305eb476302753ff858e49c9902b95 (patch) | |
tree | 840eaace776eed70303b6d45b647ba4f7f150604 | |
parent | 02e6c67dee5d39681622fd2c40b827957d550fc3 (diff) | |
download | compiler-rt-07d40687af305eb476302753ff858e49c9902b95.tar.gz |
[compiler-rt][UBSan] Sanitization for alignment assumptions.
Summary:
This is the compiler-rt part.
The clang part is D54589.
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
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@351106 91177308-0d34-0410-b5e6-96231b3b80d8
19 files changed, 366 insertions, 0 deletions
diff --git a/lib/ubsan/ubsan_checks.inc b/lib/ubsan/ubsan_checks.inc index e976ea4f6..ea82f89e1 100644 --- a/lib/ubsan/ubsan_checks.inc +++ b/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/lib/ubsan/ubsan_handlers.cc b/lib/ubsan/ubsan_handlers.cc index 53430a607..11e09b0ff 100644 --- a/lib/ubsan/ubsan_handlers.cc +++ b/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/lib/ubsan/ubsan_handlers.h b/lib/ubsan/ubsan_handlers.h index 04405770e..2bf9ff432 100644 --- a/lib/ubsan/ubsan_handlers.h +++ b/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/lib/ubsan_minimal/ubsan_minimal_handlers.cc b/lib/ubsan_minimal/ubsan_minimal_handlers.cc index e8fc3a849..ed62ddd0f 100644 --- a/lib/ubsan_minimal/ubsan_minimal_handlers.cc +++ b/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") diff --git a/test/fuzzer/AlignmentAssumptionTest.cpp b/test/fuzzer/AlignmentAssumptionTest.cpp new file mode 100644 index 000000000..c100928fe --- /dev/null +++ b/test/fuzzer/AlignmentAssumptionTest.cpp @@ -0,0 +1,27 @@ +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. + +// Test for alignment assumption failure. + +#include <assert.h> +#include <climits> +#include <cstddef> +#include <cstdint> +#include <cstdlib> +#include <iostream> + +static volatile int32_t Sink; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + assert(Data); + if (Size > 0 && Data[0] == 'H') { + Sink = 1; + if (Size > 1 && Data[1] == 'i') { + Sink = 2; + if (Size > 2 && Data[2] == '!') { + __builtin_assume_aligned(Data, 0x80000000); + } + } + } + return 0; +} diff --git a/test/fuzzer/fuzzer-alignment-assumption.test b/test/fuzzer/fuzzer-alignment-assumption.test new file mode 100644 index 000000000..8b39e22d4 --- /dev/null +++ b/test/fuzzer/fuzzer-alignment-assumption.test @@ -0,0 +1,7 @@ +RUN: rm -f %t-AlignmentAssumptionTest-Ubsan +RUN: %cpp_compiler -fsanitize=alignment -fno-sanitize-recover=all %S/AlignmentAssumptionTest.cpp -o %t-AlignmentAssumptionTest-Ubsan +RUN: not %run %t-AlignmentAssumptionTest-Ubsan 2>&1 | FileCheck %s +CHECK: AlignmentAssumptionTest.cpp:22:34: runtime error: assumption of 2147483648 byte alignment for pointer of type 'const {{.*}} *' (aka 'const unsigned char *') failed +CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + +CHECK: Test unit written to ./crash- diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-lvalue.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-lvalue.cpp new file mode 100644 index 000000000..8230edd1f --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-lvalue.cpp @@ -0,0 +1,30 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +typedef char ** __attribute__((align_value(0x80000000))) aligned_char; + +struct ac_struct { + aligned_char a; +}; + +char **load_from_ac_struct(struct ac_struct* x) { + return x->a; +} + +int main(int argc, char* argv[]) { + struct ac_struct x; + x.a = argv; // FIXME: it is weird that this does not also have an assumption. + load_from_ac_struct(&x); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-7]]:13: runtime error: assumption of 2147483648 byte alignment for pointer of type 'aligned_char' (aka 'char **') failed + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-15]]:32: note: alignment assumption was specified here + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-paramvar.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-paramvar.cpp new file mode 100644 index 000000000..cfa83b1b7 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-paramvar.cpp @@ -0,0 +1,24 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +char** passthrough(__attribute__((align_value(0x80000000))) char **x) { + return x; +} + +int main(int argc, char* argv[]) { + passthrough(argv); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-5]]:10: runtime error: assumption of 2147483648 byte alignment for pointer of type 'char **' failed + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-7]]:35: note: alignment assumption was specified here + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + // FIXME: shouldn't there be an assumption on the caller's side too? + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function-variable.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function-variable.cpp new file mode 100644 index 000000000..008531512 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function-variable.cpp @@ -0,0 +1,27 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +char **__attribute__((alloc_align(2))) +passthrough(char **x, unsigned long alignment) { + return x; +} + +unsigned long alignment; + +int main(int argc, char* argv[]) { + alignment = 0x80000000; + + passthrough(argv, alignment); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:3: runtime error: assumption of 2147483648 byte alignment for pointer of type 'char **' failed + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-12]]:23: note: alignment assumption was specified here + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function.cpp new file mode 100644 index 000000000..ddf79c287 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function.cpp @@ -0,0 +1,23 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +char **__attribute__((alloc_align(2))) +passthrough(char **x, unsigned long alignment) { + return x; +} + +int main(int argc, char* argv[]) { + passthrough(argv, 0x80000000); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:3: runtime error: assumption of 2147483648 byte alignment for pointer of type 'char **' failed + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-8]]:23: note: alignment assumption was specified here + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp new file mode 100644 index 000000000..e89c0bf5f --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp @@ -0,0 +1,22 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +char ** __attribute__((assume_aligned(0x80000000, 42))) passthrough(char** x) { + return x; +} + +int main(int argc, char* argv[]) { + passthrough(argv); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:3: runtime error: assumption of 2147483648 byte alignment (with offset of 42 byte) for pointer of type 'char **' failed + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-7]]:24: note: alignment assumption was specified here + // CHECK: 0x{{.*}}: note: offset address is {{.*}} aligned, misalignment offset is {{.*}} byte + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function.cpp new file mode 100644 index 000000000..e856b166d --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function.cpp @@ -0,0 +1,22 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +char ** __attribute__((assume_aligned(0x80000000))) passthrough(char** x) { + return x; +} + +int main(int argc, char* argv[]) { + passthrough(argv); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:3: runtime error: assumption of 2147483648 byte alignment for pointer of type 'char **' failed + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-7]]:24: note: alignment assumption was specified here + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-blacklist.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-blacklist.cpp new file mode 100644 index 000000000..c220f0b5b --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-blacklist.cpp @@ -0,0 +1,19 @@ +// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316 +// I'm not sure this is actually *that* issue, but this seems oddly similar to the other XFAIL'ed cases. +// XFAIL: android +// UNSUPPORTED: ios + +// RUN: %clang -fsanitize=alignment -fno-sanitize-recover=alignment -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " + +// RUN: rm -f %tmp +// RUN: echo "[alignment]" >> %tmp +// RUN: echo "fun:main" >> %tmp +// RUN: %clang -fsanitize=alignment -fno-sanitize-recover=alignment -fsanitize-blacklist=%tmp -O0 %s -o %t && %run %t 2>&1 + +int main(int argc, char* argv[]) { + __builtin_assume_aligned(argv, 0x80000000); + // CHECK: {{.*}}alignment-assumption-blacklist.cpp:[[@LINE-1]]:28: runtime error: assumption of 2147483648 byte alignment for pointer of type 'char **' failed + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params-variable.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params-variable.cpp new file mode 100644 index 000000000..8a2bc8906 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params-variable.cpp @@ -0,0 +1,21 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +volatile long offset; + +int main(int argc, char* argv[]) { + offset = 42; + + __builtin_assume_aligned(argv, 0x80000000, offset); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:28: runtime error: assumption of 2147483648 byte alignment (with offset of 42 byte) for pointer of type 'char **' failed + // CHECK: 0x{{.*}}: note: offset address is {{.*}} aligned, misalignment offset is {{.*}} byte + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params.cpp new file mode 100644 index 000000000..0134ca919 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params.cpp @@ -0,0 +1,17 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +int main(int argc, char* argv[]) { + __builtin_assume_aligned(argv, 0x80000000, 42); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:28: runtime error: assumption of 2147483648 byte alignment (with offset of 42 byte) for pointer of type 'char **' failed + // CHECK: 0x{{.*}}: note: offset address is {{.*}} aligned, misalignment offset is {{.*}} byte + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-two-params.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-two-params.cpp new file mode 100644 index 000000000..59557cdb9 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-two-params.cpp @@ -0,0 +1,17 @@ +// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +int main(int argc, char* argv[]) { + __builtin_assume_aligned(argv, 0x80000000); + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:28: runtime error: assumption of 2147483648 byte alignment for pointer of type 'char **' failed + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-openmp.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-openmp.cpp new file mode 100644 index 000000000..ee7053dc8 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-openmp.cpp @@ -0,0 +1,19 @@ +// RUN: %clang -x c -fsanitize=alignment -fopenmp-simd -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -fopenmp-simd -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -fopenmp-simd -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c -fsanitize=alignment -fopenmp-simd -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +// RUN: %clang -x c++ -fsanitize=alignment -fopenmp-simd -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -fopenmp-simd -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -fopenmp-simd -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" +// RUN: %clang -x c++ -fsanitize=alignment -fopenmp-simd -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:" + +int main(int argc, char* argv[]) { +#pragma omp for simd aligned(argv : 0x40000000) + for(int x = 0; x < 1; x++) + argv[x] = argv[x]; + // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-3]]:30: runtime error: assumption of 1073741824 byte alignment for pointer of type 'char **' failed + // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte + + return 0; +} diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-summary.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-summary.cpp new file mode 100644 index 000000000..90ecd4d84 --- /dev/null +++ b/test/ubsan/TestCases/Pointer/alignment-assumption-summary.cpp @@ -0,0 +1,11 @@ +// RUN: %clangxx -fsanitize=alignment %s -o %t +// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOTYPE +// RUN: %env_ubsan_opts=report_error_type=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TYPE +// REQUIRES: !ubsan-standalone && !ubsan-standalone-static + +int main(int argc, char* argv[]) { + __builtin_assume_aligned(argv, 0x80000000); + // CHECK-NOTYPE: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior {{.*}}summary.cpp:[[@LINE-1]]:28 + // CHECK-TYPE: SUMMARY: UndefinedBehaviorSanitizer: alignment-assumption {{.*}}summary.cpp:[[@LINE-2]]:28 + return 0; +} diff --git a/test/ubsan_minimal/TestCases/alignment-assumption.c b/test/ubsan_minimal/TestCases/alignment-assumption.c new file mode 100644 index 000000000..ea088080a --- /dev/null +++ b/test/ubsan_minimal/TestCases/alignment-assumption.c @@ -0,0 +1,11 @@ +// RUN: %clang -fsanitize=alignment %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK + +int main(int argc, char* argv[]) { +// CHECK-NOT: alignment-assumption + + __builtin_assume_aligned(argv, 0x80000000); +// CHECK: alignment-assumption +// CHECK-NOT: alignment-assumption + + return 0; +} |