Files
chimera-gfx-Public/docs/evidence/probe-9.60-offline-2026-07-17.md
T
Chimera GFX release export a6037502d7
phase0-ci / build-and-audit (push) Successful in 2m14s
Publish Chimera GFX source
2026-09-03 03:27:14 +02:00

148 lines
6.0 KiB
Markdown

# Firmware 9.60 capability-probe offline evidence
Date: 2026-07-17. No PS5 connection, transfer, deployment, or execution was
performed.
## Artifact identity
| Field | Value |
|---|---|
| Artifact | `chimera-gfx-capability-probe-0.1.0-fw-9.60-offline-audit-only.elf` |
| Size | 110424 bytes |
| SHA-256 | `4be1c17b4964f2b68c39b5145bc4af4619c32512d60269ecf5c39728b390fa63` |
| Source commit | `ba8f6a40cf37dff628254caa9b11d83a73957cf8` |
| SDK | PS5 Payload SDK v0.41, commit `d2e2e585740362976a39fdd5ccf390f199a7bc37` |
| Build type | Release, C11, warnings as errors |
| Phase-1 VideoOut | explicitly `OFF`; target not built or linked |
| Transfer / execution | false / false |
| Execution eligibility | **false** |
Two clean builds around an audit-tool-only commit produced the same size and
SHA-256. The tracked manifest is
`manifests/artifacts/chimera-gfx-capability-probe-0.1.0-fw-9.60.json`.
## Firmware gate
The checked-in discovery allowlist is exactly `["9.60"]`; CMake still defaults
to `NONE`. Configure rejects `9.61`. The Phase-1 target rejects `9.60` and every
other non-`NONE` value.
The ELF embeds `9.60` and requires exactly these application arguments:
```text
--firmware 9.60 --acknowledge-read-only-probe
```
Disassembly places `chimera_gfx_firmware_gate_allows` at `main+0x7f`, before
`chimera_gfx_ps5_make_loader_ops` at `main+0xa5` and the probe call at
`main+0xb2`. This is only a comparison against an operator-supplied string; it
does not independently attest the console firmware. SDK startup occurs before
`main` and therefore before this gate.
## Complete dynamic import inventory
Undefined symbols (`prospero-nm -u`), exact set:
- `__stderrp`
- `__stdoutp`
- `fprintf`
- `fwrite`
- `snprintf`
- `strcmp`
`DT_NEEDED` modules (`llvm-readelf-18 --dynamic-table`), exact set:
- `libkernel_web.sprx`
- `libSceLibcInternal.sprx`
- `libSceNet.sprx`
There are zero direct `sce*`, GNM, VideoOut, SDL, draw, dispatch, submit, or
flip imports. `libSceVideoOut.sprx` text is present only because the SDK rtld
statically includes a general sysmodule-name table; there is no corresponding
import or call. `INIT_ARRAYSZ` and `FINI_ARRAYSZ` are both zero.
## Project-requested functions
Before the firmware gate, project `main` uses only argument checks, `strcmp`,
and a refusal log on error. After the gate, the complete project path is:
1. `chimera_gfx_ps5_make_loader_ops`;
2. `chimera_gfx_ps5_probe_symbols`;
3. internal `log_line`/`write_log` callbacks for boolean JSON events;
4. loader callback `open_module`, which calls
`dlopen("libSceGnmDriver.sprx", RTLD_LAZY | RTLD_LOCAL)`;
5. loader callback `resolve_symbol` 21 times; it calls `dlerror`, `dlsym`, then
`dlerror`; every returned address is reduced to a boolean and discarded;
6. `snprintf` plus `fprintf`/compiler-selected `fwrite` for boolean JSON lines;
7. loader callback `close_module`, which calls `dlclose`;
8. `chimera_gfx_status_string` and a final summary log.
No resolved GNM pointer is cast to a callable type or invoked. The 21 exact
names are machine-checked against `manifests/ps5_gnm_symbols.json`.
## SDK startup and loader side effects
Pinned-source review plus disassembly proves this pre-`main` success path:
1. `_start` clears payload BSS.
2. `__crt_syscall_init`, `__kernel_init`, and `__klog_init` initialize SDK
state from loader-supplied arguments.
3. libc `__isthreaded` is set to one.
4. `__patch_init` reads current process credentials, calls
`kernel_set_ucred_caps` and `kernel_set_ucred_attrs`, and performs two
`kernel_copyin` writes that change the process syscall-address bounds.
5. `__rtld_init` initializes SPRX/SO/payload/dlfcn support and may call
`sceKernelLoadStartModule` for `libSceSysmodule.sprx` if it is absent.
6. payload dependencies are opened and relocations modify payload memory;
payload init/fini arrays themselves are empty.
After the project gate, SDK `dlopen` first checks loaded modules through SDK
kernel reads. If GNM is absent it can call `sceKernelLoadStartModule`. It then
uses `kernel_copyout` to copy module metadata, symbol tables, and string tables
into allocated user memory. The pinned SPRX-specific `init` callback is empty,
but the internal behavior of the system load/start call is unknown.
These facts mean the ELF is non-rendering at project level but is not globally
non-mutating. The pre-`main` kernel writes violate the project's userland-only
execution boundary.
## Cleanup audit
The bounded project loop attempts `dlclose` after all lookups and on lookup or
format failures. SDK `dlclose` calls rtld fini, close, and destroy. The pinned
SPRX `fini` callback is empty. If this open loaded the module, `sprx_close`
calls `sceKernelStopUnloadModule`, then frees copied tables and clears local
state.
Cleanup is not guaranteed:
- there is no documented cancellation or bounded timeout around loader calls;
- a crash or hang can bypass `dlclose`;
- a stop/unload failure can leave the module loaded while SDK bookkeeping is
destroyed;
- the CRT's credential/syscall-permission changes have no matching restoration
path in the pinned source;
- a `libSceSysmodule.sprx` load during rtld initialization has no observed
matching unload in this call chain.
## Offline verification results
- Windows MSVC Debug: 11/11 tests passed.
- WSL Clang 18 with clang-tidy and formatting: 12/12 tests passed.
- Strict artifact audit: six exact undefined symbols, three exact
`DT_NEEDED` modules, empty init/fini arrays, all 21 manifest names, zero
direct Sce/GNM imports.
- SDK runtime source audit: passed and concluded execution eligibility false.
- Negative configure tests: firmware `9.61` rejected; Phase-1 with `9.60`
rejected.
- Artifact-manifest digest/size verification: passed.
- Secret scan and `git diff --check`: passed.
## Remaining blockers
The exact system-module initialization effects, runtime argument delivery,
firmware attestation, loader timeout behavior, and partial-failure recovery are
unproven. More decisively, the SDK v0.41 CRT performs prohibited kernel writes
before the project firmware gate. This exact artifact must not be transferred
or executed.