Skip to content

1.11.0: the Off + ASLR-on row was measured against the previous chain - #4

Merged
JoshRob297 merged 1 commit into
mainfrom
1.11.0-gap-closed
Nov 10, 2026
Merged

JoshRob297 merged 1 commit into
mainfrom
1.11.0-gap-closed

Conversation

@JoshRob297

Copy link
Copy Markdown
Owner

The open item on the coverage matrix is closed, and the correction matters more than the closure.

What was wrong

COVERAGE.md said display_errors=Off with ASLR on was not achieved (0/3), and that the 9bie chain "stops at stage 1 because its 8/8 needs display_errors=On". That measurement was real, but it was taken against the previous chain, the one whose stage 1 needs PHP to print a warning. It was never a measurement of the chain the author ships today.

What is true now

Upstream commit d6f888e (24 Oct) adds pure/, which replaces that stage 1 with an OOM at the end of the request (php_session_send_cookie) plus a stale-id OOB read. Measured on 2026-11-09, stock php:8.4.26-apache + php.ini-production, 128M, official prefork 150 workers, display_errors=Off, randomize_va_space=2:

  • 10/10, ten fresh ASLR layouts, ten distinct libphp bases, ten distinct main allocations, real command execution as www-data
  • 0/5 on the same profile against php:8.4.27-apache
  • no gdb, no symbols, no /proc of the target, no setarch

What is still bounded, and is now written down

  • The row is the stock 128M geometry. At memory_limit=8M the chain is 0/3 — A1 never exhausts memory, so B1 never gets its stale id.
  • The repo's own tooling/docker-compose.yml does not reproduce it: vuln-8426 loads no php.ini (Loaded Configuration File => (none)) and reports display_errors => STDOUT. Adding only display_errors=Off on top of hardening-off.ini gives 0/3, because the chain is calibrated for php.ini-production, not for a conf.d overlay.
  • Cold start is not characterized: a first run on a fresh target gave 0/3, the same target after docker restart gave 3/3. The 10/10 restarts before each run.
  • FPM and CVE-2026-115560 were not measured in this pass; the stock path closed the question first.

Changed

  • COVERAGE §1 row, §4 PoC table, §5 deployment scope and §6 gaps, in both languages: the 0/3 is now attributed to the previous chain, the 10/10 to pure/, and the "mutually exclusive" conclusion is scoped to our cookie chain instead of the whole family.
  • README 9bie paragraph: same correction, with the commit that changed it.
  • raw/9bie-pure-off-aslr-on-10run.txt: the transcript — target facts, the canonical run, the ten rows, the 0/5 control, and the boundaries.
  • PORTABILITY: a note separating the 8M lab row from the stock-128M cell.

The honest summary: the gap was not a capability of the attacker base, it was a stale row in our own matrix. That is worth saying plainly in a report that asks others to trust its numbers.

@JoshRob297
JoshRob297 merged commit e6d774e into main Nov 10, 2026
1 check passed
@JoshRob297
JoshRob297 deleted the 1.11.0-gap-closed branch November 10, 2026 03:31
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.

2 participants