at 25.11-pre 4.3 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7let 8 cfg = config.environment.memoryAllocator; 9 10 # The set of alternative malloc(3) providers. 11 providers = { 12 graphene-hardened = { 13 libPath = "${pkgs.graphene-hardened-malloc}/lib/libhardened_malloc.so"; 14 description = '' 15 Hardened memory allocator coming from GrapheneOS project. 16 The default configuration template has all normal optional security 17 features enabled and is quite aggressive in terms of sacrificing 18 performance and memory usage for security. 19 ''; 20 }; 21 22 graphene-hardened-light = { 23 libPath = "${pkgs.graphene-hardened-malloc}/lib/libhardened_malloc-light.so"; 24 description = '' 25 Hardened memory allocator coming from GrapheneOS project. 26 The light configuration template disables the slab quarantines, 27 write after free check, slot randomization and raises the guard 28 slab interval from 1 to 8 but leaves zero-on-free and slab canaries enabled. 29 The light configuration has solid performance and memory usage while still 30 being far more secure than mainstream allocators with much better security 31 properties. 32 ''; 33 }; 34 35 jemalloc = { 36 libPath = "${pkgs.jemalloc}/lib/libjemalloc.so"; 37 description = '' 38 A general purpose allocator that emphasizes fragmentation avoidance 39 and scalable concurrency support. 40 ''; 41 }; 42 43 scudo = 44 let 45 platformMap = { 46 aarch64-linux = "aarch64"; 47 x86_64-linux = "x86_64"; 48 }; 49 50 systemPlatform = 51 platformMap.${pkgs.stdenv.hostPlatform.system} 52 or (throw "scudo not supported on ${pkgs.stdenv.hostPlatform.system}"); 53 in 54 { 55 libPath = "${pkgs.llvmPackages_14.compiler-rt}/lib/linux/libclang_rt.scudo-${systemPlatform}.so"; 56 description = '' 57 A user-mode allocator based on LLVM Sanitizers CombinedAllocator, 58 which aims at providing additional mitigations against heap based 59 vulnerabilities, while maintaining good performance. 60 ''; 61 }; 62 63 mimalloc = { 64 libPath = "${pkgs.mimalloc}/lib/libmimalloc.so"; 65 description = '' 66 A compact and fast general purpose allocator, which may 67 optionally be built with mitigations against various heap 68 vulnerabilities. 69 ''; 70 }; 71 }; 72 73 providerConf = providers.${cfg.provider}; 74 75 # An output that contains only the shared library, to avoid 76 # needlessly bloating the system closure 77 mallocLib = 78 pkgs.runCommand "malloc-provider-${cfg.provider}" 79 rec { 80 preferLocalBuild = true; 81 allowSubstitutes = false; 82 origLibPath = providerConf.libPath; 83 libName = baseNameOf origLibPath; 84 } 85 '' 86 mkdir -p $out/lib 87 cp -L $origLibPath $out/lib/$libName 88 ''; 89 90 # The full path to the selected provider shlib. 91 providerLibPath = "${mallocLib}/lib/${mallocLib.libName}"; 92in 93 94{ 95 meta = { 96 maintainers = [ lib.maintainers.joachifm ]; 97 }; 98 99 options = { 100 environment.memoryAllocator.provider = lib.mkOption { 101 type = lib.types.enum ([ "libc" ] ++ lib.attrNames providers); 102 default = "libc"; 103 description = '' 104 The system-wide memory allocator. 105 106 Briefly, the system-wide memory allocator providers are: 107 108 - `libc`: the standard allocator provided by libc 109 ${lib.concatStringsSep "\n" ( 110 lib.mapAttrsToList ( 111 name: value: "- `${name}`: ${lib.replaceStrings [ "\n" ] [ " " ] value.description}" 112 ) providers 113 )} 114 115 ::: {.warning} 116 Selecting an alternative allocator (i.e., anything other than 117 `libc`) may result in instability, data loss, 118 and/or service failure. 119 ::: 120 ''; 121 }; 122 }; 123 124 config = lib.mkIf (cfg.provider != "libc") { 125 environment.etc."ld-nix.so.preload".text = '' 126 ${providerLibPath} 127 ''; 128 security.apparmor.includes = { 129 "abstractions/base" = '' 130 r /etc/ld-nix.so.preload, 131 r ${config.environment.etc."ld-nix.so.preload".source}, 132 include "${ 133 pkgs.apparmorRulesFromClosure { 134 name = "mallocLib"; 135 baseRules = [ "mr $path/lib/**.so*" ]; 136 } [ mallocLib ] 137 }" 138 ''; 139 }; 140 }; 141}