You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: PERFORMANCE.md
+33-21Lines changed: 33 additions & 21 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -34,6 +34,16 @@ If you know your program will not require multi-threaded access to IsoAlloc you
34
34
35
35
`DISABLE_CANARY` can be set to 1 to disable the creation and verification of canary chunks. This removes a useful security feature but will significantly improve performance and RSS.
36
36
37
+
`MASK_PTRS` is enabled by default and causes the `user_pages_start` and `bitmap_start` pointers stored in every zone's metadata to be XOR'd with a per-zone random secret between alloc and free operations. This protects against attackers who can read or corrupt zone metadata. Each alloc and free pays a small cost for these XOR operations. Setting `MASK_PTRS=0` removes this overhead at the cost of this security property.
38
+
39
+
`CANARY_COUNT_DIV` in `conf.h` controls what fraction of chunks in a zone are reserved as canaries. It is used as a right-shift on the total chunk count: `chunk_count >> CANARY_COUNT_DIV`. The default value of 7 reserves less than 1% of chunks. Increasing this value reduces canary density and frees more chunks for user allocations; decreasing it increases security coverage at the cost of usable memory.
40
+
41
+
`ZONE_ALLOC_RETIRE` in `conf.h` controls how frequently zones are retired and replaced. A zone is retired once it has completed `ZONE_ALLOC_RETIRE * max_chunk_count_for_zone` total alloc/free cycles. Lowering this value causes zones to be replaced more often, reducing the window for use-after-free exploitation but increasing the frequency of zone creation. `BIG_ZONE_ALLOC_RETIRE` is the equivalent for big zones.
42
+
43
+
`SMALL_MEM_STARTUP` reduces the number and size of default zones created at startup. This decreases initial RSS at the cost of more frequent zone creation for programs with diverse allocation sizes.
44
+
45
+
`STRONG_SIZE_ISOLATION` enforces stricter isolation by size class. When enabled, chunk sizes are rounded up to a smaller set of buckets which increases isolation between differently-sized allocations. This may increase per-allocation waste but reduces cross-size heap exploitation primitives.
46
+
37
47
By default IsoAlloc will attempt to use Huge Pages (for both Linux and Mac OS) for any allocations that are a multiple of 2 mb in size. This is the default huge page size on most systems but it might not be on yours. On Linux you can check the value for your system by running the following command:
The following benchmarks were collected from [mimalloc-bench](https://github.com/daanx/mimalloc-bench) with the default configuration of IsoAlloc. As you can see from the data IsoAlloc is competitive with other allocators for some benchmarks but clearly falls behind on others. For any benchmark that IsoAlloc scores poorly on I was able to tweak its build to improve the CPU time and memory consumption. It's worth noting that IsoAlloc was able to stay competitive even with performing many security checks not present in other allocators. Please note these are 'best case' measurements, not averages.
# test alloc time rss user sys page-faults page-reclaims
148
-
cfrac je 02.99 4912 2.99 0.00 0 454
149
-
cfrac mi 03.01 2484 3.00 0.00 0 346
150
-
cfrac iso 05.84 26616 5.75 0.09 0 6502
160
+
cfrac je 03.07 4552 3.06 0.00 0 454
161
+
cfrac mi 02.97 2484 2.96 0.00 0 347
162
+
cfrac iso 04.78 30612 4.69 0.09 0 7503
151
163
152
-
espresso je 02.52 4872 2.50 0.01 0 538
153
-
espresso mi 02.46 3060 2.45 0.01 0 3637
154
-
espresso iso 03.65 69876 3.56 0.09 0 21695
164
+
espresso je 02.51 4872 2.50 0.01 0 540
165
+
espresso mi 02.43 3032 2.42 0.01 0 3630
166
+
espresso iso 03.16 69608 3.07 0.07 0 30334
155
167
156
-
barnes je 01.62 60268 1.59 0.02 0 16687
157
-
barnes mi 01.71 57672 1.68 0.02 0 16550
158
-
barnes iso 01.66 74628 1.62 0.03 0 20851
168
+
barnes je 01.71 59900 1.67 0.03 0 16686
169
+
barnes mi 01.65 57672 1.62 0.02 0 16550
170
+
barnes iso 01.65 74812 1.62 0.03 0 20849
159
171
160
-
gs je 00.16 37592 0.15 0.01 0 5808
161
-
gs mi 00.16 32588 0.13 0.02 0 5109
162
-
gs iso 00.23 71152 0.16 0.07 0 19698
172
+
gs je 00.17 37748 0.15 0.01 0 5814
173
+
gs mi 00.16 33888 0.14 0.01 0 5109
174
+
gs iso 00.22 68136 0.15 0.06 0 18916
163
175
164
-
larsonN je 1.171 266596 98.81 0.92 0 409842
165
-
larsonN mi 1.016 299768 99.38 0.44 0 83755
166
-
larsonN iso 918.582 126528 99.64 0.37 0 31368
176
+
larsonN je 1.188 261884 98.91 0.92 0 421848
177
+
larsonN mi 1.016 299752 99.53 0.38 0 80202
178
+
larsonN iso 1328.904 121096 6.15 69.78 0 30219
167
179
168
-
rocksdb je 02.48 162424 2.05 0.63 0 38384
169
-
rocksdb mi 02.48 159812 2.04 0.66 0 37464
170
-
rocksdb iso 02.74 197220 2.49 0.55 0 46815
180
+
rocksdb je 02.46 162340 2.05 0.63 0 38383
181
+
rocksdb mi 02.33 160156 1.92 0.63 0 37585
182
+
rocksdb iso 02.96 195948 2.64 0.66 0 46584
171
183
172
-
redis je 3.180 9496 0.14 0.02 0 1538
173
-
redis mi 3.080 7088 0.12 0.03 0 1256
174
-
redis iso 6.880 52816 0.31 0.05 0 16317
184
+
redis je 3.160 9492 0.13 0.02 0 1528
185
+
redis mi 2.780 7084 0.12 0.02 0 1257
186
+
redis iso 7.579 50516 0.35 0.05 0 15187
175
187
```
176
188
177
189
IsoAlloc isn't quite ready for performance sensitive server workloads. However it's more than fast enough for client side mobile/desktop applications with risky C/C++ attack surfaces. These environments have threat models similar to what IsoAlloc was designed for.
Copy file name to clipboardExpand all lines: README.md
+4-1Lines changed: 4 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -61,7 +61,7 @@ When enabled, the `CPU_PIN` feature will restrict allocations from a given zone
61
61
* A chunk can be permanently free'd with a call to `iso_free_permanently`.
62
62
* If `SANITIZE_CHUNKS` is set all user chunks are cleared when passed to `iso_free` with the constant `0xde`.
63
63
* When freeing a chunk the canary in adjacent chunks above/below are verified.
64
-
*Some important zone metadata pointers are masked in-between `iso_alloc` and `iso_free` operations.
64
+
*When `MASK_PTRS` is enabled (default) the `user_pages_start` and `bitmap_start`pointers stored in zone metadata are XOR'd with a per-zone random secret between alloc and free operations, making them useless to an attacker who reads or corrupts zone metadata.
65
65
* Passing a pointer to `iso_free` that was not allocated with `iso_alloc` will abort.
66
66
* Pointers passed to `iso_free` must be 8 byte aligned, and a multiple of the zone chunk size.
67
67
* The free bit slot cache provides a chunk quarantine or delayed free mechanism.
@@ -76,6 +76,7 @@ When enabled, the `CPU_PIN` feature will restrict allocations from a given zone
76
76
* Randomized hints are passed to `mmap` to ensure contiguous page ranges are not allocated.
77
77
* When `ABORT_ON_NULL` is enabled IsoAlloc will abort instead of returning `NULL`.
78
78
* By default `NO_ZERO_ALLOCATIONS` will return a pointer to a page marked `PROT_NONE` for all `0` sized allocations.
79
+
* When `ABORT_ON_UNOWNED_PTR` is enabled (default) IsoAlloc will abort whenever it is passed a pointer it does not own.
79
80
* When `ABORT_NO_ENTROPY` is enabled IsoAlloc will abort when it can't gather enough entropy.
80
81
* When `RANDOMIZE_FREELIST` is enabled IsoAlloc will randomize the free list upon creation. May have a perf hit.
81
82
* Zones are retired and replaced after they've allocated and freed a specific number of chunks. This is calculated as `ZONE_ALLOC_RETIRE * max_chunk_count_for_zone`.
@@ -94,6 +95,8 @@ The Makefile targets are very simple:
94
95
95
96
`make library` - Builds a release version of the library without C++ support
96
97
98
+
`make library_less_strict` - Builds a release library with `ABORT_ON_UNOWNED_PTR=0`. Recommended when using IsoAlloc via `LD_PRELOAD`.
99
+
97
100
`make library_debug` - Builds a debug version of the library
98
101
99
102
`make library_debug_no_output` - Builds a debug version of the library with no logging output
0 commit comments