Skip to content

Commit

Permalink
Hardware re-factoring:
Browse files Browse the repository at this point in the history
- moved hardware from common to a flake-module
- re-factored 'generation' as parameter to hardware definition
- quick fixed network device required in desktop stack (hw definition not available in vm namespaces)
- fix references to modules/common/hardware

Signed-off-by: Manuel Bluhm <[email protected]>
  • Loading branch information
mbssrc authored and brianmcgillion committed May 9, 2024
1 parent 715eb1e commit a4f747c
Show file tree
Hide file tree
Showing 42 changed files with 135 additions and 90 deletions.
4 changes: 2 additions & 2 deletions .reuse/dep5
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Source: https://github.com/tiiuae/ghaf

Copyright: 2022-2024 Technology Innovation Institute (TII) <https://github.com/tiiuae/ghaf>
License: Apache-2.0
Files:
Files:
*.lock *.png *.svg *.patch *.db *.key *.pem *.cer *.p12
modules/common/hardware/x86_64-generic/kernel/configs/ghaf_host_hardened_baseline-x86
modules/hardware/x86_64-generic/kernel/configs/ghaf_host_hardened_baseline-x86
modules/jetpack/ghaf_host_hardened_baseline-jetson-orin
10 changes: 5 additions & 5 deletions docs/src/architecture/hardening.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ NixOS provides several mechanisms to customize the kernel. The main methods are:

* [Declaring kernel command line parameters](https://nixos.wiki/wiki/Linux_kernel#Custom_kernel_commandline): [usage in Ghaf](https://github.com/search?q=repo%3Atiiuae%2Fghaf%20kernelparams&type=code).
* [Declaring kernel custom configuration](https://nixos.org/manual/nixos/stable/#sec-linux-config-customizing): [usage in Ghaf](https://github.com/tiiuae/ghaf/blob/main/modules/host/kernel.nix).

Example of entering the kernel development shell to customize the `.config` and build it:

```
~/ghaf $ nix develop .#devShells.x86_64-linux.kernel-x86
...
[ghaf-kernel-devshell:~/ghaf/linux-6.6.7]$ cp ../modules/common/hardware/x86_64-generic/kernel/configs/ghaf_host_hardened_baseline .config
[ghaf-kernel-devshell:~/ghaf/linux-6.6.7]$ cp ../modules/hardware/x86_64-generic/kernel/configs/ghaf_host_hardened_baseline .config
[ghaf-kernel-devshell:~/ghaf/linux-6.6.7]$ make menuconfig
...
[ghaf-kernel-devshell:~/ghaf/linux-6.6.7]$ make -j$(nproc)
Expand All @@ -42,8 +42,8 @@ NixOS provides several mechanisms to customize the kernel. The main methods are:
* [Validating with kernel hardening checker](https://github.com/a13xp0p0v/kernel-hardening-checker):

```
[ghaf-kernel-devshell:~/ghaf/linux-6.6.7]$ cp ../modules/common/hardware/x86_64-generic/kernel/configs/ghaf_host_hardened_baseline .config
[ghaf-kernel-devshell:~/ghaf/linux-6.6.7]$ HS=../modules/common/hardware/x86_64-generic/kernel/host/configs GS=../modules/common/hardware/x86_64-generic/kernel/guest/configs
[ghaf-kernel-devshell:~/ghaf/linux-6.6.7]$ cp ../modules/hardware/x86_64-generic/kernel/configs/ghaf_host_hardened_baseline .config
[ghaf-kernel-devshell:~/ghaf/linux-6.6.7]$ HS=../modules/hardware/x86_64-generic/kernel/host/configs GS=../modules/hardware/x86_64-generic/kernel/guest/configs
[ghaf-kernel-devshell:~/ghaf/linux-6.6.7]$ ./scripts/kconfig/merge_config.sh .config $HS/virtualization.config $HS/networking.config $HS/usb.config $HS/user-input-devices.config $HS/debug.config $GS/guest.config $GS/display-gpu.config
[ghaf-kernel-devshell:~/ghaf/linux-6.6.7]$ kernel-hardening-checker -c .config
[+] Kconfig file to check: .config
Expand Down Expand Up @@ -74,7 +74,7 @@ The host kernel runs on bare metal. The kernel is provided either with Linux ups
The host kernel hardening is based on Linux `make tinyconfig`. The
default `tinyconfig` fails to assertions on NixOS without
modifications. Assertions are fixed in the `ghaf_host_hardened_baseline` Linux configuration under Ghaf
`modules/common/hardware/x86_64-generic/kernel/configs`. Resulting baseline
`modules/hardware/x86_64-generic/kernel/configs`. Resulting baseline
kernel configuration is generic for x86_64 hardware architecture devices.

In addition, NixOS (Ghaf baseline dependency) requires several kernel modules that are added to the config or ignored with `allowMissing = true`. As of now, the kernel builds and early boots on Lenovo X1.
Expand Down
1 change: 0 additions & 1 deletion modules/common/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
./common.nix
./development
./firewall
./hardware
./profiles
./security
./tpm2
Expand Down
52 changes: 0 additions & 52 deletions modules/common/hardware/lenovo-x1/definitions/default.nix

This file was deleted.

1 change: 1 addition & 0 deletions modules/desktop/graphics/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
./fonts.nix
./window-manager.nix
./boot.nix
./hardware.nix
];
}
14 changes: 14 additions & 0 deletions modules/desktop/graphics/hardware.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Copyright 2024 TII (SSRC) and the Ghaf contributors
# SPDX-License-Identifier: Apache-2.0
{lib, ...}:
with lib; {
options.ghaf.graphics.hardware = {
networkDevice = mkOption {
type = types.anything;
default = {};
description = ''
Network device interface for use with graphics stack.
'';
};
};
}
2 changes: 1 addition & 1 deletion modules/desktop/graphics/waybar.config.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
...
}: let
cfg = config.ghaf.graphics.labwc;
networkDevice = config.ghaf.hardware.definition.network.pciDevices;
inherit (config.ghaf.graphics.hardware) networkDevice;
inherit (import ../../../lib/icons.nix {inherit pkgs lib;}) svgToPNG;

launchpad-icon = svgToPNG "launchpad" ../../../assets/icons/svg/launchpad.svg "38x38";
Expand Down
5 changes: 4 additions & 1 deletion modules/flake-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
# Modules to be exported from Flake
#
{inputs, ...}: {
imports = [./disko/flake-module.nix];
imports = [
./disko/flake-module.nix
./hardware/flake-module.nix
];

flake.nixosModules = {
common.imports = [
Expand Down
File renamed without changes.
File renamed without changes.
15 changes: 15 additions & 0 deletions modules/hardware/flake-module.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Copyright 2024 TII (SSRC) and the Ghaf contributors
# SPDX-License-Identifier: Apache-2.0
_: {
flake.nixosModules = {
hw-lenovo-x1.imports = [
./definition.nix
./x86_64-generic
./lenovo-x1
];
hw-x86_64-generic.imports = [
./definition.nix
./x86_64-generic
];
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
# SPDX-License-Identifier: Apache-2.0
{
imports = [
./x86_64-linux.nix
./x86_64-generic
./definition.nix

./definitions
./ax88179_178a.nix
];
}
69 changes: 69 additions & 0 deletions modules/hardware/lenovo-x1/definitions/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors
# SPDX-License-Identifier: Apache-2.0
#
{
config,
lib,
...
}: let
hwDefinition = import (./. + "/x1-${config.ghaf.hardware.generation}.nix");
in {
imports = [
../../definition.nix
];

options.ghaf.hardware.generation = lib.mkOption {
description = "Generation of the hardware configuration";
type = lib.types.str;
default = "gen11";
};

config = {
ghaf.hardware.definition = {
inherit (hwDefinition) mouse;
inherit (hwDefinition) touchpad;
inherit (hwDefinition) disks;
inherit (hwDefinition) network;
inherit (hwDefinition) gpu;

virtioInputHostEvdevs = [
# Lenovo X1 touchpad and keyboard
"/dev/input/by-path/platform-i8042-serio-0-event-kbd"
"/dev/mouse"
"/dev/touchpad"
# Lenovo X1 trackpoint (red button/joystick)
"/dev/input/by-path/platform-i8042-serio-1-event-mouse"
];
};

disko.devices.disk = hwDefinition.disks;

# Notes:
# 1. This assembles udev rules for different hw configurations (i.e., different mice/touchpads) by adding
# all of them to the configuration. This was chosen for simplicity to not have to provide hw identifier at build,
# but is not ideal and should be changed.
# 2. USB camera "passthrough" is handled by qemu and thus available on host. If peripheral VM is implemented,
# the entire host controller should be passthrough'd using the PCI bus (14.0). In x1, bluetooth and fingerprint
# reader are on this bus.
services.udev.extraRules = let
mapMouseRules =
builtins.map (d: '' SUBSYSTEM=="input", ATTRS{name}=="${d}", KERNEL=="event*", GROUP="kvm", SYMLINK+="mouse"
'');
mapTouchpadRules =
builtins.map (d: '' SUBSYSTEM=="input", ATTRS{name}=="${d}", KERNEL=="event*", GROUP="kvm", SYMLINK+="touchpad"
'');
in ''
# Laptop keyboard
SUBSYSTEM=="input", ATTRS{name}=="AT Translated Set 2 keyboard", GROUP="kvm"
# Laptop TrackPoint
SUBSYSTEM=="input", ATTRS{name}=="TPPS/2 Elan TrackPoint", GROUP="kvm"
# Lenovo X1 integrated webcam
KERNEL=="3-8", SUBSYSTEM=="usb", ATTR{busnum}=="3", ATTR{devnum}=="3", GROUP="kvm"
# Lenovo X1 integrated fingerprint reader
KERNEL=="3-6", SUBSYSTEM=="usb", ATTR{busnum}=="3", ATTR{devnum}=="2", GROUP="kvm"
# Mouse and Touchpad
${lib.strings.concatStrings (mapMouseRules hwDefinition.mouse)}
${lib.strings.concatStrings (mapTouchpadRules hwDefinition.touchpad)}
'';
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
./kernel/hardening.nix
./kernel/host
./kernel/host/pkvm
./x86_64-linux.nix
];
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
...
}: let
# Importing kernel builder function from packages and checking hardening options
buildKernel = import ../../../../../../packages/kernel {inherit config pkgs lib;};
buildKernel = import ../../../../../packages/kernel {inherit config pkgs lib;};
config_baseline = ../configs/ghaf_host_hardened_baseline-x86;
host_hardened_kernel = buildKernel {
inherit config_baseline;
Expand Down
File renamed without changes.
6 changes: 3 additions & 3 deletions nix/checks.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
touch $out
'';
module-test-hardened-generic-host-kernel =
pkgs.callPackage ../modules/common/hardware/x86_64-generic/kernel/host/test {inherit pkgs;};
pkgs.callPackage ../modules/hardware/x86_64-generic/kernel/host/test {inherit pkgs;};
module-test-hardened-lenovo-x1-guest-guivm-kernel =
pkgs.callPackage ../modules/common/hardware/lenovo-x1/kernel/guest/test {inherit pkgs;};
pkgs.callPackage ../modules/hardware/lenovo-x1/kernel/guest/test {inherit pkgs;};
module-test-hardened-pkvm-kernel =
pkgs.callPackage ../modules/common/hardware/x86_64-generic/kernel/host/pkvm/test {inherit pkgs;};
pkgs.callPackage ../modules/hardware/x86_64-generic/kernel/host/pkvm/test {inherit pkgs;};
}
// (lib.mapAttrs' (n: lib.nameValuePair "package-${n}") self'.packages);
};
Expand Down
2 changes: 1 addition & 1 deletion nix/devshell/kernel.nix
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
export PS1="[ghaf-kernel-${platform}-devshell:\w]$ "
'';
# use "eval $checkPhase" - see https://discourse.nixos.org/t/nix-develop-and-checkphase/25707
checkPhase = "cp ../modules/common/hardware/${platform}/kernel/configs/ghaf_host_hardened_baseline-${arch} ./.config && make -j$(nproc)";
checkPhase = "cp ../modules/hardware/${platform}/kernel/configs/ghaf_host_hardened_baseline-${arch} ./.config && make -j$(nproc)";
};
in {
devShells.kernel-x86 = mkKernelShell {
Expand Down
4 changes: 2 additions & 2 deletions packages/kernel/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
configfile = config_baseline;
};

generic_host_configs = ../../modules/common/hardware/x86_64-generic/kernel/host/configs;
generic_guest_configs = ../../modules/common/hardware/x86_64-generic/kernel/guest/configs;
generic_host_configs = ../../modules/hardware/x86_64-generic/kernel/host/configs;
generic_guest_configs = ../../modules/hardware/x86_64-generic/kernel/guest/configs;
# TODO: refactor - do we yet have any X1 specific host kernel configuration options?
# - we could add a configuration fragment for host debug via usb-ethernet-adapter(s)

Expand Down
1 change: 1 addition & 0 deletions targets/generic-x86_64/flake-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
self.nixosModules.desktop
self.nixosModules.host
self.nixosModules.microvm
self.nixosModules.hw-x86_64-generic

{
ghaf = {
Expand Down
28 changes: 12 additions & 16 deletions targets/lenovo-x1/everything.nix
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
## To here

lenovo-x1 = generation: variant: extraModules: let
hwDefinition = import ../../modules/common/hardware/lenovo-x1/definitions {
inherit generation lib;
};
hostConfiguration = lib.nixosSystem {
inherit system;
modules =
Expand All @@ -34,6 +31,7 @@
self.nixosModules.microvm

self.nixosModules.disko-lenovo-x1-basic-v1
self.nixosModules.hw-lenovo-x1

({
pkgs,
Expand All @@ -42,8 +40,6 @@
}: let
powerControl = pkgs.callPackage ../../packages/powercontrol {};
in {
security.polkit.extraConfig = powerControl.polkitExtraConfig;
services.udev.extraRules = hwDefinition.udevRules;
time.timeZone = "Asia/Dubai";

# Enable pulseaudio support for host as a service
Expand All @@ -61,23 +57,23 @@
disko.devices.disk = config.ghaf.hardware.definition.disks;

ghaf = {
hardware.definition = hwDefinition;
# To enable guest hardening enable host hardening first
# Hardware definitions
hardware.x86_64.common.enable = true;
hardware.generation = generation;

hardware.ax88179_178a.enable = true;
security.tpm2.enable = true;

# Kernel hardening
host.kernel.hardening.enable = false;
host.kernel.hardening.virtualization.enable = false;
host.kernel.hardening.networking.enable = false;
host.kernel.hardening.inputdevices.enable = false;

host.kernel.hardening.hypervisor.enable = false;
guest.kernel.hardening.enable = false;
guest.kernel.hardening.graphics.enable = false;

host.kernel.hardening.hypervisor.enable = false;

hardware.x86_64.common.enable = true;
hardware.ax88179_178a.enable = true;

security.tpm2.enable = true;

# Virtualization options
virtualization.microvm-host.enable = true;
virtualization.microvm-host.networkSupport = true;

Expand Down Expand Up @@ -107,7 +103,7 @@
vms = import ./appvms/default.nix {inherit pkgs config;};
};

# Enable all the default UI applications
# UI applications
profiles = {
applications.enable = false;
};
Expand Down
2 changes: 1 addition & 1 deletion targets/lenovo-x1/guivmExtraModules.nix
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
};

guivmExtraConfigurations = {
ghaf.hardware.definition.network.pciDevices = configH.ghaf.hardware.definition.network.pciDevices;
ghaf.graphics.hardware.networkDevice = configH.ghaf.hardware.definition.network.pciDevices;
ghaf.profiles.graphics.compositor = "labwc";
ghaf.graphics.launchers = let
hostAddress = "192.168.101.2";
Expand Down
1 change: 1 addition & 0 deletions targets/vm/flake-module.nix
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
self.nixosModules.desktop
self.nixosModules.host
self.nixosModules.microvm
self.nixosModules.hw-x86_64-generic

{
ghaf = {
Expand Down

0 comments on commit a4f747c

Please sign in to comment.