nixos/binfmt: Initial binfmt_msc support.
This commit is contained in:
parent
6952a2b101
commit
c64639b54c
@ -694,6 +694,7 @@
|
|||||||
./services/x11/xserver.nix
|
./services/x11/xserver.nix
|
||||||
./system/activation/activation-script.nix
|
./system/activation/activation-script.nix
|
||||||
./system/activation/top-level.nix
|
./system/activation/top-level.nix
|
||||||
|
./system/boot/binfmt.nix
|
||||||
./system/boot/coredump.nix
|
./system/boot/coredump.nix
|
||||||
./system/boot/emergency-mode.nix
|
./system/boot/emergency-mode.nix
|
||||||
./system/boot/grow-partition.nix
|
./system/boot/grow-partition.nix
|
||||||
|
139
nixos/modules/system/boot/binfmt.nix
Normal file
139
nixos/modules/system/boot/binfmt.nix
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
inherit (lib) mkOption types optionalString;
|
||||||
|
|
||||||
|
cfg = config.boot.binfmtMiscRegistrations;
|
||||||
|
|
||||||
|
makeBinfmtLine = name: { recognitionType, offset, magicOrExtension
|
||||||
|
, mask, preserveArgvZero, openBinary
|
||||||
|
, matchCredentials, fixBinary, ...
|
||||||
|
}: let
|
||||||
|
type = if recognitionType == "magic" then "M" else "E";
|
||||||
|
offset' = toString offset;
|
||||||
|
mask' = toString mask;
|
||||||
|
interpreter = "/run/binfmt/${name}";
|
||||||
|
flags = if !(matchCredentials -> openBinary)
|
||||||
|
then throw "boot.binfmtMiscRegistrations.${name}: you can't specify openBinary = false when matchCredentials = true."
|
||||||
|
else optionalString preserveArgvZero "P" +
|
||||||
|
optionalString (openBinary && !matchCredentials) "O" +
|
||||||
|
optionalString matchCredentials "C" +
|
||||||
|
optionalString fixBinary "F";
|
||||||
|
in ":${name}:${type}:${offset'}:${magicOrExtension}:${mask'}:${interpreter}:${flags}";
|
||||||
|
|
||||||
|
binfmtFile = builtins.toFile "binfmt_nixos.conf"
|
||||||
|
(lib.concatStringsSep "\n" (lib.mapAttrsToList makeBinfmtLine cfg));
|
||||||
|
|
||||||
|
activationSnippet = name: { interpreter, ... }:
|
||||||
|
"ln -sf ${interpreter} /run/binfmt/${name}";
|
||||||
|
activationScript = ''
|
||||||
|
mkdir -p -m 0755 /run/binfmt
|
||||||
|
${lib.concatStringsSep "\n" (lib.mapAttrsToList activationSnippet cfg)}
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
options = {
|
||||||
|
boot.binfmtMiscRegistrations = mkOption {
|
||||||
|
default = {};
|
||||||
|
|
||||||
|
description = ''
|
||||||
|
Extra binary formats to register with the kernel.
|
||||||
|
See https://www.kernel.org/doc/html/latest/admin-guide/binfmt-misc.html for more details.
|
||||||
|
'';
|
||||||
|
|
||||||
|
type = types.attrsOf (types.submodule ({ config, ... }: {
|
||||||
|
options = {
|
||||||
|
recognitionType = mkOption {
|
||||||
|
default = "magic";
|
||||||
|
description = "Whether to recognize executables by magic number or extension.";
|
||||||
|
type = types.enum [ "magic" "extension" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
offset = mkOption {
|
||||||
|
default = null;
|
||||||
|
description = "The byte offset of the magic number used for recognition.";
|
||||||
|
type = types.nullOr types.int;
|
||||||
|
};
|
||||||
|
|
||||||
|
magicOrExtension = mkOption {
|
||||||
|
description = "The magic number or extension to match on.";
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
mask = mkOption {
|
||||||
|
default = null;
|
||||||
|
description =
|
||||||
|
"A mask to be ANDed with the byte sequence of the file before matching";
|
||||||
|
type = types.nullOr types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
interpreter = mkOption {
|
||||||
|
description = ''
|
||||||
|
The interpreter to invoke to run the program.
|
||||||
|
|
||||||
|
Note that the actual registration will point to
|
||||||
|
/run/binfmt/''${name}, so the kernel interpreter length
|
||||||
|
limit doesn't apply.
|
||||||
|
'';
|
||||||
|
type = types.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
preserveArgvZero = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to pass the original argv[0] to the interpreter.
|
||||||
|
|
||||||
|
See the description of the 'P' flag in the kernel docs
|
||||||
|
for more details;
|
||||||
|
'';
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
|
||||||
|
openBinary = mkOption {
|
||||||
|
default = config.matchCredentials;
|
||||||
|
description = ''
|
||||||
|
Whether to pass the binary to the interpreter as an open
|
||||||
|
file descriptor, instead of a path.
|
||||||
|
'';
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
|
||||||
|
matchCredentials = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to launch with the credentials and security
|
||||||
|
token of the binary, not the interpreter (e.g. setuid
|
||||||
|
bit).
|
||||||
|
|
||||||
|
See the description of the 'C' flag in the kernel docs
|
||||||
|
for more details.
|
||||||
|
|
||||||
|
Implies/requires openBinary = true.
|
||||||
|
'';
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
|
||||||
|
fixBinary = mkOption {
|
||||||
|
default = false;
|
||||||
|
description = ''
|
||||||
|
Whether to open the interpreter file as soon as the
|
||||||
|
registration is loaded, rather than waiting for a
|
||||||
|
relevant file to be invoked.
|
||||||
|
|
||||||
|
See the description of the 'F' flag in the kernel docs
|
||||||
|
for more details.
|
||||||
|
'';
|
||||||
|
type = types.bool;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf (cfg != {}) {
|
||||||
|
environment.etc."binfmt.d/nixos.conf".source = binfmtFile;
|
||||||
|
system.activationScripts.binfmt = activationScript;
|
||||||
|
systemd.additionalUpstreamSystemUnits =
|
||||||
|
[ "proc-sys-fs-binfmt_misc.automount"
|
||||||
|
"proc-sys-fs-binfmt_misc.mount"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user