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