This is an archive of the discontinued LLVM Phabricator instance.

[libc] add integration tests for scudo in libc
ClosedPublic

Authored by michaelrj on Jul 27 2021, 2:50 PM.

Details

Summary

This change adds tests to make sure that SCUDO is being properly
included with llvm libc. This change also adds the toggles to properly
use SCUDO, as GWP-ASan is enabled by default and must be included for
SCUDO to function.

Diff Detail

Event Timeline

michaelrj created this revision.Jul 27 2021, 2:50 PM
michaelrj requested review of this revision.Jul 27 2021, 2:50 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 27 2021, 2:50 PM
Herald added a subscriber: Restricted Project. · View Herald Transcript
cryptoad added inline comments.Jul 27 2021, 2:53 PM
compiler-rt/CMakeLists.txt
51

s/COMPILER_RT_BUILD_ORC/COMPILER_RT_BUILD_GWP_ASAN/

michaelrj updated this revision to Diff 362192.Jul 27 2021, 2:56 PM
michaelrj marked an inline comment as done.

fix copy paste error.

hctim added inline comments.Jul 27 2021, 3:09 PM
libc/lib/CMakeLists.txt
19

COMPILER_RT_HAS_GWP_ASAN

sivachandra added inline comments.Jul 27 2021, 3:31 PM
libc/lib/CMakeLists.txt
19

Should this be under if(LLVM_LIBC_INCLUDE_SCUDO)?

libc/test/integration/CMakeLists.txt
2

Fix.

libc/test/integration/scudo/CMakeLists.txt
11

We don't need this as you have added a target_link_libraries call below to link to llvmlibc.

18

Remove this?

40

Fix.

libc/test/integration/scudo/integration_test.cpp
13

Add calls to all allocator related libc functions? For example, follow malloc with free and do the same with realloc, calloc and aligned_alloc?

michaelrj updated this revision to Diff 362217.Jul 27 2021, 4:14 PM
michaelrj marked 7 inline comments as done.

responding to comments.

libc/lib/CMakeLists.txt
19

I can't make this COMPILER_RT_HAS_GWP_ASAN since that variable won't be defined yet because the llvm libc cmake code runs before the compiler-rt cmake code does.

If this was under if(LLVM_LIBC_INCLUDE_SCUDO) then you couldn't include GWP-ASan without also including SCUDO, and I figured it was better to give the user the option.

sivachandra added inline comments.Jul 27 2021, 4:21 PM
libc/lib/CMakeLists.txt
19

Is GWP-ASan useful without something like SCUDO calling into it?

hctim added inline comments.Jul 28 2021, 8:45 AM
libc/lib/CMakeLists.txt
19

That seems weird that libc's full cmake runs before compiler-rt's config-ix.

I think you might run into a problem where you want GWP-ASan, but GWP-ASan isn't supported on your architecture (like mips). In these cases COMPILER_RT_BUILD_GWP_ASAN == True but COMPILER_RT_HAS_GWP_ASAN == False.

Is GWP-ASan useful without something like SCUDO calling into it?

Nope, GWP-ASan needs be called from malloc().

michaelrj marked 2 inline comments as done.

move the gwp-asan if statement inside of the scudo if statement

libc/lib/CMakeLists.txt
19

based on this I've moved the if(COMPILER_RT_BUILD_GWP_ASAN) inside of the if(LLVM_LIBC_INCLUDE_SCUDO).
As for the cmake running order, I'm not actually sure how it ends up working, but I do know that COMPILER_RT_HAS_GWP_ASAN wasn't defined when I tried to use it in this case. Could it have something to do with scopes? I'm not very experienced with cmake.

sivachandra added inline comments.Jul 28 2021, 10:38 AM
libc/lib/CMakeLists.txt
19

Try setting COMPILER_RT_HAS_GWP_ASAN in the PARENT_SCOPE?

michaelrj added inline comments.Jul 28 2021, 3:10 PM
libc/lib/CMakeLists.txt
19

I have now tried that, and it didn't seem to work. I'm not sure why though, given that I think the parent scope should be the one above the compiler-rt directory. My guess would be that the problem is the execution order, but if you have other things to try feel free to suggest them.

sivachandra added inline comments.Jul 28 2021, 3:40 PM
libc/lib/CMakeLists.txt
19

I have no more straightforward ideas. But, a question for @hctim - Why do we have code like this in config-ix.cmake:

list_intersect(GWP_ASAN_SUPPORTED_ARCH
  ALL_GWP_ASAN_SUPPORTED_ARCH
  SANITIZER_COMMON_SUPPORTED_ARCH)

The reason I am asking this is because, if GWP-ASan is standalone, why should the supported archs be deduced from what sanitizer common supports? If we can decouple GWP-ASan CMake logic from the rest of compiler-rt logic, we can potentially put GWP-ASan related pieces in a .cmake file and include that file from within config-ix.cmake and libc CMake files.

hctim added inline comments.Jul 28 2021, 3:57 PM
libc/lib/CMakeLists.txt
19

It doesn't have a dependency on sanitizer-common, but the files are in compiler-rt for licensing/ease-of-setup/historical reasons.

michaelrj marked 3 inline comments as done.

I've added some new CMake machinery to allow for building the SCUDO standalone and GWP-ASan more separately from compiler-rt as a whole, specifically by adding extra conditions that only build the object files. In addition I've separated out the definitions for the different parts of compiler-rt so that llvm libc can check against those.

sivachandra added inline comments.Jul 30 2021, 4:21 PM
compiler-rt/lib/gwp_asan/CMakeLists.txt
81

If GWP-ASan is a standalone (as it does not depend on rest of compiler-rt), can we add the following object libraries unconditionally with ARCHS ${ALL_GWP_ASAN_SUPPORTED_ARCH}? Otherwise, there is again a disconnect between GWP-ASan build and libc build - GWP-ASan object libraries are condition to GWP_ASAN_BUILD_OBJECTS, which depends on GWP_ASAN_SUPPORTED_ARCH, which in turn depends on COMPILER_RT_SUPPORTED_ARCH. May be we can even add the above runtime libraries also unconditionally?

compiler-rt/lib/scudo/standalone/CMakeLists.txt
171 ↗(On Diff #363163)

A similar question for this as well.

michaelrj added inline comments.Aug 2 2021, 9:58 AM
compiler-rt/lib/gwp_asan/CMakeLists.txt
81

If I set this to ARCHS ${ALL_GWP_ASAN_SUPPORTED_ARCH} then I get errors due to the supported platform checking in the add_compiler_rt_object_libraries function. Without modifying that I simply cannot tell it to build for archs not supported by compiler-rt as a whole. If we made a change (such as adding a new function for building just object libraries for all possible archs) I think adding the libraries unconditionally would be fine.

hctim added inline comments.Aug 2 2021, 2:34 PM
compiler-rt/cmake/config-ix.cmake
703

why create a copy of SCUDO_STANDALONE_SUPPORTED_ARCH?

741

remove this

749–753

not necessary if we delete COMPILER_RT_HAS_SANITIZER_COMMON, then we can guard things by COMPILER_RT_HAS_GWP_ASAN

compiler-rt/lib/gwp_asan/CMakeLists.txt
36

remove this

40

add append_list_if(COMPILER_RT_HAS_SANITIZER_COMMON, ${SANITIZER_COMMON_CFLAGS} GWP_ASAN_CFLAGS)

80–82

can revert this diff now that COMPILER_RT_HAS_GWP_ASAN is back to being the source of truth

michaelrj updated this revision to Diff 363596.Aug 2 2021, 4:03 PM
michaelrj marked 6 inline comments as done.

address comments

compiler-rt/cmake/config-ix.cmake
703

I figured it was probably better to condition off of a proper bool as opposed to a list, but if we're not using this at all then I can remove it.

compiler-rt/lib/gwp_asan/CMakeLists.txt
80–82

COMPILER_RT_HAS_GWP_ASAN being the source of truth is useful, but from what I can tell it's still conditioned on the compiler-rt supported architectures. The problem there is that I don't see an easy way to tell compiler-rt that you want to compile for an architecture that isn't the current one. If there's a cmake flag to do that that I have missed, then that would be very helpful.

hctim accepted this revision.Aug 3 2021, 11:16 AM

Have you tested that GWP-ASan works? I know your test runner can't capture stderr/stdout right now, but can you link a program with scudo+llvm-libc+gwp-asan and run a malloc->free->uaf loop and see GWP-ASan crash? Something like compiler-rt/test/gwp_asan/use_after_free.cpp.

libc/lib/CMakeLists.txt
6

nit: break across multiple lines

11

nit: break across multiple lines

This revision is now accepted and ready to land.Aug 3 2021, 11:16 AM
michaelrj updated this revision to Diff 363883.Aug 3 2021, 2:40 PM
michaelrj marked 2 inline comments as done.

add gwp asan test, currently failing.

I added a file copied from use_after_free.cpp but it's not crashing like it's supposed to, which to me means that something might be wrong with the gwp-asan include? I will investigate it further.

hctim added a comment.Aug 3 2021, 2:56 PM

I added a file copied from use_after_free.cpp but it's not crashing like it's supposed to, which to me means that something might be wrong with the gwp-asan include? I will investigate it further.

Yeah, sorry, the bad access should be done in a loop or with GWP_ASAN_OPTIONS=SampleRate=1, i.e.

int main() {
  for (unsigned i = 0; i < 0x10000; ++i) {
    char *Ptr = reinterpret_cast<char *>(malloc(10));

    for (unsigned i = 0; i < 10; ++i) {
      *(Ptr + i) = 0x0;
    }

    free(Ptr);
    volatile char x = *Ptr;
  }
  return x;
}

I should've made that more clear.

michaelrj updated this revision to Diff 363901.Aug 3 2021, 4:13 PM

Ah, I see. I've changed it according to your suggestion and it works properly now.

hctim accepted this revision.Aug 3 2021, 8:35 PM

LGTM w/ nit. Thanks for doing this!

libc/test/integration/scudo/gwp_asan_should_crash.cpp
23

is this necessary?

sivachandra added inline comments.Aug 3 2021, 9:28 PM
libc/lib/CMakeLists.txt
5

I think this check and the GWP-ASan check below are best effort checks. For, it can so happen that the SCUDO and GWP-ASan object libraries might not be available while satisfying this check. Am I right?

libc/test/integration/scudo/CMakeLists.txt
40

This showed up again.

sivachandra accepted this revision.Aug 3 2021, 9:28 PM
michaelrj updated this revision to Diff 364173.Aug 4 2021, 10:17 AM
michaelrj marked 4 inline comments as done.

final nits

libc/lib/CMakeLists.txt
5

Correct. If compiler-rt and llvm libc are set to compile to different architectures then there will be an error here, but hopefully that won't be a problem in the real world.

libc/test/integration/scudo/gwp_asan_should_crash.cpp
23

yes, because otherwise the compiler warns about x being an unused variable.

michaelrj retitled this revision from [libc][wip] add integration tests for scudo in libc to [libc] add integration tests for scudo in libc.Aug 4 2021, 10:18 AM
michaelrj edited the summary of this revision. (Show Details)
michaelrj updated this revision to Diff 364179.Aug 4 2021, 10:34 AM

removed a debug message

This revision was automatically updated to reflect the committed changes.