Skip to content
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

Pr/fasan multithreading fixes upstream #2955

Merged

Conversation

mkravchik
Copy link
Contributor

This PR makes it possible to use Frida ASAN in realistic Windows multithreaded applications. On Windows, an application is created by default with a thread pool, and many system APIs invoke COM behind the scenes as a part of their normal functionality. COM can initiate a lot of activity on these thread pool threads without any direct request from the harness.
The main highlights of the PR are:

  1. Mutex-protected ASAN allocator.
  2. More rigorous hook reentrancy protection, including environments without TLS (which happens very early and very late in the thread lifecycle).
  3. Correct initialization of Stalker, which excludes the fuzzer itself from being Stalkered (which is dangerous and completely unnecessary).
  4. Correct hooking of some required C runtime functions (e.g., memcpy).
  5. Static linking of the harness with C runtime, required for preventing Frida to hook its own calls to C runtime (e.g., memcpy, memcmp, etc.).
  6. Proper handling of Map/UnmapViewOfFile
  7. Unit test fix
  8. Removing Frida hooks and ASAN upon crashing before running other observers. This is necessary as collecting module symboling information for minibsod can easily cause OOM under ASAN. For this purpose, a new observer was introduced that should be the first in the chain.

Known limitations:

  1. No extensive testing on Linux/MacOS. The existing fuzzers and unit test work on Linux.
  2. I don't know how to link statically with C runtime on Linux (and haven't looked at MacOS, because I don't have one). glibc can't really be linked statically (because its TLS functionality is not in the static library) and musl has no cpp...
  3. In order to have correct coverage in the multithreaded environment, more changes are required (such as per-thread coverage map). This goes beyond my current scope of work....

…o add the observer, clippy, fmt, and at least linux compilation
…b functions. Only frida_windows_gdiplus tested. Linux not tested
@addisoncrump
Copy link
Collaborator

Okay, I think I figured it out but it required digging around a lot in the guts of libafl_targets. Hopefully still works...

@addisoncrump
Copy link
Collaborator

I see, CI doesn't run if conflicts are present 🤦

@addisoncrump
Copy link
Collaborator

Seems to work. @mkravchik see diff when you get a chance, the trick was to just not use msvc but instead gnullvm and not specify this in the .cargo/config.toml.

@mkravchik
Copy link
Contributor Author

@addisoncrump - thanks a lot! Indeed, lots of black magic involved.

@@ -12,7 +12,7 @@ runs:
with: { shared-key: "${{ runner.os }}-shared-fuzzer-cache" }
- name: Install fuzzers deps
shell: bash
run: sudo apt-get update && sudo apt-get install -y nasm nlohmann-json3-dev gcc-aarch64-linux-gnu g++-aarch64-linux-gnu gcc-mipsel-linux-gnu g++-mipsel-linux-gnu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-i386-cross libc6-dev libc6-dev-i386 lib32gcc-11-dev lib32stdc++-11-dev libgtk-3-dev pax-utils python3-msgpack python3-jinja2
run: sudo apt-get update && sudo apt-get install -y nasm nlohmann-json3-dev gcc-aarch64-linux-gnu g++-aarch64-linux-gnu gcc-mipsel-linux-gnu g++-mipsel-linux-gnu gcc-powerpc-linux-gnu g++-powerpc-linux-gnu libc6-dev-i386-cross libc6-dev libc6-dev-i386 lib32gcc-11-dev lib32stdc++-11-dev libgtk-3-dev pax-utils python3-msgpack python3-jinja2 g++-mingw-w64
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@addisoncrump
we need this?
but it is strange that it fixed your problem. this action file is not used by windows vm at all

Copy link
Member

@tokatoka tokatoka Feb 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(including frida_gdi_plus vm, the ci that failed before this change of yours)

Copy link
Member

@tokatoka tokatoka Feb 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now i understand that build is also running on ubuntu but it's useless.
we removed it in #2949

can you delete it?

and after we merge #2949 then that should be gone.
or you can just ignore that error we'll remove that anyway

@@ -47,7 +47,7 @@ EXT_FUNC_IMPL(main, int, (int argc, char **argv), false) {
#endif
}

#if defined(_WIN32)
#if defined(_WIN32) && !defined(__clang__)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if this doesn't break libfuzzer_windows_asan.
i added the tests in #2961 let's see

@mkravchik
Copy link
Contributor Author

Is there anything you need on my side to merge this?

@tokatoka
Copy link
Member

no but for now i want #2949 to be merged and bring those tests in that PR to see if it works on this branch too

@tokatoka
Copy link
Member

tokatoka commented Feb 13, 2025

in my opinion probably better to change !defined(__clang__) to defined(_MSC_VER) instead. i don't think current code in libafl-targets works with other compilers

@tokatoka
Copy link
Member

On which platform are you building this frida-gdiplus stuff with? You are using windows no?

@tokatoka
Copy link
Member

@mkravchik

@tokatoka
Copy link
Member

tokatoka commented Feb 13, 2025

@mkravchik

Can you delete g++-mingw-w64 dependency that was added in .github/workflows/fuzzer-tester-prepare/action.yml in your branch?

Can you revert this
https://github.com/mkravchik/LibAFL/blob/pr/fasan-multithreading-fixes-upstream/libafl_targets/src/libfuzzer.c#L50
back to #if defined(_MSC_VER) and see if it works for you?

Also please test frida_windows_gdiplus on windows, you should not run or test this on Linux

@mkravchik
Copy link
Contributor Author

Hi, I test on Windows, of course. The failure on Linux was fuzzer_test that ran clippy. only.
These were the changes added by @addisoncrump, if you get rid of clippy on Linux they are not necessary, I guess.
I will check today

@@ -15,7 +15,7 @@ void *__libafl_asan_region_is_poisoned(void *beg, size_t size) {
return NULL;
}

#if defined(__clang__)
#if defined(__clang__) && defined(_MSC_VER)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for this you don't have to revert

@tokatoka
Copy link
Member

@mkravchik
for common.h and cmplog.c don't revert it.. (i.e. don't make any change)

@tokatoka
Copy link
Member

it's not reverted.
can you just run git checkout origin/main -- libafl_targets/src ?

@mkravchik
Copy link
Contributor Author

Here you go.

@tokatoka tokatoka merged commit b3fe744 into AFLplusplus:main Feb 14, 2025
106 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants