diff --git a/WORKAROUNDS.md b/WORKAROUNDS.md index 37533691..2b225b28 100644 --- a/WORKAROUNDS.md +++ b/WORKAROUNDS.md @@ -55,6 +55,8 @@ A setting that works around a bug or a hardware quirk. | WA-042 | Colmena nodes set `system.nixos.versionSuffix` and `revision` from the flake's lib — `outputs/default.nix` (`rawColmenaHive`) | Colmena evaluates each node with nixpkgs' `eval-config.nix` and plain lib, which reports `26.11pre-git`, so without the override a Colmena deploy differs from the `nixosConfigurations` toplevel; the `colmena-parity` eval test guards the match | Drop once Colmena evaluates nodes with the flake's lib or accepts `nixosConfigurations` directly, keeping `colmena-parity` green | 2026-10-21 | on a colmena bump | active | | WA-046 | xdg-desktop-portal-wlr pinned to 0.8.2 — `modules/nixos/desktop/xdg.nix` | niri's GNOME ScreenCast path exposes only DMA-BUF with modifiers, which Zoom 7.2.1 rejects; xdg-desktop-portal-wlr 0.8.2 provides the working SHM path, while 0.8.4 regresses Zoom's SelectSources. | Drop once niri's ScreenCast path works with Zoom or xdg-desktop-portal-wlr 0.8.4+ is fixed. | 2026-10-31 | on xdg-desktop-portal-wlr or Zoom updates | active | +| WA-048 | Nixpak GUI fontconfig comes from the host — `hardening/nixpaks/modules/desktop-base.nix` | Nixpak normally generates a standalone `/etc/fonts` and font package list for each sandbox; that bypasses the host `defaultFonts` and made browser chrome, Telegram, QQ and other sandboxed apps choose a different CJK fallback from the host. The wrapper now disables Nixpak fonts and bind-mounts `/etc/static/fonts` at `/etc/fonts`, so sandboxed GUI apps reuse the host font packages and family preferences through the already-mounted `/nix/store`. | Drop once Nixpak can directly reuse the host fontconfig or no longer overrides `/etc/fonts`, then remove the bind and restore the library-supported configuration path | 2026-11-01 | on a nixpak update | active | + If WA-008 freezes recur, the fallback is to restore the parameters commented out in `hosts/idols-ai/hardware-configuration.nix` — `nvme_core.default_ps_max_latency_us=0 nvme_core.io_timeout=4294967295 pcie_aspm=off`; this is a diff --git a/hardening/nixpaks/modules/desktop-base.nix b/hardening/nixpaks/modules/desktop-base.nix index 1f152ede..d9ae4610 100644 --- a/hardening/nixpaks/modules/desktop-base.nix +++ b/hardening/nixpaks/modules/desktop-base.nix @@ -17,20 +17,6 @@ provider = "nixos"; bundlePackage = pkgs.mesa.drivers; }; - fonts = { - enable = true; - # Preserve nixpak's default coverage and add Chinese/Japanese/Korean glyphs. - fonts = with pkgs; [ - cantarell-fonts - dejavu_fonts - liberation_ttf - gyre-fonts - source-sans - source-code-pro - noto-fonts-color-emoji - noto-fonts-cjk-sans - ]; - }; locale.enable = true; dbus = { policies = { @@ -87,6 +73,15 @@ ] ]; bind.ro = [ + # Reuse the host's NixOS fontconfig instead of maintaining a second font + # set in every sandbox. Nixpak's own font module generates an isolated + # /etc/fonts with no host defaultFonts, so GUI apps otherwise resolve CJK + # glyphs differently from the host. The font files and caches referenced + # by this config live in /nix/store, which Nixpak already mounts. + [ + "/etc/static/fonts" + "/etc/fonts" + ] "/etc/localtime" "/etc/zoneinfo" (sloth.concat' sloth.xdgConfigHome "/gtk-2.0") @@ -131,7 +126,7 @@ pkgs.shared-mime-info ]; XCURSOR_PATH = "${pkgs.bibata-cursors}/share/icons:${pkgs.bibata-cursors}/share/pixmaps"; - # Fontconfig configuration mounted by nixpak fonts.enable. + # Host NixOS fontconfig, bind-mounted above. FONTCONFIG_FILE = "/etc/fonts/fonts.conf"; NIXOS_XDG_OPEN_USE_PORTAL = "1"; } diff --git a/hardening/tests/policy-lib.nix b/hardening/tests/policy-lib.nix index 96fb8885..371aad46 100644 --- a/hardening/tests/policy-lib.nix +++ b/hardening/tests/policy-lib.nix @@ -44,6 +44,8 @@ let || path == "/run/dbus" || path == "/run/dbus/system_bus_socket"; + hasHostFontconfig = app: lib.elem [ "/etc/static/fonts" "/etc/fonts" ] app.bubblewrap.bind.ro; + hasPrivateTmp = app: let @@ -117,6 +119,8 @@ let "${name}/noBroadKeyring" = !lib.any (argument: argument == "--talk=org.freedesktop.secrets") app.dbus.args; "${name}/noForbiddenMounts" = !lib.any forbiddenMountFor (mountStrings app); + "${name}/hostFontconfig" = hasHostFontconfig app; + "${name}/noSandboxFonts" = !app.fonts.enable; "${name}/privateTmp" = hasPrivateTmp app; "${name}/network" = networkCheck app spec.network; "${name}/x11" = app.bubblewrap.sockets.x11 == (spec.x11 or false); diff --git a/modules/base/fonts.nix b/modules/base/fonts.nix index f5aa5f13..28121eed 100644 --- a/modules/base/fonts.nix +++ b/modules/base/fonts.nix @@ -12,6 +12,9 @@ in fonts.enable = lib.mkEnableOption "Rich Fonts - Add NerdFonts Icons, emojis & CJK Fonts"; }; + # This is the single font package list for the host and its Nixpak sandboxes: + # Nixpak GUI wrappers bind the generated host fontconfig rather than + # installing their own fonts. config.fonts.packages = with pkgs; lib.mkIf cfg.fonts.enable [ diff --git a/modules/nixos/desktop/fonts.nix b/modules/nixos/desktop/fonts.nix index 84820f7c..b8184170 100644 --- a/modules/nixos/desktop/fonts.nix +++ b/modules/nixos/desktop/fonts.nix @@ -10,7 +10,9 @@ # packages = [ ... ]; fontconfig = { - # User defined default fonts + # User defined default fonts. Nixpak GUI wrappers bind this generated + # host configuration into their sandboxes, so host and sandboxed apps + # share one font stack; do not duplicate these families there. # https://catcat.cc/post/2021-03-07/ defaultFonts = { serif = [