Skip to content

[PHP] fix: enforce RLIMIT_FSIZE at file-write operation boundaries#748

Merged
brandonpayton merged 1 commit into
integration/kd-6nz-php-phpt-platform-fixesfrom
gascity/kd-6nz/split-pr717-posix-file-size-limit
Jul 11, 2026
Merged

[PHP] fix: enforce RLIMIT_FSIZE at file-write operation boundaries#748
brandonpayton merged 1 commit into
integration/kd-6nz-php-phpt-platform-fixesfrom
gascity/kd-6nz/split-pr717-posix-file-size-limit

Conversation

@brandonpayton

@brandonpayton brandonpayton commented Jun 20, 2026

Copy link
Copy Markdown
Member

Purpose

Make RLIMIT_FSIZE obey one file-write operation boundary across Kandelo's
kernel and host paths. An operation that starts below the soft limit returns
the prefix that fits without a signal; a later non-empty operation with no
room fails with EFBIG and directs SIGXFSZ to the calling thread. Pipes,
terminals, sockets, and other non-size-bearing objects remain unaffected.

This supersedes the original non-compiling two-syscall patch with a reviewed
replacement built on the current Batch 2 aggregate tip.

Summary

  • Computes one wasm32-safe budget for scalar, vectored, and host-decomposed
    writes, including offsets and limits above 4 GiB.
  • Applies the same boundary to sendfile, copy_file_range, splice, regular
    files, memfds, ftruncate/truncate, and mode-0 fallocate without
    over-consuming transfer input.
  • Adds the host-required kernel_prepare_write_operation export and keeps
    slow writev/pwritev error, offset, retry, and signal behavior coherent.
  • Keeps SIGXFSZ directed at the exact calling thread. Main-thread-directed
    pending state remains separate from process-shared pending state across
    signal delivery, signalfd/poll/select, fork, exec, and /proc/<pid>/status.
  • Advances the internal fork/exec state wire format from v10 to v11 so legacy
    exec preserves the main thread's directed pending queue.
  • Adds Rust coverage plus a wasm32/wasm64 C guest exercised by Node and real
    Chromium, and updates the POSIX status documentation and ABI snapshot.

Review changes

The review replaced the original implementation rather than preserving its
unsafe per-chunk check. It fixed the original borrow-check failure, wasm32
integer wrap, memfd bypass, append-side effects, transfer read-ahead, invalid
input/error ordering, truncate/fallocate overflow and shrink behavior, host
scratch-buffer decomposition, split pwritev offsets, non-EAGAIN error
loss, and exact-thread signal routing. Final audit repairs also bounded the
serialized directed-signal queue and preserved directed pending visibility in
procfs.

View

Accept into Batch 2 only. The repaired behavior and focused evidence are
sound, but this PR is deliberately not independently main-ready. It adds a
host-required kernel export and changes observable syscall, signal, and
exec-state-wire semantics while still reporting ABI 16. It must remain
quarantined for the aggregate ABI 16→17 reconciliation, regenerated/rebuilt
PHP and opcache artifacts, the exact opcache PHPT on Node and Chromium, and
the one full aggregate gate plus manual browser verification.

The generic pre-existing short-write source-advancement behavior outside an
RLIMIT-induced budget and broader worker signal-mask gaps are not claimed as
fixed here.

Verification on the replacement commit

  • scripts/dev-shell.sh cargo test -p kandelo --target aarch64-apple-darwin --lib
    — 1,089 passed, 0 failed.
  • scripts/dev-shell.sh cargo check -p kandelo --target wasm32-unknown-unknown --lib
    — passed.
  • scripts/dev-shell.sh bash -lc 'cd host && npm run typecheck' — passed.
  • scripts/dev-shell.sh bash -lc 'cd host && npx vitest run test/rlimit-fsize.test.ts'
    — wasm32 and wasm64 guests passed, 2/2.
  • Isolated fresh-server Chromium Playwright run of
    test/rlimit-fsize.spec.ts — passed, 1/1.
  • Fresh wasm32 and wasm64 musl builds followed by bash build.sh — passed.
  • scripts/dev-shell.sh bash scripts/check-abi-version.sh — snapshot/header/TS
    synchronization passed and classified the new export as structurally
    additive. This is not semantic ABI clearance; ABI 17 remains required.
  • git diff --check — clean.

Per the locked batch policy, the complete host/libc/conformance/PHPT/browser
gate is deferred to the exact aggregate branch after ABI 17 rather than run
per constituent.

Compute one wasm32-safe file-size budget per scalar, vectored, transfer, truncate, and mode-0 fallocate operation, including memfd and host scratch-buffer paths.

Keep SIGXFSZ directed at the calling thread across fork/exec state, expose an additive host preflight export, and add wasm32/wasm64 Node plus Chromium guest coverage and POSIX documentation.

This changes observable syscall and signal semantics and the exec-state wire format; it remains quarantined for the Batch 2 ABI 16-to-17 reconciliation.
@brandonpayton
brandonpayton force-pushed the gascity/kd-6nz/split-pr717-posix-file-size-limit branch from 96b4600 to 7122d91 Compare July 11, 2026 18:03
@brandonpayton brandonpayton changed the title [PHP] fix: apply POSIX file size limit writes [PHP] fix: enforce RLIMIT_FSIZE at file-write operation boundaries Jul 11, 2026
@brandonpayton
brandonpayton changed the base branch from integration/kd-6nz-php-phpt-harness-only-base to integration/kd-6nz-php-phpt-platform-fixes July 11, 2026 18:04
@brandonpayton
brandonpayton merged commit 4c7bac7 into integration/kd-6nz-php-phpt-platform-fixes Jul 11, 2026
@brandonpayton
brandonpayton deleted the gascity/kd-6nz/split-pr717-posix-file-size-limit branch July 11, 2026 18:04
brandonpayton added a commit that referenced this pull request Jul 13, 2026
Write preflight, fork and exec state, exact-thread SIGXFSZ ownership, return values, and error behavior alter existing file-operation contracts. Advance ABI 30 to 31 and regenerate ABI evidence atomically.

Source-PR: #748
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