-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
AddressSanitizer #187
Merged
AddressSanitizer #187
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
yuri91
requested changes
Nov 30, 2023
This change is made in preparation for another change where also stack information is added.
ASan and LSan need to be know where the stack top and bottom are.
libasan makes heavy use of unsigned integers instead of pointers, but in the IR calls functions with pointers. Previously cheerp did not accepts these conversions in replaceCallOfBitCastWithBitCastOfCall. Made it so that on wasm/asmjs these conversions do take place.
The `simplifyCalls` routine in the GDA does not only "simplify calls" but also replaces calls of bitcasts with bitcasts of the call. While working on supporting exceptions with ASan, there was some generated code where an invoke happened on a bitcast of a function. Because the bitcast did not happen on the invoke, it later resulted in the (wrong) assumption that this call was an indirect call of an unsupported type. Causing the call to be replaced by an unreachable instruction. Made it so that the `simplifyCalls` routine runs on CallBase.
This allows asan to intercept calls to these functions.
This is allows libasan to intercept __cxa_throw_wasm while still calling the internal implementation.
This instrinsic returns the offset from the stack pointer to the most recent alloca instruction on the callers stack. Which is 0 on cheerp. This change is required for Asan, which uses this intrinsic to determine where to poison when doing dynamic allocas.
Hyxogen
force-pushed
the
feat-asan
branch
3 times, most recently
from
December 28, 2023 12:17
14533f7
to
9a157fc
Compare
yuri91
requested changes
Jan 2, 2024
ASan, by default, uses a big integer to poison multiple shadow bytes at the same time. However, this doesn't take into account the alignment requirements of the target platform, like on AsmJS, which requires natural alignment. This change adds the option -fsanitize-address-aligned-poisoning, which will force ASan to poison the shadow byte by byte.
Cheerp doesn't accept globals without a name.
libasan and libwasm both define their own memset and memcpy, causing the first one that's specified to be used. This can lead to false negatives when using ASan when libwasm is the first one linked.
Hyxogen
force-pushed
the
feat-asan
branch
2 times, most recently
from
January 3, 2024 10:05
51da83e
to
77ffe74
Compare
yuri91
approved these changes
Jan 3, 2024
I'm sure that something in the CI will not work, but this PR should be ready |
yuri91
approved these changes
Jan 4, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR implements (basic) AddressSanitizer functionality for cheerp-wasm.
For now I'll leave this as a draft, as I'm still planning some minor changes, need to setup some other stuff for the ci, and would also like to get some feedback.
Getting started
Docker
If you want to use it right away, you can use the following docker image: hyxogen/cheerp-asan:latest. I'll update this docker image with the latest changes from my development branch
Cheerp will be located in /opt/cheerp, and you'll also have the following aliases set:
Building it yourself
If you want to build it on your own system, then build the entire cheerp toolchain like normal with compiler-rt at the end. Please note that you'll need the latest versions from all the cheerp repositories. And if you haven't been keeping up with them, you'll have to do a rebuild of them all, lest you want a lot of errors.
building compiler-rt
To be able to use asan, you'll have to compile and install the asan runtime library.
Build instructions:
If for some reason the above command does not work, you're probably using an old version of clang (<14.0). You should
be able to still setup with the following (assuming that you've already built cheerp, and that the cheerp build
directory is
build
at the root of the repo)Usage
Once installed, address sanitizer should work (pretty much) like on native. An example:
Two step compilation
If you're doing compiling and linking separately, you'll have to specify the
-fsanitize=address
flag for both stepsNotes
LeakSanitizer
For LeakSanitizer to trigger, you'll have to manually call
exit
, as code compiled with cheerp doesn't call the atexitcallbacks when returning from main.
LeakSanitizer is not perfect.
It simply scans the memory if there are any pointers still pointing to allocated memory. Thus it might not find leaks
for cheerp-wasm which it can find for native.
Function "x" does not detect memory errors
ASan can only detect memory errors in instrumented code or intercepted functions. If you're using a library, you'll have
to compile it with ASan as well for it to be able to pick up these errors.
As for the intercepted functions, currently ASan only intercepts a handful of libc functions, thus it might be the case
you're using one that isn't intercepted.
More reading
If you want to find out how AddressSanitizer works in depth:
https://github.com/google/sanitizers/wiki/AddressSanitizer
EDIT: Implemented asan flags and exceptions support