This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user