148 lines
6.0 KiB
Markdown
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.
|