2015-08-25 07:18:49 +08:00
|
|
|
//===-- ubsan_checks.inc ----------------------------------------*- C++ -*-===//
|
|
|
|
//
|
2019-01-19 16:50:56 +08:00
|
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
2015-08-25 07:18:49 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// List of checks handled by UBSan runtime.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef UBSAN_CHECK
|
|
|
|
# error "Define UBSAN_CHECK prior to including this file!"
|
|
|
|
#endif
|
|
|
|
|
2015-12-09 07:29:36 +08:00
|
|
|
// UBSAN_CHECK(Name, SummaryKind, FSanitizeFlagName)
|
|
|
|
// SummaryKind and FSanitizeFlagName should be string literals.
|
2015-08-25 07:18:49 +08:00
|
|
|
|
2015-12-09 07:29:36 +08:00
|
|
|
UBSAN_CHECK(GenericUB, "undefined-behavior", "undefined")
|
|
|
|
UBSAN_CHECK(NullPointerUse, "null-pointer-use", "null")
|
2020-02-29 06:09:14 +08:00
|
|
|
UBSAN_CHECK(NullPointerUseWithNullability, "null-pointer-use",
|
|
|
|
"nullability-assign")
|
[UBSan][clang][compiler-rt] Applying non-zero offset to nullptr is undefined behaviour
Summary:
Quote from http://eel.is/c++draft/expr.add#4:
```
4 When an expression J that has integral type is added to or subtracted
from an expression P of pointer type, the result has the type of P.
(4.1) If P evaluates to a null pointer value and J evaluates to 0,
the result is a null pointer value.
(4.2) Otherwise, if P points to an array element i of an array object x with n
elements ([dcl.array]), the expressions P + J and J + P
(where J has the value j) point to the (possibly-hypothetical) array
element i+j of x if 0≤i+j≤n and the expression P - J points to the
(possibly-hypothetical) array element i−j of x if 0≤i−j≤n.
(4.3) Otherwise, the behavior is undefined.
```
Therefore, as per the standard, applying non-zero offset to `nullptr`
(or making non-`nullptr` a `nullptr`, by subtracting pointer's integral value
from the pointer itself) is undefined behavior. (*if* `nullptr` is not defined,
i.e. e.g. `-fno-delete-null-pointer-checks` was *not* specified.)
To make things more fun, in C (6.5.6p8), applying *any* offset to null pointer
is undefined, although Clang front-end pessimizes the code by not lowering
that info, so this UB is "harmless".
Since rL369789 (D66608 `[InstCombine] icmp eq/ne (gep inbounds P, Idx..), null -> icmp eq/ne P, null`)
LLVM middle-end uses those guarantees for transformations.
If the source contains such UB's, said code may now be miscompiled.
Such miscompilations were already observed:
* https://lists.llvm.org/pipermail/llvm-commits/Week-of-Mon-20190826/687838.html
* https://github.com/google/filament/pull/1566
Surprisingly, UBSan does not catch those issues
... until now. This diff teaches UBSan about these UB's.
`getelementpointer inbounds` is a pretty frequent instruction,
so this does have a measurable impact on performance;
I've addressed most of the obvious missing folds (and thus decreased the performance impact by ~5%),
and then re-performed some performance measurements using my [[ https://github.com/darktable-org/rawspeed | RawSpeed ]] benchmark:
(all measurements done with LLVM ToT, the sanitizer never fired.)
* no sanitization vs. existing check: average `+21.62%` slowdown
* existing check vs. check after this patch: average `22.04%` slowdown
* no sanitization vs. this patch: average `48.42%` slowdown
Reviewers: vsk, filcab, rsmith, aaron.ballman, vitalybuka, rjmccall, #sanitizers
Reviewed By: rsmith
Subscribers: kristof.beyls, nickdesaulniers, nikic, ychen, dtzWill, xbolva00, dberris, arphaman, rupprecht, reames, regehr, llvm-commits, cfe-commits
Tags: #clang, #sanitizers, #llvm
Differential Revision: https://reviews.llvm.org/D67122
llvm-svn: 374293
2019-10-10 17:25:02 +08:00
|
|
|
UBSAN_CHECK(NullptrWithOffset, "nullptr-with-offset", "pointer-overflow")
|
2019-10-10 19:32:06 +08:00
|
|
|
UBSAN_CHECK(NullptrWithNonZeroOffset, "nullptr-with-nonzero-offset",
|
|
|
|
"pointer-overflow")
|
|
|
|
UBSAN_CHECK(NullptrAfterNonZeroOffset, "nullptr-after-nonzero-offset",
|
|
|
|
"pointer-overflow")
|
2017-06-02 03:40:59 +08:00
|
|
|
UBSAN_CHECK(PointerOverflow, "pointer-overflow", "pointer-overflow")
|
2015-12-09 07:29:36 +08:00
|
|
|
UBSAN_CHECK(MisalignedPointerUse, "misaligned-pointer-use", "alignment")
|
[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
2019-01-15 17:44:27 +08:00
|
|
|
UBSAN_CHECK(AlignmentAssumption, "alignment-assumption", "alignment")
|
2015-12-09 07:29:36 +08:00
|
|
|
UBSAN_CHECK(InsufficientObjectSize, "insufficient-object-size", "object-size")
|
2015-08-25 07:18:49 +08:00
|
|
|
UBSAN_CHECK(SignedIntegerOverflow, "signed-integer-overflow",
|
2015-12-09 07:29:36 +08:00
|
|
|
"signed-integer-overflow")
|
2015-08-25 07:18:49 +08:00
|
|
|
UBSAN_CHECK(UnsignedIntegerOverflow, "unsigned-integer-overflow",
|
2015-12-09 07:29:36 +08:00
|
|
|
"unsigned-integer-overflow")
|
2015-08-25 07:18:49 +08:00
|
|
|
UBSAN_CHECK(IntegerDivideByZero, "integer-divide-by-zero",
|
2015-12-09 07:29:36 +08:00
|
|
|
"integer-divide-by-zero")
|
|
|
|
UBSAN_CHECK(FloatDivideByZero, "float-divide-by-zero", "float-divide-by-zero")
|
2017-07-29 08:20:02 +08:00
|
|
|
UBSAN_CHECK(InvalidBuiltin, "invalid-builtin-use", "invalid-builtin-use")
|
2019-12-14 04:59:40 +08:00
|
|
|
UBSAN_CHECK(InvalidObjCCast, "invalid-objc-cast", "invalid-objc-cast")
|
2018-10-11 17:09:52 +08:00
|
|
|
UBSAN_CHECK(ImplicitUnsignedIntegerTruncation,
|
|
|
|
"implicit-unsigned-integer-truncation",
|
|
|
|
"implicit-unsigned-integer-truncation")
|
|
|
|
UBSAN_CHECK(ImplicitSignedIntegerTruncation,
|
|
|
|
"implicit-signed-integer-truncation",
|
|
|
|
"implicit-signed-integer-truncation")
|
[compiler-rt][ubsan] Implicit Conversion Sanitizer - integer sign change - compiler-rt part
Summary:
This is a compiler-rt part.
The clang part is D50250.
See [[ https://bugs.llvm.org/show_bug.cgi?id=21530 | PR21530 ]], https://github.com/google/sanitizers/issues/940.
Reviewers: vsk, filcab, #sanitizers
Reviewed By: filcab, #sanitizers
Subscribers: mclow.lists, srhines, kubamracek, dberris, rjmccall, rsmith, llvm-commits, regehr
Tags: #sanitizers
Differential Revision: https://reviews.llvm.org/D50251
llvm-svn: 345659
2018-10-31 05:58:54 +08:00
|
|
|
UBSAN_CHECK(ImplicitIntegerSignChange,
|
|
|
|
"implicit-integer-sign-change",
|
|
|
|
"implicit-integer-sign-change")
|
|
|
|
UBSAN_CHECK(ImplicitSignedIntegerTruncationOrSignChange,
|
|
|
|
"implicit-signed-integer-truncation-or-sign-change",
|
|
|
|
"implicit-signed-integer-truncation,implicit-integer-sign-change")
|
2015-12-09 07:29:36 +08:00
|
|
|
UBSAN_CHECK(InvalidShiftBase, "invalid-shift-base", "shift-base")
|
|
|
|
UBSAN_CHECK(InvalidShiftExponent, "invalid-shift-exponent", "shift-exponent")
|
|
|
|
UBSAN_CHECK(OutOfBoundsIndex, "out-of-bounds-index", "bounds")
|
|
|
|
UBSAN_CHECK(UnreachableCall, "unreachable-call", "unreachable")
|
|
|
|
UBSAN_CHECK(MissingReturn, "missing-return", "return")
|
|
|
|
UBSAN_CHECK(NonPositiveVLAIndex, "non-positive-vla-index", "vla-bound")
|
|
|
|
UBSAN_CHECK(FloatCastOverflow, "float-cast-overflow", "float-cast-overflow")
|
|
|
|
UBSAN_CHECK(InvalidBoolLoad, "invalid-bool-load", "bool")
|
|
|
|
UBSAN_CHECK(InvalidEnumLoad, "invalid-enum-load", "enum")
|
|
|
|
UBSAN_CHECK(FunctionTypeMismatch, "function-type-mismatch", "function")
|
2015-08-25 07:18:49 +08:00
|
|
|
UBSAN_CHECK(InvalidNullReturn, "invalid-null-return",
|
2015-12-09 07:29:36 +08:00
|
|
|
"returns-nonnull-attribute")
|
2020-02-29 06:09:14 +08:00
|
|
|
UBSAN_CHECK(InvalidNullReturnWithNullability, "invalid-null-return",
|
|
|
|
"nullability-return")
|
2015-12-09 07:29:36 +08:00
|
|
|
UBSAN_CHECK(InvalidNullArgument, "invalid-null-argument", "nonnull-attribute")
|
2020-02-29 06:09:14 +08:00
|
|
|
UBSAN_CHECK(InvalidNullArgumentWithNullability, "invalid-null-argument",
|
|
|
|
"nullability-arg")
|
2015-12-09 07:29:36 +08:00
|
|
|
UBSAN_CHECK(DynamicTypeMismatch, "dynamic-type-mismatch", "vptr")
|
|
|
|
UBSAN_CHECK(CFIBadType, "cfi-bad-type", "cfi")
|