xref: /aosp_15_r20/external/llvm/docs/ScudoHardenedAllocator.rst (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker========================
2*9880d681SAndroid Build Coastguard WorkerScudo Hardened Allocator
3*9880d681SAndroid Build Coastguard Worker========================
4*9880d681SAndroid Build Coastguard Worker
5*9880d681SAndroid Build Coastguard Worker.. contents::
6*9880d681SAndroid Build Coastguard Worker   :local:
7*9880d681SAndroid Build Coastguard Worker   :depth: 1
8*9880d681SAndroid Build Coastguard Worker
9*9880d681SAndroid Build Coastguard WorkerIntroduction
10*9880d681SAndroid Build Coastguard Worker============
11*9880d681SAndroid Build Coastguard WorkerThe Scudo Hardened Allocator is a user-mode allocator based on LLVM Sanitizer's
12*9880d681SAndroid Build Coastguard WorkerCombinedAllocator, which aims at providing additional mitigations against heap
13*9880d681SAndroid Build Coastguard Workerbased vulnerabilities, while maintaining good performance.
14*9880d681SAndroid Build Coastguard Worker
15*9880d681SAndroid Build Coastguard WorkerThe name "Scudo" has been retained from the initial implementation (Escudo
16*9880d681SAndroid Build Coastguard Workermeaning Shield in Spanish and Portuguese).
17*9880d681SAndroid Build Coastguard Worker
18*9880d681SAndroid Build Coastguard WorkerDesign
19*9880d681SAndroid Build Coastguard Worker======
20*9880d681SAndroid Build Coastguard WorkerChunk Header
21*9880d681SAndroid Build Coastguard Worker------------
22*9880d681SAndroid Build Coastguard WorkerEvery chunk of heap memory will be preceded by a chunk header. This has two
23*9880d681SAndroid Build Coastguard Workerpurposes, the first one being to store various information about the chunk,
24*9880d681SAndroid Build Coastguard Workerthe second one being to detect potential heap overflows. In order to achieve
25*9880d681SAndroid Build Coastguard Workerthis, the header will be checksumed, involving the pointer to the chunk itself
26*9880d681SAndroid Build Coastguard Workerand a global secret. Any corruption of the header will be detected when said
27*9880d681SAndroid Build Coastguard Workerheader is accessed, and the process terminated.
28*9880d681SAndroid Build Coastguard Worker
29*9880d681SAndroid Build Coastguard WorkerThe following information is stored in the header:
30*9880d681SAndroid Build Coastguard Worker
31*9880d681SAndroid Build Coastguard Worker- the 16-bit checksum;
32*9880d681SAndroid Build Coastguard Worker- the user requested size for that chunk, which is necessary for reallocation
33*9880d681SAndroid Build Coastguard Worker  purposes;
34*9880d681SAndroid Build Coastguard Worker- the state of the chunk (available, allocated or quarantined);
35*9880d681SAndroid Build Coastguard Worker- the allocation type (malloc, new, new[] or memalign), to detect potential
36*9880d681SAndroid Build Coastguard Worker  mismatches in the allocation APIs used;
37*9880d681SAndroid Build Coastguard Worker- whether or not the chunk is offseted (ie: if the chunk beginning is different
38*9880d681SAndroid Build Coastguard Worker  than the backend allocation beginning, which is most often the case with some
39*9880d681SAndroid Build Coastguard Worker  aligned allocations);
40*9880d681SAndroid Build Coastguard Worker- the associated offset;
41*9880d681SAndroid Build Coastguard Worker- a 16-bit salt.
42*9880d681SAndroid Build Coastguard Worker
43*9880d681SAndroid Build Coastguard WorkerOn x64, which is currently the only architecture supported, the header fits
44*9880d681SAndroid Build Coastguard Workerwithin 16-bytes, which works nicely with the minimum alignment requirements.
45*9880d681SAndroid Build Coastguard Worker
46*9880d681SAndroid Build Coastguard WorkerThe checksum is computed as a CRC32 (requiring the SSE 4.2 instruction set)
47*9880d681SAndroid Build Coastguard Workerof the global secret, the chunk pointer itself, and the 16 bytes of header with
48*9880d681SAndroid Build Coastguard Workerthe checksum field zeroed out.
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard WorkerThe header is atomically loaded and stored to prevent races (this requires
51*9880d681SAndroid Build Coastguard Workerplatform support such as the cmpxchg16b instruction). This is important as two
52*9880d681SAndroid Build Coastguard Workerconsecutive chunks could belong to different threads. We also want to avoid
53*9880d681SAndroid Build Coastguard Workerany type of double fetches of information located in the header, and use local
54*9880d681SAndroid Build Coastguard Workercopies of the header for this purpose.
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard WorkerDelayed Freelist
57*9880d681SAndroid Build Coastguard Worker-----------------
58*9880d681SAndroid Build Coastguard WorkerA delayed freelist allows us to not return a chunk directly to the backend, but
59*9880d681SAndroid Build Coastguard Workerto keep it aside for a while. Once a criterion is met, the delayed freelist is
60*9880d681SAndroid Build Coastguard Workeremptied, and the quarantined chunks are returned to the backend. This helps
61*9880d681SAndroid Build Coastguard Workermitigate use-after-free vulnerabilities by reducing the determinism of the
62*9880d681SAndroid Build Coastguard Workerallocation and deallocation patterns.
63*9880d681SAndroid Build Coastguard Worker
64*9880d681SAndroid Build Coastguard WorkerThis feature is using the Sanitizer's Quarantine as its base, and the amount of
65*9880d681SAndroid Build Coastguard Workermemory that it can hold is configurable by the user (see the Options section
66*9880d681SAndroid Build Coastguard Workerbelow).
67*9880d681SAndroid Build Coastguard Worker
68*9880d681SAndroid Build Coastguard WorkerRandomness
69*9880d681SAndroid Build Coastguard Worker----------
70*9880d681SAndroid Build Coastguard WorkerIt is important for the allocator to not make use of fixed addresses. We use
71*9880d681SAndroid Build Coastguard Workerthe dynamic base option for the SizeClassAllocator, allowing us to benefit
72*9880d681SAndroid Build Coastguard Workerfrom the randomness of mmap.
73*9880d681SAndroid Build Coastguard Worker
74*9880d681SAndroid Build Coastguard WorkerUsage
75*9880d681SAndroid Build Coastguard Worker=====
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard WorkerLibrary
78*9880d681SAndroid Build Coastguard Worker-------
79*9880d681SAndroid Build Coastguard WorkerThe allocator static library can be built from the LLVM build tree thanks to
80*9880d681SAndroid Build Coastguard Workerthe "scudo" CMake rule. The associated tests can be exercised thanks to the
81*9880d681SAndroid Build Coastguard Worker"check-scudo" CMake rule.
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard WorkerLinking the static library to your project can require the use of the
84*9880d681SAndroid Build Coastguard Worker"whole-archive" linker flag (or equivalent), depending on your linker.
85*9880d681SAndroid Build Coastguard WorkerAdditional flags might also be necessary.
86*9880d681SAndroid Build Coastguard Worker
87*9880d681SAndroid Build Coastguard WorkerYour linked binary should now make use of the Scudo allocation and deallocation
88*9880d681SAndroid Build Coastguard Workerfunctions.
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard WorkerOptions
91*9880d681SAndroid Build Coastguard Worker-------
92*9880d681SAndroid Build Coastguard WorkerSeveral aspects of the allocator can be configured through environment options,
93*9880d681SAndroid Build Coastguard Workerfollowing the usual ASan options syntax, through the variable SCUDO_OPTIONS.
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard WorkerFor example: SCUDO_OPTIONS="DeleteSizeMismatch=1:QuarantineSizeMb=16".
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard WorkerThe following options are available:
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker- QuarantineSizeMb (integer, defaults to 64): the size (in Mb) of quarantine
100*9880d681SAndroid Build Coastguard Worker  used to delay the actual deallocation of chunks. Lower value may reduce
101*9880d681SAndroid Build Coastguard Worker  memory usage but decrease the effectiveness of the mitigation; a negative
102*9880d681SAndroid Build Coastguard Worker  value will fallback to a default of 64Mb;
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker- ThreadLocalQuarantineSizeKb (integer, default to 1024): the size (in Kb) of
105*9880d681SAndroid Build Coastguard Worker  per-thread cache used to offload the global quarantine. Lower value may
106*9880d681SAndroid Build Coastguard Worker  reduce memory usage but might increase the contention on the global
107*9880d681SAndroid Build Coastguard Worker  quarantine.
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker- DeallocationTypeMismatch (boolean, defaults to true): whether or not we report
110*9880d681SAndroid Build Coastguard Worker  errors on malloc/delete, new/free, new/delete[], etc;
111*9880d681SAndroid Build Coastguard Worker
112*9880d681SAndroid Build Coastguard Worker- DeleteSizeMismatch (boolean, defaults to true): whether or not we report
113*9880d681SAndroid Build Coastguard Worker  errors on mismatch between size of new and delete;
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker- ZeroContents (boolean, defaults to false): whether or not we zero chunk
116*9880d681SAndroid Build Coastguard Worker  contents on allocation and deallocation.
117*9880d681SAndroid Build Coastguard Worker
118