370 Commits

Author SHA1 Message Date
Florian Mayer
3f6c0e62d5
[clang][KCFI] Respect -fsanitize-cfi-icall-generalize-pointers (#152400)
This flag was previously ignored by KCFI.
2025-08-11 17:21:13 -07:00
Anthony Tran
29992cfd62
[Clang][CodeGen] Emit “trap reasons” on UBSan traps (#145967)
This patch adds a human readable trap category and message to UBSan
traps. The category and message are encoded in a fake frame in the debug
info where the function is a fake inline function where the name encodes
the trap category and message. This is the same mechanism used by
Clang’s `__builtin_verbose_trap()`.

This change allows consumers of binaries built with trapping UBSan to
more easily identify the reason for trapping. In particular LLDB already
has a frame recognizer that recognizes the fake function names emitted
in debug info by this patch. A patch testing this behavior in LLDB will
be added in a separately.

The human readable trap messages are based on the messages currently
emitted by the userspace runtime for UBSan in compiler-rt. Note the
wording is not identical because the userspace UBSan runtime has access
to dynamic information that is not available during Clang’s codegen.

Test cases for each UBSan trap kind are included.

This complements the [`-fsanitize-annotate-debug-info`
feature](https://github.com/llvm/llvm-project/pull/141997). While
`-fsanitize-annotate-debug-info` attempts to annotate all UBSan-added
instructions, this feature (`-fsanitize-debug-trap-reasons`) only
annotates the final trap instruction using SanitizerHandler information.

This work is part of a GSoc 2025 project.
2025-07-26 08:50:25 -07:00
Aaron Ballman
479ae4aa8f
Revert "fix: replace report_fatal_error with Diags and exit" (#150662)
Reverts llvm/llvm-project#147959
2025-07-25 13:24:00 -04:00
woruyu
9d3dd8efe0
fix: replace report_fatal_error with Diags and exit (#147959)
report_fatal_error is not a good way to report diagnostics to the users, so this switches to using actual diagnostic reporting mechanisms instead.

Fixes #147187
2025-07-25 10:20:30 -04:00
Dmitry Chestnykh
593fd44a9d
[clang] Don't pass sanitizers' rtlibs to linker with -r (#147905)
If clang is invoked with `-r` (relocatable linking) then we shouldn't
construct sanitizer arguments and then pass sanitizer runtime libs to
the linker
GCC also skips runtime linking if `-r` is also here
2025-07-12 09:44:14 +03:00
Florian Mayer
b413bea435
[NFC] [sanitizer] get rid of references to fsanitize-top-hot (#145810)
That flag does not exist.
2025-06-25 16:42:35 -07:00
Sinkevich Artem
1acac5cd38
[sanitizer] Fix empty string in unsupported argument error for -fsanitize-trap (#136549)
When using `-fsanitize-trap` with a sanitizer group that doesn't support
trapping, an empty argument is passed to
`err_drv_unsupported_option_argument`. Use new `toStringWithGroups` for
the diagnostic.
2025-05-15 11:12:42 -07:00
Kazu Hirata
f5f8ddc166
[clang] Remove redundant calls to std::unique_ptr<T>::get (NFC) (#139399) 2025-05-10 12:11:17 -07:00
Thurston Dang
6a28d8c24a
[sanitizer] Add plumbing for -fsanitize-annotate-debug-info and partly replace '-mllvm -array-bounds-pseudofn' (#138577)
@fmayer introduced '-mllvm -array-bounds-pseudofn'
(https://github.com/llvm/llvm-project/pull/128977/) to make it easier to
see why crashes occurred, and to estimate with a profiler the cycles
spent on these array-bounds checks. This functionality could be usefully
generalized to other checks in future work.

This patch adds the plumbing for -fsanitize-annotate-debug-info, and
connects it to the existing array-bounds-pseudo-fn functionality i.e.,
-fsanitize-annotate-debug-info=array-bounds can be used as a replacement
for '-mllvm -array-bounds-pseudofn', though we do not yet delete the
latter.

Note: we replaced '-mllvm -array-bounds-pseudofn' in
clang/test/CodeGen/bounds-checking-debuginfo.c, because adding test
cases would modify the line numbers in the test assertions, and
therefore obscure that the test output is the same between '-mllvm
-array-bounds-pseudofn' and -fsanitize-annotate-debug-info=array-bounds.
2025-05-07 15:57:01 -07:00
Kees Cook
c7b2d98c93
[sancov] Introduce optional callback for stack-depth tracking (#138323)
Normally -fsanitize-coverage=stack-depth inserts inline arithmetic to
update thread_local __sancov_lowest_stack. To support stack depth
tracking in the Linux kernel, which does not implement traditional
thread_local storage, provide the option to call a function instead.

This matches the existing "stackleak" implementation that is supported
in Linux via a GCC plugin. To make this coverage more performant, a
minimum estimated stack depth can be chosen to enable the callback mode,
skipping instrumentation of functions with smaller stacks.

With -fsanitize-coverage-stack-depth-callback-min set greater than 0,
the __sanitize_cov_stack_depth() callback will be injected when the
estimated stack depth is greater than or equal to the given minimum.
2025-05-07 05:41:24 -07:00
Douglas
efd46bc1ef
[sanitizer] Allow use-after-scope front-end argument to take effect with -fsanitize=kernel-address (#137015)
Allow `-f[no]-sanitize-address-use-after-scope` to take effect under
kernel-address sanitizer (`-fsanitize=kernel-address`). `use-after-scope` is
now enabled by default under kernel-address sanitizer.

Previously, users may have enabled `use-after-scope` checks for kernel-address
sanitizer via `-mllvm -asan-use-after-scope=true`. While this may have worked
for optimization levels > O0, the required lifetime intrinsics to allow for
`use-after-scope` detection were not emitted under O0. This commit ensures
the required lifetime intrinsics are emitted under O0 with kernel-address
sanitizer.
2025-04-28 11:54:43 -07:00
Vitaly Buka
7aa8ece256
[Driver][CFI] Allow CFI with minimal runtime (#137103)
It was introduced with original "minimal runtime"
patch without explanation:
https://reviews.llvm.org/D36810#:~:text=if%20(-,NonTrappingCfi,-)

Note, the same commit contains `cfi_check_fail` handler,
which can not be reached with `-fsanitize-trap=cfi`.

This patch makes CFI min runtime behavior consistent with UBSAN:
`-fsanitize-trap=` ignores `-fsanitize-minimal-runtime`,
`-fno-sanitize-trap=` with `-fsanitize-minimal-runtime` compiles and
link
minimal runtime.
2025-04-25 00:55:05 -07:00
Vitaly Buka
cb8495c0fc
[Driver][CFI] Add missing '-' into error message (#137097)
Co-authored-by: Jim Lin <jim@andestech.com>
2025-04-23 21:13:18 -07:00
Thurston Dang
20cd74a1c1
[sanitizer] Apply AlwaysIn/Out in parseSanitizeArgs (#129405)
For backwards compatibility, `parseSanitizeArgs`/`parseSanitizeTrapArgs` had an incomplete refactoring in
https://github.com/llvm/llvm-project/pull/119819, in order to accommodate the special case of vptr in -fsanitize=undefined and its interaction with -fsanitize-trap=undefined. Now that vptr is no longer part of -fsanitize=undefined (https://github.com/llvm/llvm-project/pull/121115), this patch changes parseSanitizeArgs to apply the AlwaysIn/Out invariants in parseSanitizeArgs, which allows simplifying calls to parseSanitizeArgs.

This is not quite NFC: it changes the error message of -fsanitize-trap=vptr.
2025-04-17 15:14:52 -07:00
Vitaly Buka
d13135134c
[NFC][Driver][CFI] Rename to clarify purpose of CFI runtime (#135885)
CFI runtime (diagnostics, or not) is only needed
for cross-dso support.
2025-04-16 08:12:27 -07:00
Vitaly Buka
2e9ab7cf96
[NFC][Driver][CFI] Update boolean expression (#135881)
Show why we don't need regular CFI runtime, when CFI diag runtime is
linked.
2025-04-16 08:09:34 -07:00
Maxim Zhukov
2b7daaf967
[sanitizer][CFI] Add support to build CFI with sanitize-coverage (#131296)
Added ability to build together with -fsanitize=cfi and
-fsanitize-coverage=trace-cmp at the same time.
2025-04-02 16:05:44 +03:00
Vitaly Buka
038731c709
[ubsan] Remove -fsanitizer=vptr from -fsanitizer=undefined (#121115)
This makes `undefined` more consistent.

`vptr` check adds additional constraints:
1. trap is off,  or silently disabled
2. rtti is no, or compilation error
3. c++abi, or linking error

So it's not obvious if `-fsanitizer=undefined`
will have it on.

https://discourse.llvm.org/t/rfc-remove-vptr-from-undefined/83830
2025-03-01 13:21:47 -08:00
Scott Constable
e223485c9b
[X86] Extend kCFI with a 3-bit arity indicator (#121070)
Kernel Control Flow Integrity (kCFI) is a feature that hardens indirect
calls by comparing a 32-bit hash of the function pointer's type against
a hash of the target function's type. If the hashes do not match, the
kernel may panic (or log the hash check failure, depending on the
kernel's configuration). These hashes are computed at compile time by
applying the xxHash64 algorithm to each mangled canonical function (or
function pointer) type, then truncating the result to 32 bits. This hash
is written into each indirect-callable function header by encoding it as
the 32-bit immediate operand to a `MOVri` instruction, e.g.:
```
__cfi_foo:
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	movl	$199571451, %eax                # hash of foo's type = 0xBE537FB
foo:
        ...
```

This PR extends x86-based kCFI with a 3-bit arity indicator encoded in
the `MOVri` instruction's register (reg) field as follows:

| Arity Indicator | Description | Encoding in reg field |
| --------------- | --------------- | --------------- |
| 0 | 0 parameters | EAX |
| 1 | 1 parameter in RDI | ECX |
| 2 | 2 parameters in RDI and RSI | EDX |
| 3 | 3 parameters in RDI, RSI, and RDX | EBX |
| 4 | 4 parameters in RDI, RSI, RDX, and RCX | ESP |
| 5 | 5 parameters in RDI, RSI, RDX, RCX, and R8 | EBP |
| 6 | 6 parameters in RDI, RSI, RDX, RCX, R8, and R9 | ESI |
| 7 | At least one parameter may be passed on the stack | EDI |

For example, if `foo` takes 3 register arguments and no stack arguments
then the `MOVri` instruction in its kCFI header would instead be written
as:
```
	movl	$199571451, %ebx                # hash of foo's type = 0xBE537FB
```

This PR will benefit other CFI approaches that build on kCFI, such as
FineIBT. For example, this proposed enhancement to FineIBT must be able
to infer (at kernel init time) which registers are live at an indirect
call target: https://lkml.org/lkml/2024/9/27/982. If the arity bits are
available in the kCFI function header, then this information is trivial
to infer.

Note that there is another existing PR proposal that includes the 3-bit
arity within the existing 32-bit immediate field, which introduces
different security properties:
https://github.com/llvm/llvm-project/pull/117121.
2025-02-06 10:54:22 +08:00
Nikita Popov
1295aa2e81
[Clang] Add -fwrapv-pointer flag (#122486)
GCC supports three flags related to overflow behavior:
 * `-fwrapv`: Makes signed integer overflow well-defined.
 * `-fwrapv-pointer`: Makes pointer overflow well-defined.
* `-fno-strict-overflow`: Implies `-fwrapv -fwrapv-pointer`, making both
signed integer overflow and pointer overflow well-defined.

Clang currently only supports `-fno-strict-overflow` and `-fwrapv`, but
not `-fwrapv-pointer`.

This PR proposes to introduce `-fwrapv-pointer` and adjust the semantics
of `-fwrapv` to match GCC.

This allows signed integer overflow and pointer overflow to be
controlled independently, while `-fno-strict-overflow` still exists to
control both at the same time (and that option is consistent across GCC
and Clang).
2025-01-28 09:57:00 +01:00
Thurston Dang
76fac9c017
[sanitizer] Parse weighted sanitizer args and -fsanitize-skip-hot-cutoff (#121619)
This adds a function to parse weighted sanitizer flags (e.g.,
`-fsanitize-blah=undefined=0.5,null=0.3`) and adds the plumbing to apply
that to a new flag, `-fsanitize-skip-hot-cutoff`.

`-fsanitize-skip-hot-cutoff` currently has no effect; future work will
use it to generalize ubsan-guard-checks (originally introduced in
5f9ed2ff8364ff3e4fac410472f421299dafa793).

---------

Co-authored-by: Vitaly Buka <vitalybuka@google.com>
2025-01-09 21:52:30 -08:00
Vitaly Buka
cd66c9b6a0
[Ubsan][Driver] Remove UBSAN C++ runtime from other sanitizers (#121006)
Linking this runtime requires C++ ABI, which breaks -nostdlib++ builds.
However, UBSAN C++ runtime is only needed for CFI and VPTR checks.

Unblocks #120370.
2024-12-24 13:57:03 -08:00
Vitaly Buka
c2aee50620
[ubsan] Runtime and driver support for local-bounds (#120515)
Implements ``-f[no-]sanitize-trap=local-bounds``,
and ``-f[no-]sanitize-recover=local-bounds``.

LLVM part is here #120513.
2024-12-19 16:38:07 -08:00
Vitaly Buka
beea5acc5e
Reapply "[driver] Fix sanitizer libc++ runtime linking (#120370)" (#120538)
Reland without item 2 from #120370 to avoid breaking libc++ tests.

This reverts commit 60a2f32cf5ce75c9a2511d7fc2b0f24699605912.
2024-12-19 01:07:54 -08:00
Thurston Dang
ffff7bb582
Reapply "[ubsan] Add -fsanitize-merge (and -fno-sanitize-merge) (#120…464)" (#120511)
This reverts commit 2691b964150c77a9e6967423383ad14a7693095e. This
reapply fixes the buildbot breakage of the original patch, by updating
clang/test/CodeGen/ubsan-trap-debugloc.c to specify -fsanitize-merge
(the default, which is merge, is applied by the driver but not
clang_cc1).

This reapply also expands clang/test/CodeGen/ubsan-trap-merge.c.

----

Original commit message:
'-mllvm -ubsan-unique-traps'
(https://github.com/llvm/llvm-project/pull/65972) applies to all UBSan
checks. This patch introduces -fsanitize-merge (defaults to on,
maintaining the status quo behavior) and -fno-sanitize-merge (equivalent
to '-mllvm -ubsan-unique-traps'), with the option to selectively
applying non-merged handlers to a subset of UBSan checks (e.g.,
-fno-sanitize-merge=bool,enum).

N.B. we do not use "trap" in the argument name since
https://github.com/llvm/llvm-project/pull/119302 has generalized
-ubsan-unique-traps to work for non-trap modes (min-rt and regular rt).

This patch does not remove the -ubsan-unique-traps flag; that will
override -f(no-)sanitize-merge.
2024-12-18 18:13:26 -08:00
Thurston Dang
60a2f32cf5 Revert "[driver] Fix sanitizer libc++ runtime linking (#120370)"
This reverts commit 9af5de320b77d3757ea2b7e3d85c67f88dfbabb5.

Reason: buildbot breakage
(https://lab.llvm.org/buildbot/#/builders/24/builds/3394/steps/10/logs/stdio)
"Unexpectedly Passed Tests (1):
   llvm-libc++-shared.cfg.in :: libcxx/language.support/support.dynamic/libcpp_deallocate.sh.cpp"
2024-12-19 01:41:14 +00:00
Thurston Dang
2691b96415 Revert "[ubsan] Add -fsanitize-merge (and -fno-sanitize-merge) (#120464)"
This reverts commit 7eaf4708098c216bf432fc7e0bc79c3771e793a4.

Reason: buildbot breakage (e.g.,
https://lab.llvm.org/buildbot/#/builders/144/builds/14299/steps/6/logs/FAIL__Clang__ubsan-trap-debugloc_c)
2024-12-18 23:50:01 +00:00
Thurston Dang
7eaf470809
[ubsan] Add -fsanitize-merge (and -fno-sanitize-merge) (#120464)
'-mllvm -ubsan-unique-traps'
(https://github.com/llvm/llvm-project/pull/65972) applies to all UBSan
checks. This patch introduces -fsanitize-merge (defaults to on,
maintaining the status quo behavior) and -fno-sanitize-merge (equivalent
to '-mllvm -ubsan-unique-traps'), with the option to selectively
applying non-merged handlers to a subset of UBSan checks (e.g.,
-fno-sanitize-merge=bool,enum).

N.B. we do not use "trap" in the argument name since
https://github.com/llvm/llvm-project/pull/119302 has generalized
-ubsan-unique-traps to work for non-trap modes (min-rt and regular rt).

This patch does not remove the -ubsan-unique-traps flag; that will
override -f(no-)sanitize-merge.
2024-12-18 15:36:12 -08:00
Vitaly Buka
9af5de320b
[driver] Fix sanitizer libc++ runtime linking (#120370)
1. -f[no-]sanitize-link-c++-runtime suppose to
   override defauld behavior implied from `CCCIsCXX`
2. Take into account -nostdlib++ (unblocks #108357)
3. Fix typo hasFlag vs hasArg.
2024-12-18 10:37:44 -08:00
Thurston Dang
c48d45e6a3
[sanitizer] Refactor -f(no-)?sanitize-recover parsing (#119819)
This moves the -f(no-)?sanitize-recover parsing into a generic
parseSanitizerArgs function, and then applies it to parse
-f(no-)?sanitize-recover and -f(no-)?sanitize-trap.

N.B. parseSanitizeTrapArgs does *not* remove non-TrappingSupported
arguments. This maintains the legacy behavior of '-fsanitize=undefined
-fsanitize-trap=undefined' (clang/test/Driver/fsanitize.c), which is
that vptr is not enabled at all (not even in recover mode) in order to
avoid the need for a ubsan runtime.
2024-12-17 16:35:11 -08:00
Florian Hahn
c135f6ffe2
[TySan] Add initial Type Sanitizer support to Clang) (#76260)
This patch introduces the Clang components of type sanitizer: a
sanitizer for type-based aliasing violations.

It is based on Hal Finkel's https://reviews.llvm.org/D32198.

The Clang changes are mostly formulaic, the one specific change being
that when the TBAA sanitizer is enabled, TBAA is always generated, even
at -O0.

It goes together with the corresponding LLVM changes
(https://github.com/llvm/llvm-project/pull/76259) and compiler-rt
changes (https://github.com/llvm/llvm-project/pull/76261)

PR: https://github.com/llvm/llvm-project/pull/76260
2024-12-17 15:13:42 +00:00
Thurston Dang
7077896a54
[NFCI][sanitizer] Refactor parseSanitizeTrapArgs (#119797)
parseSanitizeTrapArgs follows the general pattern of "compute the
sanitizer mask based on the default plus opt-in (if supported) minus
opt-out". This patch refactors the functionality into a generalized
function, parseSanitizeArgs, which will be useful for future sanitizer
flag parsing.
2024-12-12 18:31:01 -08:00
Csanád Hajdú
1946d32f1f
[Clang] Improve error for -fsanitize=function/kcfi -mexecute-only incompatibility (#118816)
The current error message when using the `-fsanitize=function
-mexecute-only` flags together points to the target triple as the reason
that `-fsanitize=function` is not allowed to be used, even when the
function sanitizer is otherwise supported on the target when not using
`-mexecute-only`.

The error message is improved to give `-mexecute-only` as the reason for
disallowing `-fsanitize=function` if it was passed to the driver.

Fixes https://github.com/llvm/llvm-project/issues/117974
2024-12-11 09:06:56 -08:00
Axel Lundberg
668f2c7fab
[clang][UBSan] Make sure that the implicit-conversion group is compatible with minimal runtime (#114865)
We are currently getting:

`clang: error: invalid argument '-fsanitize-minimal-runtime' not allowed
with '-fsanitize=implicit-conversion'`

when running

`-fsanitize=implicit-conversion -fsanitize-minimal-runtime`

because `implicit-conversion` now includes
`implicit-bitfield-conversion` which is not included in the `integer`
check. The `integer` check includes the `implicit-integer-conversion`
checks and is supported by the trapping option and because of that
compatible with the minimal runtime. It is thus reasonable to make
`implicit-bitfield-conversion` compatible with the minimal runtime.
2024-11-20 14:57:23 -08:00
Kazu Hirata
4d6a5fc702
[Driver] Remove unused includes (NFC) (#116316)
Identified with misc-include-cleaner.
2024-11-15 07:26:05 -08:00
Charlie Barto
53a81d4d26
Reland [asan][windows] Eliminate the static asan runtime on windows (#107899)
This reapplies 8fa66c6ca7272268747835a0e86805307b62399c ([asan][windows]
Eliminate the static asan runtime on windows) for a second time.

That PR bounced off the tests because it caused failures in the other
sanitizer runtimes, these have been fixed by only building interception,
sanitizer_common, and asan with /MD, and continuing to build the rest of
the runtimes with /MT. This does mean that any usage of the static
ubsan/fuzzer/etc runtimes will mean you're mixing different runtime
library linkages in the same app, the interception, sanitizer_common,
and asan runtimes are designed for this, however it does result in some
linker warnings.

Additionally, it turns out when building in release-mode with
LLVM_ENABLE_PDBs the build system forced /OPT:ICF. This totally breaks
asan's "new" method of doing "weak" functions on windows, and so
/OPT:NOICF was explicitly added to asan's link flags.

---------

Co-authored-by: Amy Wishnousky <amyw@microsoft.com>
2024-09-09 13:41:08 -07:00
Justin Stitt
76236fafda
[Clang] Overflow Pattern Exclusion - rename some patterns, enhance docs (#105709)
From @vitalybuka's review on
https://github.com/llvm/llvm-project/pull/104889:
- [x] remove unused variable in tests
- [x] rename `post-decr-while` --> `unsigned-post-decr-while`
- [x] split `add-overflow-test` into `add-unsigned-overflow-test` and
`add-signed-overflow-test`
- [x] be more clear about defaults within docs
- [x] add table to docs

Here's a screenshot of the rendered table so you don't have to build the
html docs yourself to inspect the layout:

![image](https://github.com/user-attachments/assets/5d3497c4-5f5a-4579-b29b-96a0fd192faa)


CCs: @vitalybuka

---------

Signed-off-by: Justin Stitt <justinstitt@google.com>
Co-authored-by: Vitaly Buka <vitalybuka@google.com>
2024-08-23 23:33:23 -07:00
Chris Apple
f77e8f765e
[clang][rtsan] Reland realtime sanitizer codegen and driver (#102622)
This reverts commit a1e9b7e646b76bf844e8a9a101ebd27de11992ff
This relands commit d010ec6af8162a8ae4e42d2cac5282f83db0ce07

No modifications from the original patch. It was determined that the
ubsan build failure was happening even after the revert, some examples:

https://lab.llvm.org/buildbot/#/builders/159/builds/4477 
https://lab.llvm.org/buildbot/#/builders/159/builds/4478 
https://lab.llvm.org/buildbot/#/builders/159/builds/4479
2024-08-23 08:16:52 -07:00
Chris Apple
a1e9b7e646
Revert "[clang][rtsan] Introduce realtime sanitizer codegen and drive… (#105744)
…r (#102622)"

This reverts commit d010ec6af8162a8ae4e42d2cac5282f83db0ce07.

Build failure: https://lab.llvm.org/buildbot/#/builders/159/builds/4466
2024-08-22 15:19:41 -07:00
Chris Apple
d010ec6af8
[clang][rtsan] Introduce realtime sanitizer codegen and driver (#102622)
Introduce the `-fsanitize=realtime` flag in clang driver

Plug in the RealtimeSanitizer PassManager pass in Codegen, and attribute
a function based on if it has the `[[clang::nonblocking]]` function
effect.
2024-08-22 14:08:24 -07:00
Justin Stitt
295fe0bd43
[Clang] Re-land Overflow Pattern Exclusions (#104889)
Introduce "-fsanitize-undefined-ignore-overflow-pattern=" which can
be used to disable sanitizer instrumentation for common overflow-dependent
code patterns.

For a wide selection of projects, proper overflow sanitization could
help catch bugs and solve security vulnerabilities. Unfortunately, in
some cases the integer overflow sanitizers are too noisy for their users
and are often left disabled. Providing users with a method to disable
sanitizer instrumentation of common patterns could mean more projects
actually utilize the sanitizers in the first place.

One such project that has opted to not use integer overflow (or
truncation) sanitizers is the Linux Kernel. There has been some
discussion[1] recently concerning mitigation strategies for unexpected
arithmetic overflow. This discussion is still ongoing and a succinct
article[2] accurately sums up the discussion. In summary, many Kernel
developers do not want to introduce more arithmetic wrappers when
most developers understand the code patterns as they are.

Patterns like:

  if (base + offset < base) { ... }

or

  while (i--) { ... }

or

  #define SOME -1UL

are extremely common in a code base like the Linux Kernel. It is
perhaps too much to ask of kernel developers to use arithmetic wrappers
in these cases. For example:

  while (wrapping_post_dec(i)) { ... }

which wraps some builtin would not fly. This would incur too many
changes to existing code; the code churn would be too much, at least too
much to justify turning on overflow sanitizers.

Currently, this commit tackles three pervasive idioms:

1. "if (a + b < a)" or some logically-equivalent re-ordering like "if (a > b + a)"
2. "while (i--)" (for unsigned) a post-decrement always overflows here
3. "-1UL, -2UL, etc" negation of unsigned constants will always overflow

The patterns that are excluded can be chosen from the following list:

- add-overflow-test
- post-decr-while
- negated-unsigned-const

These can be enabled with a comma-separated list:

  -fsanitize-undefined-ignore-overflow-pattern=add-overflow-test,negated-unsigned-const

"all" or "none" may also be used to specify that all patterns should be
excluded or that none should be.

[1] https://lore.kernel.org/all/202404291502.612E0A10@keescook/
[2] https://lwn.net/Articles/979747/

CCs: @efriedma-quic @kees @jyknight @fmayer @vitalybuka
Signed-off-by: Justin Stitt <justinstitt@google.com>
Co-authored-by: Bill Wendling <morbo@google.com>
2024-08-20 20:13:44 +00:00
Thurston Dang
e398da2b37 Revert "[Clang] Overflow Pattern Exclusions (#100272)"
This reverts commit 9a666deecb9ff6ca3a6b12e6c2877e19b74b54da.

Reason: broke buildbots

e.g., fork-ubsan.test started failing at
https://lab.llvm.org/buildbot/#/builders/66/builds/2819/steps/9/logs/stdio

  Clang :: CodeGen/compound-assign-overflow.c
  Clang :: CodeGen/sanitize-atomic-int-overflow.c
started failing with https://lab.llvm.org/buildbot/#/builders/52/builds/1570
2024-08-15 10:18:52 -07:00
Justin Stitt
9a666deecb
[Clang] Overflow Pattern Exclusions (#100272)
Introduce "-fsanitize-overflow-pattern-exclusion=" which can be used to
disable sanitizer instrumentation for common overflow-dependent code
patterns.

For a wide selection of projects, proper overflow sanitization could
help catch bugs and solve security vulnerabilities. Unfortunately, in
some cases the integer overflow sanitizers are too noisy for their users
and are often left disabled. Providing users with a method to disable
sanitizer instrumentation of common patterns could mean more projects
actually utilize the sanitizers in the first place.

One such project that has opted to not use integer overflow (or
truncation) sanitizers is the Linux Kernel. There has been some
discussion[1] recently concerning mitigation strategies for unexpected
arithmetic overflow. This discussion is still ongoing and a succinct
article[2] accurately sums up the discussion. In summary, many Kernel
developers do not want to introduce more arithmetic wrappers when
most developers understand the code patterns as they are.

Patterns like:

    if (base + offset < base) { ... }

or

    while (i--) { ... }

or

    #define SOME -1UL

are extremely common in a code base like the Linux Kernel. It is
perhaps too much to ask of kernel developers to use arithmetic wrappers
in these cases. For example:

    while (wrapping_post_dec(i)) { ... }

which wraps some builtin would not fly. This would incur too many
changes to existing code; the code churn would be too much, at least too
much to justify turning on overflow sanitizers.

Currently, this commit tackles three pervasive idioms:

1. "if (a + b < a)" or some logically-equivalent re-ordering like "if (a > b + a)"
2. "while (i--)" (for unsigned) a post-decrement always overflows here
3. "-1UL, -2UL, etc" negation of unsigned constants will always overflow

The patterns that are excluded can be chosen from the following list:

- add-overflow-test
- post-decr-while
- negated-unsigned-const

These can be enabled with a comma-separated list:

    -fsanitize-overflow-pattern-exclusion=add-overflow-test,negated-unsigned-const

"all" or "none" may also be used to specify that all patterns should be
excluded or that none should be.

[1] https://lore.kernel.org/all/202404291502.612E0A10@keescook/
[2] https://lwn.net/Articles/979747/

CCs: @efriedma-quic @kees @jyknight @fmayer @vitalybuka
Signed-off-by: Justin Stitt <justinstitt@google.com>
Co-authored-by: Bill Wendling <morbo@google.com>
2024-08-15 00:17:06 +00:00
Fangrui Song
9324c952e5 [Driver] -fsanitize=numerical: work with ubsan and support -shared-libsan
* `-fsanitize=numerical,undefined`: don't link in the ubsan standalone
  runtime.
* `-shared-libsan`: link against `libclang_rt.nsan.so`

The compiler-rt part will be properly fixed by #98415
2024-07-10 17:32:17 -07:00
Alexander Shaposhnikov
48f8130a49
[Clang][Sanitizers] Add numerical sanitizer (#93783)
Add plumbing for the numerical sanitizer on Clang's side.
2024-06-10 22:14:26 -07:00
Charlie Barto
0a93e9f2e2 Revert "[asan][windows] Eliminate the static asan runtime on windows (#93770)"
This reverts commit 8fa66c6ca7272268747835a0e86805307b62399c.
2024-05-30 11:41:44 -07:00
Charlie Barto
8fa66c6ca7
[asan][windows] Eliminate the static asan runtime on windows (#93770)
Re-Apply: 246234ac70faa1e3281a2bb83dfc4dd206a7d59c
Originally #81677

The static asan runtime on windows had various buggy hacks to ensure loaded dlls got the executable's copy of asan, these never worked all that well, so we have eliminated the static runtime altogether and made the dynamic runtime work for applications linking any flavor of the CRT.

Among other things this allows non-asan-instrumented applications to load asan-instrumented dlls that link against the static CRT.

Co-authored-by: Amy Wishnousky <amyw@microsoft.com>
2024-05-30 11:22:26 -07:00
Charlie Barto
10436aede2 Revert "[asan][windows] Eliminate the static asan runtime on windows (#81677)"
This reverts commit 246234ac70faa1e3281a2bb83dfc4dd206a7d59c.
2024-05-29 17:52:54 -07:00
Charlie Barto
246234ac70
[asan][windows] Eliminate the static asan runtime on windows (#81677)
This is one of the major changes we (Microsoft) have made in the version
of asan we ship with Visual Studio.

@amyw-msft wrote a blog post outlining this work at
https://devblogs.microsoft.com/cppblog/msvc-address-sanitizer-one-dll-for-all-runtime-configurations/

> With Visual Studio 2022 version 17.7 Preview 3, we have refactored the
MSVC Address Sanitizer (ASan) to depend on one runtime DLL regardless of
the runtime configuration. This simplifies project onboarding and
supports more scenarios, particularly for projects statically linked
(/MT, /MTd) to the C Runtimes. However, static configurations have a new
dependency on the ASan runtime DLL.

> Summary of the changes:

> ASan now works with /MT or /MTd built DLLs when the host EXE was not
compiled with ASan. This includes Windows services, COM components, and
plugins.
Configuring your project with ASan is now simpler, since your project
doesn’t need to uniformly specify the same [runtime
configuration](https://learn.microsoft.com/en-us/cpp/build/reference/md-mt-ld-use-run-time-library?view=msvc-170)
(/MT, /MTd, /MD, /MDd).
ASan workflows and pipelines for /MT or /MTd built projects will need to
ensure the ASan DLL (clang_rt.asan_dynamic-<arch>.dll) is available on
PATH.
The names of the ASan .lib files needed by the linker have changed (the
linker normally takes care of this if not manually specifying lib names
via /INFERASANLIBS)
You cannot mix ASan-compiled binaries from previous versions of the MSVC
Address Sanitizer (this is always true, but especially true in this
case).

Here's the description of these changes from our internal PR

1. Build one DLL that includes everything debug mode needs (not included
here, already contributed upstream).
* Remove #if _DEBUG checks everywhere.
* In some places, this needed to be replaced with a runtime check. In
asan_win.cpp, IsDebugRuntimePresent was added where we are searching for
allocations prior to ASAN initialization.
* In asan_win_runtime_functions.cpp and interception_win.cpp, we need to
be aware of debug runtime DLLs even when not built with _DEBUG.
2. Redirect statically linked functions to the ASAN DLL for /MT
* New exports for each of the C allocation APIs so that the statically
linked portion of the runtime can call them (see asan_malloc_win.cpp,
search MALLOC_DLL_EXPORT). Since we want our stack trace information to
be accurate and without noise, this means we need to capture stack frame
info from the original call and tell it to our DLL export. For this, I
have reused the __asan_win_new_delete_data used for op new/delete
support from asan_win_new_delete_thunk_common.h and moved it into
asan_win_thunk_common.h renamed as __asan_win_stack_data.
* For the C allocation APIs, a new file is included in the
statically-linked /WHOLEARCHIVE lib - asan_malloc_win_thunk.cpp. These
functions simply provide definitions for malloc/free/etc to be used
instead of the UCRT's definitions for /MT and instead call the ASAN DLL
export. /INFERASANLIBS ensures libucrt.lib will not take precedence via
/WHOLEARCHIVE.
* For other APIs, the interception code was called, so a new export is
provided: __sanitizer_override_function.
__sanitizer_override_function_by_addr is also provided to support
__except_handler4 on x86 (due to the security cookie being per-module).
3. Support weak symbols for /MD
* We have customers (CoreCLR) that rely on this behavior and would force
/MT to get it.
* There was sanitizer_win_weak_interception.cpp before, which did some
stuff for setting up the .WEAK section, but this only worked on /MT. Now
stuff registered in the .WEAK section is passed to the ASAN DLL via new
export __sanitizer_register_weak_function (impl in
sanitizer_win_interception.cpp). Unlike linux, multiple weak symbol
registrations are possible here. Current behavior is to give priority on
module load order such that whoever loads last (so priority is given to
the EXE) will have their weak symbol registered.
* Unfortunately, the registration can only occur during the user module
startup, which is after ASAN DLL startup, so any weak symbols used by
ASAN during initialization will not be picked up. This is most notable
for __asan_default_options and friends (see asan_flags.cpp). A mechanism
was made to add a callback for when a certain weak symbol was
registered, so now we process __asan_default_options during module
startup instead of ASAN startup. This is a change in behavior, but
there's no real way around this due to how DLLs are.
4. Build reorganization
* I noticed that our current build configuration is very MSVC-specific
and so did a bit of reworking. Removed a lot of
create_multiple_windows_obj_lib use since it's no longer needed and it
changed how we needed to refer to each object_lib by adding runtime
configuration to the name, conflicting with how it works for non-MSVC.
* No more Win32 static build, use /MD everywhere.
* Building with /Zl to avoid defaultlib warnings.

In addition:
* I've reapplied "[sanitizer][asan][win] Intercept _strdup on Windows
instead of strdup" which broke the previous static asan runtime. That
runtime is gone now and this change is required for the strdup tests to
work.
* I've modified the MSVC clang driver to support linking the correct
asan libraries, including via defining _DLL (which triggers different
defaultlibs and should result in the asan dll thunk being linked, along
with the dll CRT (via defaultlib directives).
* I've made passing -static-libsan an error on windows, and made
-shared-libsan the default. I'm not sure I did this correctly, or in the
best way.
* Modified the test harnesses to add substitutions for the dynamic and
static thunks and to make the library substitutions point to the dynamic
asan runtime for all test configurations on windows. Both the static and
dynamic windows test configurations remain, because they correspond to
the static and dynamic CRT, not the static and dynamic asan runtime
library.

---------

Co-authored-by: Amy Wishnousky <amyw@microsoft.com>
2024-05-29 17:24:45 -07:00
Matheus Izvekov
b86e0992bf
[clang] Enable C++17 relaxed template template argument matching by default (#89807)
This patch will finally allow us to mark C++17 support in clang as
complete.
    
In order to implement this as a DR and avoid breaking reasonable code
that worked before P0522, this patch implements a provisional resolution
for CWG2398: When deducing template template parameters against each other,
and the argument side names a template specialization, instead of just
deducing A, we deduce a synthesized template template parameter based
on A, but with it's parameters using the template specialization's arguments
as defaults.
    
The driver flag is deprecated with a warning.
    
Fixes https://github.com/llvm/llvm-project/issues/36505
2024-05-02 02:02:35 -03:00