summaryrefslogtreecommitdiff
path: root/lib/scudo
AgeCommit message (Collapse)Author
2017-12-14[scudo] Refactor ScudoChunkKostya Kortchinsky
Summary: The initial implementation used an ASan like Chunk class that was deriving from a Header class. Due to potential races, we ended up working with local copies of the Header and never using the parent class fields. ScudoChunk was never constructed but cast, and we were using `this` as the pointer needed for our computations. This was meh. So we refactored ScudoChunk to be now a series of static functions within the namespace `__scudo::Chunk` that take a "user" pointer as first parameter (former `this`). A compiled binary doesn't really change, but the code is more sensible. Clang tends to inline all those small function (in -O2), but GCC left a few not inlined, so we add the `INLINE` keyword to all. Since we don't have `ScudoChunk` pointers anymore, a few variables were renamed here and there to introduce a clearer distinction between a user pointer (usually `Ptr`) and a backend pointer (`BackendPtr`). Reviewers: alekseyshl, flowerhack Reviewed By: alekseyshl Subscribers: #sanitizers, llvm-commits Differential Revision: https://reviews.llvm.org/D41200 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@320745 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-13[scudo] Adding a public Scudo interfaceKostya Kortchinsky
Summary: The first and only function to start with allows to set the soft or hard RSS limit at runtime. Add associated tests. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: mgorny, #sanitizers, llvm-commits Differential Revision: https://reviews.llvm.org/D41128 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@320611 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-13[sanitizer] Introduce a vDSO aware timing functionKostya Kortchinsky
Summary: See D40657 & D40679 for previous versions of this patch & description. A couple of things were fixed here to have it not break some bots. Weak symbols can't be used with `SANITIZER_GO` so the previous version was breakin TsanGo. I set up some additional local tests and those pass now. I changed the workaround for the glibc vDSO issue: `__progname` is initialized after the vDSO and is actually public and of known type, unlike `__vdso_clock_gettime`. This works better, and with all compilers. The rest is the same. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: srhines, kubamracek, krytarowski, llvm-commits, #sanitizers Differential Revision: https://reviews.llvm.org/D41121 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@320594 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-13[scudo] Inline getScudoChunk function.Kostya Kortchinsky
Summary: getScudoChunk function is implicitly inlined for optimized builds on clang, but not on gcc. It's a small enough function that it seems sensible enough to just inline it by default. Reviewers: cryptoad, alekseyshl Reviewed By: cryptoad Differential Revision: https://reviews.llvm.org/D41138 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@320592 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-11[sanitizer] Revert rL320409Kostya Kortchinsky
Summary: D40679 broke a couple of builds, reverting while investigating. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: srhines, kubamracek, krytarowski, llvm-commits, #sanitizers Differential Revision: https://reviews.llvm.org/D41088 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@320417 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-11[sanitizer] Introduce a vDSO aware time function, and use it in the ↵Kostya Kortchinsky
allocator [redo] Summary: Redo of D40657, which had the initial discussion. The initial code had to move into a libcdep file, and things had to be shuffled accordingly. `NanoTime` is a time sink when checking whether or not to release memory to the OS. While reducing the amount of calls to said function is in the works, another solution that was found to be beneficial was to use a timing function that can leverage the vDSO. We hit a couple of snags along the way, like the fact that the glibc crashes when clock_gettime is called from a preinit_array, or the fact that `__vdso_clock_gettime` is mangled (for security purposes) and can't be used directly, and also that clock_gettime can be intercepted. The proposed solution takes care of all this as far as I can tell, and significantly improve performances and some Scudo load tests with memory reclaiming enabled. @mcgrathr: please feel free to follow up on https://reviews.llvm.org/D40657#940857 here. I posted a reply at https://reviews.llvm.org/D40657#940974. Reviewers: alekseyshl, krytarowski, flowerhack, mcgrathr, kubamracek Reviewed By: alekseyshl, krytarowski Subscribers: #sanitizers, mcgrathr, srhines, llvm-commits, kubamracek Differential Revision: https://reviews.llvm.org/D40679 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@320409 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-08[scudo] Minor code generation improvementKostya Kortchinsky
Summary: It looks like clang was generating somewhat weird assembly with the current code. `FromPrimary`, even though `const`, was replaced every time with the code generated for `size <= SizeClassMap::kMaxSize` instead of using a variable or register, and `FromPrimary` didn't induce `ClassId != 0` for the compiler, so a dead branch was generated for `getActuallyAllocatedSize(Ptr, ClassId)` since it's never called for `ClassId = 0` (Secondary backed allocations) [this one was more wishful thinking on my side than anything else]. I rearranged the code bit so that the generated assembly is less clunky. Also changed 2 whitespace inconsistencies that were bothering me. Reviewers: alekseyshl, flowerhack Reviewed By: flowerhack Subscribers: llvm-commits, #sanitizers Differential Revision: https://reviews.llvm.org/D40976 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@320160 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-06[scudo] Correct performance regression in SecondaryKostya Kortchinsky
Summary: This wasn't noticed: `RoundUpTo` doesn't produce a constant expression, so the sizes were not constant either. Enforce them to be static const, replace `RoundUpTo` by its expression. The compiler can now optimize the associated computations accordingly. Also looking at the produced assembly, `PageSize` was fetched multiple times during `Allocate`, so keep a local value of it. As a result it's fetched once and kept in a register. Reviewers: alekseyshl, flowerhack Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D40862 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@319903 91177308-0d34-0410-b5e6-96231b3b80d8
2017-12-05[scudo] Get rid of the thread local PRNG & header saltKostya Kortchinsky
Summary: It was deemed that the salt in the chunk header didn't improve security significantly (and could actually decrease it). The initial idea was that the same chunk would different headers on different allocations, allowing for less predictability. The issue is that gathering the same chunk header with different salts can give information about the other "secrets" (cookie, pointer), and that if an attacker leaks a header, they can reuse it anyway for that same chunk anyway since we don't enforce the salt value. So we get rid of the salt in the header. This means we also get rid of the thread local Prng, and that we don't need a global Prng anymore as well. This makes everything faster. We reuse those 8 bits to store the `ClassId` of a chunk now (0 for a secondary based allocation). This way, we get some additional speed gains: - `ClassId` is computed outside of the locked block; - `getActuallyAllocatedSize` doesn't need the `GetSizeClass` call; - same for `deallocatePrimary`; We add a sanity check at init for this new field (all sanity checks are moved in their own function, `init` was getting crowded). Reviewers: alekseyshl, flowerhack Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D40796 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@319791 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-29[scudo] Allow for compile-time choice of the SizeClassMapKostya Kortchinsky
Summary: With this change, we allow someone to chose the `SizeClassMap` they want to use at compile time via a define. I feel somewhat unimaginative with the name of the defines, so if someone has a better idea, let me know. I have been alternating between those and `SCUDO_USE_xxx_SIZECLASSMAP` which is clearer but also longer. The issue with those is that it wouldn't be consistent with `SCUDO_TSD_EXCLUSIVE` that should probably become `SCUDO_USE_EXCLUSIVE_TSD` maybe? Anyway, naming is hard, and I am not sure what makes more sense! Reviewers: alekseyshl, flowerhack Reviewed By: alekseyshl Subscribers: llvm-commits, srhines Differential Revision: https://reviews.llvm.org/D40521 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@319350 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-27[scudo] Workaround for uninitialized Bionic globalsKostya Kortchinsky
Summary: Bionic doesn't initialize its globals early enough. This causes issues when trying to access them from a preinit_array (b/25751302) or from another constructor called before the libc one (b/68046352). __progname is initialized after the other globals, so we can check its value to know if calling `getauxval` is safe. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: srhines, llvm-commits Differential Revision: https://reviews.llvm.org/D40504 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@319099 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-22[scudo] Overhaul hardware CRC32 feature detectionKostya Kortchinsky
Summary: This patch aims at condensing the hardware CRC32 feature detection and making it slightly more effective on Android. The following changes are included: - remove the `CPUFeature` enum, and get rid of one level of nesting of functions: we only used CRC32, so we just implement and use `hasHardwareCRC32`; - allow for a weak `getauxval`: the Android toolchain is compiled at API level 14 for Android ARM, meaning no `getauxval` at compile time, yet we will run on API level 27+ devices. The `/proc/self/auxv` fallback can work but is worthless for a process like `init` where the proc filesystem doesn't exist yet. If a weak `getauxval` doesn't exist, then fallback. - couple of extra corrections. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: kubamracek, aemerson, srhines, kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D40322 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@318859 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-21[scudo] Make getNumberOfCPUs Fuchsia compliant v2Kostya Kortchinsky
Summary: This change allows Fuchsia to boot properly using the Scudo allocator. A first version of this commit was reverted by rL317834 because it broke Android builds for toolchains generated with older NDKs. This commit introduces a fall back to solve that issue. Reviewers: cryptoad, krytarowski, rnk, alekseyshl Reviewed By: cryptoad, krytarowski, alekseyshl Subscribers: llvm-commits, srhines, kubamracek, krytarowski Differential Revision: https://reviews.llvm.org/D40121 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@318802 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-15[scudo] Soft and hard RSS limit checksKostya Kortchinsky
Summary: This implements an opportunistic check for the RSS limit. For ASan, this was implemented thanks to a background thread checking the current RSS vs the set limit every 100ms. This was deemed problematic for Scudo due to potential Android concerns (Zygote as pointed out by Aleksey) as well as the general inconvenience of having a permanent background thread. If a limit (soft or hard) is specified, we will attempt to update the RSS limit status (exceeded or not) every 100ms. This is done in an opportunistic way: if we can update it, we do it, if not we return the current status, mostly because we don't need it to be fully consistent (it's done every 100ms anyway). If the limit is exceeded `allocate` will act as if OOM for a soft limit, or just die for a hard limit. We use the `common_flags()`'s `hard_rss_limit_mb` & `soft_rss_limit_mb` for configuration of the limits. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D40038 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@318301 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-14[scudo] Simplify initialization and flagsKostya Kortchinsky
Summary: This is mostly some cleanup and shouldn't affect functionalities. Reviewing some code for a future addition, I realized that the complexity of the initialization path was unnecessary, and so was maintaining a structure for the allocator options throughout the initialization. So we get rid of that structure, of an extraneous level of nesting for the `init` function, and correct a couple of related code inaccuracies in the flags cpp. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39974 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@318157 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-13[sanitizer] Update scudo to use new APIKostya Kortchinsky
Summary: The ScudoAllocator uses a SecondaryHeader to keep track of the size and base address of each mmap'd chunk. This aligns well with what the ReservedAddressRange is trying to do. This changeset converts the scudo allocator from using the MmapNoAccess/MmapFixed APIs to the ReservedAddressRange::Init and ::Map APIs. In doing so, it replaces the SecondayHeader struct with the ReservedAddressRange object. This is part 3 of a 4 part changeset; part 1 https://reviews.llvm.org/D39072 and part 2 https://reviews.llvm.org/D38592 Reviewers: alekseyshl, mcgrathr, cryptoad, phosek Reviewed By: cryptoad Subscribers: llvm-commits, cryptoad, kubamracek Differential Revision: https://reviews.llvm.org/D38593 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@318080 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-10[scudo] Bump the Android API level requirement to 21 for getauxvalKostya Kortchinsky
Summary: `getauxval` was introduced in 18 & 21 depending on the architecture. Bump the requirement to 21. It also turns out that the NDK is finicky: NDK r13b doesn't include sys/auxv.h when creating a standalone toolchain at API level 19 for ARM. So 18 didn't work well with older NDKs. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: aemerson, srhines, llvm-commits, kristof.beyls Differential Revision: https://reviews.llvm.org/D39905 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317907 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-09[sanitizer] Revert rL317822Kostya Kortchinsky
Summary: This reverts D39490. For toolchains generated with older NDKs (<=r13b as far as we tested), `cpu_set_t` doesn't exist in `sched.h`. We have to figure out another way to get the number of CPUs without this. Reviewers: rnk Reviewed By: rnk Subscribers: kubamracek, llvm-commits, krytarowski Differential Revision: https://reviews.llvm.org/D39867 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317834 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-09[scudo] Make getNumberOfCPUs Fuchsia compliantKostya Kortchinsky
Summary: This change allows Fuchsia to boot properly using the Scudo allocator. Reviewers: cryptoad, alekseyshl, krytarowski Reviewed By: cryptoad, krytarowski Subscribers: rnk, krytarowski, kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D39490 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317822 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-08[sanitizer] Add Scudo to the sanitizer lint checks.Kostya Kortchinsky
Summary: Scudo abides by the coding style enforced by the sanitizer_common linter, but as of right now, it's not linter-enforced. Add Scudo to the list of directories checked by check_lint.sh. Also: fixes some linter errors found after getting this running. Reviewers: cryptoad Reviewed By: cryptoad Subscribers: llvm-commits, kubamracek Differential Revision: https://reviews.llvm.org/D39757 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317699 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-08Revert "[scudo] Make getNumberOfCPUs Fuchsia compliant"Reid Kleckner
This reverts commit r317604. Android doesn't have cpu_set_t. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317655 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-07[scudo] Make getNumberOfCPUs Fuchsia compliantKostya Kortchinsky
Summary: This change allows Fuchsia to boot properly using the Scudo allocator. Reviewers: cryptoad, alekseyshl, krytarowski Reviewed By: cryptoad, krytarowski Subscribers: krytarowski, kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D39490 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317604 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-03[scudo] Rearrange #include orderKostya Kortchinsky
Summary: To be compliant with https://llvm.org/docs/CodingStandards.html#include-style, system headers have to come after local headers. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39623 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317390 91177308-0d34-0410-b5e6-96231b3b80d8
2017-11-01[scudo] Implement stricter separation of C vs C++Kostya Kortchinsky
Summary: Initially, Scudo had a monolithic design where both C and C++ functions were living in the same library. This was not necessarily ideal, and with the work on -fsanitize=scudo, it became more apparent that this needed to change. We are splitting the new/delete interceptor in their own C++ library. This allows more flexibility, notably with regard to std::bad_alloc when the work is done. This also allows us to not link new & delete when using pure C. Additionally, we add the UBSan runtimes with Scudo, in order to be able to have a -fsanitize=scudo,undefined in Clang (see work in D39334). The changes in this patch: - split the cxx specific code in the scudo cmake file into a new library; (remove the spurious foreach loop, that was not necessary) - add the UBSan runtimes (both C and C++); - change the test cmake file to allow for specific C & C++ tests; - make C tests pure C, rename their extension accordingly. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: srhines, mgorny, llvm-commits Differential Revision: https://reviews.llvm.org/D39461 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@317097 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-27[scudo] Allow to specify the maximum number of TSDs at compile timeKostya Kortchinsky
Summary: This introduces `SCUDO_MAX_CACHES` allowing to define an upper bound to the number of `ScudoTSD` created in the Shared TSD model (by default 32U). This name felt clearer than `SCUDO_MAX_TSDS` which is technically what it really is. I am opened to suggestions if that doesn't feel right. Additionally change `getNumberOfCPUs` to return a `u32` to be more consistent. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39338 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@316788 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-25[scudo] Remove comment about security of the 32-bit allocatorKostya Kortchinsky
Summary: The 32-bit allocator is now on par with the 64-bit in terms of security (chunks randomization is done, batches separation is done). Unless objection, the comment can go away. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D39303 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@316620 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-23[scudo] Add a shared runtimeKostya Kortchinsky
Summary: Up to now, the Scudo cmake target only provided a static library that had to be linked to an executable to benefit from the hardened allocator. This introduces a shared library as well, that can be LD_PRELOAD'ed. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: srhines, mgorny, llvm-commits Differential Revision: https://reviews.llvm.org/D38980 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@316342 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-16[scudo] Do not include sanitizer_posix.h if not on a Posix platformKostya Kortchinsky
Summary: Move the `sanitizer_posix.h` include within the `SANITIZER_ANDROID` `#if`, otherwise this errors when built on non-Posix platforms (eg: Fuchsia). Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D38956 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@315917 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-13[scudo] Allow for non-Android Shared TSD platforms, part 2Kostya Kortchinsky
Summary: Follow up to D38826. We introduce `pthread_{get,set}specific` versions of `{get,set}CurrentTSD` to allow for non Android platforms to use the Shared TSD model. We now allow `SCUDO_TSD_EXCLUSIVE` to be defined at compile time. A couple of things: - I know that `#if SANITIZER_ANDROID` is not ideal within a function, but in the end I feel it looks more compact and clean than going the .inc route; I am open to an alternative if anyone has one; - `SCUDO_TSD_EXCLUSIVE=1` requires ELF TLS support (and not emutls as this uses malloc). I haven't found anything to enforce that, so it's currently not checked. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: srhines, llvm-commits Differential Revision: https://reviews.llvm.org/D38854 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@315751 91177308-0d34-0410-b5e6-96231b3b80d8
2017-10-12[scudo] Allow for non-Android Shared TSD platforms, part 1Kostya Kortchinsky
Summary: This first part just prepares the grounds for part 2 and doesn't add any new functionality. It mostly consists of small refactors: - move the `pthread.h` include higher as it will be used in the headers; - use `errno.h` in `scudo_allocator.cpp` instead of the sanitizer one, update the `errno` assignments accordingly (otherwise it creates conflicts on some platforms due to `pthread.h` including `errno.h`); - introduce and use `getCurrentTSD` and `setCurrentTSD` for the shared TSD model code; Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits, srhines Differential Revision: https://reviews.llvm.org/D38826 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@315583 91177308-0d34-0410-b5e6-96231b3b80d8
2017-09-26[scudo] Scudo thread specific data refactor, part 3Kostya Kortchinsky
Summary: Previous parts: D38139, D38183. In this part of the refactor, we abstract the Linux vs Android TSD dissociation in favor of a Exclusive vs Shared one, allowing for easier platform introduction and configuration. Most of this change consist of shuffling the files around to reflect the new organization. We introduce `scudo_platform.h` where platform specific definition lie. This involves the TSD model and the platform specific allocator parameters. In an upcoming CL, those will be configurable via defines, but we currently stick with conservative defaults. Reviewers: alekseyshl, dvyukov Reviewed By: alekseyshl, dvyukov Subscribers: srhines, llvm-commits, mgorny Differential Revision: https://reviews.llvm.org/D38244 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@314224 91177308-0d34-0410-b5e6-96231b3b80d8
2017-09-25[scudo] Scudo thread specific data refactor, part 2Kostya Kortchinsky
Summary: Following D38139, we now consolidate the TSD definition, merging the shared TSD definition with the exclusive TSD definition. We introduce a boolean set at initializaton denoting the need for the TSD to be unlocked or not. This adds some unused members to the exclusive TSD, but increases consistency and reduces the definitions fragmentation. We remove the fallback mechanism from `scudo_allocator.cpp` and add a fallback TSD in the non-shared version. Since the shared version doesn't require one, this makes overall more sense. There are a couple of additional cosmetic changes: removing the header guards from the remaining `.inc` files, added error string to a `CHECK`. Question to reviewers: I thought about friending `getTSDAndLock` in `ScudoTSD` so that the `FallbackTSD` could `Mutex.Lock()` directly instead of `lock()` which involved zeroing out the `Precedence`, which is unused otherwise. Is it worth doing? Reviewers: alekseyshl, dvyukov, kcc Reviewed By: dvyukov Subscribers: srhines, llvm-commits Differential Revision: https://reviews.llvm.org/D38183 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@314110 91177308-0d34-0410-b5e6-96231b3b80d8
2017-09-22[scudo] Scudo thread specific data refactor, part 1Kostya Kortchinsky
Summary: We are going through an overhaul of Scudo's TSD, to allow for new platforms to be integrated more easily, and make the code more sound. This first part is mostly renaming, preferring some shorter names, correcting some comments. I removed `getPrng` and `getAllocatorCache` to directly access the members, there was not really any benefit to them (and it was suggested by Dmitry in D37590). The only functional change is in `scudo_tls_android.cpp`: we enforce bounds to the `NumberOfTSDs` and most of the logic in `getTSDAndLockSlow` is skipped if we only have 1 TSD. Reviewers: alekseyshl, dvyukov, kcc Reviewed By: dvyukov Subscribers: llvm-commits, srhines Differential Revision: https://reviews.llvm.org/D38139 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@313987 91177308-0d34-0410-b5e6-96231b3b80d8
2017-09-14[scudo] Fix bad request handling when allocator has not been initializedKostya Kortchinsky
Summary: In a few functions (`scudoMemalign` and the like), we would call `ScudoAllocator::FailureHandler::OnBadRequest` if the parameters didn't check out. The issue is that if the allocator had not been initialized (eg: if this is the first heap related function called), we would use variables like `allocator_may_return_null` and `exitcode` that still had their default value (as opposed to the one set by the user or the initialization path). To solve this, we introduce `handleBadRequest` that will call `initThreadMaybe`, allowing the options to be correctly initialized. Unfortunately, the tests were passing because `exitcode` was still 0, so the results looked like success. Change those tests to do what they were supposed to. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D37853 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@313294 91177308-0d34-0410-b5e6-96231b3b80d8
2017-09-11[scudo] Fix improper TSD init after TLS destructors are calledKostya Kortchinsky
Summary: Some of glibc's own thread local data is destroyed after a user's thread local destructors are called, via __libc_thread_freeres. This might involve calling free, as is the case for strerror_thread_freeres. If there is no prior heap operation in the thread, this free would end up initializing some thread specific data that would never be destroyed properly (as user's pthread destructors have already been called), while still being deallocated when the TLS goes away. As a result, a program could SEGV, usually in __sanitizer::AllocatorGlobalStats::Unregister, where one of the doubly linked list links would refer to a now unmapped memory area. To prevent this from happening, we will not do a full initialization from the deallocation path. This means that the fallback cache & quarantine will be used if no other heap operation has been called, and we effectively prevent the TSD being initialized and never destroyed. The TSD will be fully initialized for all other paths. In the event of a thread doing only frees and nothing else, a TSD would never be initialized for that thread, but this situation is unlikely and we can live with that. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D37697 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@312939 91177308-0d34-0410-b5e6-96231b3b80d8
2017-09-06[scudo] getauxval alternative for AndroidKostya Kortchinsky
Summary: `getauxval` was introduced with API level 18. In order to get things to work at lower API levels (for the toolchain itself which is built at 14 for 32-bit), we introduce an alternative implementation reading directly from `/proc/self/auxv`. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: srhines, llvm-commits Differential Revision: https://reviews.llvm.org/D37488 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@312653 91177308-0d34-0410-b5e6-96231b3b80d8
2017-08-28[sanitizer] Re-introduce kUseSeparateSizeClassForBatch for the 32-bit PrimaryKostya Kortchinsky
Summary: Currently `TransferBatch` are located within the same memory regions as "regular" chunks. This is not ideal for security: they make for an interesting target to overwrite, and are not protected by the frontend (namely, Scudo). To solve this, we re-introduce `kUseSeparateSizeClassForBatch` for the 32-bit Primary allowing for `TransferBatch` to end up in their own memory region. Currently only Scudo would use this new feature, the default behavior remains unchanged. The separate `kBatchClassID` was used for a brief period of time previously but removed when the 64-bit ended up using the "free array". Reviewers: alekseyshl, kcc, eugenis Reviewed By: alekseyshl Subscribers: llvm-commits, kubamracek Differential Revision: https://reviews.llvm.org/D37082 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@311891 91177308-0d34-0410-b5e6-96231b3b80d8
2017-08-16[scudo] Application & platform compatibility changesKostya Kortchinsky
Summary: This patch changes a few (small) things around for compatibility purposes for the current Android & Fuchsia work: - `realloc`'ing some memory that was not allocated with `malloc`, `calloc` or `realloc`, while UB according to http://pubs.opengroup.org/onlinepubs/009695399/functions/realloc.html is more common that one would think. We now only check this if `DeallocationTypeMismatch` is set; change the "mismatch" error messages to be more homogeneous; - some sketchily written but widely used libraries expect a call to `realloc` to copy the usable size of the old chunk to the new one instead of the requested size. We have to begrundingly abide by this de-facto standard. This doesn't seem to impact security either way, unless someone comes up with something we didn't think about; - the CRC32 intrinsics for 64-bit take a 64-bit first argument. This is misleading as the upper 32 bits end up being ignored. This was also raising `-Wconversion` errors. Change things to take a `u32` as first argument. This also means we were (and are) only using 32 bits of the Cookie - not a big thing, but worth mentioning. - Includes-wise: prefer `stddef.h` to `cstddef`, move `scudo_flags.h` where it is actually needed. - Add tests for the memalign-realloc case, and the realloc-usable-size one. (Edited typos) Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D36754 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@311018 91177308-0d34-0410-b5e6-96231b3b80d8
2017-08-14[sanitizers] Add a blocking boolean to GetRandom prototypeKostya Kortchinsky
Summary: On platforms with `getrandom`, the system call defaults to blocking. This becomes an issue in the very early stage of the boot for Scudo, when the RNG source is not set-up yet: the syscall will block and we'll stall. Introduce a parameter to specify that the function should not block, defaulting to blocking as the underlying syscall does. Update Scudo to use the non-blocking version. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits, kubamracek Differential Revision: https://reviews.llvm.org/D36399 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@310839 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-25[scudo] Check for pvalloc overflowKostya Kortchinsky
Summary: Previously we were rounding up the size passed to `pvalloc` to the next multiple of page size no matter what. There is an overflow possibility that wasn't accounted for. So now, return null in the event of an overflow. The man page doesn't seem to indicate the errno to set in this particular situation, but the glibc unit tests go for ENOMEM (https://code.woboq.org/userspace/glibc/malloc/tst-pvalloc.c.html#54) so we'll do the same. Update the aligned allocation funtions tests to check for properly aligned returned pointers, and the `pvalloc` corner cases. @alekseyshl: do you want me to do the same in the other Sanitizers? Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: kubamracek, alekseyshl, llvm-commits Differential Revision: https://reviews.llvm.org/D35818 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@309033 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-24[scudo] Quarantine overhaulKostya Kortchinsky
Summary: First, some context. The main feedback we get about the quarantine is that it's too memory hungry. A single MB of quarantine will have an impact of 3 to 4MB of PSS/RSS, and things quickly get out of hand in terms of memory usage, and the quarantine ends up disabled. The main objective of the quarantine is to protect from use-after-free exploitation by making it harder for an attacker to reallocate a controlled chunk in place of the targeted freed chunk. This is achieved by not making it available to the backend right away for reuse, but holding it a little while. Historically, what has usually been the target of such attacks was objects, where vtable pointers or other function pointers could constitute a valuable targeti to replace. Those are usually on the smaller side. There is barely any advantage in putting the quarantine several megabytes of RGB data or the like. Now for the patch. This patch introduces a new way the Quarantine behaves in Scudo. First of all, the size of the Quarantine will be defined in KB instead of MB, then we introduce a new option: the size up to which (lower than or equal to) a chunk will be quarantined. This way, we only quarantine smaller chunks, and the size of the quarantine remains manageable. It also prevents someone from triggering a recycle by allocating something huge. We default to 512 bytes on 32-bit and 2048 bytes on 64-bit platforms. In details, the patches includes the following: - introduce `QuarantineSizeKb`, but honor `QuarantineSizeMb` if set to fall back to the old behavior (meaning no threshold in that case); `QuarantineSizeMb` is described as deprecated in the options descriptios; documentation update will follow; - introduce `QuarantineChunksUpToSize`, the new threshold value; - update the `quarantine.cpp` test, and other tests using `QuarantineSizeMb`; - remove `AllocatorOptions::copyTo`, it wasn't used; - slightly change the logic around `quarantineOrDeallocateChunk` to accomodate for the new logic; rename a couple of variables there as well; Rewriting the tests, I found a somewhat annoying bug where non-default aligned chunks would account for more than needed when placed in the quarantine due to `<< MinAlignment` instead of `<< MinAlignmentLog`. This is fixed and tested for now. Reviewers: alekseyshl, kcc Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D35694 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@308884 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-18[Sanitizers] ASan/MSan/LSan allocators set errno on failure.Alex Shlyapnikov
Summary: ASan/MSan/LSan allocators set errno on allocation failures according to malloc/calloc/etc. expected behavior. MSan allocator was refactored a bit to make its structure more similar with other allocators. Also switch Scudo allocator to the internal errno definitions. TSan allocator changes will follow. Reviewers: eugenis Subscribers: llvm-commits, kubamracek Differential Revision: https://reviews.llvm.org/D35275 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@308344 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-14[Sanitizers] Scudo allocator set errno on failure.Alex Shlyapnikov
Summary: Set proper errno code on alloction failure and change pvalloc and posix_memalign implementation to satisfy their man-specified requirements. Reviewers: cryptoad Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D35429 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@308053 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-13[scudo] Do not grab a cache for secondary allocation & per related changesKostya Kortchinsky
Summary: Secondary backed allocations do not require a cache. While it's not necessary an issue when each thread has its cache, it becomes one with a shared pool of caches (Android), as a Secondary backed allocation or deallocation holds a cache that could be useful to another thread doing a Primary backed allocation. We introduce an additional PRNG and its mutex (to avoid contention with the Fallback one for Primary allocations) that will provide the `Salt` needed for Secondary backed allocations. I changed some of the code in a way that feels more readable to me (eg: using some values directly rather than going through ternary assigned variables, using directly `true`/`false` rather than `FromPrimary`). I will let reviewers decide if it actually is. An additional change is to mark `CheckForCallocOverflow` as `UNLIKELY`. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D35358 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@307958 91177308-0d34-0410-b5e6-96231b3b80d8
2017-07-12[scudo] PRNG makeoverKostya Kortchinsky
Summary: This follows the addition of `GetRandom` with D34412. We remove our `/dev/urandom` code and use the new function. Additionally, change the PRNG for a slightly faster version. One of the issues with the old code is that we have 64 full bits of randomness per "next", using only 8 of those for the Salt and discarding the rest. So we add a cached u64 in the PRNG that can serve up to 8 u8 before having to call the "next" function again. During some integration work, I also realized that some very early processes (like `init`) do not benefit from `/dev/urandom` yet. So if there is no `getrandom` syscall as well, we have to fallback to some sort of initialization of the PRNG. Now a few words on why XoRoShiRo and not something else. I have played a while with various PRNGs on 32 & 64 bit platforms. Some results are below. LCG 32 & 64 are usually faster but produce respectively 15 & 31 bits of entropy, meaning that to get a full 64-bit, you would need to call them several times. The simple XorShift is fast, produces 32 bits but is mediocre with regard to PRNG test suites, PCG is slower overall, and XoRoShiRo is faster than XorShift128+ and produces full 64 bits. %%% root@tulip-chiphd:/data # ./randtest.arm [+] starting xs32... [?] xs32 duration: 22431833053ns [+] starting lcg32... [?] lcg32 duration: 14941402090ns [+] starting pcg32... [?] pcg32 duration: 44941973771ns [+] starting xs128p... [?] xs128p duration: 48889786981ns [+] starting lcg64... [?] lcg64 duration: 33831042391ns [+] starting xos128p... [?] xos128p duration: 44850878605ns root@tulip-chiphd:/data # ./randtest.aarch64 [+] starting xs32... [?] xs32 duration: 22425151678ns [+] starting lcg32... [?] lcg32 duration: 14954255257ns [+] starting pcg32... [?] pcg32 duration: 37346265726ns [+] starting xs128p... [?] xs128p duration: 22523807219ns [+] starting lcg64... [?] lcg64 duration: 26141304679ns [+] starting xos128p... [?] xos128p duration: 14937033215ns %%% Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: aemerson, kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D35221 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@307798 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-29MergeAlex Shlyapnikov
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@306748 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-29[scudo] Change aligned alloc functions to be more compliant & perf changesKostya Kortchinsky
Summary: We were not following the `man` documented behaviors for invalid arguments to `memalign` and associated functions. Using `CHECK` for those was a bit extreme, so we relax the behavior to return null pointers as expected when this happens. Adapt the associated test. I am using this change also to change a few more minor performance improvements: - mark as `UNLIKELY` a bunch of unlikely conditions; - the current `CHECK` in `__sanitizer::RoundUpTo` is redundant for us in *all* calls. So I am introducing our own version without said `CHECK`. - change our combined allocator `GetActuallyAllocatedSize`. We already know if the pointer is from the Primary or Secondary, so the `PointerIsMine` check is redundant as well, and costly for the 32-bit Primary. So we get the size by directly using the available Primary functions. Finally, change a `int` to `uptr` to avoid a warning/error when compiling on Android. Reviewers: alekseyshl Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D34782 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@306698 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-28[Sanitizers] Operator new() interceptors always die on allocation errorAlex Shlyapnikov
Summary: Operator new interceptors behavior is now controlled by their nothrow property as well as by allocator_may_return_null flag value: - allocator_may_return_null=* + new() - die on allocation error - allocator_may_return_null=0 + new(nothrow) - die on allocation error - allocator_may_return_null=1 + new(nothrow) - return null Ideally new() should throw std::bad_alloc exception, but that is not trivial to achieve, hence TODO. Reviewers: eugenis Subscribers: kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D34731 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@306604 91177308-0d34-0410-b5e6-96231b3b80d8
2017-06-20[Sanitizers] Move cached allocator_may_return_null flag to sanitizer_allocatorAlex Shlyapnikov
Summary: Move cached allocator_may_return_null flag to sanitizer_allocator.cc and provide API to consolidate and unify the behavior of all specific allocators. Make all sanitizers using CombinedAllocator to follow AllocatorReturnNullOrDieOnOOM() rules to behave the same way when OOM happens. When OOM happens, turn allocator_out_of_memory flag on regardless of allocator_may_return_null flag value (it used to not to be set when allocator_may_return_null == true). release_to_os_interval_ms and rss_limit_exceeded will likely be moved to sanitizer_allocator.cc too (later). Reviewers: eugenis Subscribers: srhines, kubamracek, llvm-commits Differential Revision: https://reviews.llvm.org/D34310 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@305858 91177308-0d34-0410-b5e6-96231b3b80d8
2017-05-26[scudo] Check the return values of the pthread_* functionsKostya Kortchinsky
Summary: Currently we are not enforcing the success of `pthread_once`, and `pthread_setspecific`. Errors could lead to harder to debug issues later in the thread's life. This adds checks for a 0 return value for both. If `pthread_setspecific` fails in the teardown path, opt for an immediate teardown as opposed to a fatal failure. Reviewers: alekseyshl, kcc Reviewed By: alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D33555 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@303998 91177308-0d34-0410-b5e6-96231b3b80d8