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.
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 |
Without this kernel tunable, the user is likely to experience out-of-memory errors across the system, despite having free memory. |
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.
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.
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.
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 |
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. |
In order to preload the hardened_malloc shared library on boot, the following actions should be performed:
/etc/environment or a configuration file within
/etc/environment.d/ (suffixed with .conf
filename extension):LD_PRELOAD=/usr/local/lib/libhardened_malloc.so
/etc/ld.so.preload:/usr/local/lib/libhardened_malloc.so