Linux - hardened_malloc

This documentation contains instructions to use hardened_malloc memory allocator as the system's default memory allocator via dynamic linking as a shared library. These instructions apply to both musl and glibc C libraries on Linux-based systems.

This documentation focuses on system-wide usage of hardened_malloc, assumes root privileges, and assumes that the compiled library will readable and executable by all users of the system.

hardened_malloc can also be used per-user and/or per-application, in which case root permissions are not required. This configuration is currently out-of-scope for this documentation.

This documentation uses Linux Filesystem Hierarchy Standard paths, with the modern /usr/-merge approach of most Linux distributions. For non-standard configurations, adjust the paths, accordingly.

Within this documentation, # is used to denote running the command as the root user, and $ is used to denote running the command as an unprivileged user. The lowest-privileged user able to run the commands will be used for each command. Some shells may present different characters for privileged and unprivileged users than used in this documentation; the shell's documentation should be consulted if this is true for the system being used.

For the complete hardened_malloc documentation, visit its official documentation.

0. Increase Permitted Amount of Memory Pages

The following kernel tunable should be added to /etc/sysctl.conf or a configuration file within /etc/sysctl.d/ (suffixed with .conf filename extension) to accommodate hardened_malloc's large amount of guard pages:

vm.max_map_count = 1048576
Caution triangle.

CAUTION

Without this kernel tunable, the user is likely to experience out-of-memory errors across the system, despite having free memory.

1. Clone hardened_malloc Source Code

The source code can be cloned from the official Git repository via the following command:

$ git clone https://github.com/GrapheneOS/hardened_malloc.git

If the user has an alternative source-code repository, such as a mirror, they can use that, instead. The source should be trusted before the clone command is initiated.

It is also possible to use another method to obtain hardened_malloc's source code, such as via .tar files.

2. Enter hardened_malloc Local Git Repository

The cloned source-code repository which is now locally-stored on the system can be entered via the following command:

$ cd hardened_malloc/

If hardened_malloc's source code was obtained via a non-Git method, such as via .tar files, that directory should be entered, instead.

3. Compile hardened_malloc

hardened_malloc should be compiled via the following command from within the local source-code repository:

$ make <arguments>

It is recommended to use Clang as the C compiler for hardened_malloc, in order to take advantage of its forward-edge, type-based control-flow integrity (CFI), which GCC does not support. This can be achieved by adding CC=clang as a compilation command argument if it is not the system's default compiler.

CONFIG_N_ARENA=n can be adjusted to increase parallel performance at the expense of memory usage, or decrease memory usage at the expense of parallel performance, where n is a positive integer. Higher values prefer parallel performance, whereas lower values prefer lower memory usage. The number of arenas has no impact on the security properties of hardened_malloc.

The following table shows the arena-counts of hardened_malloc:

Minimum Maximum Default
1 256 4

NOTE

Having too many arenas may cause memory fragmentation and decrease system performance. If unsure, the default number of arenas should be used.

For extra security, CONFIG_SEAL_METADATA=true can be used in order to control whether Memory Protection Keys are used to disable access to all writable allocator state outside of the memory allocator code. This feature is currently disabled by default due to a significant performance cost for this use case on current-generation hardware. Whether or not this feature is enabled, all metadata is contained within an isolated memory region with high-entropy random guard regions around it.

For low-memory systems, VARIANT=light can be used to compile the light variant of hardened_malloc, which sacrifices some security for less memory usage. This option still produces a more hardened memory allocator than both the default musl and glibc memory allocators, despite the security sacrifices over the full variant.

For all compile-time options, see the configuration section of hardened_malloc's official documentation.

4. Copy Compiled hardened_malloc Library

The compiled hardened_malloc library can be copied to the standard location for shared libraries compiled outside of the system's package manager via the following command:

# cp out/libhardened_malloc.so /usr/local/lib/libhardened_malloc.so

If the user has integrated a hardened_malloc package into their system's package manager, such as a custom Gentoo-Linux ebuild, it should be installed to /usr/lib/libhardened_malloc.so, instead.

Caution triangle.

CAUTION

All users of the system must have read and execute permissions in order to preload and use hardened_malloc. If permissions are not correctly set, the system's standard memory allocator will be used and/or errors may occur.

5. Set System to Preload hardened_malloc on Boot

In order to preload the hardened_malloc shared library on boot, the following actions should be performed:

Sitemap