From abc404ca21dcd15ff85f514a73e351f1f78b2cea Mon Sep 17 00:00:00 2001 From: alice Date: Sun, 13 Sep 2026 17:52:55 +0000 Subject: [PATCH] vms-ac3: anchor test_syssvc_rms_workload (rms-dirfind-exact-version-ignored) Closes the rms_workload unanchored-suite gap and doubles as live validation of vms-b8a2 (its require_fail label carries a ';N' version spec that the old selftest ';.*' truncation would have dropped). New defect rms-dirfind-exact-version-ignored: forces acp_dirfind_scan_cb()'s exact-version gate (kernel-core/vmsfs_acp.c) to ignore the requested version, so an explicit-version open matches whichever entry the newest-first scan reaches first -- A4 (;1) wrongly reads the ;2 payload, A6 (;3, nonexistent) returns NORMAL instead of RMS$_FNF. require_fail "sys$open WKOBJ.OBJ;1 still reads the ;1 payload 'V1'" + knock_on "...;3 -> RMS$_FNF (fail-honest)"; anchors above the A4/A6 checks. Floor 149->150. Static-verified: bash -n clean; selftest anchors + BROKEN-FIXTURE teeth confirmed (the ';N' labels now match, post-b8a2); test_syssvc_rms_workload off both unanchored FAIL lists; no net-new FAILs vs origin/main. register-continue + identcont left at their origin/main baseline (register-continue's real fix is a separate option-1 re-anchor PR, so identcont is never orphaned). Runtime redden proof via negctl-adhoc on the fixed rail (following). Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_01HMDFjHCqxDuXgbyxNU572h --- tests/qemu/facility_defects.sh | 31 ++++++++++++++++++++++++++- tests/qemu/facility_defects_floor.txt | 6 +++++- tests/qemu/test_syssvc_rms_workload.c | 2 ++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/tests/qemu/facility_defects.sh b/tests/qemu/facility_defects.sh index 06e42e1ac..75482c175 100755 --- a/tests/qemu/facility_defects.sh +++ b/tests/qemu/facility_defects.sh @@ -559,7 +559,8 @@ crtl-fwrite-bypasses-rms rms-open-no-file-access-enq rms-record-lock-not-enqueued crtl-fwrite-chunk-loop-stops-early -crtl-unlink-fabricates-erase" +crtl-unlink-fabricates-erase +rms-dirfind-exact-version-ignored" # --------------------------------------------------------------------------- # SCOPE, DECLARED @@ -1047,6 +1048,26 @@ EOF knock_on_why) echo "the SAME never-erased FOPDEL.DAT is invisible to the immediate call-site check (which only reads the fabricated return code, unaffected) but visible to BOTH independent readers that later look for it by name: the direct sys\$search right after the unlink (require_fail) and the later opendir/readdir enumeration pass that re-checks the same file is gone (knock_on_fail) -- one un-erased file, found twice.";; esac;; + rms-dirfind-exact-version-ignored) + case "$_f" in + facility) echo "RMS/ACP directory-find exact-version lookup (acp_dirfind_scan_cb, vms-1b5)";; + targets) echo "kernel-core/vmsfs_acp.c";; + suites_red) echo "test_syssvc_rms_workload";; + blind_suites) echo "";; + blind_why) echo "";; + isolation) echo "isolated";; + why) echo "acp_dirfind_scan_cb()'s exact-version gate 'if (version == c->want_ver)' is forced always-true, so an explicit-version open (WKOBJ.OBJ;N) stops comparing the scanned entry's version at all and matches -- and stops the walk on -- whichever directory entry the scan reaches FIRST for that name, instead of the one actually requested. ODS-2 directory blocks are scanned newest-version-first (proven by this same suite's B5 enumeration order, ';2 and ;1'), so the first entry reached is always the highest version. WKOBJ.OBJ;1 (A4) then wrongly resolves the ;2 entry and reads back 'V2' instead of 'V1', and WKOBJ.OBJ;3 (A6, no such version) wrongly matches that same real ;2 entry and reports RMS\$_NORMAL instead of RMS\$_FNF. WKOBJ.OBJ;2 (A5) happens to BE the first-scanned entry already, so it still resolves correctly by coincidence, and the versionless want_ver==0 path (A1-A3) is a completely different branch, untouched -- so only A4/A6 redden (minimality). The comparison text is gone after substitution, so a second apply is a no-op (selftest; vms-b8a2 unblocked this ';N'-bearing anchor).";; + require_fail) cat <<'EOF' +sys$open WKOBJ.OBJ;1 still reads the ;1 payload 'V1' +EOF + ;; + knock_on_fail) cat <<'EOF' +sys$open WKOBJ.OBJ;3 (no such version) -> RMS$_FNF (fail-honest) +EOF + ;; + knock_on_why) echo "the SAME always-true version-match gate lets an explicit-version open resolve against whichever entry the scan reaches first (the newest version, since ODS-2 directory blocks are scanned newest-first) instead of the version actually asked for: A4's request for the OLDER ;1 wrongly returns the newer ;2 payload (require_fail), and A6's request for a NONEXISTENT ;3 wrongly matches that same newest real entry and reports NORMAL instead of RMS\$_FNF (knock_on_fail) -- both off the one bypassed comparison.";; + esac;; + setprv-grants-unauthorized) case "$_f" in facility) echo "access modes and privileges (\$SETPRV authorization against the AUTHORIZED mask, VMS_IOCTL_SETPRV)";; @@ -6621,6 +6642,14 @@ apply_edit() { # replaced with a hardcoded NORMAL, so the file is never really erased. # Gone after apply (no-op re-apply). sed -i 's|uint32_t st = sys\$erase(&fab, 0, 0);|uint32_t st = RMS$_NORMAL; /* NEGCTL crtl-unlink-fabricates-erase: sys$erase skipped */|' "$_file";; + rms-dirfind-exact-version-ignored) + # UNIQUE TEXT, no range anchor needed: `if (version == c->want_ver) {` + # occurs once, in acp_dirfind_scan_cb's exact-version branch. Forcing it + # always-true drops the version comparison entirely, so an explicit- + # version open matches whichever entry the scan reaches first. The + # comparison text is gone after apply, so a second apply is a no-op + # (selftest). + sed -i 's|if (version == c->want_ver) {|if (1 /* NEGCTL rms-dirfind-exact-version-ignored */) {|' "$_file";; setprv-grants-unauthorized) # Unique text (vms_ioctl_setprv's authorized-subset intersection); the # replacement drops the `& proc->perm_privs` term, so a second apply diff --git a/tests/qemu/facility_defects_floor.txt b/tests/qemu/facility_defects_floor.txt index 33e7bba98..a7a0958a0 100644 --- a/tests/qemu/facility_defects_floor.txt +++ b/tests/qemu/facility_defects_floor.txt @@ -462,4 +462,8 @@ # defect_field case, apply_edit case, and the two anchor comments in those # suites); both suites revert to unanchored pending a real append-EOF # assertion, tracked separately. -149 +# +# Raised to 150 by rms-dirfind-exact-version-ignored (vms-b8a2 unblocked the +# ';N'-bearing anchor text for test_syssvc_rms_workload's A4/A6 assertions; +# see its entry in facility_defects.sh for what it covers and why). +150 diff --git a/tests/qemu/test_syssvc_rms_workload.c b/tests/qemu/test_syssvc_rms_workload.c index eb440aca7..6888384b8 100644 --- a/tests/qemu/test_syssvc_rms_workload.c +++ b/tests/qemu/test_syssvc_rms_workload.c @@ -291,6 +291,7 @@ int main(void) "(newest version resolves)"); st = open_first_rec(DIRSPEC "WKOBJ.OBJ;1", rec, sizeof(rec)); + /* negctl: rms-dirfind-exact-version-ignored */ check(st == RMS$_NORMAL && strcmp(rec, "V1") == 0, "A4: sys$open WKOBJ.OBJ;1 still reads the ;1 payload 'V1' -- both versions " "COEXIST (the VMS-versioning teeth a POSIX overwrite cannot fake)"); @@ -300,6 +301,7 @@ int main(void) "A5: sys$open WKOBJ.OBJ;2 reads 'V2' (explicit newest version)"); st = open_first_rec(DIRSPEC "WKOBJ.OBJ;3", rec, sizeof(rec)); + /* negctl: rms-dirfind-exact-version-ignored */ check(st == RMS$_FNF, "A6: sys$open WKOBJ.OBJ;3 (no such version) -> RMS$_FNF (fail-honest)");