vuls: init at 0.27.0
[NixPkgs.git] / nixos / modules / config / malloc.nix
blob665cbdd27874c03bfc9a8034901310a9b3deadff
1 { config, lib, pkgs, ... }:
2 let
3   cfg = config.environment.memoryAllocator;
5   # The set of alternative malloc(3) providers.
6   providers = {
7     graphene-hardened = {
8       libPath = "${pkgs.graphene-hardened-malloc}/lib/libhardened_malloc.so";
9       description = ''
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.
14       '';
15     };
17     graphene-hardened-light = {
18       libPath = "${pkgs.graphene-hardened-malloc}/lib/libhardened_malloc-light.so";
19       description = ''
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
26         properties.
27       '';
28     };
30     jemalloc = {
31       libPath = "${pkgs.jemalloc}/lib/libjemalloc.so";
32       description = ''
33         A general purpose allocator that emphasizes fragmentation avoidance
34         and scalable concurrency support.
35       '';
36     };
38     scudo = let
39       platformMap = {
40         aarch64-linux = "aarch64";
41         x86_64-linux  = "x86_64";
42       };
44       systemPlatform = platformMap.${pkgs.stdenv.hostPlatform.system} or (throw "scudo not supported on ${pkgs.stdenv.hostPlatform.system}");
45     in {
46       libPath = "${pkgs.llvmPackages_14.compiler-rt}/lib/linux/libclang_rt.scudo-${systemPlatform}.so";
47       description = ''
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.
51       '';
52     };
54     mimalloc = {
55       libPath = "${pkgs.mimalloc}/lib/libmimalloc.so";
56       description = ''
57         A compact and fast general purpose allocator, which may
58         optionally be built with mitigations against various heap
59         vulnerabilities.
60       '';
61     };
62   };
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}"
69     rec {
70       preferLocalBuild = true;
71       allowSubstitutes = false;
72       origLibPath = providerConf.libPath;
73       libName = baseNameOf origLibPath;
74     }
75     ''
76       mkdir -p $out/lib
77       cp -L $origLibPath $out/lib/$libName
78     '';
80   # The full path to the selected provider shlib.
81   providerLibPath = "${mallocLib}/lib/${mallocLib.libName}";
85   meta = {
86     maintainers = [ lib.maintainers.joachifm ];
87   };
89   options = {
90     environment.memoryAllocator.provider = lib.mkOption {
91       type = lib.types.enum ([ "libc" ] ++ lib.attrNames providers);
92       default = "libc";
93       description = ''
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}")
101             providers)}
103         ::: {.warning}
104         Selecting an alternative allocator (i.e., anything other than
105         `libc`) may result in instability, data loss,
106         and/or service failure.
107         :::
108       '';
109     };
110   };
112   config = lib.mkIf (cfg.provider != "libc") {
113     environment.etc."ld-nix.so.preload".text = ''
114       ${providerLibPath}
115     '';
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 {
121             name = "mallocLib";
122             baseRules = ["mr $path/lib/**.so*"];
123           } [ mallocLib ] }"
124       '';
125     };
126   };