update
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
# P15-019 Stage0 Decision
|
||||
|
||||
Status: `GO`. G03 authorizes B16 for P15-019 only. P15-046 remains the B01
|
||||
test-only legacy xattr prefix fallback contract; it neither changes this
|
||||
decision nor authorizes any exact-header or xattr behavior change.
|
||||
|
||||
The decision is bound to DUT BASE
|
||||
`d645feb720c7022d2138d2a62eb72c022eb75351`, FreeBSD source HEAD
|
||||
`106727738dcfb6c001b46f25363b91cece970085`, erofs-utils source HEAD
|
||||
`7db78788b000999e2de88decd2ba90654f26171c`, and
|
||||
`mkfs.erofs (erofs-utils) 1.8.6`.
|
||||
|
||||
## Authoritative Run
|
||||
|
||||
The gate ran from `/work/erofs-freebsd-pre/repo-pre-15` as:
|
||||
|
||||
```sh
|
||||
umask 077
|
||||
timeout -k 10 240 tests/pre15/gates/P15-019.sh \
|
||||
--base d645feb720c7022d2138d2a62eb72c022eb75351 \
|
||||
--output /work/erofs-freebsd-pre-evidence/pre15/\
|
||||
20260815T093800Z-G03-P15-019-umask-fix/gate-output
|
||||
```
|
||||
|
||||
It returned zero with `GO`. The authoritative hashes are:
|
||||
|
||||
- gate script: `afa20cbd28ca9dfc8064596a312248756ed7cde54398efb5ef713818cc04ea54`
|
||||
- gate input: `291bf12838981ef650e16bbf7381eaa9b2921de957e97dec46e6a573750a19b8`
|
||||
- result: `bb52e1a88cb09554a51432ec545ed98d5509a529832141ed0ce83b0c336be5bb`
|
||||
- cases: `0c12cdce8b3ed37e85f349af0715a728d4acabbb758451fb65546dd9836066b5`
|
||||
- fixture manifest/set: `5e99e5ad9112508991e78ae6e65928973d6b0da78285a059894bed06010cf373`
|
||||
- semantics: `090e6b0cd5eaa197f17da12daf29f30bd8f337d3d4ae2f0f4f5819ad41e906f9`
|
||||
- cleanup: `8e3b52610ee1492262494d00c48bf66ea04d313ab9ac1ef27565fa0e607b9a97`
|
||||
|
||||
An additional independent replay from `umask 077` produced the same result,
|
||||
cases, fixture manifest, semantics, and cleanup hashes byte for byte. The gate
|
||||
sets `umask 022` internally because erofs-utils records the packed fragment
|
||||
inode's source mode; this makes the fixture set independent of its caller.
|
||||
|
||||
## Real EROFS Fixture Oracle
|
||||
|
||||
The gate creates 35 deterministic EROFS images and seven external chunk blobs
|
||||
in owned output. Nothing is committed as an image, blob, binary, or KLD. Each
|
||||
of the five required storage paths has these seven cases:
|
||||
|
||||
- normal short target;
|
||||
- normal 1,024-byte `MAXPATHLEN` target;
|
||||
- zero-byte target;
|
||||
- embedded NUL at the first, middle, and last byte;
|
||||
- 1,025-byte over-limit target.
|
||||
|
||||
Inline positives are native mkfs symlinks. Plain, chunk, compact compressed
|
||||
ztailpacking, and whole-file fragment cases start as real mkfs regular-file
|
||||
carriers because the host cannot create a symlink containing NUL and mkfs does
|
||||
not select those layouts for symlinks. The transform changes only inode mode,
|
||||
the root dirent type, and, for empty cases, inode size, then recomputes the real
|
||||
EROFS checksum. Chunk data remains on a real `--blobdev`; fragment data remains
|
||||
in the real packed inode. Changed-byte offsets are recorded for every case.
|
||||
|
||||
The independent Python parser reads the superblock, checksum span, inode,
|
||||
dirent, layout, and target bytes directly. It resolves chunk indexes and the
|
||||
external blob, decodes compact inline-pcluster raw LZ4 without a DUT helper,
|
||||
and resolves the whole-fragment offset through the packed inode. It does not
|
||||
compile, call, or inject values into any DUT internal function. `dump.erofs`
|
||||
is only a layout/type cross-check. All legal targets also pass
|
||||
`fsck.erofs --extract` and reproduce the exact source bytes.
|
||||
|
||||
The independent decision model returns positive FreeBSD `EINTEGRITY` (97) for
|
||||
empty or embedded-NUL targets, positive `ENAMETOOLONG` (63) before target I/O
|
||||
for size greater than `MAXPATHLEN`, and success for exact non-NUL bytes. No
|
||||
trailing NUL is required. All 35 expected results match, so every layout has a
|
||||
bounded positive and negative oracle as required by G03.
|
||||
|
||||
## Linux and FreeBSD Semantics
|
||||
|
||||
Linux `erofs_fill_symlink()` validates only flat-inline fast symlinks while
|
||||
building `i_link`; it uses `kmemdup_nul()`/`strlen()` and returns negative
|
||||
`-EFSCORRUPTED`. Non-inline Linux symlinks use `page_get_link`. That page/cache
|
||||
shape is not a FreeBSD implementation contract.
|
||||
|
||||
FreeBSD enters through `VOP_READLINK` on a vnode and currently streams through
|
||||
`erofs_readlink_target`, the common map/read path, GEOM or the compressed
|
||||
backing path, and `uiomove`. It has no Linux `i_link` or page-get-link path and
|
||||
uses positive errno. B16 must therefore validate the complete immutable target
|
||||
before any `uiomove`, use the existing layout-specific map/read machinery, and
|
||||
keep the scan bounded by `MAXPATHLEN=1024`.
|
||||
|
||||
The 1,024-byte case is a successful `readlink(2)` byte target. Pathname follow
|
||||
may still return `ENAMETOOLONG` when that target plus the remaining pathname
|
||||
exceeds FreeBSD's namei buffer; that VFS result is distinct from the on-disk
|
||||
target validator. The 1,025-byte inode is rejected by B16 before target I/O.
|
||||
|
||||
## Scope and Cleanup
|
||||
|
||||
The gate did not modify `src/**`, build a KLD, start QEMU, or run a feature
|
||||
suite. It observed but did not signal or otherwise alter protected PID 26318,
|
||||
port 9222, or `/work/debug-qemu/local/vm-freebsd-build.qcow2.bp`; their recorded
|
||||
identity was unchanged before and after the run. Owned temporary source and
|
||||
extract directories were removed, with zero leftovers.
|
||||
|
||||
B16 may now modify only its planned source/test write set and must pass the
|
||||
specified host TC166, D, zstdio0 build, and targeted TC166 QEMU acceptance.
|
||||
Reference in New Issue
Block a user