33 Commits

Author SHA1 Message Date
Fabio D'Urso
adc11b34b1
Sync FuchsiaConfig with downstream's custom_scudo_config.h (#89244)
Downstream disabled EnableContiguousRegions on RISCV-64 to avoid
running out of virtual memory, but our tests still use the internal
FuchsiaConfig class, which therefore needs to be changed too.
2024-04-19 21:27:53 +02:00
ChiaHungDuan
2dc9ec47fb
[scudo] Refactor allocator config to support optional flags (#81805)
Instead of explicitly disabling a feature by declaring the variable and
set it to false, this change supports the optional flags. I.e., you can
skip certain flags if you are not using it.

This optional feature supports both forms,
  1. Value: A parameter for a feature. E.g., EnableRandomOffset
  2. Type: A C++ type implementing a feature. E.g., ConditionVariableT

On the other hand, to access the flags will be through one of the
wrappers, BaseConfig/PrimaryConfig/SecondaryConfig/CacheConfig
(CacheConfig is embedded in SecondaryConfig). These wrappers have the
getters to access the value and the type. When adding a new feature, we
need to add it to `allocator_config.def` and mark the new variable with
either *_REQUIRED_* or *_OPTIONAL_* macro so that the accessor will be
generated properly.

In addition, also remove the need of `UseConditionVariable` to flip
on/off of condition variable. Now we only need to define the type of
condition variable.
2024-03-13 16:05:24 -07:00
ChiaHungDuan
ab17ecd107
[scudo] Add ConditionVariable in SizeClassAllocator64 (#69031)
This may improve the waiting of `Region->MMLock` while trying to refill
the freelist. Instead of always waiting on the completion of
`populateFreeListAndPopBatch()` or `releaseToOSMaybe()`, `pushBlocks()`
also refills the freelist. This increases the chance of earlier return
from `popBatches()`.

The support of condition variable hasn't been done for all platforms.
Therefore, add another `popBatchWithCV()` and it can be configured in
the allocator configuration by setting `Primary::UseConditionVariable`
and the desired `ConditionVariableT`.

Reviewed By: cferris

Differential Revision: https://reviews.llvm.org/D156146
2023-10-19 15:47:18 -07:00
Christopher Ferris
e2a9d3f851
[scudo] Remove AndroidSvelteConfig. (#66444)
This config is not actually used anywhere and it is not used on Android.
Since it does not test anything not tested elsewhere, remove it.

Remove the size class data associated with this config too.
2023-09-18 13:57:55 -07:00
Marco Nelissen
146f4c26ac [scudo] Enable MTE in Trusty
Trusty now has MTE support.
Back-ported from https://r.android.com/2332745.

Reviewed By: Chia-hungDuan

Differential Revision: https://reviews.llvm.org/D152219
2023-06-07 00:15:04 +00:00
Dmitriy Filchenko
94407e1bba [scudo] Change configuration for Trusty, use mmap()
Trusty runs in memory constrained environments, with many apps
having only one page (4KB) of heap memory available. However, we
still want to mmap() multiples of PAGE_SIZE at a time.

Additionally, switch Scudo from using sbrk() to mmap().

Reviewed By: cferris

Differential Revision: https://reviews.llvm.org/D151968
2023-06-05 18:28:10 +00:00
Chia-hung Duan
2f08a08f61 [scudo] Support importing custom configuration
To define custom allocation, you only need to put the configuration in
custom_scudo_config.h and define two required aliases, then you will be
switched to the customized config and the tests will also run with your
configuration.

In this CL, we also have a minor refactor the structure of
configuration. Now the essential fields are put under the associated
hierarchy and which will make the defining new configuration easier.

Reviewed By: cferris

Differential Revision: https://reviews.llvm.org/D150481
2023-06-02 16:28:00 +00:00
Caslyn Tonelli
96005d75b2 [scudo] Tune FuchsiaConfig for RiscV
Reduce `PrimaryRegionSizeLog` to 28U to be compatible with a 38bit user
address space on the fuchsia-riscv platform. `PrimaryGroupSizeLog` is
reduced to 19 to preserve 512 BatchGroups per region.

This change can be tested on Fuchsia with:

```
fx set --auto-dir bringup.riscv64 --with //bundles:boot_tests \
fx build bundles:boot_tests \
fx run-boot-test --args={-s,1} boot-libc-unittests \
--cmdline='--gtest_filter=-*DeathTest*:PthreadGetSet*:ScudoSecondaryTest*'
```
The gtest filter ignores pthread and death tests due to non-scudo
related issues on fuchsia-riscv (ScudoSecondaryTest includes a death
check).

Related Ticket: https://fxbug.dev/125263

Differential Revision: https://reviews.llvm.org/D148475
2023-04-17 20:15:55 +00:00
Guillaume Chelfi
4e3dac6f0a [scudo] Call __scudo_deallocate_hook on reallocations.
Scudo is expected to call __scudo_allocate_hook on allocations, and
__scudo_deallocate_hook on deallocations, but it's behavior is not
clear on reallocations. Currently, non-trivial reallocations call
__scudo_allocate_hook but never __scudo_deallocate_hook. We should
prefer either calling both, none, or a dedicated
hook (__scudo_reallocate_hook, for instance).

This patch implements the former, and adds a unit test to enforce
those expectations.

Reviewed By: Chia-hungDuan

Differential Revision: https://reviews.llvm.org/D141407
2023-02-14 18:44:38 +00:00
Luke Nicholson
ab17a08d0f [fuchsia] Tune PrimaryGroupSizeLog to reduce fragmentation.
21U is the default group size, which demonstrates ~15mb reduction
in heap size for some highly fragmented heaps on Fuchsia, and
a general 5mb savings when devices are under no load.

Microbenchmarks show no performance regressions, but most of our
benchmarks perform no significant mallocs. So we are choosing the
default setting, and monitoring for potential performance
issues.

Reviewed By: Chia-hungDuan

Differential Revision: https://reviews.llvm.org/D140311
2022-12-20 02:33:52 +00:00
Chia-hung Duan
c0f91856a3 Reland "[scudo] Manage free blocks in BatchGroup."
This is not a pure revert of c929bcb7d85700494217f3a2148549f8757e0eed.
It also includes a bug fix.

Differential Revision: https://reviews.llvm.org/D136029
2022-10-21 19:57:28 +00:00
Kamau Bridgeman
c929bcb7d8 Revert "[scudo] Manage free blocks in BatchGroup."
This reverts commit cf9d7f55d3bec7640fa8b2f8ec1d9c1268233caa.
2022-10-14 15:11:57 -05:00
Chia-hung Duan
cf9d7f55d3 [scudo] Manage free blocks in BatchGroup.
Scudo is supposed to allocate any blocks across the entired mapped
pages and each page is equally likely to be selected. Which means Scudo
is leaning to touch as many pages as possible. This brings better
security but it also sacrifices the chance of releasing dirty pages.

To alleviate the unmanagable footprint growing, this CL introduces the
BatchGroup concept. Each blocks will be classified into a BatchGroup
according to its address. While allocation, we are leaning to allocate
blocks in the same group first. Note that the blocks selected from a
group is still random over several pages. At the same time, we have
better prediction of dirty page growing speed. Besides, we are able to
do partial page releasing by examing part of BatchGroups.

Reviewed By: cryptoad, cferris

Differential Revision: https://reviews.llvm.org/D133897
2022-10-13 23:35:06 +00:00
Vitaly Buka
533abb7ecf [scudo] Enabled MTE before the first allocator
Reviewed By: pcc

Differential Revision: https://reviews.llvm.org/D103726
2021-06-23 23:01:26 -07:00
Daniel Michael
2551053e8d [scudo] Add Scudo support for Trusty OS
trusty.cpp and trusty.h define Trusty implementations of map and other
platform-specific functions. In addition to adding Trusty configurations
in allocator_config.h and size_class_map.h, MapSizeIncrement and
PrimaryEnableRandomOffset are added as configurable options in
allocator_config.h.
Background on Trusty: https://source.android.com/security/trusty

Differential Revision: https://reviews.llvm.org/D103578
2021-06-08 14:02:10 -07:00
Kostya Kortchinsky
20c1f94220 [scudo] Separate Fuchsia & Default SizeClassMap
The Fuchsia allocator config was using the default size class map.

This CL gives Fuchsia its own size class map and changes a couple of
things in the default one:
- make `SizeDelta` configurable in `Config` for a fixed size class map
  as it currently is for a table size class map;
- switch `SizeDelta` to 0 for the default config, it allows for size
  classes that allow for power of 2s, and overall better wrt pages
  filling;
- increase the max number of caches pointers to 14 in the default,
  this makes the transfer batch 64/128 bytes on 32/64-bit platforms,
  which is cache-line friendly (previous size was 48/96 bytes).

The Fuchsia size class map remains untouched for now, this doesn't
impact Android which uses the table size class map.

Differential Revision: https://reviews.llvm.org/D102783
2021-05-24 08:54:08 -07:00
Peter Collingbourne
3f71ce8589 scudo: Support memory tagging in the secondary allocator.
This patch enhances the secondary allocator to be able to detect buffer
overflow, and (on hardware supporting memory tagging) use-after-free
and buffer underflow.

Use-after-free detection is implemented by setting memory page
protection to PROT_NONE on free. Because this must be done immediately
rather than after the memory has been quarantined, we no longer use the
combined allocator quarantine for secondary allocations. Instead, a
quarantine has been added to the secondary allocator cache.

Buffer overflow detection is implemented by aligning the allocation
to the right of the writable pages, so that any overflows will
spill into the guard page to the right of the allocation, which
will have PROT_NONE page protection. Because this would require the
secondary allocator to produce a header at the correct position,
the responsibility for ensuring chunk alignment has been moved to
the secondary allocator.

Buffer underflow detection has been implemented on hardware supporting
memory tagging by tagging the memory region between the start of the
mapping and the start of the allocation with a non-zero tag. Due to
the cost of pre-tagging secondary allocations and the memory bandwidth
cost of tagged accesses, the allocation itself uses a tag of 0 and
only the first four pages have memory tagging enabled.

This is a reland of commit 7a0da8894348 which was reverted in commit
9678b07e42ee. This reland includes the following changes:

- Fix the calculation of BlockSize which led to incorrect statistics
  returned by mallinfo().
- Add -Wno-pedantic to silence GCC warning.
- Optionally add some slack at the end of secondary allocations to help
  work around buggy applications that read off the end of their
  allocation.

Differential Revision: https://reviews.llvm.org/D93731
2021-03-08 14:39:33 -08:00
Peter Collingbourne
9678b07e42 Revert 7a0da8894348, "scudo: Support memory tagging in the secondary allocator."
We measured a 2.5 seconds (17.5%) regression in Android boot time
performance with this change.
2021-02-25 16:50:02 -08:00
Kostya Kortchinsky
2c56776a31 [scudo][standalone] Compact pointers for Caches/Batches
This CL introduces configuration options to allow pointers to be
compacted in the thread-specific caches and transfer batches. This
offers the possibility to have them use 32-bit of space instead of
64-bit for the 64-bit Primary, thus cutting the size of the caches
and batches by nearly half (and as such the memory used in size
class 0). The cost is an additional read from the region information
in the fast path.

This is not a new idea, as it's being used in the sanitizer_common
64-bit primary. The difference here is that it is configurable via
the allocator config, with the possibility of not compacting at all.

This CL enables compacting pointers in the Android and Fuchsia default
configurations.

Differential Revision: https://reviews.llvm.org/D96435
2021-02-25 12:14:38 -08:00
Peter Collingbourne
7a0da88943 scudo: Support memory tagging in the secondary allocator.
This patch enhances the secondary allocator to be able to detect buffer
overflow, and (on hardware supporting memory tagging) use-after-free
and buffer underflow.

Use-after-free detection is implemented by setting memory page
protection to PROT_NONE on free. Because this must be done immediately
rather than after the memory has been quarantined, we no longer use the
combined allocator quarantine for secondary allocations. Instead, a
quarantine has been added to the secondary allocator cache.

Buffer overflow detection is implemented by aligning the allocation
to the right of the writable pages, so that any overflows will
spill into the guard page to the right of the allocation, which
will have PROT_NONE page protection. Because this would require the
secondary allocator to produce a header at the correct position,
the responsibility for ensuring chunk alignment has been moved to
the secondary allocator.

Buffer underflow detection has been implemented on hardware supporting
memory tagging by tagging the memory region between the start of the
mapping and the start of the allocation with a non-zero tag. Due to
the cost of pre-tagging secondary allocations and the memory bandwidth
cost of tagged accesses, the allocation itself uses a tag of 0 and
only the first four pages have memory tagging enabled.

Differential Revision: https://reviews.llvm.org/D93731
2021-02-22 14:35:39 -08:00
Peter Collingbourne
6dfe5801e0 scudo: Move the configuration for the primary allocator to Config. NFCI.
This will allow the primary and secondary allocators to share
the MaySupportMemoryTagging bool.

Differential Revision: https://reviews.llvm.org/D93728
2020-12-22 14:54:40 -08:00
Peter Collingbourne
f21f3339ba scudo: Remove positional template arguments for secondary cache. NFCI.
Make these arguments named constants in the Config class instead
of being positional arguments to MapAllocatorCache. This makes the
configuration easier to follow.

Eventually we should follow suit with the other classes but this is
a start.

Differential Revision: https://reviews.llvm.org/D93251
2020-12-14 15:40:07 -08:00
Kostya Kortchinsky
6f00f3b56e [scudo][standalone] mallopt runtime configuration options
Summary:
Partners have requested the ability to configure more parts of Scudo
at runtime, notably the Secondary cache options (maximum number of
blocks cached, maximum size) as well as the TSD registry options
(the maximum number of TSDs in use).

This CL adds a few more Scudo specific `mallopt` parameters that are
passed down to the various subcomponents of the Combined allocator.

- `M_CACHE_COUNT_MAX`: sets the maximum number of Secondary cached items
- `M_CACHE_SIZE_MAX`: sets the maximum size of a cacheable item in the Secondary
- `M_TSDS_COUNT_MAX`: sets the maximum number of TSDs that can be used (Shared Registry only)

Regarding the TSDs maximum count, this is a one way option, only
allowing to increase the count.

In order to allow for this, I rearranged the code to have some `setOption`
member function to the relevant classes, using the `scudo::Option` class
enum to determine what is to be set.

This also fixes an issue where a static variable (`Ready`) was used in
templated functions without being set back to `false` every time.

Reviewers: pcc, eugenis, hctim, cferris

Subscribers: jfb, llvm-commits, #sanitizers

Tags: #sanitizers

Differential Revision: https://reviews.llvm.org/D84667
2020-07-28 11:57:54 -07:00
Christopher Ferris
5f91c7b980 [scudo][standalone] Allow setting release to OS
Summary:
Add a method to set the release to OS value as the system runs,
and allow this to be set differently in the primary and the secondary.
Also, add a default value to use for primary and secondary. This
allows Android to have a default that is different for
primary/secondary.

Update mallopt to support setting the release to OS value.

Reviewers: pcc, cryptoad

Reviewed By: cryptoad

Subscribers: cryptoad, jfb, #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D74448
2020-02-14 12:57:34 -08:00
Kostya Kortchinsky
64cb77b946 [scudo][standalone] Change default Android config
Summary:
This changes a couple of parameters in the default Android config to
address some performance and memory footprint issues (well to be closer
to the default Bionic allocator numbers).

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D73750
2020-01-31 14:46:35 -08:00
Kostya Kortchinsky
993e3c9269 [scudo][standalone] Secondary & general other improvements
Summary:
This CL changes multiple things to improve performance (notably on
Android).We introduce a cache class for the Secondary that is taking
care of this mechanism now.

The changes:
- change the Secondary "freelist" to an array. By keeping free secondary
  blocks linked together through their headers, we were keeping a page
  per block, which isn't great. Also we know touch less pages when
  walking the new "freelist".
- fix an issue with the freelist getting full: if the pattern is an ever
  increasing size malloc then free, the freelist would fill up and
  entries would not be used. So now we empty the list if we get to many
  "full" events;
- use the global release to os interval option for the secondary: it
  was too costly to release all the time, particularly for pattern that
  are malloc(X)/free(X)/malloc(X). Now the release will only occur
  after the selected interval, when going through the deallocate path;
- allow release of the `BatchClassId` class: it is releasable, we just
  have to make sure we don't mark the batches containing batches
  pointers as free.
- change the default release interval to 1s for Android to match the
  current Bionic allocator configuration. A patch is coming up to allow
  changing it through `mallopt`.
- lower the smallest class that can be released to `PageSize/64`.

Reviewers: cferris, pcc, eugenis, morehouse, hctim

Subscribers: phosek, #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D73507
2020-01-28 07:28:55 -08:00
Kostya Kortchinsky
990acd450c [scudo][standalone] Reduce Android region sizes to 128MB
Summary:
Unity is making irresponsible assumptions as to how clumped up memory
should be. With larger regions, we break those, resulting in errors
like:

"Using memoryadresses from more that 16GB of memory"

This is unfortunately one of those situations where we have to bend to
existing code because we doubt it's going to change any time soon.

128MB should be enough, but we could be flirting with OOMs in the
higher class sizes.

Reviewers: cferris, eugenis, hctim, morehouse, pcc

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D73143
2020-01-22 09:42:07 -08:00
Peter Collingbourne
c299d1981d scudo: Add initial memory tagging support.
When the hardware and operating system support the ARM Memory Tagging
Extension, tag primary allocation granules with a random tag. The granules
either side of the allocation are tagged with tag 0, which is normally
excluded from the set of tags that may be selected randomly. Memory is
also retagged with a random tag when it is freed, and we opportunistically
reuse the new tag when the block is reused to reduce overhead. This causes
linear buffer overflows to be caught deterministically and non-linear buffer
overflows and use-after-free to be caught probabilistically.

This feature is currently only enabled for the Android allocator
and depends on an experimental Linux kernel branch available here:
https://github.com/pcc/linux/tree/android-experimental-mte

All code that depends on the kernel branch is hidden behind a macro,
ANDROID_EXPERIMENTAL_MTE. This is the same macro that is used by the Android
platform and may only be defined in non-production configurations. When the
userspace interface is finalized the code will be updated to use the stable
interface and all #ifdef ANDROID_EXPERIMENTAL_MTE will be removed.

Differential Revision: https://reviews.llvm.org/D70762
2020-01-16 13:27:49 -08:00
Peter Collingbourne
29f0a65671 scudo: Add a basic malloc/free benchmark.
Differential Revision: https://reviews.llvm.org/D71104
2019-12-09 10:10:19 -08:00
Kostya Kortchinsky
0d3d4d3b0f [scudo][standalone] Make tests work on Fuchsia
Summary:
This CL makes unit tests compatible with Fuchsia's zxtest. This
required a few changes here and there, but also unearthed some
incompatibilities that had to be addressed.

A header is introduced to allow to account for the zxtest/gtest
differences, some `#if SCUDO_FUCHSIA` are used to disable incompatible
code (the 32-bit primary, or the exclusive TSD).

It also brought to my attention that I was using
`__scudo_default_options` in different tests, which ended up in a
single binary, and I am not sure how that ever worked. So move
this to the main cpp.

Additionally fully disable the secondary freelist on Fuchsia as we do
not track VMOs for secondary allocations, so no release possible.

With some modifications to Scudo's BUILD.gn in Fuchsia:
```
[==========] 79 tests from 23 test cases ran (10280 ms total).
[  PASSED  ] 79 tests
```

Reviewers: mcgrathr, phosek, hctim, pcc, eugenis, cferris

Subscribers: srhines, jfb, #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D70682
2019-11-27 09:17:40 -08:00
Kostya Kortchinsky
19ea1d46cc [scudo][standalone] Add a free list to the Secondary
Summary:
The secondary allocator is slow, because we map and unmap each block
on allocation and deallocation.

While I really like the security benefits of such a behavior, this
yields very disappointing performance numbers on Android for larger
allocation benchmarks.

So this change adds a free list to the secondary, that will hold
recently deallocated chunks, and (currently) release the extraneous
memory. This allows to save on some memory mapping operations on
allocation and deallocation. I do not think that this lowers the
security of the secondary, but can increase the memory footprint a
little bit (RSS & VA).

The maximum number of blocks the free list can hold is templatable,
`0U` meaning that we fallback to the old behavior. The higher that
number, the higher the extra memory footprint.

I added default configurations for all our platforms, but they are
likely to change in the near future based on needs and feedback.

Reviewers: hctim, morehouse, cferris, pcc, eugenis, vitalybuka

Subscribers: mgorny, #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D69570
2019-10-30 08:55:58 -07:00
Kostya Kortchinsky
161cca266a [scudo][standalone] Android related improvements
Summary:
This changes a few things to improve memory footprint and performances
on Android, and fixes a test compilation error:
- add `stdlib.h` to `wrappers_c_test.cc` to address
  https://bugs.llvm.org/show_bug.cgi?id=42810
- change Android size class maps, based on benchmarks, to improve
  performances and lower the Svelte memory footprint. Also change the
  32-bit region size for said configuration
- change the `reallocate` logic to reallocate in place for sizes larger
  than the original chunk size, when they still fit in the same block.
  This addresses patterns from `memory_replay` dumps like the following:
```
202: realloc 0xb48fd000 0xb4930650 12352
202: realloc 0xb48fd000 0xb48fd000 12420
202: realloc 0xb48fd000 0xb48fd000 12492
202: realloc 0xb48fd000 0xb48fd000 12564
202: realloc 0xb48fd000 0xb48fd000 12636
202: realloc 0xb48fd000 0xb48fd000 12708
202: realloc 0xb48fd000 0xb48fd000 12780
202: realloc 0xb48fd000 0xb48fd000 12852
202: realloc 0xb48fd000 0xb48fd000 12924
202: realloc 0xb48fd000 0xb48fd000 12996
202: realloc 0xb48fd000 0xb48fd000 13068
202: realloc 0xb48fd000 0xb48fd000 13140
202: realloc 0xb48fd000 0xb48fd000 13212
202: realloc 0xb48fd000 0xb48fd000 13284
202: realloc 0xb48fd000 0xb48fd000 13356
202: realloc 0xb48fd000 0xb48fd000 13428
202: realloc 0xb48fd000 0xb48fd000 13500
202: realloc 0xb48fd000 0xb48fd000 13572
202: realloc 0xb48fd000 0xb48fd000 13644
202: realloc 0xb48fd000 0xb48fd000 13716
202: realloc 0xb48fd000 0xb48fd000 13788
...
```
  In this situation we were deallocating the old chunk, and
  allocating a new one for every single one of those, but now we can
  keep the same chunk (we just updated the header), which saves some
  heap operations.

Reviewers: hctim, morehouse, vitalybuka, eugenis, cferris, rengolin

Reviewed By: morehouse

Subscribers: srhines, delcypher, #sanitizers, llvm-commits

Tags: #llvm, #sanitizers

Differential Revision: https://reviews.llvm.org/D67293

llvm-svn: 371628
2019-09-11 14:48:41 +00:00
Kostya Kortchinsky
e4eadf174c [scudo][standalone] Introduce the combined allocator
Summary:
The Combined allocator hold together all the other components, and
provides a memory allocator interface based on various template
parameters. This will be in turn used by "wrappers" that will provide
the standard C and C++ memory allocation functions, but can be
used as is as well.

This doesn't depart significantly from the current Scudo implementation
except for a few details:
- Quarantine batches are now protected by a header a well;
- an Allocator instance has its own TSD registry, as opposed to a
  static one for everybody;
- a function to iterate over busy chunks has been added, for Android
  purposes;

This also adds the associated tests, and a few default configurations
for several platforms, that will likely be further tuned later on.

Reviewers: morehouse, hctim, eugenis, vitalybuka

Reviewed By: morehouse

Subscribers: srhines, mgorny, delcypher, jfb, #sanitizers, llvm-commits

Tags: #llvm, #sanitizers

Differential Revision: https://reviews.llvm.org/D63231

llvm-svn: 363569
2019-06-17 15:23:11 +00:00