For an odr-violation error due to a source file linked into two DSOs, or
one DSO and the main executable, it can be difficult to identify the DSO
name. Let's print the module name in the error report.
```
echo 'extern long var; int main() { return var; }' > a.cc
echo 'long var;' > b.cc
clang++ -fpic -fsanitize=address -shared b.cc -o b.so
clang++ -fsanitize=address a.cc b.cc ./b.so -o a
```
w/o this patch:
```
==1375386==ERROR: AddressSanitizer: odr-violation (0x56067cb06240):
[1] size=8 'var' b.cc
[2] size=8 'var' b.cc
...
```
w/ this patch:
```
==1375386==ERROR: AddressSanitizer: odr-violation (0x56067cb06240):
[1] size=8 'var' b.cc in /tmp/c/a
[2] size=8 'var' b.cc in ./b.so
```
In addition, update the `report_globals=2` message to include the module
name
```
==1451005==Added Global[0x7fcfe59ae040]: beg=0x7fcfe59ae140 size=8/32 name=var source=b.cc module=./b.so dyn_init=0 odr_indicator=0x55754f939260
```
These test cases are checking specific functions in call stacks.
But if the call stack order is changed (e.g. another function is not inlined),
the frame number would be different.
This patch loose the frame number checks for those conditions.
Depends on D139827
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D152991
Almost NFC, as blocks over max quarantine size will trigger immediate
drain anyway. In followup patches we can optimize passthrough case.
Reviewed By: thurston
Differential Revision: https://reviews.llvm.org/D153495
D135716 introduced -ftrivial-auto-var-init=pattern where supported.
Unfortunately this introduces unwanted memset() for large stack arrays,
as shown by the new tests added for asan and msan (tsan already had this
test).
In general, the problem of compiler-inserted memintrinsic calls
(memset/memcpy/memmove) is not new to compiler-rt, and has been a
problem before.
To avoid introducing unwanted memintrinsic calls, we redefine
memintrinsics as __sanitizer_internal_mem* at the assembly level for
most source files automatically (where sanitizer_common_internal_defs.h
is included).
In few cases, redefining a symbol in this way causes issues for
interceptors, namely the memintrinsic interceptor themselves. For such
source files we have to selectively disable the redefinition.
Other alternatives have been considered, but simply do not work well in
the context of compiler-rt:
1. Linker --wrap: this does not work because --wrap only
applies to the final link, and would not apply when building
sanitizer static libraries.
2. Changing references to memset() via objcopy: this may work,
but due to the complexities of the build system, introducing
such a post-processing step for the right object files (in
particular object files defining memset cannot be touched)
seems infeasible.
The chosen solution works well (as shown by the tests). Other libraries
have chosen the same solution where nothing else works (see e.g. glibc's
"symbol-hacks.h").
v4:
- Add interface attribute to __sanitizer_internal_mem* declarations as
well, as otherwise some compilers (MSVC) will complain.
- Add SANITIZER_COMMON_NO_REDEFINE_BUILTINS to source files using
C++STL, since this could lead to ODR violations (see added comment).
v3:
- Don't use ALIAS() to alias internal_mem*() functions to
__sanitizer_internal_mem*() functions, but just define them as
ALWAYS_INLINE functions instead. This will work on darwin and windows.
v2:
- Fix ubsan_minimal build where compiler decides to insert
memset/memcpy: ubsan_minimal has work without RTSanitizerCommonLibc,
therefore do not redefine the builtins.
- Fix definition of internal_mem* functions with compilers that want the
aliased function to already be defined before.
- Fix definition of __sanitizer_internal_mem* functions with compilers
more pedantic about attribute placement around extern "C".
Reviewed By: vitalybuka, dvyukov
Differential Revision: https://reviews.llvm.org/D151152
D135716 introduced -ftrivial-auto-var-init=pattern where supported.
Unfortunately this introduces unwanted memset() for large stack arrays,
as shown by the new tests added for asan and msan (tsan already had this
test).
In general, the problem of compiler-inserted memintrinsic calls
(memset/memcpy/memmove) is not new to compiler-rt, and has been a
problem before.
To avoid introducing unwanted memintrinsic calls, we redefine
memintrinsics as __sanitizer_internal_mem* at the assembly level for
most source files automatically (where sanitizer_common_internal_defs.h
is included).
In few cases, redefining a symbol in this way causes issues for
interceptors, namely the memintrinsic interceptor themselves. For such
source files we have to selectively disable the redefinition.
Other alternatives have been considered, but simply do not work well in
the context of compiler-rt:
1. Linker --wrap: this does not work because --wrap only
applies to the final link, and would not apply when building
sanitizer static libraries.
2. Changing references to memset() via objcopy: this may work,
but due to the complexities of the build system, introducing
such a post-processing step for the right object files (in
particular object files defining memset cannot be touched)
seems infeasible.
The chosen solution works well (as shown by the tests). Other libraries
have chosen the same solution where nothing else works (see e.g. glibc's
"symbol-hacks.h").
v3:
- Don't use ALIAS() to alias internal_mem*() functions to
__sanitizer_internal_mem*() functions, but just define them as
ALWAYS_INLINE functions instead. This will work on darwin and windows.
v2:
- Fix ubsan_minimal build where compiler decides to insert
memset/memcpy: ubsan_minimal has work without RTSanitizerCommonLibc,
therefore do not redefine the builtins.
- Fix definition of internal_mem* functions with compilers that want the
aliased function to already be defined before.
- Fix definition of __sanitizer_internal_mem* functions with compilers
more pedantic about attribute placement around extern "C".
Reviewed By: vitalybuka, dvyukov
Differential Revision: https://reviews.llvm.org/D151152
D135716 introduced -ftrivial-auto-var-init=pattern where supported.
Unfortunately this introduces unwanted memset() for large stack arrays,
as shown by the new tests added for asan and msan (tsan already had this
test).
In general, the problem of compiler-inserted memintrinsic calls
(memset/memcpy/memmove) is not new to compiler-rt, and has been a
problem before.
To avoid introducing unwanted memintrinsic calls, we redefine
memintrinsics as __sanitizer_internal_mem* at the assembly level for
most source files automatically (where sanitizer_common_internal_defs.h
is included).
In few cases, redefining a symbol in this way causes issues for
interceptors, namely the memintrinsic interceptor themselves. For such
source files we have to selectively disable the redefinition.
Other alternatives have been considered, but simply do not work well in
the context of compiler-rt:
1. Linker --wrap: this does not work because --wrap only
applies to the final link, and would not apply when building
sanitizer static libraries.
2. Changing references to memset() via objcopy: this may work,
but due to the complexities of the build system, introducing
such a post-processing step for the right object files (in
particular object files defining memset cannot be touched)
seems infeasible.
The chosen solution works well (as shown by the tests). Other libraries
have chosen the same solution where nothing else works (see e.g. glibc's
"symbol-hacks.h").
v2:
- Fix ubsan_minimal build where compiler decides to insert
memset/memcpy: ubsan_minimal has work without RTSanitizerCommonLibc,
therefore do not redefine the builtins.
- Fix definition of internal_mem* functions with compilers that want the
aliased function to already be defined before.
- Fix definition of __sanitizer_internal_mem* functions with compilers
more pedantic about attribute placement around extern "C".
Reviewed By: vitalybuka, dvyukov
Differential Revision: https://reviews.llvm.org/D151152
D135716 introduced -ftrivial-auto-var-init=pattern where supported.
Unfortunately this introduces unwanted memset() for large stack arrays,
as shown by the new tests added for asan and msan (tsan already had this
test).
In general, the problem of compiler-inserted memintrinsic calls
(memset/memcpy/memmove) is not new to compiler-rt, and has been a
problem before.
To avoid introducing unwanted memintrinsic calls, we redefine
memintrinsics as __sanitizer_internal_mem* at the assembly level for
most source files automatically (where sanitizer_common_internal_defs.h
is included).
In few cases, redefining a symbol in this way causes issues for
interceptors, namely the memintrinsic interceptor themselves. For such
source files we have to selectively disable the redefinition.
Other alternatives have been considered, but simply do not work well in
the context of compiler-rt:
1. Linker --wrap: this does not work because --wrap only
applies to the final link, and would not apply when building
sanitizer static libraries.
2. Changing references to memset() via objcopy: this may work,
but due to the complexities of the build system, introducing
such a post-processing step for the right object files (in
particular object files defining memset cannot be touched)
seems infeasible.
The chosen solution works well (as shown by the tests). Other libraries
have chosen the same solution where nothing else works (see e.g. glibc's
"symbol-hacks.h").
Reviewed By: vitalybuka, dvyukov
Differential Revision: https://reviews.llvm.org/D151152
This is an ongoing series of commits that are reformatting our
Python code. This catches the last of the python files to
reformat. Since they where so few I bunched them together.
Reformatting is done with `black`.
If you end up having problems merging this commit because you
have made changes to a python file, the best way to handle that
is to run git checkout --ours <yourfile> and then reformat it
with black.
If you run into any problems, post to discourse about it and
we will try to help.
RFC Thread below:
https://discourse.llvm.org/t/rfc-document-and-standardize-python-code-style
Reviewed By: jhenderson, #libc, Mordante, sivachandra
Differential Revision: https://reviews.llvm.org/D150784
Resetting oucp's stack to zero in swapcontext interception is incorrect,
since it breaks ucp cleanup after swapcontext returns in some cases:
Say we have two contexts, A and B, and we swapcontext from A to B, do
some work on Bs stack and then swapcontext back from B to A. At this
point shadow memory of Bs stack is in arbitrary state, but since we
can't know whether B will ever swapcontext-ed to again we clean up it's
shadow memory, because otherwise it remains poisoned and blows in
completely unrelated places when heap-allocated memory of Bs context
gets reused later (see https://github.com/llvm/llvm-project/issues/58633
for example). swapcontext prototype is swapcontext(ucontext* oucp,
ucontext* ucp), so in this example A is oucp and B is ucp, and i refer
to the process of cleaning up Bs shadow memory as ucp cleanup.
About how it breaks:
Take the same example with A and B: when we swapcontext back from B to A
the oucp parameter of swapcontext is actually B, and current trunk
resets its stack in a way that it becomes "uncleanupable" later. It
works fine if we do A->B->A, but if we do A->B->A->B->A no cleanup is
performed for Bs stack after B "returns" to A second time. That's
exactly what happens in the test i provided, and it's actually a pretty
common real world scenario.
Instead of resetting oucp's we make use of uc_stack.ss_flags to mark
context as "cleanup-able" by storing stack specific hash. It should be
safe since this field is not used in [get|make|swap]context functions
and is hopefully never meaningfully used in real-world scenarios (and i
haven't seen any).
Fixes https://github.com/llvm/llvm-project/issues/58633
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D137654
This amends commit 00be3578e0 to demangle symbol
names in global descriptors. We keep the mangled name for the `__odr_gen_asan_*`
variables and the runtime __cxa_demangle call site change (which fixed possible
leaks for other scenarios: non-fatal diagnostics).
compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp uses
an undefined weak `__cxa_demangle` which does not pull in an archive definition.
A -static-libstdc++ executable link does not get demangled names.
Unfortunately this means we cannot rely on runtime demangling.
See compiler-rt/test/asan/TestCases/global-demangle.cpp
The runtime calls `MaybeDemangleGlobalName` for error reporting and
`__cxxabiv1::__cxa_demangle` is called if available, so demanging Itanium
mangled names in global metadata is unnecessary and wastes data size.
Add `MaybeDemangleGlobalName` in ODR violation detection to support demangled
names in a suppressions file. `MaybeDemangleGlobalName` may call
`DemangleCXXABI` and leak memory. Use an internal allocation to prevent lsan
leak (in case there is no fatal asan error).
The debug feature `report_globals=2` prints information for all instrumented
global variables. `MaybeDemangleGlobalName` would be slow, so don't do that.
The output looks like `Added Global[0x56448f092d60]: beg=0x56448fa66d60 size=4/32 name=_ZL13test_global_2`
and I think the mangled name is fine.
Other mangled schemes e.g. Windows (see win-string-literal.ll) remain the
current behavior.
Reviewed By: hctim
Differential Revision: https://reviews.llvm.org/D138095
Add ptrace interceptor support for LoongArch, `ptrace.cpp` has been
tested and passed.
Reviewed By: SixWeining
Differential Revision: https://reviews.llvm.org/D137228
Fix a brown paper bag error made by me in D129418. I didn't set
ASAN_INTERCEPT_VFORK correctly for loongarch64, but created an all-zero
object for __interception::real_vfork. This caused anything calling
vfork() to die instantly.
Fix this issue by setting ASAN_INTERCEPT_VFORK and remove the bad
all-zero definition. Other ports have an all-zero common definition but
we don't need it at least for now.
And, enable ASAN vfork test for loongarch64 to prevent regression in the
future.
Differential Revision: https://reviews.llvm.org/D137160
This enables odr indicators on all platforms and private aliases on non-Windows.
Note that GCC also uses private aliases: this fixes bogus
`The following global variable is not properly aligned.` errors for interposed global variables
Fix https://github.com/google/sanitizers/issues/398
Fix https://github.com/google/sanitizers/issues/1017
Fix https://github.com/llvm/llvm-project/issues/36893 (we can restore D46665)
Global variables of non-hasExactDefinition() linkages (i.e.
linkonce/linkonce_odr/weak/weak_odr/common/external_weak) are not instrumented.
If an instrumented variable gets interposed to an uninstrumented variable due to
symbol interposition (e.g. in issue 36893, _ZTS1A in foo.so is resolved to _ZTS1A in
the executable), there may be a bogus error.
With private aliases, the register code will not resolve to a definition in
another module, and thus prevent the issue.
Cons: minor size increase. This is mainly due to extra `__odr_asan_gen_*` symbols.
(ELF) In addition, in relocatable files private aliases replace some relocations
referencing global symbols with .L symbols and may introduce some STT_SECTION symbols.
For lld, with -g0, the size increase is 0.07~0.09% for many configurations I
have tested: -O0, -O1, -O2, -O3, -O2 -ffunction-sections -fdata-sections
-Wl,--gc-sections. With -g1 or above, the size increase ratio will be even smaller.
This patch obsoletes D92078.
Don't migrate Windows for now: the static data member of a specialization
`std::num_put<char>::id` is a weak symbol, as well as its ODR indicator.
Unfortunately, link.exe (and lld without -lldmingw) generally doesn't support
duplicate weak definitions (weak symbols in different TUs likely pick different
defined external symbols and conflict).
Differential Revision: https://reviews.llvm.org/D137227
ClearShadowMemoryForContextStack assumes that context contains the stack
bounds. This is not true for a context from getcontext or oucp of
swapcontext.
Reviewed By: kstoimenov
Differential Revision: https://reviews.llvm.org/D130218
This patches exposed existing incorectness of swapcontext imlementation.
swapcontext does not set oucp->uc_stack. Unpoisoning works if ucp is
from makecontext, but may try to use garbage pointers if it's from
previos swapcontext or from getcontext. Existing limit reduces
probability of garbage pointers are used.
I restore behavour which we had for years, and will look to improve
swapcontext support.
This reverts commit d0751c9725.
This reverts commit 99796d06db.
Hint: Looking here because your manual invocation of something in
'check-asan' broke? You need a new symbolizer (after D123538).
An upcoming patch will remove the internal metadata for global
variables. With D123534 and D123538, clang now emits DWARF debug info
for constant strings (the only global variable type it was missing), and
llvm-symbolizer is now able to symbolize all global variable addresses
(where previously it wouldn't give you the file:line information).
Move ASan's runtime over from the internal metadata to DWARF.
Differential Revision: https://reviews.llvm.org/D127552
Hint: Looking here because your manual invocation of something in
'check-asan' broke? You need a new symbolizer (after D123538).
An upcoming patch will remove the internal metadata for global
variables. With D123534 and D123538, clang now emits DWARF debug info
for constant strings (the only global variable type it was missing), and
llvm-symbolizer is now able to symbolize all global variable addresses
(where previously it wouldn't give you the file:line information).
Move ASan's runtime over from the internal metadata to DWARF.
Differential Revision: https://reviews.llvm.org/D127552
TLS teardown is currently broken, as we unpoison the shadow a little bit
and to the right of the TLS section, rather than the full TLS section
itself. This currently breaks at -O0, and breaks with some upcoming
globals code that I have.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D120080
There were changes made to the linux version of this test that were not made for darwin
(see https://reviews.llvm.org/D115837) and this caused downstream failures.
Adding comment to this test to remind people to edit interface_symbols_darwin.cpp.
There is the reverse of this comment in the darwin file to remind us to edit the linux version already.
Differential Revision: https://reviews.llvm.org/D115899
This change moves optimized callbacks from each .o file to compiler-rt. Instead of using code generation it uses direct assembly implementation. Please note that the 'or' version is not implemented and it will produce unresolved external if somehow 'or' version is requested.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D114558
This change moves optimized callbacks from each .o file to compiler-rt. Instead of using code generation it uses direct assembly implementation. Please note that the 'or' version is not implemented and it will produce unresolved external if somehow 'or' version is requested.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D114558
This change moves optimized callbacks from each .o file to compiler-rt. Instead of using code generation it uses direct assembly implementation. Please note that the 'or' version is not implemented and it will produce unresolved external if somehow 'or' version is requested.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D114558
This change moves optimized callbacks from each .o file to compiler-rt. Instead of using code generation it uses direct assembly implementation. Please note that the 'or' version is not implemented and it will produce unresolved external if somehow 'or' version is requested.
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D114558
This adds REQUIRES: shared_cxxabi to a bunch of tests that would fail if this
weak reference in sanitizer common was undefined. This is necessary in cases
where libc++abi.a is statically linked in. Because there is no strong reference
to __cxa_demangle in compiler-rt, then if libc++abi is linked in via a static
archive, then the linker will not extract the archive member that would define
that weak symbol. This causes a handful of tests to fail because this leads to
the symbolizer printing mangled symbols where tests expect them demangled.
Technically, this feature is WAI since sanitizer runtimes shouldn't fail if
this symbol isn't resolved, and linking statically means you wouldn't need to
link in all of libc++abi. As a workaround, we can simply make it a requirement
that these tests use shared libc++abis.
Differential Revision: https://reviews.llvm.org/D109639
I can't be sure of the cause but I believe these fail
due to to fast unwinding not working on Thumb.
Whatever the case, they have been failing on our bots
for a long time:
https://lab.llvm.org/buildbot/#/builders/170/builds/46
Require fast-unwinder-works for both.