1 { config, lib, pkgs, ... }:
3 cfg = config.environment.memoryAllocator;
5 # The set of alternative malloc(3) providers.
8 libPath = "${pkgs.graphene-hardened-malloc}/lib/libhardened_malloc.so";
10 Hardened memory allocator coming from GrapheneOS project.
11 The default configuration template has all normal optional security
12 features enabled and is quite aggressive in terms of sacrificing
13 performance and memory usage for security.
17 graphene-hardened-light = {
18 libPath = "${pkgs.graphene-hardened-malloc}/lib/libhardened_malloc-light.so";
20 Hardened memory allocator coming from GrapheneOS project.
21 The light configuration template disables the slab quarantines,
22 write after free check, slot randomization and raises the guard
23 slab interval from 1 to 8 but leaves zero-on-free and slab canaries enabled.
24 The light configuration has solid performance and memory usage while still
25 being far more secure than mainstream allocators with much better security
31 libPath = "${pkgs.jemalloc}/lib/libjemalloc.so";
33 A general purpose allocator that emphasizes fragmentation avoidance
34 and scalable concurrency support.
40 aarch64-linux = "aarch64";
41 x86_64-linux = "x86_64";
44 systemPlatform = platformMap.${pkgs.stdenv.hostPlatform.system} or (throw "scudo not supported on ${pkgs.stdenv.hostPlatform.system}");
46 libPath = "${pkgs.llvmPackages_14.compiler-rt}/lib/linux/libclang_rt.scudo-${systemPlatform}.so";
48 A user-mode allocator based on LLVM Sanitizer’s CombinedAllocator,
49 which aims at providing additional mitigations against heap based
50 vulnerabilities, while maintaining good performance.
55 libPath = "${pkgs.mimalloc}/lib/libmimalloc.so";
57 A compact and fast general purpose allocator, which may
58 optionally be built with mitigations against various heap
64 providerConf = providers.${cfg.provider};
66 # An output that contains only the shared library, to avoid
67 # needlessly bloating the system closure
68 mallocLib = pkgs.runCommand "malloc-provider-${cfg.provider}"
70 preferLocalBuild = true;
71 allowSubstitutes = false;
72 origLibPath = providerConf.libPath;
73 libName = baseNameOf origLibPath;
77 cp -L $origLibPath $out/lib/$libName
80 # The full path to the selected provider shlib.
81 providerLibPath = "${mallocLib}/lib/${mallocLib.libName}";
86 maintainers = [ lib.maintainers.joachifm ];
90 environment.memoryAllocator.provider = lib.mkOption {
91 type = lib.types.enum ([ "libc" ] ++ lib.attrNames providers);
94 The system-wide memory allocator.
96 Briefly, the system-wide memory allocator providers are:
98 - `libc`: the standard allocator provided by libc
99 ${lib.concatStringsSep "\n" (lib.mapAttrsToList
100 (name: value: "- `${name}`: ${lib.replaceStrings [ "\n" ] [ " " ] value.description}")
104 Selecting an alternative allocator (i.e., anything other than
105 `libc`) may result in instability, data loss,
106 and/or service failure.
112 config = lib.mkIf (cfg.provider != "libc") {
113 environment.etc."ld-nix.so.preload".text = ''
116 security.apparmor.includes = {
117 "abstractions/base" = ''
118 r /etc/ld-nix.so.preload,
119 r ${config.environment.etc."ld-nix.so.preload".source},
120 include "${pkgs.apparmorRulesFromClosure {
122 baseRules = ["mr $path/lib/**.so*"];