mi-malloc: Build Modes

| mi-malloc 1.8/2.1 |

Loading...
Searching...
No Matches
Build Modes

We can build mimalloc in various modes.

## Secure Mode

mimalloc can be build in secure mode by using the `-DMI_SECURE=ON` flags in `cmake`. This build enables various mitigations to make mimalloc more robust against exploits. In particular:

- All internal mimalloc pages are surrounded by guard pages and the heap metadata is behind a guard page as well (so a buffer overflow exploit cannot reach into the metadata).
- All free list pointers are encoded with per-page keys which is used both to prevent overwrites with a known pointer, as well as to detect heap corruption.
- Double free's are detected (and ignored).
- The free lists are initialized in a random order and allocation randomly chooses between extension and reuse within a page to mitigate against attacks that rely on a predicable allocation order. Similarly, the larger heap blocks allocated by mimalloc from the OS are also address randomized.

As always, evaluate with care as part of an overall security strategy as all of the above are mitigations but not guarantees.

## Debug Mode

When mimalloc is built using debug mode, (`-DCMAKE_BUILD_TYPE=Debug`), various checks are done at runtime to catch development errors.

- Statistics are maintained in detail for each object size. They can be shown using `MIMALLOC_SHOW_STATS=1` at runtime.
- All objects have padding at the end to detect (byte precise) heap block overflows.
- Double free's, and freeing invalid heap pointers are detected.
- Corrupted free-lists and some forms of use-after-free are detected.

## Guarded Mode

mimalloc can be build in guarded mode using the `-DMI_GUARDED=ON` flags in `cmake`. This enables placing OS guard pages behind certain object allocations to catch buffer overflows as they occur. This can be invaluable to catch buffer-overflow bugs in large programs. However, it also means that any object allocated with a guard page takes at least 8 KiB memory for the guard page and its alignment. As such, allocating a guard page for every allocation may be too expensive both in terms of memory, and in terms of performance with many system calls. Therefore, there are various environment variables (and options) to tune this:

- `MIMALLOC_GUARDED_SAMPLE_RATE=N`: Set the sample rate to `N` (by default 4000). This mode places a guard page behind every `N` suitable object allocations (per thread). Since the performance in guarded mode without placing guard pages is close to release mode, this can be used to enable guard pages even in production to catch latent buffer overflow bugs. Set the sample rate to `1` to guard every object, and to `0` to place no guard pages at all.
- `MIMALLOC_GUARDED_SAMPLE_SEED=N`: Start sampling at `N` (by default random). Can be used to reproduce a buffer overflow if needed.
- `MIMALLOC_GUARDED_MIN=N`, `MIMALLOC_GUARDED_MAX=N`: Minimal and maximal rounded object sizes for which a guard page is considered (`0` and `1GiB` respectively). If you suspect a buffer overflow occurs with an object of size 141, set the minimum and maximum to `148` and the sample rate to `1` to have all of those guarded.
- `MIMALLOC_GUARDED_PRECISE=1`: If we have an object of size 13, we would usually place it an aligned 16 bytes in front of the guard page. Using `MIMALLOC_GUARDED_PRECISE` places it exactly 13 bytes before a page so that even a 1 byte overflow is detected. This violates the C/C++ minimal alignment guarantees though so use with care.