From d43ff35013e056f6641d0ed46469e786fcf63d1f Mon Sep 17 00:00:00 2001 From: Jamie Magee Date: Wed, 6 May 2026 21:33:24 -0700 Subject: [PATCH] buildFHSEnv: fix substring match incorrectly skipping host directories The auto-mount loop used bash regex =~ which does substring matching, so top-level directories whose names are prefixes of FHS paths (e.g. /sb matches /sbin) were silently skipped instead of bind-mounted into the chroot. Switch to associative array for exact-match lookup. Fixes #241151 --- .../build-fhsenv-bubblewrap/default.nix | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/pkgs/build-support/build-fhsenv-bubblewrap/default.nix b/pkgs/build-support/build-fhsenv-bubblewrap/default.nix index 214656bbb955..2c6a297cb7cb 100644 --- a/pkgs/build-support/build-fhsenv-bubblewrap/default.nix +++ b/pkgs/build-support/build-fhsenv-bubblewrap/default.nix @@ -222,9 +222,14 @@ let ro_mounts+=(--ro-bind /etc /.host-etc) fi + declare -A etc_ignored_set + for ign in "''${etc_ignored[@]}"; do + etc_ignored_set[$ign]=1 + done + # link selected etc entries from the actual root for i in ${escapeShellArgs etcBindEntries}; do - if [[ "''${etc_ignored[@]}" =~ "$i" ]]; then + if [[ -n "''${etc_ignored_set[$i]:-}" ]]; then continue fi if [[ -e $i ]]; then @@ -232,11 +237,21 @@ let fi done + declare -A ignored_set + for ign in "''${ignored[@]}"; do + ignored_set[$ign]=1 + done + declare -a auto_mounts # loop through all directories in the root for dir in /*; do - # if it is a directory and it is not ignored - if [[ -d "$dir" ]] && [[ ! "''${ignored[@]}" =~ "$dir" ]]; then + # if it is a directory and not already provided by the FHS env or + # explicitly ignored, bind-mount it into the chroot. Use exact match + # via associative array because regex substring matching incorrectly + # skips prefixes (e.g. /sb would match /sbin and never get mounted, + # breaking --chdir when CWD is on a custom mount like /sb/project). + # https://github.com/NixOS/nixpkgs/issues/241151 + if [[ -d "$dir" ]] && [[ -z "''${ignored_set[$dir]:-}" ]]; then # add it to the mount list auto_mounts+=(--bind "$dir" "$dir") fi