From 3d613a4c9ff80e806f83d1387253c5848e1837f5 Mon Sep 17 00:00:00 2001 From: PETRO YAKOVYSHYN Date: Mon, 10 Aug 2026 22:21:38 -0700 Subject: [PATCH] fix(test): qualify build-dir owner with its domain The Windows DACL stamps in run-tests-parallel.sh, soak-test.sh and memlab.sh pass the current user to icacls by bare name. Git Bash resolves whoami to coreutils, which prints an unqualified name, and icacls resolves an unqualified name against the machine before the user. On a host whose name equals the user's (COMPUTERNAME=BUILD with user build) the grant lands on an empty principal: BUILD\:(OI)(CI)(F) Combined with the /inheritance:r on the same invocation, the directory ends up granting no usable account. run-tests-parallel.sh then cannot write its own log directory and the wave dies with: build/c/test-logs/results.txt: Permission denied FAIL: test-runner --list-suites exited nonzero Prefix the name with USERDOMAIN when it is set, which makes the account unambiguous, and fall back to the bare name otherwise. SYSTEM and Administrators in the same invocations already use SID form and are unaffected. Signed-off-by: PETRO YAKOVYSHYN --- scripts/memlab.sh | 6 ++++++ scripts/run-tests-parallel.sh | 9 +++++++++ scripts/soak-test.sh | 6 ++++++ 3 files changed, 21 insertions(+) diff --git a/scripts/memlab.sh b/scripts/memlab.sh index c849db5a13..ffe5969f79 100644 --- a/scripts/memlab.sh +++ b/scripts/memlab.sh @@ -35,7 +35,13 @@ if [[ "$BINARY" == *.exe ]] && command -v cygpath >/dev/null 2>&1 && ! command -v winepath >/dev/null 2>&1; then WIN_ROOT=$(mktemp -d "$(cygpath "$USERPROFILE")/cbm-memlab.XXXXXX") WIN_ROOT_W="$(cygpath -w "$WIN_ROOT")" + # Qualify with the domain: a bare name from coreutils `whoami` resolves + # against the machine first, so on a host whose name equals the user's the + # grant lands on an empty principal. ME="$(whoami | tr -d '\r')" + if [ -n "${USERDOMAIN:-}" ]; then + ME="${USERDOMAIN}\\${ME}" + fi MSYS2_ARG_CONV_EXCL='*' icacls "$WIN_ROOT_W" /reset /Q >/dev/null 2>&1 || true if ! MSYS2_ARG_CONV_EXCL='*' icacls "$WIN_ROOT_W" /inheritance:r \ /grant:r "${ME}:(OI)(CI)F" '*S-1-5-18:(OI)(CI)F' '*S-1-5-32-544:(OI)(CI)F' \ diff --git a/scripts/run-tests-parallel.sh b/scripts/run-tests-parallel.sh index 7bd69b1ffc..d7f8c0e8c3 100644 --- a/scripts/run-tests-parallel.sh +++ b/scripts/run-tests-parallel.sh @@ -58,7 +58,16 @@ stamp_windows_build_dir() { esac local runner_dir_w me norm_out stamp_out reset_out runner_dir_w="$(cygpath -w "$(dirname "$RUNNER")")" + # Qualify the account with its domain. Git Bash resolves `whoami` to + # coreutils, which prints a bare name, and icacls resolves a bare name + # against the machine first: on a host whose name equals the user's + # (COMPUTERNAME=BUILD, user build) the grant lands on an empty principal + # (BUILD\) and, combined with /inheritance:r above, locks this script out + # of its own log directory. me="$(whoami | tr -d '\r')" + if [ -n "${USERDOMAIN:-}" ]; then + me="${USERDOMAIN}\\${me}" + fi # Normalize FIRST: some runner images stamp EXPLICIT (non-inherited) # Authenticated-Users ACEs onto the workspace tree, which /inheritance:r # cannot strip and /grant:r does not touch (it replaces only the granted diff --git a/scripts/soak-test.sh b/scripts/soak-test.sh index 1aba4d327e..12910bbd1f 100755 --- a/scripts/soak-test.sh +++ b/scripts/soak-test.sh @@ -77,7 +77,13 @@ mkdir -p "$RESULTS_DIR" soak_stamp_windows_dir() { local dir_w me output dir_w="$(cygpath -w "$1")" + # Qualify with the domain: a bare name from coreutils `whoami` resolves + # against the machine first, so on a host whose name equals the user's the + # grant lands on an empty principal. me="$(whoami | tr -d '\r')" + if [ -n "${USERDOMAIN:-}" ]; then + me="${USERDOMAIN}\\${me}" + fi if ! output=$(MSYS2_ARG_CONV_EXCL='*' icacls "$dir_w" /reset /Q 2>&1); then echo "FAIL: soak DACL normalize failed (dir=$dir_w user=$me)" >&2 printf '%s\n' "$output" >&2