Awesome
LibRedFat -- A Hardened Malloc Implementation
LibRedFat is a hardened malloc
/free
implementation based on two
complementary memory error detection technologies:
- Poisoned Redzones
- Low-Fat-Pointers
You can use LibRedFat to harden binaries without the need for recompilation or instrumentation.
Building
To build LibRedFat, simply run the script:
$ ./build.sh
Usage
To test LibRedFat, simply replace the default malloc
implementation
using LD_PRELOAD
, e.g.:
$ LD_PRELOAD=$PWD/libredfat.so xterm
Alternatively, you can statically link libredfat.a
into your program.
Protections
LibRedFat replaces several libc
functions with hardened versions that
check for memory errors, including:
memcpy()
memset()
memcmp()
strcmp()
strcpy()
strlen()
strcat()
- etc.
Memory errors on heap pointers allocated using LibRedFat will be automatically detected by these replacement functions.
LibRedFat can be used in conjunction with the RedFat binary hardening system. For this, please see the RedFat project for more information.
Performance
Security and performance are a trade-off, and most existing malloc
implementations are optimized for performance.
In contrast, LibRedFat attempts to optimize towards security, provided
that the performance impact is "reasonable".
As such, the runtime performance of LibRedFat should be somewhat similar
to the default malloc
/free
implementation for most programs.
The memory performance of LibRedFat should be slightly worse than the
default malloc
/free
implementation, mainly because of the use of
poisoned redzones, low-fat pointer size binning, and a disjoint metadata
for the freelists.
It is recommended to profile each potential use case.
Options
LibRedFat supports various optional features that can be enabled using
environment variables.
Some features can also be statically enabled using the build.sh
script (see
build.sh --help
for more information):
REDFAT_PROFILE=1
: Enable profiling information such as the number of allocations and total library checks. Default: disabled.REDFAT_TEST=N
: Enable "test"-mode that randomly (once perN
allocations) under-allocates by a single byte. If instrumented code accesses the missing byte then a memory error should be detected. A zero value disables test-mode. Default: 0 (disabled).REDFAT_QUARANTINE=N
: Delay re-allocation of objects untilN
bytes have been free'ed. This can help detect reuse-after-free errors by not immediately reallocating objects, at the cost of increased memory overheads. However, this can increase memory overheads. Note thatN
is a per-region value for each allocation size-class, so the total overhead could beN*M
whereM
is the number of regions (typically ~60). Default: 0.REDFAT_ZERO=1
: Enable the zeroing of objects during deallocation. Provides additional defense against use-after-free errors and a basic defense against uninitialized-read errors. However, zeroing adds additional performance overheads. Default: disabled.REDFAT_CANARY=1
: Enables a randomized canary to be placed at the end of all allocated objects. The canary provides additional protection for out-of-bounds write errors that may go undetected in uninstrumented code. This consumes an additional 8 bytes per allocation. Note that a canary is always placed at the beginning of all allocated objects since this does not consume additional space. Default: disabled.REDFAT_ASLR=1
: Enables Address Space Layout Randomization (ASLR) for heap allocations. Default: enabled.REDFAT_CPU_CHECK=0
: Disable the CPU compatibility check. This is useful for some virtual machines (e.g., VirtualBox) that incorrectly indicate that Intel BMI/BMI2 is not supported.REDFAT_SIGNAL=SIG
: If an error occurs, raise signalSIG
to terminate the program (or else fall back to abort).REDFAT_LOG=N
: SetN
to be the log-level.
History
LibRedFat is derived (after heavy modification) from the liblowfat.so
library, which is part of the LowFat
project.
Several new features have been added, including:
- Lock-free (thread-local) allocation
- Redzones
- A disjoint metadata for freelists
- Intercepting (and protecting) several common libc functions (
memcpy
, etc.) - Several additional hardening options (quarantines, zeroing, canaries).
- Improved ASLR.
- Improved virtual address space management.
- Compatible with
LD_PRELOAD
. - Etc.
LibRedFat was originally developed as part of the
RedFat project.
However, libredfat.so
can be used independently of RedFat as a hardened
malloc
implementation.
LibRedFat is beta quality software, and has not yet been properly tested. It is possible that there are bugs or security vulnerabilities, so should be independently accessed before use in production code. LibRedFat is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Further Reading
- Gregory J. Duck, Yuntong Zhang, Roland H. C. Yap, Hardening Binaries against More Memory Errors, European Conference on Computer Systems (EuroSys), 2022
License
This software has been released under the MIT License.
Acknowledgements
This work was partially supported by the National Satellite of Excellence in Trustworthy Software Systems, funded by the National Research Foundation (NRF) Singapore under the National Cybersecurity R&D (NCR) programme.
This work was partially supported by the Ministry of Education, Singapore (Grant No. MOE2018-T2-1-142).