comparison docs/ScudoHardenedAllocator.rst @ 134:3a76565eade5 LLVM5.0.1

update 5.0.1
author mir3636
date Sat, 17 Feb 2018 09:57:20 +0900
parents 803732b1fca8
children c2174574ed3a
comparison
equal deleted inserted replaced
133:c60214abe0e8 134:3a76565eade5
24 meaning Shield in Spanish and Portuguese). 24 meaning Shield in Spanish and Portuguese).
25 25
26 Design 26 Design
27 ====== 27 ======
28 28
29 Allocator
30 ---------
31 Scudo can be considered a Frontend to the Sanitizers' common allocator (later
32 referenced as the Backend). It is split between a Primary allocator, fast and
33 efficient, that services smaller allocation sizes, and a Secondary allocator
34 that services larger allocation sizes and is backed by the operating system
35 memory mapping primitives.
36
37 Scudo was designed with security in mind, but aims at striking a good balance
38 between security and performance. It is highly tunable and configurable.
39
29 Chunk Header 40 Chunk Header
30 ------------ 41 ------------
31 Every chunk of heap memory will be preceded by a chunk header. This has two 42 Every chunk of heap memory will be preceded by a chunk header. This has two
32 purposes, the first one being to store various information about the chunk, 43 purposes, the first one being to store various information about the chunk,
33 the second one being to detect potential heap overflows. In order to achieve 44 the second one being to detect potential heap overflows. In order to achieve
34 this, the header will be checksumed, involving the pointer to the chunk itself 45 this, the header will be checksummed, involving the pointer to the chunk itself
35 and a global secret. Any corruption of the header will be detected when said 46 and a global secret. Any corruption of the header will be detected when said
36 header is accessed, and the process terminated. 47 header is accessed, and the process terminated.
37 48
38 The following information is stored in the header: 49 The following information is stored in the header:
39 50
40 - the 16-bit checksum; 51 - the 16-bit checksum;
41 - the unused bytes amount for that chunk, which is necessary for computing the 52 - the class ID for that chunk, which is the "bucket" where the chunk resides
42 size of the chunk; 53 for Primary backed allocations, or 0 for Secondary backed allocations;
54 - the size (Primary) or unused bytes amount (Secondary) for that chunk, which is
55 necessary for computing the size of the chunk;
43 - the state of the chunk (available, allocated or quarantined); 56 - the state of the chunk (available, allocated or quarantined);
44 - the allocation type (malloc, new, new[] or memalign), to detect potential 57 - the allocation type (malloc, new, new[] or memalign), to detect potential
45 mismatches in the allocation APIs used; 58 mismatches in the allocation APIs used;
46 - the offset of the chunk, which is the distance in bytes from the beginning of 59 - the offset of the chunk, which is the distance in bytes from the beginning of
47 the returned chunk to the beginning of the backend allocation; 60 the returned chunk to the beginning of the Backend allocation;
48 - a 8-bit salt.
49 61
50 This header fits within 8 bytes, on all platforms supported. 62 This header fits within 8 bytes, on all platforms supported.
51 63
52 The checksum is computed as a CRC32 (made faster with hardware support) 64 The checksum is computed as a CRC32 (made faster with hardware support)
53 of the global secret, the chunk pointer itself, and the 8 bytes of header with 65 of the global secret, the chunk pointer itself, and the 8 bytes of header with
54 the checksum field zeroed out. 66 the checksum field zeroed out. It is not intended to be cryptographically
67 strong.
55 68
56 The header is atomically loaded and stored to prevent races. This is important 69 The header is atomically loaded and stored to prevent races. This is important
57 as two consecutive chunks could belong to different threads. We also want to 70 as two consecutive chunks could belong to different threads. We also want to
58 avoid any type of double fetches of information located in the header, and use 71 avoid any type of double fetches of information located in the header, and use
59 local copies of the header for this purpose. 72 local copies of the header for this purpose.
60 73
61 Delayed Freelist 74 Delayed Freelist
62 ----------------- 75 -----------------
63 A delayed freelist allows us to not return a chunk directly to the backend, but 76 A delayed freelist allows us to not return a chunk directly to the Backend, but
64 to keep it aside for a while. Once a criterion is met, the delayed freelist is 77 to keep it aside for a while. Once a criterion is met, the delayed freelist is
65 emptied, and the quarantined chunks are returned to the backend. This helps 78 emptied, and the quarantined chunks are returned to the Backend. This helps
66 mitigate use-after-free vulnerabilities by reducing the determinism of the 79 mitigate use-after-free vulnerabilities by reducing the determinism of the
67 allocation and deallocation patterns. 80 allocation and deallocation patterns.
68 81
69 This feature is using the Sanitizer's Quarantine as its base, and the amount of 82 This feature is using the Sanitizer's Quarantine as its base, and the amount of
70 memory that it can hold is configurable by the user (see the Options section 83 memory that it can hold is configurable by the user (see the Options section
105 118
106 .. code:: 119 .. code::
107 120
108 LD_PRELOAD=`pwd`/scudo-allocator.so ./a.out 121 LD_PRELOAD=`pwd`/scudo-allocator.so ./a.out
109 122
123 Clang
124 -----
125 With a recent version of Clang (post rL317337), the allocator can be linked with
126 a binary at compilation using the ``-fsanitize=scudo`` command-line argument, if
127 the target platform is supported. Currently, the only other Sanitizer Scudo is
128 compatible with is UBSan (eg: ``-fsanitize=scudo,undefined``). Compiling with
129 Scudo will also enforce PIE for the output binary.
130
110 Options 131 Options
111 ------- 132 -------
112 Several aspects of the allocator can be configured through the following ways: 133 Several aspects of the allocator can be configured through the following ways:
113 134
114 - by defining a ``__scudo_default_options`` function in one's program that 135 - by defining a ``__scudo_default_options`` function in one's program that
115 returns the options string to be parsed. Said function must have the following 136 returns the options string to be parsed. Said function must have the following
116 prototype: ``extern "C" const char* __scudo_default_options()``. 137 prototype: ``extern "C" const char* __scudo_default_options(void)``.
117 138
118 - through the environment variable SCUDO_OPTIONS, containing the options string 139 - through the environment variable SCUDO_OPTIONS, containing the options string
119 to be parsed. Options defined this way will override any definition made 140 to be parsed. Options defined this way will override any definition made
120 through ``__scudo_default_options``; 141 through ``__scudo_default_options``;
121 142