6.6 KiB
Minimal kernelwrite-free CRT feasibility
Decision: BLOCKED
A compiler-driver trace proves that SDK v0.41 can be asked to omit its stock CRT and default libraries. A freestanding BSS clear and ordinary x86-64 return instruction are mechanically expressible. Those facts do not prove that the actual PS5 loader safely calls or accepts return from such an entrypoint.
Because safe return was not proven, no custom _start source was added and no
PS5 ELF was built. This is the required fail-closed outcome, not an incomplete
artifact audit.
Necessary versus convenience or patching
| Element | Minimal need | Classification | Evidence |
|---|---|---|---|
| loader-recognized entry symbol | yes | UNPROVEN contract |
SDK provides callee only |
| correct incoming stack/register ABI | yes | UNPROVEN caller |
stock disassembly shows expectation only |
| mapped load segments and relocations | yes | UNPROVEN loader |
linker script is not loader source |
| deterministic BSS state | yes when BSS exists | SAFE implementation primitive |
linker symbols plus byte-zero loop |
| valid completion/return path | yes | UNPROVEN blocker |
exact caller absent |
payloadout write |
unknown | UNPROVEN ownership |
field exists; caller semantics absent |
__crt_syscall_init |
no for a no-call entry | convenience | stock SDK runtime only |
__kernel_init |
no | kernel transport convenience | consumes pre-existing kernel access |
__klog_init |
no | logging convenience | forbidden for minimal profile |
__patch_init |
no | prohibited patch | proven kernel writes |
__rtld_init |
no | dynamic-loader convenience | module loading and allocation |
| libc/stdio | no | convenience | omitted by -nodefaultlibs trace |
| constructors/destructors/TLS | no | convenience for this audit object | no artifact built |
Exact blockers
The smallest evidence set needed before reconsidering a build is:
- identification of the exact loader used with firmware 9.60 and a pinned, public source commit;
- the caller instructions establishing
RDI,RSPalignment, the return address, and any preserved state; - allocation and ownership of
payload_args_t, includingpayloadoutlifetime and writability; - the complete caller path after
_startreturns, including restoration and cleanup; - crash/fault behavior before and during entry;
- all process, credential, syscall, module, and memory changes performed by the loader before control reaches the artifact.
An SDK header, a function signature, or a successful link is not a substitute for these caller facts.
Verification disposition
| Requested check | Result |
|---|---|
| SDK source, Makefile, compiler and linker audit | passed offline |
| all stock startup objects/archives enumerated | passed offline |
| stock CRT disassembly and reachable callgraph | passed; stock CRT is UNSAFE |
| freestanding compiler-driver suppression | passed as no-output -### trace |
| custom source compile with warnings as errors | not performed; build blocked |
| custom linker map and full object/archive trace | not performed; build blocked |
custom undefined symbols and DT_NEEDED |
not performed; build blocked |
| custom relocations, arrays and TLS | not performed; build blocked |
| custom prohibited-code scan | not performed; no custom bytes exist |
| reproducible double clean cross-build and SHA-256 | not performed; no artifact exists |
| host tests and sanitizer tests | required by TEST_PLAN.md and run separately |
| negative build configuration | implemented; enabling the target must fail |
The non-build decision record is
manifests/runtime/minimal-startup-artifact-decision.json; it has
execution_eligible=false and deliberately has null filename, size, and hash.
Safe alternatives
- Continue
libchimera-gfxthrough its deterministic mock and a separately designed software backend. This advances API lifecycle, format conversion, scaling, adapter contracts, and cleanup without PS5 startup or GPU risk. - Maintain a separate Linux-on-PS5 backend as a long-term track. Linux
amdgpu/RADV work can inform a Linux userspace backend, but it does not establish a native PS5 userland ABI and must remain architecturally separate.
Neither alternative authorizes transfer or execution on the PS5.
Phase 0.6 disposition
Phase 0.6 found the exact installed elfldr caller, so
EXACT_LOADER_CALLER_SOURCE_ABSENT is no longer the current blocker. The
Phase-0.5 non-build decision remains historically correct because that source
was not then available.
The corrected Phase-0.6 safety model does not reject normal SDK startup merely
because __patch_init performs documented temporary process/kernel runtime
changes. A lifecycle probe would therefore use the normal pinned SDK v0.41
startup rather than reopening the custom -nostartfiles -nodefaultlibs target.
No lifecycle source or ELF was created because the surrounding exact chain still cannot enforce the required profile:
- elfldr's ptrace single-step completion loops have no finite bound;
- the detached child has no two-second loader watchdog;
- SDK return/exit/trap selection for the injected child is unproven;
- UID and some failure-path credential state are not restored;
- child exit/reaping and mapping/descriptor cleanup are unproven;
- Payload Manager launch is path-bound rather than SHA-256-bound;
- its supported upload path performs persistent filesystem writes;
- the exploit/autoloader identity and independent firmware attestation remain unproven.
Decision: BLOCKED_VERSION_OR_UNBOUNDED_EFFECT. Building a normal-CRT lifecycle probe would create bytes that cannot satisfy the mandatory runtime profile, so Phase D was correctly skipped.
Phase 0.7 disposition
The Phase-0.5 freestanding target remains blocked and was not bypassed.
Phase 0.7 instead resolves the lifecycle termination uncertainty with an
ordinary SDK v0.41 payload whose main calls _exit directly. This preserves
the public loader entry ABI and avoids relying on an unproven return to the
loader.
The resulting lifecycle ELF has exactly _exit and
sceKernelSendNotificationRequest as undefined imports and exactly
libSceLibcInternal.sprx and libkernel_web.sprx as DT_NEEDED modules.
There are no GNM, VideoOut, SDL, network, module-loader, thread, retry, or
autoload imports.
This does not prove a kernelwrite-free startup. The normal CRT is statically
linked and its reachable startup includes __patch_init. Phase 0.7 accepts
that exact process-local effect under ADR-0010/ADR-0011 and hardens the
surrounding loader lifecycle. The freestanding question remains BLOCKED;
the normal-CRT lifecycle is
READY_FOR_HARDENED_RUNTIME_DEPLOYMENT offline only.