Skip to content

vms-f57: correct three hand-recited SYSUAF claims + activate the writer negative control - #519

Merged
baron-3dl merged 1 commit into
mainfrom
work/vms-f57
Aug 14, 2026
Merged

baron-3dl merged 1 commit into
mainfrom
work/vms-f57

Conversation

@baron-3dl

Copy link
Copy Markdown
Contributor

VERACITY-OVERTURN for vms-f57 (blocks vms-14f; label security/veracity-overturn). PR #158's $GETUAI/SYSUAF parser fix was real, but three claims shipped in the comments/self-report were hand-recited, not derived — and are measurably false. Every correction here was re-derived by measurement over the shipped SYSUAF.DAT; none copied.

The shipped SYSUAF.DAT (6 rows), for reference

SYSTEM  |<hash>|1  |4  |...||ALL
OPERATOR|      |1  |6  |...||OPER,SYSPRV,TMPMBX,NETMBX
DEFAULT |      |200|200|...||TMPMBX,NETMBX
GUEST   |<hash>|200|201|...||TMPMBX
USER1   |      |200|202|...||TMPMBX,NETMBX
USER2   |      |200|203|...||TMPMBX,NETMBX

Field order: USERNAME|PWHASH|UIC_GROUP|UIC_MEMBER|DEFDIR|FLAGS|PRIVILEGES. Every row has an empty FLAGS field (the ||).

Claim 1 — "five of the six rows have an empty field" → 6 of 6 (src/libvms/rtl/sysuaf.c)

Ran the pre-fix strtok_r split and the post-fix strchr split over the shipped file:

row 1 SYSTEM    FLAGS='' [EMPTY]  PRIV strchr='ALL'                      PRIV strtok='<DROPPED>'  <-- MISPARSED
row 2 OPERATOR  FLAGS='' [EMPTY]  PRIV strchr='OPER,SYSPRV,TMPMBX,NETMBX' PRIV strtok='<DROPPED>' <-- MISPARSED
row 3 DEFAULT   FLAGS='' [EMPTY]  PRIV strchr='TMPMBX,NETMBX'            PRIV strtok='<DROPPED>'  <-- MISPARSED
row 4 GUEST     FLAGS='' [EMPTY]  PRIV strchr='TMPMBX'                   PRIV strtok='<DROPPED>'  <-- MISPARSED
row 5 USER1     FLAGS='' [EMPTY]  PRIV strchr='TMPMBX,NETMBX'            PRIV strtok='<DROPPED>'  <-- MISPARSED
row 6 USER2     FLAGS='' [EMPTY]  PRIV strchr='TMPMBX,NETMBX'            PRIV strtok='<DROPPED>'  <-- MISPARSED
=> rows=6  empty-FLAGS=6  strtok-misparsed=6

All six rows carry an empty FLAGS field, so the strtok split dropped PRIVILEGES on every row → $GETUAI(UAI$_PRIV) returned mask 0 for every account (SYSTEM's "ALL" and GUEST's "TMPMBX" alike). Corrected to 6 of 6.

Claim 2 — "SYSTEM's 1|4 is the only both-bases row" → two rows (sysuaf.c, test_syssvc_setuai.c, radix negctl why)

For each row, compared decimal vs octal parse of the UIC fields:

SYSTEM   1|4   -> both single digits ≤7 -> SAME IN BOTH BASES
OPERATOR 1|6   -> both single digits ≤7 -> SAME IN BOTH BASES
DEFAULT  200|200  oct 128 vs dec 200 -> differs
GUEST/USER1/USER2 200|20x -> differ
=> identical in both bases = 2  {SYSTEM, OPERATOR}

A row reads identically iff both UIC components are a single octal digit (0-7). Two shipped rows qualify — SYSTEM (1|4) and OPERATOR (1|6) — not one.

Claim 3 — "128|130 reads back as octal 88|88" → 10|88 (test_syssvc_setuai.c)

strtoul("128",NULL,8) = 10   ('8' is not an octal digit, parse stops after "12")
strtoul("130",NULL,8) = 88
=> read-back = 10|88, NOT 88|88

128 reads back as octal 10 (not 88); 130 reads back as 88. Corrected.

Unexecuted negative control → new sysuaf-uic-writeback-decimal

The WRITER's octal UIC formatting (sysuaf_format_record's %o) had no dedicated control: sysuaf-uic-radix-decimal mutates the reader radix, and the manifest itself noted "a WRITE alone is not reached." Scenario 4's two write-back assertions are the exact subject of false claim 3, yet nothing injected a writer defect to prove they have teeth.

Added sysuaf-uic-writeback-decimal: flips both %o%u in the writer. Scenario 4 rewrites USER1 (200|202 → struct 128|130) and reads the row text back — measured host-side:

writer %o (current):  '200|202'  -> scenario-4 checks want 200/202 => PASS
writer %u (injected): '128|130'  -> scenario-4 reads 128/130     => FAIL (red)

So %u reddens exactly the two "rewritten UIC {GROUP,MEMBER} field still reads 2xx" assertions. Static audit: no other qemu suite writes via sysuaf_format_record and reads a UIC field back (test_syssvc_authorize's session only EXITs), so nothing outside test_syssvc_setuai reddens. Anchored both assertions, added the manifest entry + idempotent inject, raised the derived floor 97→98.

Manifest gates (run locally):

  • selftest: sysuaf-uic-writeback-decimal injects into the current tree ✓, teeth ✓, every require_fail/knock_on_fail text exists literally ✓, 98 defect(s) >= floor 98
  • coverage: new defect clean (no ungated/orphaned-anchor FAIL), 98 >= floor 98
  • Injected %u variant compiles clean under -Wall -Wextra -Wformat (args already (unsigned)).

Pre-existing (NOT this item): selftest/coverage still FAIL on 3 unanchored suites — test_kmod_vmsfs_mountvis, test_kmod_vmsfs_sysgroup, test_syssvc_initialize — identical on pristine origin/main (floor 97). Flagged, unrelated to vms-f57.

No security fix or test was weakened; source changes are comment-only plus a new injected-defect control. INV-6.

🤖 Generated with Claude Code

…er negctl

VERACITY-OVERTURN (blocks vms-14f). PR #158's $GETUAI/SYSUAF parser fix was
real, but three claims shipped alongside it were hand-recited, not measured,
and are measurably false. Each correction below is DERIVED by running the
relevant parse/format over the shipped SYSUAF.DAT, not re-typed.

1. src/libvms/rtl/sysuaf.c (strtok comment): was "five of the six rows OVMX
   ships have an empty field". MEASURED 6 of 6: every shipped row carries an
   empty FLAGS field, so the strtok split dropped PRIVILEGES on ALL SIX rows
   and $GETUAI(UAI$_PRIV) returned mask 0 for every account (SYSTEM's "ALL"
   and GUEST's "TMPMBX" alike), not "nearly the whole" file.

2. src/libvms/rtl/sysuaf.c + test_syssvc_setuai.c (both-bases comment): implied
   SYSTEM's 1|4 is the unique row that reads the same octal and decimal.
   MEASURED: TWO rows do -- SYSTEM (1|4) and OPERATOR (1|6) -- because both UIC
   components are single octal digits; the four [200,20x] rows discriminate.
   Corrected in both spots and in the radix negctl's `why` (Rule 10 consistency).

3. test_syssvc_setuai.c (write-back comment): claimed a %u write of USER1's
   128|130 "reads back as octal 88|88". MEASURED 10|88: '8' is not an octal
   digit, so strtoul("128",8) stops at "12" (=10); strtoul("130",8)=88.

Unexecuted negative control: the WRITER's octal UIC formatting
(sysuaf_format_record's %o) had no dedicated control -- sysuaf-uic-radix-decimal
mutates the READER radix, and the manifest itself noted "a WRITE alone is not
reached". Scenario 4's two write-back assertions were the exact subject of the
false claim #3 yet nothing injected a writer defect to prove they have teeth.
Added sysuaf-uic-writeback-decimal: flips both %o->%u in the writer so a rewritten
record whose UIC digits differ between bases is written decimal. Scenario 4
rewrites USER1 (200|202 -> struct 128|130) and reads the row text back, so %u
reddens exactly the two "still reads 200/202" assertions (measured host-side:
%o of 128/130 = "200"/"202", %u = "128"/"130"). No other qemu suite writes via
sysuaf_format_record and reads a UIC field back, so nothing else reddens.
Anchored both assertions, added the manifest entry + inject, raised the derived
floor 97->98. manifest selftest + coverage: the new defect injects with teeth,
require_fail texts exist literally, 98>=floor 98. (The 3 remaining selftest/
coverage FAILs -- test_kmod_vmsfs_mountvis/sysgroup, test_syssvc_initialize
unanchored -- pre-exist identically on origin/main; unrelated to this item.)

No security fix or test was weakened; source changes are comment-only + a new
injected-defect control. INV-6.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@baron-3dl
baron-3dl merged commit 331940e into main Aug 14, 2026
79 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant