at 23.05-pre 3.4 kB view raw
1{ config, lib, pkgs, ... }: 2with lib; 3 4let 5 cfg = config.environment.memoryAllocator; 6 7 # The set of alternative malloc(3) providers. 8 providers = { 9 graphene-hardened = { 10 libPath = "${pkgs.graphene-hardened-malloc}/lib/libhardened_malloc.so"; 11 description = '' 12 An allocator designed to mitigate memory corruption attacks, such as 13 those caused by use-after-free bugs. 14 ''; 15 }; 16 17 jemalloc = { 18 libPath = "${pkgs.jemalloc}/lib/libjemalloc.so"; 19 description = '' 20 A general purpose allocator that emphasizes fragmentation avoidance 21 and scalable concurrency support. 22 ''; 23 }; 24 25 scudo = let 26 platformMap = { 27 aarch64-linux = "aarch64"; 28 x86_64-linux = "x86_64"; 29 }; 30 31 systemPlatform = platformMap.${pkgs.stdenv.hostPlatform.system} or (throw "scudo not supported on ${pkgs.stdenv.hostPlatform.system}"); 32 in { 33 libPath = "${pkgs.llvmPackages_latest.compiler-rt}/lib/linux/libclang_rt.scudo-${systemPlatform}.so"; 34 description = '' 35 A user-mode allocator based on LLVM Sanitizers CombinedAllocator, 36 which aims at providing additional mitigations against heap based 37 vulnerabilities, while maintaining good performance. 38 ''; 39 }; 40 41 mimalloc = { 42 libPath = "${pkgs.mimalloc}/lib/libmimalloc.so"; 43 description = '' 44 A compact and fast general purpose allocator, which may 45 optionally be built with mitigations against various heap 46 vulnerabilities. 47 ''; 48 }; 49 }; 50 51 providerConf = providers.${cfg.provider}; 52 53 # An output that contains only the shared library, to avoid 54 # needlessly bloating the system closure 55 mallocLib = pkgs.runCommand "malloc-provider-${cfg.provider}" 56 rec { 57 preferLocalBuild = true; 58 allowSubstitutes = false; 59 origLibPath = providerConf.libPath; 60 libName = baseNameOf origLibPath; 61 } 62 '' 63 mkdir -p $out/lib 64 cp -L $origLibPath $out/lib/$libName 65 ''; 66 67 # The full path to the selected provider shlib. 68 providerLibPath = "${mallocLib}/lib/${mallocLib.libName}"; 69in 70 71{ 72 meta = { 73 maintainers = [ maintainers.joachifm ]; 74 }; 75 76 options = { 77 environment.memoryAllocator.provider = mkOption { 78 type = types.enum ([ "libc" ] ++ attrNames providers); 79 default = "libc"; 80 description = lib.mdDoc '' 81 The system-wide memory allocator. 82 83 Briefly, the system-wide memory allocator providers are: 84 85 - `libc`: the standard allocator provided by libc 86 ${concatStringsSep "\n" (mapAttrsToList 87 (name: value: "- `${name}`: ${replaceStrings [ "\n" ] [ " " ] value.description}") 88 providers)} 89 90 ::: {.warning} 91 Selecting an alternative allocator (i.e., anything other than 92 `libc`) may result in instability, data loss, 93 and/or service failure. 94 ::: 95 ''; 96 }; 97 }; 98 99 config = mkIf (cfg.provider != "libc") { 100 environment.etc."ld-nix.so.preload".text = '' 101 ${providerLibPath} 102 ''; 103 security.apparmor.includes = { 104 "abstractions/base" = '' 105 r /etc/ld-nix.so.preload, 106 r ${config.environment.etc."ld-nix.so.preload".source}, 107 include "${pkgs.apparmorRulesFromClosure { 108 name = "mallocLib"; 109 baseRules = ["mr $path/lib/**.so*"]; 110 } [ mallocLib ] }" 111 ''; 112 }; 113 }; 114}