132 lines
6.6 KiB
Markdown
132 lines
6.6 KiB
Markdown
# 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:
|
|
|
|
1. identification of the exact loader used with firmware 9.60 and a pinned,
|
|
public source commit;
|
|
2. the caller instructions establishing `RDI`, `RSP` alignment, the return
|
|
address, and any preserved state;
|
|
3. allocation and ownership of `payload_args_t`, including `payloadout`
|
|
lifetime and writability;
|
|
4. the complete caller path after `_start` returns, including restoration and
|
|
cleanup;
|
|
5. crash/fault behavior before and during entry;
|
|
6. 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
|
|
|
|
1. Continue `libchimera-gfx` through 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.
|
|
2. 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:
|
|
|
|
1. elfldr's ptrace single-step completion loops have no finite bound;
|
|
2. the detached child has no two-second loader watchdog;
|
|
3. SDK return/exit/trap selection for the injected child is unproven;
|
|
4. UID and some failure-path credential state are not restored;
|
|
5. child exit/reaping and mapping/descriptor cleanup are unproven;
|
|
6. Payload Manager launch is path-bound rather than SHA-256-bound;
|
|
7. its supported upload path performs persistent filesystem writes;
|
|
8. 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.
|