This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
# Controlled PS5 runtime profile
|
||||
|
||||
`manifests/controlled-runtime-profile.schema.json` defines the mandatory
|
||||
machine boundary for hardened-runtime deployment preparation. Missing metadata
|
||||
is a denial, not an invitation to infer a value.
|
||||
|
||||
## Required invariants
|
||||
|
||||
- exact firmware `9.60`, supported by Jens's explicit confirmation;
|
||||
- exact hardened Payload Manager, hardened elfldr, SDK, and artifact source
|
||||
commits, sizes, and SHA-256 values;
|
||||
- byte-identical double clean builds for every ELF;
|
||||
- lifecycle artifact filename, byte size, SHA-256, and clean source commit
|
||||
equal in artifact manifest, runtime profile, audit, and local bytes;
|
||||
- persistent writes limited to removable controlled application artifacts;
|
||||
- filesystem writes limited to the controlled artifact directory;
|
||||
- payload network access `none`;
|
||||
- maximum payload runtime 2000 ms;
|
||||
- automatic retry disabled;
|
||||
- no effect classified `PERSISTENT_WRITE` or `UNBOUNDED_OR_UNKNOWN`;
|
||||
- no hard blocker and decision
|
||||
`READY_FOR_HARDENED_RUNTIME_DEPLOYMENT`;
|
||||
- explicit `execution_eligible=true`;
|
||||
- profile name exactly `controlled-ps5-runtime`;
|
||||
- `expected_volatile_effects` exactly equal to the IDs classified
|
||||
`EXPECTED_VOLATILE_RUNTIME_EFFECT`;
|
||||
- explicit top-level `execution_authorized=false`;
|
||||
- deployment fields remain `installed=false`,
|
||||
`ready_for_installation=true`, and `rollback_prepared=true`.
|
||||
|
||||
The static pass means the exact bytes are eligible for a later, separate
|
||||
installation approval. It does not authorize a PS5 connection, transfer,
|
||||
installation, or execution.
|
||||
|
||||
`rollback_prepared=true` means only that the offline review and rollback
|
||||
packages exist. It does not claim that byte-exact stock backups are already
|
||||
present on the console. Phase 0.8 keeps installation hard-blocked until those
|
||||
current on-device rollback preconditions are proven through an admissible
|
||||
collector.
|
||||
|
||||
## Current exact profile
|
||||
|
||||
`manifests/runtime/controlled-ps5-runtime-profile.json` binds:
|
||||
|
||||
- lifecycle probe
|
||||
`bfb4a5cc768e162fe4c2fddf41c3978e152722918a39085277fd172cb95a7182`,
|
||||
112680 bytes, source
|
||||
`fe08300339a13f899fb78ea404ada381a5cba87c`;
|
||||
- hardened elfldr
|
||||
`63e810982471eb40cae3a20aa9df9a0a02892f420e429874fae4e99aa400b561`,
|
||||
397000 bytes, source
|
||||
`197623058f509eddde18868dafcb92fdcac66464`;
|
||||
- controlled Payload Manager
|
||||
`8fecf8241a46246eddbd21e8bb4d875f5d76f1f4f4c6a11384df1f131aa5e5b1`,
|
||||
99560 bytes, source
|
||||
`e23d94ff91233aa770e2342800c1467875bdef44`;
|
||||
- SDK v0.41 commit
|
||||
`d2e2e585740362976a39fdd5ccf390f199a7bc37`.
|
||||
|
||||
The profile records `installed=false`, `execution_authorized=false`,
|
||||
`transferred=false`, and `executed=false`. Firmware was not queried from the
|
||||
device because this phase was offline; the evidence string records Jens's
|
||||
exact 9.60 confirmation.
|
||||
|
||||
## Static gate
|
||||
|
||||
`tools/check_artifact_execution_policy.py` verifies the profile, artifact
|
||||
manifest, local lifecycle bytes, firmware argument, and permanent denylist. It
|
||||
returns `PASS_STATIC_DEPLOYMENT_ELIGIBILITY_GATE` only for the exact reviewed
|
||||
set and still emits `execution_authorized=false`.
|
||||
|
||||
The gate rejects a blocked decision, altered bytes, wrong firmware, an
|
||||
uninstalled-identity claim, a widened budget, a hard effect, missing hardened
|
||||
runtime identity, any authorization/transfer/execution claim, or a permanent
|
||||
denylist match.
|
||||
|
||||
## Historical boundary
|
||||
|
||||
Phase 0.5's freestanding startup and Phase 0.6's unmodified public loader chain
|
||||
remain blocked historical records. Phase 0.7 does not weaken or overwrite
|
||||
those findings; it builds new hardened binaries that close the Phase-0.6
|
||||
implementation blockers.
|
||||
|
||||
Phase 0.8 is a separate operational preflight gate. Its current decision is
|
||||
`READ_ONLY_PREFLIGHT_BLOCKED`; it neither revokes the exact Phase-0.7 static
|
||||
build evidence nor promotes it into connection, installation, transfer, or
|
||||
execution authority.
|
||||
@@ -0,0 +1,93 @@
|
||||
# Kernelwrite proof matrix
|
||||
|
||||
Statuses mean: `SAFE` is proven only for the named scope, `UNSAFE` has a proven
|
||||
policy violation, and `UNPROVEN` lacks necessary primary evidence. Absence of
|
||||
an import is never used as the sole proof because SDK code is statically
|
||||
combined in `crt1.o`.
|
||||
|
||||
| Component or behavior | Source | Linked in stock `crt1.o` | Reachable from stock `_start` | Status | Basis |
|
||||
|---|---|---:|---:|---|---|
|
||||
| `payload_args_t` order/offsets | public header + disassembly | yes | yes | `SAFE` | six x86-64 fields; `payloadout` at `0x28` |
|
||||
| stock SDK startup | `crt/crt.c` | yes | yes | `UNSAFE` | invokes patch and rtld paths |
|
||||
| `__patch_init` | `crt/patch.c` | yes | yes | `UNSAFE` | relocation and callgraph edge from `_start` |
|
||||
| `kernel_copyin/out` | `crt/kernel.c` | yes | yes | `UNSAFE` | reachable read/write transport |
|
||||
| `kernel_set_ucred_caps` | `crt/kernel.c` | yes | yes | `UNSAFE` | reaches `kernel_copyin` |
|
||||
| `kernel_set_ucred_attrs` | `crt/kernel.c` | yes | yes | `UNSAFE` | reaches `kernel_copyin` |
|
||||
| syscall address lower/upper bounds | `crt/patch.c` | yes | yes | `UNSAFE` | writes offsets `0xf0` and `0xf8` |
|
||||
| JIT capability change | `crt/patch.c` | yes | yes | `UNSAFE` | `caps[15] |= 0x40` before credential write |
|
||||
| ptrace attribute change | `crt/patch.c` | yes | yes | `UNSAFE` | `attrs[3] |= 0x80` before attribute write |
|
||||
| runtime symbol discovery | `syscall.c`, `crt.c`, rtld | yes | yes | `UNSAFE` for minimal profile | multiple reachable dynamic resolutions |
|
||||
| `__dlopen`/`__dlsym` facade | `rtld_dlfcn.c` | yes | no static startup edge | `UNSAFE` linked capability | absence from imports is not absence from bytes |
|
||||
| Sce module load/start | `rtld_sprx.c` | yes | yes | `UNSAFE` | `__rtld_sprx_init` reaches function-pointer call |
|
||||
| Sce module stop/unload | `rtld_sprx.c` | yes | cleanup-dependent | `UNPROVEN` cleanup | no guarantee after crash or partial init |
|
||||
| SO mapping/`mprotect` | `rtld_so.c` | yes | path-dependent | `UNSAFE` linked capability | forbidden for minimal profile |
|
||||
| socket-overlap helper | `kernel.c` | yes | no static startup edge | `UNSAFE` linked capability | still present in monolithic startup object |
|
||||
| new network initialization | driver adds `libSceNet` | dependency present in stock links | module-init internals unknown | `UNPROVEN` | no caller/module initialization contract |
|
||||
| GNM calls | no Phase-0.5 candidate source | no candidate | no candidate | `SAFE` source scope only | no custom source or artifact created |
|
||||
| VideoOut calls | no Phase-0.5 candidate source | no candidate | no candidate | `SAFE` source scope only | no custom source or artifact created |
|
||||
| SDL calls | no Phase-0.5 candidate source | no candidate | no candidate | `SAFE` source scope only | no custom source or artifact created |
|
||||
| direct MMIO/register writes | audited project source | no candidate | no candidate | `SAFE` source scope only | none added |
|
||||
| `-nostartfiles -nodefaultlibs` suppression | compiler `-###` | not linked in trace | n/a | `SAFE` driver fact | no CRT or default library added |
|
||||
| loader stack/return contract | exact caller absent | n/a | n/a | `UNPROVEN` | callee cannot prove caller |
|
||||
| pre-entry loader changes | exact caller absent | n/a | before entry | `UNPROVEN` | incoming kernel access exists; origin unknown |
|
||||
|
||||
The full source hashes, stock-object hashes, relocation-table hash,
|
||||
disassembly hash, all reachable edges, and linked-but-unreachable prohibited
|
||||
functions are in `manifests/runtime/phase-0.5-startup-audit.json`.
|
||||
|
||||
## Phase 0.6 controlled-runtime classification
|
||||
|
||||
The table above preserves the stricter Phase-0.5 "kernelwrite-free" question.
|
||||
Phase 0.6 uses the user's corrected policy: a documented temporary runtime
|
||||
write is not automatically unsafe. Only `PERSISTENT_WRITE` and
|
||||
`UNBOUNDED_OR_UNKNOWN` are hard blockers.
|
||||
|
||||
| Component/effect | Classification | Review status | Basis |
|
||||
|---|---|---|---|
|
||||
| first-stage QA flag enable | `EXPECTED_VOLATILE_RUNTIME_EFFECT` | `SAFE` only as exact-source classification | loader bootstrap, before payload |
|
||||
| child creation with `rfork_thread`/`execve` | `PAYLOAD_PROCESS_LOCAL` | `SAFE` source fact | separate SceSpZeroConf child |
|
||||
| ptrace service authid, normal path | `RESTORED_BY_LOADER` | `SAFE` success path | authid backed up and restored |
|
||||
| ptrace authid restore failure | `UNBOUNDED_OR_UNKNOWN` | `UNSAFE` for controlled profile | returns without a second restore |
|
||||
| `pt_call`/`pt_syscall` completion | `UNBOUNDED_OR_UNKNOWN` | `UNSAFE` | no step or time bound |
|
||||
| breakpoint byte | `RESTORED_BY_LOADER` | `SAFE` source fact | original byte copied back |
|
||||
| breakpoint page RWX permission | `PAYLOAD_PROCESS_LOCAL` | `UNPROVEN` cleanup | permission not restored; relies on child exit |
|
||||
| child root/jail/caps/authid | `RESTORED_BY_LOADER` on success | `UNPROVEN` partial | UID is not restored |
|
||||
| payload mapping, argument page, sockets, pipe | `UNBOUNDED_OR_UNKNOWN` | `UNSAFE` for controlled profile | no success-path cleanup before detach |
|
||||
| SDK `__patch_init` | `PAYLOAD_PROCESS_LOCAL` | `SAFE` classification, not execution proof | affects payload child; not an automatic blocker |
|
||||
| SDK terminate branch | `UNBOUNDED_OR_UNKNOWN` | `UNSAFE` for controlled profile | return/exit/trap branch unresolved |
|
||||
| detached payload runtime | `UNBOUNDED_OR_UNKNOWN` | `UNSAFE` | no two-second watchdog |
|
||||
| child reaping | `UNBOUNDED_OR_UNKNOWN` | `UNSAFE` | SIGCHLD ignored; semantics undocumented |
|
||||
| Manager load hash binding | `UNBOUNDED_OR_UNKNOWN` | `UNSAFE` | path streamed without SHA-256 check |
|
||||
| Manager upload path | `PERSISTENT_WRITE` | `UNSAFE` | writes and commits under `/data/pldmgr/payloads` |
|
||||
|
||||
No source or binary evidence showed a GNM, VideoOut, SDL, direct MMIO, flash,
|
||||
firmware, savegame, database, or system-configuration write in the proposed
|
||||
payload path. Because no payload was built, that is a source-scope absence,
|
||||
not an execution claim.
|
||||
|
||||
## Phase 0.7 hardened-runtime classification
|
||||
|
||||
The machine-readable counterpart is
|
||||
`manifests/runtime/phase-0.7-kernelwrite-proof-matrix.json`.
|
||||
|
||||
| Component/effect | Phase-0.7 status | Classification | Evidence boundary |
|
||||
|---|---|---|---|
|
||||
| freestanding kernelwrite-free startup | `UNPROVEN` | historical blocked target | exact safe return contract still absent |
|
||||
| stock SDK `__patch_init` | `UNSAFE` for a kernelwrite-free claim | `PAYLOAD_PROCESS_LOCAL` accepted effect | source, linker map, disassembly, reachable callgraph |
|
||||
| stock SDK rtld module loading | `UNPROVEN` runtime branch; bounded externally | `PAYLOAD_PROCESS_LOCAL` accepted effect | linked module start/stop symbols, SDK source, child watchdog |
|
||||
| ptrace step completion | `SAFE` offline | `BOUNDED_WATCHDOG` | source, unit/fuzz tests, disassembly |
|
||||
| five-field credential restoration | `SAFE` offline | `RESTORED_BY_LOADER` | source, failure injection tests, callgraph |
|
||||
| restoration failure | `SAFE` fail-closed logic | `FAIL_CLOSED_TERMINATION` | child killed/reaped; service disables ptrace |
|
||||
| breakpoint byte/page | `SAFE` offline | `RESTORED_BY_LOADER` | source and disassembly |
|
||||
| payload child lifetime | `SAFE` offline | `BOUNDED_WATCHDOG` | 2000 ms, SIGTERM, SIGKILL, reap |
|
||||
| mapping/descriptor cleanup | `SAFE` offline | `OS_RECLAIMED_ON_EXIT` plus tracked cleanup | source, tests, callgraph |
|
||||
| manager hash-to-stream binding | `SAFE` offline | `HASH_BOUND_SAME_FD` | source, TOCTOU and negative tests |
|
||||
| receiver digest/denylist enforcement | `SAFE` offline | fail-closed | source, tests, disassembly |
|
||||
| controlled artifact-directory write | `SAFE` for reviewed deployment budget | `ALLOWED_APPLICATION_WRITE` | exclusive temp, fsync, verify, atomic rename |
|
||||
| GNM/VideoOut/SDL/MMIO/firmware mutation | `SAFE` absence claim | prohibited | source scan, imports, map, disassembly |
|
||||
| firmware-9.60 runtime behavior | `UNPROVEN` | no execution evidence | no PS5 action occurred |
|
||||
| installation, transfer, execution | `UNPROVEN` and unauthorized | action state false | manifests and offline audit |
|
||||
|
||||
The overall decision is
|
||||
`READY_FOR_HARDENED_RUNTIME_DEPLOYMENT`, not `PROVEN KERNELWRITE-FREE`.
|
||||
The known normal-CRT process-local write prevents the latter claim.
|
||||
@@ -0,0 +1,220 @@
|
||||
# PS5 payload loader contract audit
|
||||
|
||||
Audit date: 2026-07-17. Scope: pinned public PS5 Payload SDK v0.41 at
|
||||
`d2e2e585740362976a39fdd5ccf390f199a7bc37`, inspected offline. No PS5 was
|
||||
contacted and no ELF was built, transferred, or executed.
|
||||
|
||||
## Available primary evidence
|
||||
|
||||
The SDK README names three external loader families: `ps5-payload-dev/elfldr`,
|
||||
`cryonumb/elfloader` through `ps5-jar-loader`, and
|
||||
`shahrilnet/remote_lua_loader`. None of those caller repositories is present in
|
||||
the pinned local evidence set. A `git grep` of every other local primary-source
|
||||
checkout found no `payload_args_t` or `payloadout` caller implementation. The
|
||||
only available contract is therefore the SDK callee side:
|
||||
|
||||
- `include/ps5/payload.h` defines the six-field `payload_args_t`;
|
||||
- `crt/crt.c` defines `int _start(payload_args_t *args)` and labels it as the
|
||||
entry invoked by the ELF loader;
|
||||
- `crt1.o` disassembly shows the first argument consumed from `RDI` and
|
||||
`payloadout` read at offset `0x28`;
|
||||
- the SDK linker script defines image, BSS, constructor, destructor, and
|
||||
dynamic-section boundaries.
|
||||
|
||||
These facts prove the callee layout. They do not prove how a particular loader
|
||||
constructs the argument, stack, return address, or post-return state.
|
||||
|
||||
## Argument layout
|
||||
|
||||
For the audited x86-64 target the public fields are six eight-byte values in
|
||||
this order:
|
||||
|
||||
| Offset | Field | Callee use |
|
||||
|---:|---|---|
|
||||
| `0x00` | `sys_dynlib_dlsym` | SDK syscall/symbol bootstrap |
|
||||
| `0x08` | `rwpipe` | existing kernel read/write transport descriptors |
|
||||
| `0x10` | `rwpair` | existing kernel read/write transport descriptors |
|
||||
| `0x18` | `kpipe_addr` | existing kernel pipe address |
|
||||
| `0x20` | `kdata_base_addr` | existing kernel data-base address |
|
||||
| `0x28` | `payloadout` | result location written by the SDK CRT |
|
||||
|
||||
The 48-byte layout is `SAFE` as a source and disassembly fact. The lifetime,
|
||||
writability, ownership, nullability, and post-return consumption of every
|
||||
pointer are `UNPROVEN` because the caller is absent.
|
||||
|
||||
## Entry ABI and stack
|
||||
|
||||
The compiled SDK `_start` has a normal x86-64 function prologue, consumes the
|
||||
argument from `RDI`, makes further calls without dynamically realigning `RSP`,
|
||||
and ends one path with `ret`. This establishes what the callee expects, not what
|
||||
the loader guarantees. In particular, the following remain `UNPROVEN`:
|
||||
|
||||
- the exact stack alignment at entry;
|
||||
- whether a valid return address is present;
|
||||
- which registers or floating-point state the loader expects preserved;
|
||||
- whether the loader calls the entry as an ordinary function or transfers
|
||||
control by another mechanism;
|
||||
- whether the memory behind `payload_args_t` remains valid until return.
|
||||
|
||||
## BSS and image initialization
|
||||
|
||||
The SDK linker script provides `__bss_start` and `__bss_end`. The stock `_start`
|
||||
explicitly zeros that range byte-by-byte before accessing its own BSS state.
|
||||
The loop itself is freestanding and has no import, so a comparable loop is
|
||||
technically possible. It is not evidence that the loader maps every segment
|
||||
with the permissions, alignment, relocation state, or zero-fill behavior a new
|
||||
artifact would require. Those caller/mapper properties are `UNPROVEN`.
|
||||
|
||||
## Return, exit, crash, and cleanup
|
||||
|
||||
The stock CRT does not define one universal return rule. Its
|
||||
`payload_terminate()` first tries to detect a hijacked process with
|
||||
`kernel_dynlib_dlsym(-1, 0x2001, "sceKernelDlsym")`. In that branch it returns
|
||||
from `_start`. Otherwise it resolves and invokes `exit`; if that fails it
|
||||
executes a trap. This heuristic itself depends on the syscall/kernel/rtld stack
|
||||
that Phase 0.5 forbids.
|
||||
|
||||
Consequently, a custom `_start` that simply executes `ret` cannot be claimed
|
||||
safe from the SDK callee alone. No local primary evidence proves:
|
||||
|
||||
- who consumes the integer return value;
|
||||
- whether return resumes a hijacked process or exits a dedicated process;
|
||||
- which mappings, descriptors, credentials, or signal state are restored;
|
||||
- what happens after an invalid argument, fault, trap, or partial BSS clear;
|
||||
- whether any cleanup exists after a crash.
|
||||
|
||||
All five are `UNPROVEN` and are build blockers.
|
||||
|
||||
## Loader state versus artifact-caused state
|
||||
|
||||
The argument fields show that kernel read/write descriptors and kernel
|
||||
addresses already exist when the SDK entry is called. That is a fact about the
|
||||
incoming state, not proof of how the loader created it. The exact loader may
|
||||
have changed credentials, syscall bounds, mappings, modules, or other process
|
||||
state before entry; the available callee source cannot distinguish those
|
||||
possibilities.
|
||||
|
||||
The stock SDK artifact then independently causes additional writes through
|
||||
`__patch_init`; those writes are attributable to `crt1.o` and are `UNSAFE`.
|
||||
No Phase-0.5 candidate artifact exists, so it caused no new state changes.
|
||||
|
||||
## Contract decision
|
||||
|
||||
The public callee contract is insufficient for a safe-return artifact.
|
||||
Decision: **BLOCKED**. The minimal missing evidence is the exact loader used for
|
||||
firmware 9.60 at a pinned public commit, including its entry call site,
|
||||
argument ownership, return path, pre-entry changes, cleanup, and crash path.
|
||||
|
||||
Machine evidence: `manifests/runtime/phase-0.5-startup-audit.json`.
|
||||
|
||||
## Phase 0.6 exact-loader addendum
|
||||
|
||||
The Phase-0.5 conclusion above is preserved as the evidence available at that
|
||||
time. Phase 0.6 identified the installed loader exactly through the read-only
|
||||
Payload Manager inventory and a byte-for-byte public release match:
|
||||
|
||||
- Payload Manager v0.3.1, commit
|
||||
`cfbc70f30f419b09bf2b52283f7409e2d3117ee1`, SHA-256
|
||||
`518740adbacccb9094fadb07dd424c53ee290f38306449ccc9d6957fdf813c0b`;
|
||||
- `ps5-payload-dev/elfldr` v0.23, commit
|
||||
`699e8bcff03e91e8d6ca6eba281af25c5a58d8c2`, SHA-256
|
||||
`092d16ee0ede0c494947efd38d1a17bbd7cc4b022d3858ea898833c188c703e8`.
|
||||
|
||||
The proposed `itsPLK/ps5-elfldr` v0.23.2 candidate is not installed: its
|
||||
release hash is
|
||||
`2c28f847c859d3126b0f089ee23b72b84a733548da222ceafd91ae2f3df8f933`.
|
||||
The exact exploit/autoloader that originally starts the first-stage loader
|
||||
remains unidentified.
|
||||
|
||||
### Proven entry setup
|
||||
|
||||
The exact v0.23 source creates a new process using
|
||||
`rfork_thread(RFPROC | RFCFDG | RFMEM)`. The child enables tracing and executes
|
||||
`/system/vsh/app/NPXS40112/eboot.bin` (`SceSpZeroConf`). The parent stops at an
|
||||
INT3 placed 58 bytes after the mapped eboot entry, restores that byte, maps the
|
||||
payload, and then sets:
|
||||
|
||||
| Register/state | Exact loader operation | Status |
|
||||
|---|---|---|
|
||||
| `RSP` | writes observed `RIP` at `RSP - 8`, then subtracts 8 | `SAFE` source fact |
|
||||
| `RIP` | payload ELF entry | `SAFE` source fact |
|
||||
| `RDI` | loader-created `payload_args_t` page | `SAFE` source fact |
|
||||
| breakpoint byte | original byte restored before injection | `RESTORED_BY_LOADER` |
|
||||
| breakpoint page permission | changed to RWX and not restored | `PAYLOAD_PROCESS_LOCAL` |
|
||||
|
||||
This is a synthetic function-call frame. The public source does not establish
|
||||
the meaning of the observed trap `RIP`, the exact original instruction
|
||||
boundary, or the validity of resuming there after payload return. Therefore
|
||||
the continuation is still `UNPROVEN`.
|
||||
|
||||
### Argument ownership and lifetime
|
||||
|
||||
`elfldr_payload_args()` maps one page into the child, creates two IPv6 sockets
|
||||
and a pipe, overlaps the sockets through the SDK kernel helper, and populates
|
||||
the six public fields. On successful detach the loader does not unmap that
|
||||
page or close those child descriptors. They are process-local, but cleanup
|
||||
depends on the child terminating. That termination and reaping path is not
|
||||
bounded or proven.
|
||||
|
||||
### Return, exit, crash, and hang
|
||||
|
||||
The stock SDK v0.41 `_start` may return, resolve and call `exit`, or trap,
|
||||
depending on `payload_terminate()`. Which branch applies to this injected
|
||||
SceSpZeroConf child is not proven. Separately, elfldr:
|
||||
|
||||
- has no payload wall-clock deadline after `PT_DETACH`;
|
||||
- has unbounded single-step loops in both `pt_call()` and `pt_syscall()`;
|
||||
- ignores `SIGCHLD` in the service and documents no post-detach reaping
|
||||
contract;
|
||||
- kills the child on some preparation errors, but does not supervise normal
|
||||
runtime, return, crash, or hang.
|
||||
|
||||
These are `UNBOUNDED_OR_UNKNOWN`, not objections to the mere presence of
|
||||
temporary kernel/process writes. They block the requested controlled
|
||||
two-second lifecycle.
|
||||
|
||||
### Existing loader state versus artifact-caused state
|
||||
|
||||
The first-stage loader enables QA flag bits and temporarily changes
|
||||
credentials before the candidate payload exists. Those are existing-loader
|
||||
effects. For each ptrace operation the service temporarily changes its authid
|
||||
and normally restores it. The child receives process-local credentials,
|
||||
mappings, sockets, pipes, executable permissions, and SDK `__patch_init`
|
||||
changes. The artifact would cause SDK startup only after entry; it would not
|
||||
cause the loader bootstrap.
|
||||
|
||||
The separation does not make the chain ready: UID restoration is absent,
|
||||
authid restoration has an unrecovered failure path, and child lifetime is
|
||||
unbounded. Full evidence is in
|
||||
`manifests/runtime/phase-0.6-loader-runtime-audit.json`.
|
||||
|
||||
## Phase 0.7 hardened loader contract
|
||||
|
||||
Phase 0.7 does not depend on safely returning from `main`. The lifecycle
|
||||
probe calls `_exit` after exactly one notification, so the unresolved SDK
|
||||
`payload_terminate` return/exit/trap branch is outside the reachable
|
||||
application path.
|
||||
|
||||
The hardened elfldr preserves the public `payload_args_t *` entry convention
|
||||
and adds a controlled versioned transport header with exact artifact ID,
|
||||
firmware 9.60, size, SHA-256, 2000 ms timeout, and no-retry fields. Both sender
|
||||
and receiver validate the metadata; the receiver hashes the actual received
|
||||
bytes and rejects the permanent denylist.
|
||||
|
||||
The loader's process mutations are exact and bounded:
|
||||
|
||||
- the initial QA flag change is an existing volatile bootstrap effect;
|
||||
- ptrace service auth-ID and all child UID/jail/root/caps/auth fields are
|
||||
backed up, restored, and checked;
|
||||
- breakpoint byte and page protection are restored;
|
||||
- single-step loops have independent time and step limits;
|
||||
- every incomplete launch path terminates and reaps the child;
|
||||
- the detached success path is replaced with a two-second supervised wait,
|
||||
bounded termination escalation, and reap;
|
||||
- an auth restoration failure permanently disables further ptrace work and
|
||||
stops the service.
|
||||
|
||||
This is sufficient for the offline
|
||||
`READY_FOR_HARDENED_RUNTIME_DEPLOYMENT` decision. Loader behavior on firmware
|
||||
9.60 remains `UNPROVEN` until separately authorized installation and execution
|
||||
produce on-device evidence.
|
||||
@@ -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.
|
||||
@@ -0,0 +1,72 @@
|
||||
# Chimera Payload Manager artifact policy contract
|
||||
|
||||
The controlled Phase-0.7 Payload Manager is maintained in the separate private
|
||||
`chimera-ps5-payload-manager` repository. This repository supplies the
|
||||
hash-bound artifact and runtime profile that the manager must enforce.
|
||||
|
||||
## Same-file-descriptor launch boundary
|
||||
|
||||
The controlled manager:
|
||||
|
||||
1. opens the selected artifact once with read-only, no-follow, close-on-exec
|
||||
flags;
|
||||
2. requires a regular file and exact compiled byte size;
|
||||
3. hashes that same file descriptor;
|
||||
4. rejects the permanent denylist and every metadata mismatch;
|
||||
5. rewinds and streams that same descriptor;
|
||||
6. checks descriptor identity and path identity after streaming;
|
||||
7. sends an exact versioned header over loopback only;
|
||||
8. uses a compiled exact artifact ID, SHA-256, size, firmware 9.60, 2000 ms
|
||||
timeout, and `retry=false`.
|
||||
|
||||
There is no path reopen between hash and stream. A symlink, truncation,
|
||||
replacement, digest mismatch, denylist match, wrong route, wrong firmware,
|
||||
non-loopback destination, or post-stream identity change fails closed.
|
||||
|
||||
## Controlled upload boundary
|
||||
|
||||
The upload route accepts only the controlled directory, creates an exclusive
|
||||
no-follow temporary file, writes and synchronizes it, verifies exact content,
|
||||
then atomically renames it. Upload never autoloads or executes the artifact.
|
||||
The removable application write is explicit in the Phase-0.7 budget; it is not
|
||||
a firmware write.
|
||||
|
||||
## Receiver enforcement
|
||||
|
||||
The hardened elfldr independently hashes the received bytes, validates the
|
||||
exact artifact ID/size/firmware/digest/timeout/no-retry header, and enforces the
|
||||
permanent denylist. Sender metadata alone is therefore insufficient.
|
||||
|
||||
The legacy route is classified `UNVERIFIED_LEGACY` and is not a controlled
|
||||
Chimera launch path.
|
||||
|
||||
## Repository static gate
|
||||
|
||||
Before preparing a later action, the exact lifecycle bytes must also pass:
|
||||
|
||||
```text
|
||||
python3 tools/check_artifact_execution_policy.py \
|
||||
--manifest <artifact-manifest.json> \
|
||||
--denylist manifests/artifact-denylist.json \
|
||||
--artifact <exact-local-artifact> \
|
||||
--runtime-profile manifests/runtime/controlled-ps5-runtime-profile.json \
|
||||
--firmware 9.60
|
||||
```
|
||||
|
||||
Only `PASS_STATIC_DEPLOYMENT_ELIGIBILITY_GATE` is accepted. The result always
|
||||
contains `execution_authorized=false`; it is preparation evidence, not
|
||||
permission.
|
||||
|
||||
## Permanent denial
|
||||
|
||||
SHA-256 `4be1c17b4964f2b68c39b5145bc4af4619c32512d60269ecf5c39728b390fa63`
|
||||
must always return `ARTIFACT_PERMANENTLY_DENYLISTED`, regardless of metadata,
|
||||
runtime profile, or later generic approval. The entry is also copied into both
|
||||
hardened consumers.
|
||||
|
||||
## Current action state
|
||||
|
||||
No hardened binary is installed. No lifecycle artifact has been transferred
|
||||
or executed. A separate exact-hash installation approval is required first;
|
||||
after successful installation verification, lifecycle transfer and one-time
|
||||
execution require another artifact-specific approval.
|
||||
@@ -0,0 +1,48 @@
|
||||
# Phase 0.5 independent offline review
|
||||
|
||||
Date: 2026-07-17. Decision: **BLOCKED**.
|
||||
|
||||
## Review result
|
||||
|
||||
| Area | Status | Finding |
|
||||
|---|---|---|
|
||||
| SDK source pin and release | `SAFE` | local source is exact v0.41 commit |
|
||||
| stock CRT object provenance | `SAFE` | all 12 sources and six empty archives enumerated and hashed |
|
||||
| stock CRT execution | `UNSAFE` | reachable kernel credential and syscall-bound writes |
|
||||
| stock rtld initialization | `UNSAFE` | reachable module load/start path and runtime allocation |
|
||||
| freestanding flag suppression | `SAFE` | no-output driver trace removes CRT and default libraries |
|
||||
| BSS byte-clear primitive | `SAFE` | implementable without imports using linker bounds |
|
||||
| exact firmware-9.60 loader identity | `UNPROVEN` | not present in local pinned evidence |
|
||||
| incoming stack/register contract | `UNPROVEN` | caller source absent |
|
||||
| `payloadout` ownership/lifetime | `UNPROVEN` | only callee declaration exists |
|
||||
| safe return and post-return cleanup | `UNPROVEN` | caller continuation absent |
|
||||
| crash cleanup | `UNPROVEN` | loader fault path absent |
|
||||
| pre-entry process modifications | `UNPROVEN` | kernel-access state is supplied but creation is absent |
|
||||
| custom startup artifact | `SAFE` nonexistence | build gate stopped before source/link |
|
||||
| permanent legacy artifact block | `SAFE` policy control | exact SHA-256 is denylisted and ineligible |
|
||||
| Payload Manager integration surface | `SAFE` repository control | fail-closed JSON policy gate rejects false eligibility and denylisted hashes |
|
||||
| external manager implementation | `UNPROVEN` outside repository | no Chimera Payload Manager source is in this project |
|
||||
|
||||
## Side-effect conclusion
|
||||
|
||||
The stock SDK startup is conclusively not kernelwrite-free. A hypothetical
|
||||
freestanding entry could omit that startup, but safe loader return and cleanup
|
||||
are not proven. It would be unsafe to turn a compiler/linker possibility into
|
||||
an executable artifact without the caller evidence.
|
||||
|
||||
No PS5 connection, transfer, execution, VideoOut open, GNM call, framebuffer
|
||||
write, network initialization, module load, credential change, syscall-bound
|
||||
change, or new PS5 ELF occurred during this review.
|
||||
|
||||
## Artifact policy
|
||||
|
||||
The legacy capability-probe SHA-256
|
||||
`4be1c17b4964f2b68c39b5145bc4af4619c32512d60269ecf5c39728b390fa63`
|
||||
is permanently `BLOCKED`. `tools/check_artifact_execution_policy.py` returns a
|
||||
nonzero decision for either `execution_eligible=false` or an exact denylist
|
||||
match. A zero status means only that this static eligibility layer passed; its
|
||||
JSON explicitly sets `execution_authorized=false`.
|
||||
|
||||
There is no approval package for transfer or one-time execution because the
|
||||
task explicitly forbids asking for execution permission and the feasibility
|
||||
decision is blocked.
|
||||
@@ -0,0 +1,122 @@
|
||||
# Phase 0.6 exact loader audit
|
||||
|
||||
Historical record: superseded for current deployment preparation by the new
|
||||
Phase-0.7 hardened binaries. This blocked decision remains authoritative for
|
||||
the unmodified public-release chain.
|
||||
|
||||
Audit date: 2026-07-17. Decision:
|
||||
**BLOCKED_VERSION_OR_UNBOUNDED_EFFECT**.
|
||||
|
||||
No ELF was built, transferred, or executed. The PS5 was not contacted through
|
||||
raw port 9021. Read-only Payload Manager status endpoints were used only to
|
||||
identify the installed public components. A strict existing read-only status
|
||||
client on port 744 could not connect, so firmware 9.60 remains user-attested,
|
||||
not device-attested.
|
||||
|
||||
## Identity evidence
|
||||
|
||||
| Component | Observed identity | Public source/release match | Result |
|
||||
|---|---|---|---|
|
||||
| firmware | exact `9.60`, stated by Jens | no independent device response | `UNPROVEN` attestation |
|
||||
| Payload Manager | `/version` = `0.3.1`; inventory SHA-256 `518740ad...3c0b` | v0.3.1, commit `cfbc70f30...` | exact |
|
||||
| elfldr | inventory v0.23; SHA-256 `092d16ee...03e8` | `ps5-payload-dev/elfldr` v0.23, commit `699e8bcff0...` | exact |
|
||||
| itsPLK elfldr candidate | SHA-256 `2c28f847...8f933` | differs from installed hash | excluded |
|
||||
| SDK | v0.41 | commit `d2e2e58574...` | exact |
|
||||
| exploit/autoloader | local backup candidate only | no installed identity proof | `UNPROVEN` |
|
||||
|
||||
The exact source and release pins are in `manifests/upstreams.lock.json`. The
|
||||
machine audit normalizes source text to LF, hashes every reviewed file, hashes
|
||||
the complete release-binary disassembly and readelf report, and asserts the
|
||||
critical source tokens before generating its result.
|
||||
|
||||
## Exact release binary
|
||||
|
||||
The installed elfldr release asset is a stripped ELF64 PIE with entry `0x4700`.
|
||||
Its complete import surface is:
|
||||
|
||||
```text
|
||||
DT_NEEDED:
|
||||
libSceLibcInternal.sprx
|
||||
libSceNet.sprx
|
||||
libkernel_web.sprx
|
||||
|
||||
Undefined dynamic symbols:
|
||||
__error
|
||||
close
|
||||
execve
|
||||
free
|
||||
getpid
|
||||
kevent
|
||||
kill
|
||||
kqueue
|
||||
malloc
|
||||
memcpy
|
||||
memset
|
||||
open
|
||||
printf
|
||||
puts
|
||||
realloc
|
||||
recv
|
||||
rfork_thread
|
||||
sceKernelSendNotificationRequest
|
||||
strcmp
|
||||
strerror
|
||||
strlen
|
||||
sysctl
|
||||
vsnprintf
|
||||
waitpid
|
||||
```
|
||||
|
||||
It has 164 dynamic relocations, 140 of them `R_X86_64_RELATIVE`; zero-byte
|
||||
preinit/init/fini arrays; and no TLS segment or TLS sections. The first load
|
||||
segment is RWE. This import list does not prove absence of statically linked
|
||||
kernel helpers, so the source and disassembly audits remain primary.
|
||||
|
||||
## Loader lifecycle
|
||||
|
||||
The loader uses a dedicated SceSpZeroConf child. It establishes a synthetic
|
||||
call frame by placing the observed trap RIP at `RSP-8`, setting `RIP` to the
|
||||
payload entry and `RDI` to a loader-created `payload_args_t`. It restores the
|
||||
INT3 byte, jail/root/caps/authid on the child success path, and its own authid
|
||||
after each ptrace syscall on the normal path.
|
||||
|
||||
It does not prove or enforce:
|
||||
|
||||
- the continuation reached when the payload returns;
|
||||
- a finite step count in `pt_call()` or `pt_syscall()`;
|
||||
- a two-second payload runtime;
|
||||
- restoration after an authid-restore failure;
|
||||
- child UID restoration;
|
||||
- child mapping/socket/pipe cleanup after detach;
|
||||
- child termination and reaping after normal return, crash, or hang.
|
||||
|
||||
The installed service's existing QA flag and bootstrap credential effects are
|
||||
separate from new artifact effects. They are still documented because the
|
||||
full lifecycle depends on them.
|
||||
|
||||
## Payload Manager lifecycle
|
||||
|
||||
The exact `/loadpayload:` handler resolves a filename/path and streams that
|
||||
file to elfldr on loopback port 9021. It does not calculate or compare the file
|
||||
SHA-256 at launch. The `/manage:upload` path creates
|
||||
`/data/pldmgr/payloads/<filename>.tmp` and commits the upload into storage.
|
||||
Consequently the current manager cannot simultaneously provide exact-hash
|
||||
launch binding and the required zero-filesystem-write transfer budget.
|
||||
|
||||
No manager route was invoked to upload, load, kill, configure, retry, or
|
||||
contact port 9021 during this audit.
|
||||
|
||||
## Minimum evidence needed to reopen Phase D
|
||||
|
||||
1. Exact exploit/autoloader identity and public-source lifecycle evidence.
|
||||
2. Read-only, exact device attestation of firmware 9.60.
|
||||
3. A bounded loader path whose ptrace and payload phases enforce a maximum of
|
||||
2000 ms without automatic retry.
|
||||
4. Proven payload return/exit/crash continuation and child cleanup/reaping.
|
||||
5. Proven restoration or bounded termination on every credential-change
|
||||
failure path, including UID.
|
||||
6. A Payload Manager path that verifies the exact SHA-256 immediately before
|
||||
launch and performs no filesystem write.
|
||||
|
||||
No workaround is authorized. The two safe development tracks remain the
|
||||
mock/software backend and a separately scoped Linux-on-PS5 backend.
|
||||
@@ -0,0 +1,58 @@
|
||||
# Phase 0.6 independent review
|
||||
|
||||
Historical record: superseded for current deployment preparation by the new
|
||||
Phase-0.7 hardened binaries. This blocked decision remains authoritative for
|
||||
the unmodified public-release chain.
|
||||
|
||||
Date: 2026-07-17. Final decision:
|
||||
**BLOCKED_VERSION_OR_UNBOUNDED_EFFECT**.
|
||||
|
||||
`SAFE` below means proven only for the stated offline/source scope. `UNSAFE`
|
||||
means incompatible with the mandatory controlled profile. `UNPROVEN` means
|
||||
required primary evidence is absent.
|
||||
|
||||
| Component | Status | Finding |
|
||||
|---|---|---|
|
||||
| private project isolation | `SAFE` | only `chimera-gfx` changed |
|
||||
| firmware claim | `UNPROVEN` | exact 9.60 supplied by Jens; no device attestation |
|
||||
| Payload Manager identity | `SAFE` | v0.3.1 asset hash matches commit/release |
|
||||
| elfldr identity | `SAFE` | installed v0.23 asset hash matches exact public release |
|
||||
| proposed itsPLK elfldr | `SAFE` exclusion | release hash differs; not audited as installed |
|
||||
| exploit/autoloader identity | `UNPROVEN` | local backup is not installed-chain proof |
|
||||
| separate payload process | `SAFE` source fact | rfork/exec creates SceSpZeroConf child |
|
||||
| `RSP`/`RIP`/`RDI` setup | `SAFE` source fact | exact assignments identified |
|
||||
| return continuation | `UNPROVEN` | trap RIP semantics and SDK terminate branch unresolved |
|
||||
| ptrace completion | `UNSAFE` | single-step loops have no finite bound |
|
||||
| maximum runtime | `UNSAFE` | detached child has no two-second watchdog |
|
||||
| retry behavior | `SAFE` project policy | no project retry or execution path exists |
|
||||
| normal authid restore | `SAFE` success path | loader backs up and restores |
|
||||
| authid restore failure | `UNSAFE` | no recovery after failed restore |
|
||||
| child credential restore | `UNPROVEN` partial | jail/root/caps/authid restored; UID not restored |
|
||||
| breakpoint byte | `SAFE` | restored before payload detach |
|
||||
| breakpoint permissions | `UNPROVEN` cleanup | page remains RWX until unproven child exit |
|
||||
| payload args/resources | `UNPROVEN` cleanup | mappings, sockets and pipe rely on child exit |
|
||||
| `__patch_init` | `SAFE` classification | known payload-process-local effect; not an automatic blocker |
|
||||
| child exit/reaping | `UNPROVEN` | post-detach semantics not documented |
|
||||
| manager launch hash | `UNSAFE` | path-bound stream; no launch-time SHA-256 verification |
|
||||
| manager upload | `UNSAFE` | persistent `/data/pldmgr/payloads` write |
|
||||
| GNM/VideoOut/SDL/MMIO | `SAFE` nonexistence | no lifecycle source or artifact was created |
|
||||
| lifecycle artifact | `SAFE` nonexistence | Phase D stopped before source/build |
|
||||
| legacy blocked artifact | `SAFE` policy | permanent denylist unchanged |
|
||||
| transfer/execution | `SAFE` nonoccurrence | neither happened; no approval requested |
|
||||
|
||||
## Artifact disposition
|
||||
|
||||
There is no artifact path, artifact size, artifact SHA-256, or source commit
|
||||
because no lifecycle probe was built. The machine profile contains null for
|
||||
each of those fields and `execution_eligible=false`. No ELF is committed.
|
||||
|
||||
The permanent blocked SHA-256 remains:
|
||||
|
||||
```text
|
||||
4be1c17b4964f2b68c39b5145bc4af4619c32512d60269ecf5c39728b390fa63
|
||||
```
|
||||
|
||||
This review is not an approval package. Reopening Phase D requires resolving
|
||||
every minimum-evidence item in `phase-0.6-loader-audit.md`, followed by a new
|
||||
offline audit and a new decision. It does not require or request execution
|
||||
permission now.
|
||||
@@ -0,0 +1,79 @@
|
||||
# Phase 0.7 hardened runtime — offline review
|
||||
|
||||
Decision: **READY_FOR_HARDENED_RUNTIME_DEPLOYMENT**.
|
||||
|
||||
This is an offline deployment-readiness decision. No PS5 connection,
|
||||
installation, transfer, or execution occurred.
|
||||
|
||||
## Exact identities
|
||||
|
||||
| Component | Base | Hardened source | ELF SHA-256 | Size |
|
||||
|---|---|---|---|---:|
|
||||
| elfldr | `699e8bcff03e91e8d6ca6eba281af25c5a58d8c2` | `197623058f509eddde18868dafcb92fdcac66464` | `63e810982471eb40cae3a20aa9df9a0a02892f420e429874fae4e99aa400b561` | 397000 |
|
||||
| controlled Payload Manager | `cfbc70f30f419b09bf2b52283f7409e2d3117ee1` | `e23d94ff91233aa770e2342800c1467875bdef44` | `8fecf8241a46246eddbd21e8bb4d875f5d76f1f4f4c6a11384df1f131aa5e5b1` | 99560 |
|
||||
| lifecycle probe | Chimera GFX | `fe08300339a13f899fb78ea404ada381a5cba87c` | `bfb4a5cc768e162fe4c2fddf41c3978e152722918a39085277fd172cb95a7182` | 112680 |
|
||||
|
||||
All three pairs of clean builds are byte-identical. Complete disassembly,
|
||||
symbol tables, relocations, normalized linker maps, and call-edge inventories
|
||||
are in the ignored offline package under `outputs/phase07/audit/`; their
|
||||
hashes and the complete call-edge lists are committed in
|
||||
`manifests/runtime/phase-0.7-offline-audit.json`.
|
||||
|
||||
## Lifecycle binary boundary
|
||||
|
||||
The only undefined imports are:
|
||||
|
||||
- `_exit`
|
||||
- `sceKernelSendNotificationRequest`
|
||||
|
||||
The only `DT_NEEDED` modules are:
|
||||
|
||||
- `libSceLibcInternal.sprx`
|
||||
- `libkernel_web.sprx`
|
||||
|
||||
There are no GNM, VideoOut, SDL, SceNet, socket, download, thread, retry, or
|
||||
autoload imports. The normal SDK startup object is statically present and
|
||||
reaches its documented `__patch_init` and rtld initialization before `main`;
|
||||
absence from imports is not used to hide that fact. The linker map also
|
||||
contains `sceKernelLoadStartModule`/`sceKernelStopUnloadModule` through the
|
||||
stock SDK rtld; its conditional module behavior is payload-process-local and
|
||||
supervised by the external watchdog, but remains unobserved on firmware 9.60.
|
||||
After one notification, `main` calls `_exit`, so the uncertain SDK
|
||||
`main -> payload_terminate` return branch is not taken.
|
||||
|
||||
## Hardening closure
|
||||
|
||||
| Phase-0.6 finding | Phase-0.7 implementation | Review |
|
||||
|---|---|---|
|
||||
| unbounded ptrace loop | monotonic one-second deadline plus 65,536 steps | `SAFE` offline logic |
|
||||
| incomplete child credential restore | UID, jaildir, rootdir, caps, auth-ID all restored and checked | `SAFE` offline logic |
|
||||
| restore failure continues | fail-closed kill and deadline-bounded reap; no detach | `SAFE` offline logic |
|
||||
| scattered cleanup | one tracked cleanup state machine for breakpoint, mappings, fds, child | `SAFE` offline logic |
|
||||
| breakpoint page stays RWX | original byte restored and page reset RX | `SAFE` source fact |
|
||||
| detached runtime unbounded | 2000 ms wait, SIGTERM grace, SIGKILL, reap | `SAFE` offline logic |
|
||||
| ignored SIGCHLD/zombie risk | default SIGCHLD plus explicit reap | `SAFE` offline logic |
|
||||
| path-based Manager load | one no-follow FD, fstat, hash, rewind, stream, post-check | `SAFE` offline logic |
|
||||
| upload TOCTOU | exclusive temp, fsync, verify, atomic rename, inode check | `SAFE` offline logic |
|
||||
| arbitrary controlled artifact | manager binary compiled for exact hash, size, and ID | `SAFE` offline configuration |
|
||||
| sender-only hash | elfldr rehashes received bytes and checks denylist | `SAFE` offline logic |
|
||||
|
||||
`SAFE` here means source, test, map, and disassembly evidence agree. It is not
|
||||
a hardware execution claim.
|
||||
|
||||
## Remaining risks
|
||||
|
||||
- No on-device observation exists yet; loader/firmware behavior remains
|
||||
unverified at runtime.
|
||||
- QA flags are an existing expected volatile loader bootstrap effect.
|
||||
- Normal SDK startup performs known process-local credential/capability and
|
||||
syscall-bound writes before `main`.
|
||||
- The controlled manager listens for the later operator workflow, but accepts
|
||||
only the compiled exact artifact identity; installation security and
|
||||
network exposure still require a separate review.
|
||||
- Abrupt platform failure can bypass userland reporting, though OS process
|
||||
teardown should reclaim child mappings and descriptors.
|
||||
- Rollback has only been prepared offline; its on-device paths and installed
|
||||
hashes must be captured before any replacement.
|
||||
|
||||
These are deployment/execution residual risks, not unresolved compiler,
|
||||
linker, or ABI blockers for preparing the hardened runtime.
|
||||
@@ -0,0 +1,137 @@
|
||||
# Phase 0.8 read-only on-device preflight
|
||||
|
||||
Audit date: 2026-07-18. Decision:
|
||||
**READ_ONLY_PREFLIGHT_BLOCKED**.
|
||||
|
||||
This is an offline admissibility audit. No on-device preflight session was
|
||||
started, no connection to the PS5 was made, and no collector was run against
|
||||
the PS5. No file, configuration, service, process, artifact, autoload setting,
|
||||
or retry state on the console was touched. Local documentation and manifest
|
||||
changes are outside that console-action statement.
|
||||
|
||||
The attached preflight form requires both an exact permission record and a
|
||||
collector whose reads demonstrably cannot change atime, audit logs, caches,
|
||||
metadata, process state, or on-device logs. Neither condition can currently be
|
||||
filled truthfully. The form's own fail-closed rule therefore requires
|
||||
`STOP-RO`.
|
||||
|
||||
## Authorization record
|
||||
|
||||
| Field | Recorded value |
|
||||
|---|---|
|
||||
| explicit read-only preflight permission | absent; no exact text/reference was supplied |
|
||||
| connection authorized | `false` |
|
||||
| installation authorized | `false` |
|
||||
| lifecycle authorized | `false` |
|
||||
| execution authorized | `false` |
|
||||
| automatic retry | `false` |
|
||||
|
||||
The request to read and act on a blank checklist is not recorded as an exact,
|
||||
artifact-independent authorization sentence. This finding alone prevents an
|
||||
on-device session. It does not prevent this offline source audit.
|
||||
|
||||
## Collector review
|
||||
|
||||
### Stock Payload Manager HTTP
|
||||
|
||||
The exact public v0.3.1 source is commit
|
||||
`cfbc70f30f419b09bf2b52283f7409e2d3117ee1`.
|
||||
|
||||
This candidate is **UNSAFE for the Phase-0.8 read-only contract**:
|
||||
|
||||
- `src/http_server.c:131-152` calls `log_server_set_active()` for every
|
||||
non-`OPTIONS` request before route dispatch;
|
||||
- `src/log_server.c:20-23` implements that call by writing
|
||||
`server_active_flag = 1`;
|
||||
- `src/http_server.c:847-871` dispatches `/autoload_status` to
|
||||
`pldmgr_autoload_get_status()` and opens
|
||||
`/data/pldmgr/autoload.txt`;
|
||||
- `src/autoload.c:44-48` writes `autoload_triggered = 1`; the worker at
|
||||
`src/autoload.c:78-93` uses that flag to leave its frontend-wait state and
|
||||
start the countdown;
|
||||
- `src/http_server.c:911-930` also opens the autoload file for `/get_config`;
|
||||
- non-noisy routes call `pldmgr_log()` at `src/http_server.c:479-481`;
|
||||
`src/log_server.c:25-55` prints to stdout and mutates the in-process ring,
|
||||
log version, mutex/condition state, and waiting clients.
|
||||
|
||||
Even `/version`, which is filtered from the explicit request log, first calls
|
||||
`log_server_set_active()`. Therefore an apparently informational endpoint is
|
||||
not sufficient evidence of a no-side-effect collector. `/autoload_status`
|
||||
must not be used at all under this contract.
|
||||
|
||||
Pinned source-file SHA-256 values:
|
||||
|
||||
| File | SHA-256 |
|
||||
|---|---|
|
||||
| `src/http_server.c` | `35cf5d8f0dd44cf64ceab5e4b0ecc09413c82d7e9946ba9de2ca4b1898631fdd` |
|
||||
| `src/autoload.c` | `7051cab3ee1a3e0b9f6498000565eb9e160b9c63efa1771f250e98ec3aa4ae67` |
|
||||
| `src/log_server.c` | `659095f43df1bbe8eb24acb165f027edc277af1e60aabb26ba9e3920b233d6f1` |
|
||||
|
||||
### Direct filesystem or process collector
|
||||
|
||||
No exact collector, version, source, transport, or operation set was supplied.
|
||||
No evidence proves `noatime` behavior, suppression of audit records, absence
|
||||
of caches, absence of network/service counters, or absence of on-device
|
||||
logging. Classifying these effects as “probably harmless” would contradict the
|
||||
required `Onbekend -> STOP-RO` rule.
|
||||
|
||||
Historical Phase-0.6 endpoint observations are not reused as current
|
||||
Phase-0.8 evidence. They lack current pre/post identity and were gathered
|
||||
under a different, less strict observation boundary.
|
||||
|
||||
## Gate state
|
||||
|
||||
| Preflight section | Review | Reason |
|
||||
|---|---|---|
|
||||
| permission | `STOP-RO` | exact permission text/reference absent |
|
||||
| collector | `STOP-RO` | side-effect freedom unproven |
|
||||
| stock HTTP collector | `STOP-RO` | proven process-state mutations |
|
||||
| two-source firmware 9.60 | `STOP-GATE` | one user attestation, no two current device sources |
|
||||
| live elfldr path/object/hash | `STOP-GATE` | no current admissible observation |
|
||||
| live Payload Manager path/object/hash | `STOP-GATE` | no current admissible observation |
|
||||
| processes/services/listeners | `STOP-GATE` | current topology and ownership absent |
|
||||
| autoload/startup/retry | `STOP-GATE` | authoritative sources not collected |
|
||||
| separate backup destination | `STOP-GATE` | device, space, and reserve unproven |
|
||||
| stock elfldr rollback backup | `STOP-GATE` | exact separate backup unproven |
|
||||
| stock Payload Manager rollback backup | `HARD STOP-GATE` | exact separate on-device backup unproven |
|
||||
|
||||
The expected stock identities remain reference values only:
|
||||
|
||||
- elfldr: 397000 bytes,
|
||||
`092d16ee0ede0c494947efd38d1a17bbd7cc4b022d3858ea898833c188c703e8`;
|
||||
- Payload Manager: 2050320 bytes,
|
||||
`518740adbacccb9094fadb07dd424c53ee290f38306449ccc9d6957fdf813c0b`.
|
||||
|
||||
They are not claims about the console's current state.
|
||||
|
||||
## Minimum evidence to reopen
|
||||
|
||||
1. Exact permission text and a stable task reference authorizing only this
|
||||
read-only preflight, while leaving installation, lifecycle execution,
|
||||
transfer, artifact execution, and automatic retry unauthorized.
|
||||
2. A pinned public collector and transport with a complete source and
|
||||
environment proof excluding file, atime, metadata, audit-log, cache,
|
||||
process-state, service-state, network-state, and on-device-log mutation.
|
||||
3. Two authoritative current firmware sources that agree exactly on `9.60`.
|
||||
4. A side-effect-free collection plan for current object identities, full
|
||||
metadata, hashes, process/service ownership, ports 8084/8085/9021, and all
|
||||
autoload/startup/retry sources, including stable pre/post observations.
|
||||
5. Proof that separate, already-present, byte-exact rollback objects exist.
|
||||
The stock Payload Manager backup is a hard gate.
|
||||
|
||||
The stock Payload Manager HTTP interface cannot satisfy item 2 without a
|
||||
different, separately reviewed implementation. No workaround is attempted.
|
||||
|
||||
## Final state
|
||||
|
||||
- dataset complete: `false`;
|
||||
- open STOP-RO: `true`;
|
||||
- open STOP-GATE: `true`;
|
||||
- Payload Manager backup exact/current: `UNPROVEN`;
|
||||
- installation approval: **NOT AUTHORIZED**;
|
||||
- lifecycle approval: **NOT AUTHORIZED**;
|
||||
- execution authorized: `false`;
|
||||
- automatic retry: `false`.
|
||||
|
||||
The complete machine-readable record is
|
||||
`manifests/runtime/phase-0.8-read-only-preflight.json`.
|
||||
@@ -0,0 +1,289 @@
|
||||
# Phase 0.8R offline remediation and evidence contract
|
||||
|
||||
Decision: **READ_ONLY_PREFLIGHT_BLOCKED**.
|
||||
|
||||
## Scope
|
||||
|
||||
Phase 0.8R is documentation, evidence-contract design, and host-only
|
||||
regression protection. It does not contact a PS5, observe hardware, implement
|
||||
a collector, build a target artifact, transfer a file, install a component, or
|
||||
execute code on a target.
|
||||
|
||||
It grants no authority. `installation_authorized=false`,
|
||||
`lifecycle_authorized=false`, `execution_authorized=false`,
|
||||
`transfer_authorized=false`, and `automatic_retry=false`.
|
||||
|
||||
The absolute read-only rule used by historical Phase 0.8 is unchanged.
|
||||
Possible future bounded observation would be a separate phase with a new name,
|
||||
effect budget, exact permission, and review. This document does not approve
|
||||
such a phase.
|
||||
|
||||
## Immutable historical identity
|
||||
|
||||
The Phase-0.8 record is anchored to repository commit
|
||||
`2c944d6d65a08f7e1c02f518721cde061b999329`.
|
||||
|
||||
| Immutable file | Role | SHA-256 |
|
||||
|---|---|---|
|
||||
| `docs/runtime/phase-0.8-read-only-preflight.md` | human-readable historical record | `3fbe086175a6048176075f447ec1482074928e3b5282db97ea2169395fe1d508` |
|
||||
| `manifests/runtime/phase-0.8-read-only-preflight.json` | machine-readable historical record | `47d7f452f8799979fe99b3e6d56859f03544112725bf7e5b349eba5ed81b3322` |
|
||||
| `tests/test_phase08_preflight.py` | original fail-closed regression | `8a4ad7c70de28ffe3148fd3fd1f68c36a872c53c691c9068e1ff163970863c48` |
|
||||
|
||||
Historical reporting dated 2026-07-18 recorded 17/17 host tests passing,
|
||||
manifest and safety checks passing, and a secret scan passing across 558 text
|
||||
files. Those results are historical repository evidence. They are not current
|
||||
hardware observations or proof of firmware behavior.
|
||||
|
||||
The immutable result remains `READ_ONLY_PREFLIGHT_BLOCKED`. Firmware 9.60
|
||||
runtime behavior remains `UNPROVEN`. The stock elfldr and Payload Manager
|
||||
sizes and hashes remain reference values only; their current on-device
|
||||
identity is not established.
|
||||
|
||||
## Schema boundary
|
||||
|
||||
The existing artifact schema describes built target artifacts, while the
|
||||
controlled-runtime schema describes the separate Phase-0.7 hardened runtime.
|
||||
Neither can represent an offline remediation dossier without implying
|
||||
inapplicable artifact or deployment semantics. No shared schema is widened.
|
||||
The remediation manifest therefore names the dedicated
|
||||
`chimera-gfx-phase-0.8-remediation-v1` contract and is validated semantically
|
||||
by `tools/validate_phase08_remediation.py`.
|
||||
|
||||
## Side-effect classification
|
||||
|
||||
- **A — persistent mutation:** file create/write/delete/rename, configuration
|
||||
or autoload change, metadata change, or persistent platform-state change.
|
||||
- **B — process- or service-wide mutation:** functional global flags and
|
||||
counters, `server_active_flag`, `autoload_triggered`, process/service state,
|
||||
signals, or retry state.
|
||||
- **C — volatile technical effect:** socket acceptance, temporary buffers,
|
||||
allocations, scheduler activity, kernel counters, caches, audit or logging
|
||||
paths, and temporary process-local state.
|
||||
- **D — observation:** firmware fields, file metadata and hashes, process and
|
||||
listener lists, configuration, rollback identities, and storage conditions.
|
||||
|
||||
No persistent write found is not equivalent to side-effect-free. Category C
|
||||
is not claimed absent. Missing observations are unknown, never evidence of
|
||||
safe absence.
|
||||
|
||||
## Pinned Payload Manager source
|
||||
|
||||
The reviewed local source is public Payload Manager v0.3.1 commit
|
||||
`cfbc70f30f419b09bf2b52283f7409e2d3117ee1`. Relevant source identities are
|
||||
recorded in `manifests/runtime/phase-0.8-remediation.json`.
|
||||
|
||||
The three confirmed root findings are:
|
||||
|
||||
1. `http_on_request()` returns early for `OPTIONS`, then calls
|
||||
`log_server_set_active()` for every other request at
|
||||
`work/upstream/pldmgr-v0.3.1/src/http_server.c:131-152`.
|
||||
`log_server_set_active()` writes the process-global
|
||||
`server_active_flag = 1` at
|
||||
`work/upstream/pldmgr-v0.3.1/src/log_server.c:20-23`.
|
||||
2. `/autoload_status` calls `pldmgr_autoload_get_status()` at
|
||||
`work/upstream/pldmgr-v0.3.1/src/http_server.c:847-852`.
|
||||
That function writes `autoload_triggered = 1` at
|
||||
`work/upstream/pldmgr-v0.3.1/src/autoload.c:44-48`. The worker reads that
|
||||
flag when deciding whether to leave its frontend wait and begin the
|
||||
countdown at `src/autoload.c:78-93`.
|
||||
3. The same handler opens `/data/pldmgr/autoload.txt` and calls
|
||||
`config_read()` at `src/http_server.c:854-871`. `config_read()` opens
|
||||
`/data/pldmgr/pldmgr_config.txt` at `src/config.c:12-49`.
|
||||
|
||||
### Request side-effect matrix
|
||||
|
||||
All handlers below are rooted in `http_on_request()`. “Filesystem/config”
|
||||
means project source performs such a read; it does not assert that no other
|
||||
read or technical effect occurs.
|
||||
|
||||
| Method | Endpoint | Handler path | `server_active_flag` | `autoload_triggered` | Filesystem/config | Other proven or unproven effects | Strict read-only |
|
||||
|---|---|---|---:|---:|---:|---|---:|
|
||||
| `OPTIONS` | `*` | `http_on_request` | no | no | no | response/transport allocations; network, cache, audit, scheduler and kernel effects unproven | **no** |
|
||||
| `GET` | `/version` | `http_on_request` | yes | no | no | B: global flag; C: transport effects | **no** |
|
||||
| `GET` | `/log` | `http_on_request -> log_build_json` | yes | no | no | B: global flag; C: allocation and mutex; D: ring observation | **no** |
|
||||
| `GET` | `/autoload_status` | `http_on_request -> pldmgr_autoload_get_status -> config_read` | yes | yes | yes | B: functional autoload change; C: read/transport effects; D: config observation | **no** |
|
||||
| `GET` | `/get_config` | `http_on_request -> config_read` | yes | no | yes | B: global flag; C: atime/audit/cache/metadata unproven; D: config observation | **no** |
|
||||
| `GET` | `/list_payloads` | `http_on_request -> payload_mgr_list_json` | yes | no | yes | directory and sidecar scans; possible USB enumeration; technical effects unproven | **no** |
|
||||
| `GET` | `/processes_list` | `http_on_request -> process_list_json` | yes | no | no | `sysctl` snapshot and allocation; kernel/audit/scheduler effects unproven | **no** |
|
||||
| `GET` | `/sources_list` | `http_on_request -> sources_list_json` | yes | no | yes | not excluded by `is_noisy_route`, so `pldmgr_log()` also writes stdout and the log ring | **no** |
|
||||
| `GET` | `/getip` | `http_on_request -> pldmgr_get_local_ip` | yes | no | no | network-interface query; kernel/cache/audit effects unproven | **no** |
|
||||
|
||||
Supporting locations:
|
||||
|
||||
- route constants: `include/pldmgr.h:7-44`;
|
||||
- noisy-route list and generic request entry:
|
||||
`src/http_server.c:108-152`;
|
||||
- non-noisy request logging: `src/http_server.c:479-481`;
|
||||
- payload and process lists: `src/http_server.c:601-616`;
|
||||
- sources list: `src/http_server.c:706-713`;
|
||||
- version, log, IP, autoload and config handlers:
|
||||
`src/http_server.c:826-954`;
|
||||
- ring and stdout mutation: `src/log_server.c:12-55`;
|
||||
- payload scan: `src/payload_mgr.c:114-153,196-238`;
|
||||
- sources file read: `src/sources.c:28-84,112-134`;
|
||||
- process snapshot: `src/process_mgr.c:43-88`.
|
||||
|
||||
`OPTIONS` is not promoted merely because it returns before the two proven
|
||||
flag writes. It provides none of the required device evidence, and network,
|
||||
allocation, logging below the reviewed layer, cache, audit, scheduling, and
|
||||
kernel-counter effects are still unproven.
|
||||
|
||||
## Root-cause analysis
|
||||
|
||||
The current HTTP interface is a frontend-control interface, not an evidence
|
||||
collector. A request is treated as evidence that the frontend is active, so
|
||||
the server deliberately changes functional process state. The autoload route
|
||||
goes further and changes a flag consumed by the autoload worker. This makes
|
||||
the interface incompatible with the historical absolute read-only contract
|
||||
even where the response body appears informational.
|
||||
|
||||
A filesystem open using mode `"r"` prevents application-level content writes;
|
||||
it does not prove absence of atime, audit records, page-cache activity,
|
||||
metadata/cache updates, scheduling, kernel counters, or platform-specific
|
||||
effects. Those effects require an exact collector and environment contract.
|
||||
|
||||
Unavailable data cannot be interpreted as a negative observation. No current
|
||||
firmware query, file identity, process/service inventory, listener inventory,
|
||||
autoload snapshot, or rollback identity exists in this dossier.
|
||||
|
||||
A missing Payload Manager backup cannot be created in an absolute read-only
|
||||
phase. Creating it necessarily writes a new persistent object and may change
|
||||
filesystem allocation and metadata. Backup creation therefore belongs to a
|
||||
separate mutating rollback-preparation phase with separate authorization.
|
||||
|
||||
## Evidence contract for a possible future method
|
||||
|
||||
No collector is selected. Every timeout below is deliberately unset until the
|
||||
collector implementation, transport, and cleanup contract are reviewed. An
|
||||
unset timeout, timeout expiry, unknown result, identity drift, or partial
|
||||
dataset yields `STOP`.
|
||||
|
||||
| Observation | Needed fact | Possible source class | Confidence | Known mutations | Unknown effects | Required identity | Timeout | Reviewer return |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| firmware | two authoritative current values agree exactly | two independently reviewed authoritative sources | `UNPROVEN` | none established | UI/transport/audit/cache/platform query | tool/source/operation identity | unset → `STOP` | raw values, times, identities, agreement |
|
||||
| live paths | literal paths, mounts, types, no symlink | reviewed no-follow metadata operation | `UNPROVEN` | none established | atime/audit/cache/namespace | tool, source, no-follow and mount semantics | unset → `STOP` | raw paths, mounts, types, symlink decision |
|
||||
| object identities | stable pre/post object/device IDs and full metadata | same reviewed object collector | `UNPROVEN` | none established | cache/audit/race/concurrency | lookup, race, symlink policy | unset → `STOP` | complete pre/post records and errors |
|
||||
| file sizes | exact current live byte sizes | same bound object handles | `UNPROVEN` | none established | cache/audit/concurrent modification | same-object and race policy | unset → `STOP` | sizes, references, bindings |
|
||||
| SHA-256 | digest of exact current bytes | no-follow same-object streaming hash | `UNPROVEN` | none established | atime/audit/page cache/scheduling | implementation, version, commit, binary hash, open policy | unset → `STOP` | bytes, times, digest, identity, errors |
|
||||
| processes/services | all relevant owners, paths, parents, starts and startup modes | reviewed process/service snapshot | `UNPROVEN` | none established | counters/audit/scheduling/locks/cache | tool/API/source/snapshot semantics | unset → `STOP` | raw snapshot and unmapped entries |
|
||||
| listeners | owners and binding for 8084/8085/9021 | reviewed listener snapshot | `UNPROVEN` | none established | stack counters/audit/cache/locks/races | tool/API/source/owner mapping | unset → `STOP` | protocol/address/port/owner/exposure |
|
||||
| autoload/startup/retry | complete authoritative state; artifacts absent; retry off | collector distinct from stock `/autoload_status` | `UNPROVEN` | stock route mutates `autoload_triggered` | atime/audit/cache/metadata/service/race | tool/source plus complete source list and no-functional-mutation proof | unset → `STOP` | safe raw representations, identities, hashes, decisions |
|
||||
| rollback files | separate existing exact backups and restore mappings | same admissible object/hash collector | `UNPROVEN` | none established | atime/audit/cache/metadata/mount/race | hash, object and separation semantics | unset → `STOP` | paths, IDs, hashes, separation and mapping |
|
||||
| storage condition | separate target, 2447320 content bytes plus reserve | reviewed capacity/mount operation | `UNPROVEN` | none established | mount/audit/cache/accounting/concurrency | tool/API and capacity semantics | unset → `STOP` | IDs, available bytes, reserve and separation |
|
||||
|
||||
Any code-bearing collector would additionally require its exact name, version,
|
||||
origin, source commit, byte size, SHA-256, complete operation set, imports,
|
||||
transitive effects, output channel, cleanup, and fail-closed timeout behavior.
|
||||
|
||||
## Architecture options — design only
|
||||
|
||||
| Option | Can prove | Cannot prove | Transfer/execution needed | Persistent effects | Volatile effects | Required permission | Remaining blockers |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| A. Current Payload Manager endpoints | limited in-memory version/config/list responses | strict side-effect freedom, complete files/listeners/rollback identity | no new target transfer; requires a network request to an existing process | reads may affect metadata; no content write proven for selected GETs | proven global flags; autoload flag on status; sockets, allocation, logs, caches and audit | new bounded-observation permission would still be required | current interface violates the absolute read-only contract |
|
||||
| B. Future one-shot observation method | potentially a purpose-built complete bounded dataset | nothing until source, ABI, transport and cleanup are reviewed | likely transfer and execution, both currently unspecified and unauthorized | must be forbidden by contract but absence is unproven | startup, loader, transport, allocation, scheduling, cache, audit and logs | new exact artifact- and method-bound permission | no design, binary, hash, ABI, timeout or cleanup proof exists |
|
||||
| C. Manual/external firmware observation | one user-visible firmware value, possibly an independent second value | live files, processes, listeners, autoload and rollback state | no code transfer or execution if strictly manual | UI/platform persistence is unreviewed | UI, audit, cache and human transcription | new exact observation permission if used as formal evidence | insufficient for the complete preflight |
|
||||
| D. Split observation from rollback preparation | observation can be reviewed before any backup write; later backup phase can prove rollback objects | observation alone cannot create missing backups | observation method unknown; backup preparation necessarily performs writes | backup creation, allocation and metadata are expected persistent effects | tool, storage, cache, scheduling and audit effects | separate observation permission, then separate mutating rollback permission | exact live identity and admissible backup procedure remain absent |
|
||||
|
||||
None of these options is implemented by Phase 0.8R.
|
||||
|
||||
## Hard gates
|
||||
|
||||
The active blockers are:
|
||||
|
||||
1. `exact_permission_quote_absent` — `STOP-RO`;
|
||||
2. `collector_identity_absent` — `STOP-RO`;
|
||||
3. `collector_side_effect_contract_absent` — `STOP-RO`;
|
||||
4. `two_current_firmware_sources_absent` — `STOP-GATE`;
|
||||
5. `live_object_identities_absent` — `STOP-GATE`;
|
||||
6. `listeners_absent` — `STOP-GATE`;
|
||||
7. `autoload_status_absent` — `STOP-GATE`;
|
||||
8. `rollback_backups_absent` — `STOP-GATE`;
|
||||
9. `payload_manager_backup_not_byte_exact_on_device` — `HARD_STOP-GATE`;
|
||||
10. `unknown_result_is_stop` — `STOP`;
|
||||
11. `timeout_is_stop` — `STOP`;
|
||||
12. `deviation_is_stop` — `STOP`;
|
||||
13. `automatic_retry_forbidden` — `STOP`.
|
||||
|
||||
No general `READY`, `COMPLETE`, or deployment status may override any one of
|
||||
these gates. The Payload Manager backup gate can be closed only by
|
||||
artifact-specific, current, on-device evidence gathered under a separately
|
||||
approved method, not by changing this manifest.
|
||||
|
||||
## Phase separation
|
||||
|
||||
Authority never flows forward. Each step requires its own completed review and
|
||||
new permission where it involves a target:
|
||||
|
||||
1. this offline remediation;
|
||||
2. a possible later bounded-observation design;
|
||||
3. separate permission for any observation transfer or execution;
|
||||
4. review of the returned observations;
|
||||
5. separate mutating rollback preparation if a backup must be created;
|
||||
6. separate installation approval for only hardened elfldr and controlled
|
||||
Payload Manager;
|
||||
7. installation verification and complete rollback proof;
|
||||
8. separate lifecycle approval;
|
||||
9. non-graphical capability probes;
|
||||
10. much later, a graphics backend and RetroArch.
|
||||
|
||||
Installation permission does not grant lifecycle permission. Observation
|
||||
permission does not grant rollback preparation. No earlier wording may be
|
||||
reused for a later artifact, method, or phase.
|
||||
|
||||
## Relationship to RetroArch
|
||||
|
||||
RetroArch is a long-term goal, not an active Phase-0.8R workstream. The
|
||||
dependency chain is:
|
||||
|
||||
```text
|
||||
offline evidence integrity
|
||||
-> admissible bounded observation
|
||||
-> verified rollback and installation boundary
|
||||
-> separately approved lifecycle
|
||||
-> non-graphical capability evidence
|
||||
-> later graphics/runtime contracts
|
||||
-> later adapters
|
||||
-> eventual RetroArch port
|
||||
```
|
||||
|
||||
Phase 0.8R implements none of GNM, VideoOut, SDL, hardware acceleration,
|
||||
input, audio, RetroArch frontend behavior, cores, or content launching.
|
||||
|
||||
## Machine-readable consistency record
|
||||
|
||||
The validator compares this block structurally with the remediation manifest.
|
||||
|
||||
<!-- BEGIN PHASE08R_CONTRACT -->
|
||||
```json
|
||||
{
|
||||
"status": "READ_ONLY_PREFLIGHT_BLOCKED",
|
||||
"authorization": {
|
||||
"authorized": false,
|
||||
"installation_authorized": false,
|
||||
"lifecycle_authorized": false,
|
||||
"execution_authorized": false,
|
||||
"transfer_authorized": false,
|
||||
"automatic_retry": false
|
||||
},
|
||||
"blockers": [
|
||||
"exact_permission_quote_absent",
|
||||
"collector_identity_absent",
|
||||
"collector_side_effect_contract_absent",
|
||||
"two_current_firmware_sources_absent",
|
||||
"live_object_identities_absent",
|
||||
"listeners_absent",
|
||||
"autoload_status_absent",
|
||||
"rollback_backups_absent",
|
||||
"payload_manager_backup_not_byte_exact_on_device",
|
||||
"unknown_result_is_stop",
|
||||
"timeout_is_stop",
|
||||
"deviation_is_stop",
|
||||
"automatic_retry_forbidden"
|
||||
],
|
||||
"firmware_runtime_behavior": "UNPROVEN",
|
||||
"stock_identity_classification": "reference_only",
|
||||
"payload_manager_backup_classification": "hard_blocker",
|
||||
"retroarch_active_phase": false
|
||||
}
|
||||
```
|
||||
<!-- END PHASE08R_CONTRACT -->
|
||||
@@ -0,0 +1,188 @@
|
||||
# Phase 0.9A offline anti-brick threat model
|
||||
|
||||
Status: **DESIGN_ONLY**. Historical operational status:
|
||||
**READ_ONLY_PREFLIGHT_BLOCKED**.
|
||||
|
||||
This is an offline design review. It does not describe a proven PS5
|
||||
filesystem, installation method, recovery method, path, syscall or switch
|
||||
primitive. No PS5 was contacted; no file was transferred, installed or
|
||||
executed; no target artifact was created. Host simulation is not hardware
|
||||
evidence.
|
||||
|
||||
## Evidence boundary
|
||||
|
||||
The review uses only existing repository evidence:
|
||||
|
||||
- immutable Phase-0.8 record and Phase-0.8R remediation contract;
|
||||
- the permanent artifact denylist;
|
||||
- Phase-0.7 offline identities for the hardened elfldr and controlled Payload
|
||||
Manager candidates;
|
||||
- stock elfldr and Payload Manager sizes and hashes as `reference_only`;
|
||||
- the offline rollback and installation review documents;
|
||||
- clean local source identities for hardened elfldr, controlled Payload
|
||||
Manager and the unchanged lifecycle-probe source.
|
||||
|
||||
Current on-device paths, mounts, object IDs, hashes, firmware behavior,
|
||||
processes, services, listeners, autoload state, backups and recovery paths
|
||||
remain unobserved. The byte-exact on-device Payload Manager backup remains a
|
||||
hard STOP gate.
|
||||
|
||||
Severity means:
|
||||
|
||||
- `CATASTROPHIC`: can remove the only working launch/recovery path, destroy
|
||||
both live and rollback identities, run unverified code automatically, or
|
||||
make recovery depend on a failed component;
|
||||
- `HIGH`: can select or persist wrong/partial bytes, invalidate the evidence
|
||||
binding, or prevent controlled recovery;
|
||||
- `MEDIUM`: disrupts control or observation but does not alone prove loss of
|
||||
both live and recovery objects;
|
||||
- `LOW`: occurs before live mutation and should leave the old object intact,
|
||||
but still needs platform evidence.
|
||||
|
||||
## Control profiles
|
||||
|
||||
### A — wrong target
|
||||
|
||||
Possible damage is replacement of an unrelated or critical object. Before any
|
||||
future mutation, one no-follow stable object must bind literal path, mount ID,
|
||||
object ID, type, size and SHA-256, and the identity must be repeated
|
||||
immediately before mutation. AB-001, AB-003, AB-004 and AB-007 prevent the
|
||||
write. Recovery would require a separate verified backup and independent
|
||||
executor; neither is proven. Namespace and object-identity semantics remain
|
||||
`UNPROVEN`, so Phase 0.9A blocks.
|
||||
|
||||
| ID | Scenario | Severity |
|
||||
|---|---|---|
|
||||
| TM-A-01 | wrong path | CATASTROPHIC |
|
||||
| TM-A-02 | wrong mountpoint | CATASTROPHIC |
|
||||
| TM-A-03 | symlink, junction or other redirect | CATASTROPHIC |
|
||||
| TM-A-04 | path resolves to another object after preflight | CATASTROPHIC |
|
||||
| TM-A-05 | case or path normalization changes identity | HIGH |
|
||||
| TM-A-06 | target is replaced between check and write | CATASTROPHIC |
|
||||
|
||||
### B — wrong pre-image
|
||||
|
||||
Possible damage is treating modified or firmware-incompatible bytes as stock.
|
||||
The future evidence must bind firmware, manifest, stable object, size and
|
||||
digest in one current observation. AB-001 through AB-004 reject every partial
|
||||
match. Detection must happen before mutation; rollback is not a substitute.
|
||||
Current device identities and firmware runtime behavior remain `UNPROVEN`.
|
||||
|
||||
| ID | Scenario | Severity |
|
||||
|---|---|---|
|
||||
| TM-B-01 | live hash differs from stock reference | HIGH |
|
||||
| TM-B-02 | live size differs | HIGH |
|
||||
| TM-B-03 | object ID changes | CATASTROPHIC |
|
||||
| TM-B-04 | firmware differs | HIGH |
|
||||
| TM-B-05 | manifest belongs to another build | HIGH |
|
||||
| TM-B-06 | modified installation is treated as stock | CATASTROPHIC |
|
||||
|
||||
### C — backup failure
|
||||
|
||||
Possible damage is loss of all trusted rollback bytes. A backup must be
|
||||
created before staging, on a separate identity, then closed, reopened,
|
||||
re-identified and rehashed. Capacity, mapping and an independent recovery
|
||||
executor must be proven. AB-005, AB-006, AB-016 and AB-017 block mutation
|
||||
until this holds. The Payload Manager backup is currently a
|
||||
`CATASTROPHIC` hard blocker.
|
||||
|
||||
| ID | Scenario | Severity |
|
||||
|---|---|---|
|
||||
| TM-C-01 | backup missing | CATASTROPHIC |
|
||||
| TM-C-02 | backup is the same object as live | CATASTROPHIC |
|
||||
| TM-C-03 | backup is on the same vulnerable path | CATASTROPHIC |
|
||||
| TM-C-04 | backup is partial | CATASTROPHIC |
|
||||
| TM-C-05 | backup hash differs | CATASTROPHIC |
|
||||
| TM-C-06 | backup cannot be reopened | HIGH |
|
||||
| TM-C-07 | backup-to-target mapping is ambiguous | CATASTROPHIC |
|
||||
| TM-C-08 | recovery tool depends on the replaced component | CATASTROPHIC |
|
||||
| TM-C-09 | storage or metadata capacity is insufficient | HIGH |
|
||||
| TM-C-10 | backup is created only after live mutation | CATASTROPHIC |
|
||||
|
||||
### D — write and power loss
|
||||
|
||||
Possible damage is a missing, partial or ambiguous live identity. A safe design
|
||||
needs isolated staging, durable files and directory metadata, and one
|
||||
old-or-new atomic switch. AB-007 through AB-013 reject in-place overwrite and
|
||||
unproven switch semantics. No such PS5 primitive is proven.
|
||||
|
||||
| ID | Scenario | Severity |
|
||||
|---|---|---|
|
||||
| TM-D-01 | power loss before staging | LOW |
|
||||
| TM-D-02 | power loss during staging | HIGH |
|
||||
| TM-D-03 | power loss after staging before verification | HIGH |
|
||||
| TM-D-04 | power loss during live switch | CATASTROPHIC |
|
||||
| TM-D-05 | power loss immediately after live switch | CATASTROPHIC |
|
||||
| TM-D-06 | power loss before directory metadata is durable | CATASTROPHIC |
|
||||
| TM-D-07 | partial write | CATASTROPHIC |
|
||||
| TM-D-08 | short write | HIGH |
|
||||
| TM-D-09 | write error | HIGH |
|
||||
| TM-D-10 | flush or fsync error | CATASTROPHIC |
|
||||
| TM-D-11 | file bytes correct but directory not durable | CATASTROPHIC |
|
||||
| TM-D-12 | new file has wrong ownership, mode or metadata | HIGH |
|
||||
|
||||
### E — process and lifecycle
|
||||
|
||||
Possible damage is automatic launch of unverified bytes, stale mappings or a
|
||||
crash loop. A future observation must establish all relevant owners,
|
||||
instances, mappings, listeners, supervisors and authoritative autoload/retry
|
||||
state. AB-010, AB-013, AB-014 and AB-020 require quiescence and a later
|
||||
one-shot approval. Unknown topology blocks before switch.
|
||||
|
||||
| ID | Scenario | Severity |
|
||||
|---|---|---|
|
||||
| TM-E-01 | target executable is active | HIGH |
|
||||
| TM-E-02 | multiple instances exist | HIGH |
|
||||
| TM-E-03 | service restarts itself | CATASTROPHIC |
|
||||
| TM-E-04 | listener conflict | MEDIUM |
|
||||
| TM-E-05 | process holds old file or mappings | HIGH |
|
||||
| TM-E-06 | watchdog or supervisor automatically restarts | CATASTROPHIC |
|
||||
| TM-E-07 | autoload starts the candidate before verification | CATASTROPHIC |
|
||||
| TM-E-08 | automatic retry creates a crash loop | CATASTROPHIC |
|
||||
|
||||
### F — rollback failure
|
||||
|
||||
Possible damage is restoring wrong bytes to a wrong path, automatic execution
|
||||
or loss of the recovery executor. Rollback must bind the preverified backup,
|
||||
exact target mapping and independent executor. AB-006 and AB-015 through
|
||||
AB-017 require a separate approval and post-rollback identity proof. A failed
|
||||
rollback verification is `CATASTROPHIC/BLOCKED`, never a retry.
|
||||
|
||||
| ID | Scenario | Severity |
|
||||
|---|---|---|
|
||||
| TM-F-01 | wrong backup selected | CATASTROPHIC |
|
||||
| TM-F-02 | wrong rollback target path | CATASTROPHIC |
|
||||
| TM-F-03 | rollback interrupted | CATASTROPHIC |
|
||||
| TM-F-04 | restored hash is wrong | CATASTROPHIC |
|
||||
| TM-F-05 | rollback automatically starts a service | CATASTROPHIC |
|
||||
| TM-F-06 | rollback works only if Payload Manager works | CATASTROPHIC |
|
||||
| TM-F-07 | rollback works only if elfldr works | CATASTROPHIC |
|
||||
|
||||
### G — operator error
|
||||
|
||||
Possible damage is a role swap, reused authority or combined loss of both
|
||||
runtime components. Component manifests and approvals must be bound to one
|
||||
device, firmware, action, hash, size and expiration. AB-018 through AB-020
|
||||
prohibit a combined transaction, exclude the lifecycle probe and stop phase
|
||||
carryover. Component order is not guessed.
|
||||
|
||||
| ID | Scenario | Severity |
|
||||
|---|---|---|
|
||||
| TM-G-01 | hardened elfldr and Payload Manager are swapped | CATASTROPHIC |
|
||||
| TM-G-02 | lifecycle probe is treated as installation candidate | CATASTROPHIC |
|
||||
| TM-G-03 | wrong firmware or build is selected | HIGH |
|
||||
| TM-G-04 | two installation phases are combined | CATASTROPHIC |
|
||||
| TM-G-05 | approval for one component is reused for another | HIGH |
|
||||
| TM-G-06 | stale manifest is used | HIGH |
|
||||
| TM-G-07 | general READY overrides a specific blocker | CATASTROPHIC |
|
||||
|
||||
The item-specific reasons and machine bindings are in
|
||||
`manifests/runtime/phase-0.9-anti-brick-design.json`.
|
||||
|
||||
## Decision
|
||||
|
||||
Every threat is detectable only under evidence contracts that are not yet
|
||||
satisfied on the PS5. The design is fail-closed and suitable for host review,
|
||||
but not for installation engineering on a device.
|
||||
|
||||
**BLOCKER: NO PROVEN POWER-LOSS-SAFE SWITCH.**
|
||||
@@ -0,0 +1,201 @@
|
||||
# Phase 0.9A installation transaction design
|
||||
|
||||
Status: **DESIGN_ONLY — NOT INSTALLATION READY**.
|
||||
|
||||
This document defines a future evidence and state contract. It contains no
|
||||
PS5 path, install command, device write implementation, lifecycle transition,
|
||||
autoload, retry, graphics code or RetroArch transition. All approval values
|
||||
remain false.
|
||||
|
||||
## Anti-brick invariants
|
||||
|
||||
| ID | Mandatory invariant |
|
||||
|---|---|
|
||||
| AB-001 | Never write without exact stable path, mount ID, object ID, type, size and pre-image SHA-256. |
|
||||
| AB-002 | A stock hash remains `reference_only` until observed on one stable on-device object. |
|
||||
| AB-003 | Hash match without object identity is insufficient. |
|
||||
| AB-004 | Object identity without hash match is insufficient. |
|
||||
| AB-005 | Before staging, a separate backup survives close, reopen, identity, size and hash verification. |
|
||||
| AB-006 | Backup and recovery do not depend on the candidate or replaced component. |
|
||||
| AB-007 | Never overwrite a live executable in place. |
|
||||
| AB-008 | Stage under a separate inactive identity. |
|
||||
| AB-009 | Reopen and hash the candidate before activation; bytes equal the approved artifact. |
|
||||
| AB-010 | No autoload, retry, service restart or boot starts the candidate. |
|
||||
| AB-011 | Switch only with a separately proven transactional or atomic primitive. |
|
||||
| AB-012 | Unproven atomicity or durability blocks installation. |
|
||||
| AB-013 | Verify the new live identity; execution is a later approval. |
|
||||
| AB-014 | At most one manual execution and zero automatic retries. |
|
||||
| AB-015 | Failed post-switch verification enters `ROLLBACK_REQUIRED`, never execution. |
|
||||
| AB-016 | Rollback uses only the verified backup and exact target mapping. |
|
||||
| AB-017 | After rollback, re-establish size, hash, object identity and metadata. |
|
||||
| AB-018 | elfldr and Payload Manager are never replaced in one uninterrupted transaction. |
|
||||
| AB-019 | The lifecycle probe is not an installation candidate. |
|
||||
| AB-020 | No later phase begins without separate human permission. |
|
||||
|
||||
## State machine
|
||||
|
||||
The complete ordered state set is:
|
||||
|
||||
```text
|
||||
OFFLINE_ONLY
|
||||
-> OBSERVATION_NOT_AUTHORIZED
|
||||
-> OBSERVATION_AUTHORIZED
|
||||
-> DEVICE_IDENTITY_OBSERVED
|
||||
-> LIVE_OBJECTS_VERIFIED
|
||||
-> BACKUP_NOT_PRESENT
|
||||
-> BACKUP_CREATION_NOT_AUTHORIZED
|
||||
-> BACKUP_CREATION_AUTHORIZED
|
||||
-> BACKUP_CREATED
|
||||
-> BACKUP_REOPENED_AND_VERIFIED
|
||||
-> RECOVERY_PATH_VERIFIED
|
||||
-> CANDIDATE_NOT_AUTHORIZED
|
||||
-> CANDIDATE_APPROVED_OFFLINE
|
||||
-> STAGING_NOT_AUTHORIZED
|
||||
-> STAGING_AUTHORIZED
|
||||
-> CANDIDATE_STAGED
|
||||
-> CANDIDATE_REOPENED_AND_VERIFIED
|
||||
-> TARGET_NOT_QUIESCENT
|
||||
-> TARGET_QUIESCENT
|
||||
-> SWITCH_NOT_AUTHORIZED
|
||||
-> SWITCH_AUTHORIZED
|
||||
-> SWITCH_IN_PROGRESS
|
||||
-> POST_SWITCH_VERIFY
|
||||
-> MANUAL_EXECUTION_NOT_AUTHORIZED
|
||||
-> MANUAL_EXECUTION_AUTHORIZED
|
||||
-> ONE_SHOT_EXECUTION
|
||||
-> ACCEPTED
|
||||
```
|
||||
|
||||
The only recovery branch is:
|
||||
|
||||
```text
|
||||
POST_SWITCH_VERIFY
|
||||
-> ROLLBACK_REQUIRED
|
||||
-> ROLLBACK_AUTHORIZED
|
||||
-> ROLLBACK_IN_PROGRESS
|
||||
-> ROLLBACK_VERIFIED
|
||||
```
|
||||
|
||||
Any error, mismatch, timeout, unknown or object change goes to `BLOCKED`.
|
||||
No state automatically crosses an authorization state. There is no automatic
|
||||
retry, autoload, lifecycle, graphics or RetroArch transition. A general READY
|
||||
value cannot bypass a specific gate.
|
||||
|
||||
The current real state is `OFFLINE_ONLY`; the repository templates do not move
|
||||
it.
|
||||
|
||||
## Approval separation
|
||||
|
||||
Observation, backup creation, staging, switch, one-shot execution and rollback
|
||||
each require a different active-task authorization. An authorization must bind
|
||||
one component, device, exact firmware, live pre-image, candidate hash and
|
||||
size, action count, runtime, expiration and stop conditions. Reuse for another
|
||||
hash, action or component fails.
|
||||
|
||||
Phase 0.9A grants none of these authorizations. The simulator uses explicitly
|
||||
labelled synthetic authorization objects only to test state-machine logic.
|
||||
Those objects always report `installation_authorized=false` and
|
||||
`execution_authorized=false`.
|
||||
|
||||
## Component-separated models
|
||||
|
||||
### Hardened elfldr
|
||||
|
||||
- stock reference: 397000 bytes,
|
||||
`092d16ee0ede0c494947efd38d1a17bbd7cc4b022d3858ea898833c188c703e8`;
|
||||
- candidate reference: 397000 bytes,
|
||||
`63e810982471eb40cae3a20aa9df9a0a02892f420e429874fae4e99aa400b561`;
|
||||
- live path, mount, object ID and current hash: `UNPROVEN`;
|
||||
- separate on-device backup: `UNPROVEN`;
|
||||
- process, service, listener, autoload and quiescence: `UNPROVEN`;
|
||||
- target mapping, recovery independence and switch primitive: `UNPROVEN`;
|
||||
- approval, staging, switch, execution, acceptance and rollback: not
|
||||
authorized or performed.
|
||||
|
||||
### Controlled Payload Manager
|
||||
|
||||
- stock reference: 2050320 bytes,
|
||||
`518740adbacccb9094fadb07dd424c53ee290f38306449ccc9d6957fdf813c0b`;
|
||||
- candidate reference: 99560 bytes,
|
||||
`8fecf8241a46246eddbd21e8bb4d875f5d76f1f4f4c6a11384df1f131aa5e5b1`;
|
||||
- live path, mount, object ID and current hash: `UNPROVEN`;
|
||||
- byte-exact, separate, reopened on-device backup: **HARD_BLOCKER**;
|
||||
- process, service, listener, autoload and quiescence: `UNPROVEN`;
|
||||
- target mapping, recovery independence and switch primitive: `UNPROVEN`;
|
||||
- approval, staging, switch, execution, acceptance and rollback: not
|
||||
authorized or performed.
|
||||
|
||||
There is no “install all” operation and no shared approval. Component B may be
|
||||
considered only after component A is separately accepted or fully rolled back,
|
||||
but Phase 0.9A does not infer which component is A. Order requires proven
|
||||
dependency and recovery evidence. The lifecycle probe belongs to neither
|
||||
model.
|
||||
|
||||
## Switch contract
|
||||
|
||||
Design preference, without assuming platform support:
|
||||
|
||||
1. side-by-side or dual-slot activation without deleting stock;
|
||||
2. proven atomic exchange;
|
||||
3. proven transactional snapshot;
|
||||
4. another method only after separate evidence.
|
||||
|
||||
An in-place copy-overwrite is always forbidden. The sequence `rename live ->
|
||||
backup; rename candidate -> live` is forbidden while a power-loss interval can
|
||||
leave the live name absent.
|
||||
|
||||
Before a future switch, evidence must establish:
|
||||
|
||||
- filesystem type, mount identity and read/write state;
|
||||
- atomic rename or exchange behavior and replacement semantics;
|
||||
- file-flush and directory-flush durability;
|
||||
- interruption and power-loss behavior;
|
||||
- no-follow behavior and stable open-object identity;
|
||||
- ownership, mode and metadata preservation;
|
||||
- capacity, metadata reserve and maximum file size;
|
||||
- behavior while the target executable is open.
|
||||
|
||||
None is proven for the PS5 in this phase.
|
||||
|
||||
**BLOCKER: NO PROVEN POWER-LOSS-SAFE SWITCH.**
|
||||
|
||||
## Power-loss boundary table
|
||||
|
||||
All results are `UNPROVEN` for PS5. The host simulator can prove only its own
|
||||
virtual atomic primitive.
|
||||
|
||||
| # | Boundary | Possible state | Live visibility | Backup | Auto-start | Recovery | Result |
|
||||
|---:|---|---|---|---|---:|---|---|
|
||||
| 1 | before backup write | old live only | old | absent | no | no mutation yet | UNPROVEN |
|
||||
| 2 | during backup write | old plus partial backup | old | invalid partial | no | old must remain | UNPROVEN |
|
||||
| 3 | after backup write before flush | volatile backup | old | not durable | no | old must remain | UNPROVEN |
|
||||
| 4 | after flush before reopen/hash | unverified backup | old | not reverified | no | old must remain | UNPROVEN |
|
||||
| 5 | during candidate staging | partial candidate | old | verified if contract holds | no | independent | UNPROVEN |
|
||||
| 6 | after staging before verification | unverified candidate | old | verified if contract holds | no | independent | UNPROVEN |
|
||||
| 7 | immediately before switch | three verified logical objects | old | verified | no | independent | UNPROVEN |
|
||||
| 8 | during switch | must be complete old or complete new | unknown | must remain verified | no | independent | UNPROVEN |
|
||||
| 9 | immediately after switch | namespace/durability uncertain | unknown | must remain verified | no | independent | UNPROVEN |
|
||||
| 10 | after switch before live hash | nominal new live unverified | unverified | verified | no | independent | UNPROVEN |
|
||||
| 11 | after live hash before execution | nominal verified new | new | verified | no | independent | UNPROVEN |
|
||||
| 12 | during first manual execution | new plus backup | new | verified | no automatic start | must work without new component | UNPROVEN |
|
||||
| 13 | during rollback | must be complete new or complete old | unknown | must remain verified | no | independent | UNPROVEN |
|
||||
| 14 | after rollback before verification | nominal restored old | unverified old | verified | no | independent | UNPROVEN |
|
||||
|
||||
Because at least one boundary is `UNPROVEN`, the model is not
|
||||
installation-suitable. Here all fourteen are `UNPROVEN`.
|
||||
|
||||
## Host simulator
|
||||
|
||||
`tools/simulate_phase09_transaction.py` models logical objects, identities,
|
||||
hashes, mounts, approvals, transitions, failures and all fourteen power-loss
|
||||
boundaries in memory. It has no device path, network operation, cross-compiler
|
||||
call, target artifact open, production installer or output-file option.
|
||||
|
||||
The default scenario stops at
|
||||
`NO_PROVEN_POWER_LOSS_SAFE_SWITCH`. A special in-memory primitive can be
|
||||
treated as atomic for fault-testing, but every report marks it
|
||||
`host_simulation_only=true` and `hardware_evidence=false`. Even that synthetic
|
||||
happy path stops at `MANUAL_EXECUTION_NOT_AUTHORIZED`.
|
||||
|
||||
The machine-readable contract is
|
||||
`manifests/runtime/phase-0.9-anti-brick-design.json`.
|
||||
@@ -0,0 +1,106 @@
|
||||
# Phase 0.9A recovery and rollback contract
|
||||
|
||||
Status: **DESIGN_ONLY — RECOVERY UNPROVEN**.
|
||||
|
||||
This contract states what future evidence must prove. It does not authorize or
|
||||
implement backup creation, transfer, installation, switch, rollback or
|
||||
execution.
|
||||
|
||||
## Valid backup contract
|
||||
|
||||
A future backup is valid only when all conditions hold:
|
||||
|
||||
1. it is created before staging or any live mutation;
|
||||
2. the source object and exact restoration target are recorded;
|
||||
3. the source stays the same stable object throughout the read;
|
||||
4. every byte is read and the exact size is recorded;
|
||||
5. SHA-256 equals the current observed pre-image;
|
||||
6. the backup is a distinct object, not an alias of live;
|
||||
7. it is closed, reopened without redirection, re-identified and rehashed;
|
||||
8. its storage medium and mount are recorded;
|
||||
9. content and metadata capacity plus reserve are proven;
|
||||
10. autoload, cleanup and packaging cannot delete it;
|
||||
11. it is never replaced by candidate bytes;
|
||||
12. mapping is literal and not selected by a glob, basename or guess;
|
||||
13. rollback does not guess the live target;
|
||||
14. recovery can use it without the component being replaced.
|
||||
|
||||
A second byte-exact off-device copy with its own manifest and SHA-256 is
|
||||
strongly recommended. Creating or transferring that copy is a later,
|
||||
separately authorized phase and is not permitted here.
|
||||
|
||||
For the controlled Payload Manager, an absent, differing, unstable,
|
||||
non-reopenable or recovery-dependent byte-exact on-device backup remains a
|
||||
**HARD STOP-GATE**.
|
||||
|
||||
## Recovery independence
|
||||
|
||||
Before any component transaction, evidence must answer all rows without
|
||||
inference:
|
||||
|
||||
| Question | Hardened elfldr | Controlled Payload Manager |
|
||||
|---|---|---|
|
||||
| How is recovery started? | UNPROVEN | UNPROVEN |
|
||||
| Which exact component executes recovery? | UNPROVEN | UNPROVEN |
|
||||
| Is that executor outside the component being replaced? | UNPROVEN | UNPROVEN |
|
||||
| Does recovery work when elfldr does not start? | UNPROVEN | UNPROVEN |
|
||||
| Does recovery work when Payload Manager does not start? | UNPROVEN | UNPROVEN |
|
||||
| Does recovery work without autoload? | UNPROVEN | UNPROVEN |
|
||||
| Does recovery work without the replaced listener? | UNPROVEN | UNPROVEN |
|
||||
| Is a second independent recovery path proven? | UNPROVEN | UNPROVEN |
|
||||
|
||||
A generic console recovery mode is not counted. No public evidence in this
|
||||
repository proves that it restores custom project files.
|
||||
|
||||
If rollback depends on the component being replaced, the result is:
|
||||
|
||||
**CATASTROPHIC BLOCKER.**
|
||||
|
||||
## Rollback transition
|
||||
|
||||
Rollback is not an automatic exception path. It requires:
|
||||
|
||||
```text
|
||||
POST_SWITCH_VERIFY failure
|
||||
-> ROLLBACK_REQUIRED
|
||||
-> separate human ROLLBACK_AUTHORIZED
|
||||
-> ROLLBACK_IN_PROGRESS
|
||||
-> ROLLBACK_VERIFIED
|
||||
```
|
||||
|
||||
The rollback action may use only the already reopened and verified backup and
|
||||
the fixed target mapping. It may not autoload, start or retry either component.
|
||||
After the switch, path, mount, object ID, type, size, SHA-256, ownership, mode
|
||||
and relevant metadata are re-established before any later decision.
|
||||
|
||||
An interrupted rollback is acceptable only if a proven atomic primitive leaves
|
||||
exactly one complete live identity and preserves the verified backup. That
|
||||
primitive is not proven on PS5. A wrong post-rollback hash is
|
||||
`CATASTROPHIC/BLOCKED`; there is no retry.
|
||||
|
||||
## Component isolation
|
||||
|
||||
The hardened elfldr and controlled Payload Manager have separate live
|
||||
pre-images, backups, candidates, target mappings, recovery dependencies,
|
||||
process/service/listener states, autoload evidence, approvals, staging,
|
||||
switches, post-switch checks, executions, acceptances and rollbacks.
|
||||
|
||||
There is no shared approval and no combined transaction. A second component
|
||||
cannot begin until the first is separately accepted or fully rolled back.
|
||||
Which component comes first is `UNPROVEN`; order must follow demonstrated
|
||||
dependencies rather than convenience. The lifecycle probe is outside both
|
||||
installation and rollback models.
|
||||
|
||||
## Current blockers
|
||||
|
||||
- historical `READ_ONLY_PREFLIGHT_BLOCKED`;
|
||||
- current live identities and firmware behavior are unproven;
|
||||
- exact Payload Manager backup is absent as proven evidence;
|
||||
- filesystem atomicity, exchange, file durability and directory durability are
|
||||
unproven;
|
||||
- process, supervisor, listener, autoload and retry topology is unproven;
|
||||
- no independent recovery executor or second recovery path is proven;
|
||||
- no component order is proven;
|
||||
- every device authorization remains false.
|
||||
|
||||
No blocker is lifted by this design, manifest, host simulator or test result.
|
||||
@@ -0,0 +1,133 @@
|
||||
# Phase 0.9B bounded observer design
|
||||
|
||||
Status: **BLOCKED — OFFLINE AUDIT ONLY**.
|
||||
|
||||
No observer source, PS5 target, ELF, installation package, lifecycle package or
|
||||
execution package was created. No PS5 connection, scan, transfer or execution
|
||||
occurred. This document describes the rejected design boundary and the exact
|
||||
evidence needed before implementation may start.
|
||||
|
||||
## Canonical boundary
|
||||
|
||||
- Historical Phase 0.8 remains `READ_ONLY_PREFLIGHT_BLOCKED`.
|
||||
- Phase 0.9A remains `DESIGN_ONLY`.
|
||||
- Firmware 9.60 runtime behavior remains `UNPROVEN`.
|
||||
- Stock sizes and hashes remain `reference_only`.
|
||||
- The byte-exact on-device Payload Manager backup remains a `HARD_BLOCKER`.
|
||||
- Every authorization field remains `false`; automatic retry remains `false`.
|
||||
- SHA-256
|
||||
`4be1c17b4964f2b68c39b5145bc4af4619c32512d60269ecf5c39728b390fa63`
|
||||
remains permanently denied and execution-ineligible.
|
||||
|
||||
## Source identities
|
||||
|
||||
| Source | Commit | Tree |
|
||||
|---|---|---|
|
||||
| hardened elfldr | `197623058f509eddde18868dafcb92fdcac66464` | clean |
|
||||
| controlled Payload Manager | `e23d94ff91233aa770e2342800c1467875bdef44` | clean |
|
||||
| public elfldr v0.23 base | `699e8bcff03e91e8d6ca6eba281af25c5a58d8c2` | clean |
|
||||
| public Payload Manager v0.3.1 base | `cfbc70f30f419b09bf2b52283f7409e2d3117ee1` | clean |
|
||||
| PS5 Payload SDK v0.41 | `d2e2e585740362976a39fdd5ccf390f199a7bc37` | clean |
|
||||
| lifecycle-probe source | `fe08300339a13f899fb78ea404ada381a5cba87c` | byte identity checked |
|
||||
|
||||
The public bases establish provenance and the pre-hardening behavior. The
|
||||
hardened source commits establish the only controlled route considered here.
|
||||
No external source was contacted during this audit.
|
||||
|
||||
## Mandatory gates
|
||||
|
||||
| Gate | Required | Evidence | Result |
|
||||
|---|---|---|---|
|
||||
| kernelwrite-free startup | complete reachable startup path excludes kernel/process patch writes | SDK `crt/crt.c:48-80,193-220`, `crt/patch.c:25-101`, `crt/Makefile:19-26` | **FAIL** for normal CRT |
|
||||
| custom entry ABI | entry register, BSS, stack, return, exit and cleanup are all proven | elfldr `elfldr.c:273-415`; prior Phase-0.5 audit | **UNPROVEN** |
|
||||
| non-persistent output | payload bytes return over the hash-bound route without a device file, listener or global-state mutation | elfldr `socksrv.c:129-145,361-365`, `elfldr.c:499-520`; manager `verified_launcher.c:119-185`, `ps5_launcher.c:18-70` | **FAIL** |
|
||||
| bounded exit | successful and failing observer paths terminate without relying on an unproven ABI | SDK `crt/crt.c:150-220`; hardened loader watchdog | **UNPROVEN** |
|
||||
|
||||
Both implementation gates fail independently. The build gate therefore stops
|
||||
before observer source or target creation.
|
||||
|
||||
## Capability matrix
|
||||
|
||||
“Source present” does not mean firmware-9.60 behavior is proven. “Implement”
|
||||
is `no` for every row because startup/exit and output fail first.
|
||||
|
||||
| Needed fact | Available local API | Source | Evidence | Implement |
|
||||
|---|---|---|---|---|
|
||||
| firmware source 1 | `kernel_get_fw_version()` reads `sdk_ps5_ver` | SDK `crt/kernel.c:148-171` | source present; runtime unproven | no |
|
||||
| firmware source 2 | none established | — | unproven | no |
|
||||
| file metadata | `open(O_RDONLY\|O_NOFOLLOW\|O_CLOEXEC)`, `fstat`, `lstat`, `close` | manager `verified_launcher.c:76-115,174-184` | source/host evidence only | no |
|
||||
| object identity | pre/post `st_dev`, `st_ino`, `st_size` | manager `verified_launcher.c:26-29,87-101` | source/host evidence only | no |
|
||||
| SHA-256 | bounded descriptor read plus local SHA-256 | manager `verified_launcher.c:31-55`, `src/sha256.c` | source/host evidence only | no |
|
||||
| mount information | `getmntinfo()` / `getfsstat()` sample | SDK `samples/mntinfo/main.c`, `libc/getmntinfo.c` | sample present; runtime unproven | no |
|
||||
| processes/services | `sysctl(KERN_PROC)` sample; no complete service map | SDK `samples/ps/main.c` | partial and runtime unproven | no |
|
||||
| listeners | none established | — | unproven | no |
|
||||
| autoload configuration | stock file readers and mutating HTTP handlers | manager `config.c`, `autoload.c`, `http_server.c` | unsafe or unproven | no |
|
||||
| output channel | controlled route suppresses payload stdio and manager has no receive operation | elfldr `socksrv.c`, manager `ps5_launcher.c` | proven absent on controlled route | no |
|
||||
| monotonic deadline | `clock_gettime(CLOCK_MONOTONIC)` in loader watchdog | elfldr `ps5_controlled.c:26-59` | source/host evidence only | no |
|
||||
| process exit | normal CRT terminate path or custom return | SDK `crt/crt.c:150-220`, elfldr `elfldr.c:380-415` | observer ABI unproven | no |
|
||||
|
||||
Unknown capabilities remain unknown. There is no FreeBSD, PS4 or other
|
||||
firmware fallback.
|
||||
|
||||
## Rejected runtime designs
|
||||
|
||||
### Normal SDK CRT
|
||||
|
||||
The installed compiler wrapper adds `crt1.o` unless `-nostartfiles` is used.
|
||||
That object transitively contains `patch.o`. `_start()` calls
|
||||
`payload_init()`, which calls `__patch_init()` before `main`.
|
||||
`__patch_init()` changes credential capabilities/attributes and syscall
|
||||
permission bounds. This violates the Phase-0.9B kernelwrite-free requirement.
|
||||
|
||||
### Freestanding custom `_start`
|
||||
|
||||
The loader places its `payload_args_t *` in `RDI`, stores the old instruction
|
||||
pointer at `RSP-8`, and enters the ELF. Those operations show how control is
|
||||
transferred; they do not prove that a bare `ret`, a direct process-exit import,
|
||||
or another custom termination path performs every required cleanup safely.
|
||||
The prior minimal-startup gate remains blocked. It was not bypassed.
|
||||
|
||||
### Controlled stdout/stderr
|
||||
|
||||
The controlled route passes `-1` as `stdio`. The elfldr duplicates the request
|
||||
socket into standard descriptors only when `stdio > 0`. The manager transport
|
||||
exposes connect, send and close callbacks but no receive callback. The fixed
|
||||
`Controlled payload exited` response carries no observer data. The legacy
|
||||
stdio route is not the hash-bound controlled route and is inadmissible.
|
||||
|
||||
### Notifications, klog and manager HTTP
|
||||
|
||||
A system notification is not a complete deterministic machine-readable return
|
||||
channel. Klog is not proven to be a bounded host-return channel. The Payload
|
||||
Manager HTTP service is a persistent listener, and ordinary routes change
|
||||
process-global state; `/autoload_status` also changes autoload state. None is
|
||||
admissible.
|
||||
|
||||
## Intended observer shape if gates are later proven
|
||||
|
||||
This is a non-implemented contract:
|
||||
|
||||
1. enter once through a source-bound, kernelwrite-free ABI;
|
||||
2. emit a fixed offline-bound artifact identity;
|
||||
3. initialize bounded in-memory results;
|
||||
4. execute each explicitly authorized read at most once;
|
||||
5. emit raw value or explicit error;
|
||||
6. emit a final status;
|
||||
7. terminate through a proven exit/cleanup path.
|
||||
|
||||
It would have no event loop, server, thread, callback, retry, sleep, process
|
||||
signal, subprocess, module load, file mutation, lifecycle action, graphics,
|
||||
SDL, RetroArch, GNM or VideoOut behavior.
|
||||
|
||||
## Decision
|
||||
|
||||
**BLOCKED — OBSERVER STARTUP OR EXIT ABI UNPROVEN; NO PROVEN
|
||||
NON-PERSISTENT OUTPUT CHANNEL.**
|
||||
|
||||
The minimum missing evidence is:
|
||||
|
||||
1. a commit-bound, kernelwrite-free entry and termination contract that covers
|
||||
BSS, stack, return/exit, crash paths and loader cleanup; and
|
||||
2. a commit-bound controlled response route that carries bounded observer
|
||||
bytes without a device file, new listener, persistent state or Payload
|
||||
Manager global-state mutation.
|
||||
@@ -0,0 +1,108 @@
|
||||
# Phase 0.9B observer limitations
|
||||
|
||||
Status: **BLOCKED**.
|
||||
|
||||
## What was established
|
||||
|
||||
- Exact local commits and relevant source-file identities were recorded.
|
||||
- Normal SDK v0.41 startup is **UNSAFE** for this phase because
|
||||
`__patch_init()` is reachable before `main` and performs prohibited writes.
|
||||
- A `-nostartfiles` link can omit that CRT, but safe observer entry,
|
||||
return/exit, crash cleanup and resource cleanup remain **UNPROVEN**.
|
||||
- The hardened controlled route is hash-bound but passes `stdio=-1`.
|
||||
- The controlled manager transport sends and closes; it has no receive
|
||||
callback for observer data.
|
||||
- The fixed loader exit response cannot carry the requested observation set.
|
||||
- Stock Payload Manager HTTP routes and log state are not an admissible
|
||||
replacement output collector.
|
||||
|
||||
## What was not built
|
||||
|
||||
- no observer source;
|
||||
- no target declaration;
|
||||
- no PS5 object or ELF;
|
||||
- no linker map;
|
||||
- no disassembly or reachable callgraph;
|
||||
- no artifact import, relocation, string or open-flag report;
|
||||
- no double clean target build;
|
||||
- no artifact manifest;
|
||||
- no install, lifecycle or execution package; and
|
||||
- no transfer or execution instructions.
|
||||
|
||||
These are intentional consequences of the pre-build hard gates, not omitted
|
||||
positive evidence.
|
||||
|
||||
## Unsupported or unproven observations
|
||||
|
||||
All target observations remain unimplemented. In particular:
|
||||
|
||||
- only one possible firmware source exists in the reviewed SDK source;
|
||||
- no independent second firmware source is established;
|
||||
- firmware 9.60 runtime behavior of the first source is untested;
|
||||
- mount layouts and semantics are not runtime-proven;
|
||||
- a process sample exists, but complete service mapping does not;
|
||||
- no exact listener snapshot and owner-mapping API was established;
|
||||
- live and backup paths are absent;
|
||||
- live and backup objects, sizes, identities and hashes are absent;
|
||||
- authoritative autoload/startup/retry source completeness is absent;
|
||||
- stable no-follow behavior on the target filesystem is unproven;
|
||||
- atime, audit, cache, counter and scheduler effects remain possible; and
|
||||
- output and exit remain blocked.
|
||||
|
||||
## Remaining anti-brick blockers
|
||||
|
||||
1. two current firmware sources;
|
||||
2. literal live paths;
|
||||
3. live mount and object identities;
|
||||
4. live sizes and SHA-256;
|
||||
5. mount and filesystem properties;
|
||||
6. process and service inventory;
|
||||
7. listener inventory and ownership;
|
||||
8. complete autoload/startup/retry state;
|
||||
9. existing separate rollback objects;
|
||||
10. byte-exact on-device Payload Manager backup (`HARD_BLOCKER`);
|
||||
11. independent recovery;
|
||||
12. power-loss-safe switch semantics;
|
||||
13. component order;
|
||||
14. observer startup/exit ABI; and
|
||||
15. non-persistent output.
|
||||
|
||||
No offline test may promote a stock hash, clear a device blocker, prove
|
||||
firmware behavior, or authorize a later action.
|
||||
|
||||
## Risk of a later one-shot run
|
||||
|
||||
Even if a future artifact were approved, unresolved risks would include:
|
||||
|
||||
- the existing loader’s ptrace, credential, mapping, breakpoint and
|
||||
socket-overlap operations before payload entry;
|
||||
- loader cleanup failure or a child that does not terminate;
|
||||
- crash or return behavior different from the source-reviewed expectation;
|
||||
- kernel, audit, cache, atime, scheduler and counter effects from reads;
|
||||
- stale or conflicting path plans;
|
||||
- concurrent object replacement during observation;
|
||||
- incomplete process/service/listener snapshots;
|
||||
- output truncation or loss;
|
||||
- a false inference from an unsupported result; and
|
||||
- operator confusion between observation evidence and installation approval.
|
||||
|
||||
One observation could not prove atomic switch semantics, write durability,
|
||||
power-loss behavior, recovery independence under actual failure, component
|
||||
order, future runtime stability, graphics safety, RetroArch compatibility or
|
||||
the absence of every platform side effect.
|
||||
|
||||
## Minimum evidence to resume engineering
|
||||
|
||||
Resume target engineering only after both items are available in local,
|
||||
commit-bound public source and accepted by a new review:
|
||||
|
||||
1. a kernelwrite-free startup and termination ABI covering BSS, stack,
|
||||
return/exit, crash behavior and loader cleanup; and
|
||||
2. a one-shot response channel that returns bounded observer bytes over the
|
||||
controlled route without a device file, new listener, persistent state,
|
||||
global Payload Manager mutation or post-exit activity.
|
||||
|
||||
Until then the exact decision is:
|
||||
|
||||
**BLOCKED — OBSERVER STARTUP OR EXIT ABI UNPROVEN; NO PROVEN
|
||||
NON-PERSISTENT OUTPUT CHANNEL.**
|
||||
@@ -0,0 +1,114 @@
|
||||
# Phase 0.9B observer result contract
|
||||
|
||||
Status: **HOST CONTRACT ONLY — NO TARGET IMPLEMENTATION**.
|
||||
|
||||
This contract defines how a future observer result would be represented after
|
||||
startup, exit and output gates are separately proven. It does not establish
|
||||
those capabilities and does not authorize transfer or execution.
|
||||
|
||||
## Framing
|
||||
|
||||
The preferred representation is bounded JSON Lines because every entry can be
|
||||
validated independently and a final entry can mark truncation or failure.
|
||||
Whether JSON Lines is feasible without unacceptable target dependencies
|
||||
remains unproven.
|
||||
|
||||
Every future entry must contain:
|
||||
|
||||
```json
|
||||
{
|
||||
"schema_version": 1,
|
||||
"observer_build_id": "offline-bound identifier",
|
||||
"observation_id": "unique bounded identifier",
|
||||
"category": "firmware",
|
||||
"source": "exact source identity",
|
||||
"raw_value": null,
|
||||
"raw_error": "UNSUPPORTED_OR_UNPROVEN",
|
||||
"normalized_value": null,
|
||||
"confidence": "UNPROVEN",
|
||||
"persistent_mutation_performed": false,
|
||||
"retry_performed": false,
|
||||
"monotonic_offset_ms": null,
|
||||
"truncation": false,
|
||||
"fail_closed": true
|
||||
}
|
||||
```
|
||||
|
||||
Allowed confidence values are `OBSERVED`, `PARTIAL`, `UNSUPPORTED`,
|
||||
`UNPROVEN`, `CONFLICT`, and `ERROR`.
|
||||
|
||||
`raw_value` and `raw_error` are mutually exclusive. A normalized value may be
|
||||
present only when it cannot hide a raw discrepancy. The raw values from two
|
||||
firmware sources are always returned separately.
|
||||
|
||||
## Fixed limits
|
||||
|
||||
No target constants are selected while the build is blocked. A future
|
||||
observation plan must bind all of these to finite positive values:
|
||||
|
||||
- maximum complete output bytes;
|
||||
- maximum entry bytes;
|
||||
- maximum path bytes;
|
||||
- maximum observations;
|
||||
- maximum objects;
|
||||
- maximum processes;
|
||||
- maximum services;
|
||||
- maximum listeners;
|
||||
- maximum errors; and
|
||||
- maximum monotonic runtime.
|
||||
|
||||
An exceeded limit produces one final bounded error when the output channel
|
||||
still works, sets `truncation=true` and `fail_closed=true`, performs no retry,
|
||||
and exits through the proven termination path.
|
||||
|
||||
## Per-category rules
|
||||
|
||||
| Category | Success evidence | Required failure form |
|
||||
|---|---|---|
|
||||
| observer identity | offline manifest identity repeated unchanged | `UNPROVEN` if runtime self-binding is not available |
|
||||
| firmware | two separately sourced raw values and exact comparison | `UNPROVEN` for a missing source; `CONFLICT` for mismatch |
|
||||
| mount | only fields with exact ABI evidence | `UNSUPPORTED` for unproven layouts or semantics |
|
||||
| object metadata | literal authorized path, no-follow open, stable pre/post same-object metadata | explicit symlink, path, object-ID or size error |
|
||||
| SHA-256 | exact planned size, complete bounded read, stable post-read object | short read, read error, drift or hash mismatch |
|
||||
| rollback object | same rules plus a distinct available identity from live | backup missing or same-object conflict |
|
||||
| processes/services | bounded read-only snapshot with exact structures | `UNSUPPORTED` when service mapping is incomplete |
|
||||
| listeners | bounded read-only snapshot with exact owner mapping | `UNSUPPORTED` when API or ownership is unproven |
|
||||
| autoload | minimal fields from complete authoritative sources | missing source, parse error or incomplete-source `UNPROVEN` |
|
||||
|
||||
No file content unrelated to the minimal autoload/retry decision may be
|
||||
returned. Secrets and full configuration contents are excluded.
|
||||
|
||||
## Filesystem contract
|
||||
|
||||
A future target may read an object only when its compiled and audited path is:
|
||||
|
||||
```text
|
||||
authorized literal path
|
||||
-> open read-only + no-follow + close-on-exec
|
||||
-> fstat same descriptor
|
||||
-> validate regular object and planned size
|
||||
-> one bounded read stream
|
||||
-> fstat same descriptor
|
||||
-> compare identity and size
|
||||
-> no-follow path metadata comparison
|
||||
-> close
|
||||
```
|
||||
|
||||
If no-follow is not source- and artifact-proven, the result is
|
||||
`PATH_SYMLINK_SAFETY_UNPROVEN` and the object is not hashed. No path is
|
||||
hardcoded by Phase 0.9B. The default observation plan contains no paths.
|
||||
|
||||
Reads may affect atime, caches, audit records, counters or scheduling. Those
|
||||
volatile or unknown effects must be reported; this contract does not call them
|
||||
absent and does not authorize persistent writes.
|
||||
|
||||
## Terminal behavior
|
||||
|
||||
Every future path, including output failure, deadline, unsupported query,
|
||||
parse error, read error, limit exhaustion and conflict, must reach the proven
|
||||
termination path. No retry, sleep-and-retry, callback, background thread,
|
||||
listener, process signal, service action or subprocess may occur.
|
||||
|
||||
The host-only model in `tests/phase09b_observer_model.py` exercises these
|
||||
contract decisions without filesystem or network I/O. It is a guardrail, not
|
||||
PS5 code or hardware evidence.
|
||||
@@ -0,0 +1,152 @@
|
||||
# Phase 0.9B observer static audit
|
||||
|
||||
Status: **NOT PERFORMED — BLOCKED BEFORE SOURCE AND BUILD**.
|
||||
|
||||
This is a truthful negative audit record. No observer artifact exists, so no
|
||||
ELF property can be reported as passing. Absence of imports or strings is not
|
||||
used as a substitute for a reachable-code proof.
|
||||
|
||||
## Build decision
|
||||
|
||||
The source audit stopped the target build because:
|
||||
|
||||
- normal SDK startup reaches `__patch_init()` and performs prohibited writes;
|
||||
- a freestanding observer return/exit and cleanup contract remains unproven;
|
||||
- the hash-bound controlled route suppresses payload stdout/stderr; and
|
||||
- the controlled manager sends the ELF and closes without receiving observer
|
||||
output.
|
||||
|
||||
No observer source path or CMake target was added. The existing
|
||||
`CHIMERA_GFX_BUILD_PS5_MINIMAL_STARTUP` configure-time blocker remains intact.
|
||||
|
||||
## Required artifact audit status
|
||||
|
||||
| Audit | Status | Reason |
|
||||
|---|---|---|
|
||||
| SHA-256 and size | `NOT_APPLICABLE_NO_ARTIFACT` | no binary |
|
||||
| source commit binding | `NOT_APPLICABLE_NO_ARTIFACT` | no target source |
|
||||
| toolchain identity | `PARTIAL_OFFLINE_REFERENCE_ONLY` | SDK v0.41 pinned; no observer link |
|
||||
| double clean build | `NOT_PERFORMED_BLOCKED_BEFORE_BUILD` | hard gates failed |
|
||||
| ELF header | `NOT_APPLICABLE_NO_ARTIFACT` | no ELF |
|
||||
| program headers | `NOT_APPLICABLE_NO_ARTIFACT` | no ELF |
|
||||
| section headers | `NOT_APPLICABLE_NO_ARTIFACT` | no ELF |
|
||||
| dynamic dependencies | `NOT_APPLICABLE_NO_ARTIFACT` | no ELF |
|
||||
| imported/undefined symbols | `NOT_APPLICABLE_NO_ARTIFACT` | no ELF |
|
||||
| exported symbols | `NOT_APPLICABLE_NO_ARTIFACT` | no ELF |
|
||||
| relocations | `NOT_APPLICABLE_NO_ARTIFACT` | no ELF |
|
||||
| linker map | `NOT_CREATED` | no link |
|
||||
| reachable callgraph | `NOT_CREATED` | no code |
|
||||
| disassembly | `NOT_CREATED` | no code |
|
||||
| strings | `NOT_APPLICABLE_NO_ARTIFACT` | no ELF |
|
||||
| denied capabilities | `NOT_APPLICABLE_NO_ARTIFACT` | no ELF |
|
||||
| filesystem open flags | `NOT_APPLICABLE_NO_ARTIFACT` | no ELF |
|
||||
| network functions | `NOT_APPLICABLE_NO_ARTIFACT` | no ELF |
|
||||
| threads/loops | `NOT_APPLICABLE_NO_ARTIFACT` | no ELF |
|
||||
| kernelwrites | `NOT_APPLICABLE_NO_ARTIFACT` | no ELF |
|
||||
|
||||
The validator fails if a Phase-0.9B ELF, map, observer target, observer source
|
||||
directory, installation package or lifecycle package appears while the
|
||||
manifest remains blocked.
|
||||
|
||||
## Transitive startup audit
|
||||
|
||||
### Normal SDK link
|
||||
|
||||
The SDK compiler wrapper at commit
|
||||
`d2e2e585740362976a39fdd5ccf390f199a7bc37` selects
|
||||
`target/lib/crt1.o` unless `-nostartfiles` is present. The CRT Makefile links:
|
||||
|
||||
`crt.o`, `syscall.o`, `klog.o`, `nid.o`, `kernel.o`, `rtld.o`, `rtld_so.o`,
|
||||
`rtld_sprx.o`, `rtld_payload.o`, `rtld_dlfcn.o`, `mdbg.o`, and `patch.o`.
|
||||
|
||||
The installed `crt1.o` is 112256 bytes with SHA-256
|
||||
`0e4c1e5e38f22026580e856238a53e75d9e112f99a34bfe5495a3a0ffac15238`.
|
||||
It was inspected as source-bound evidence and was not linked into a new
|
||||
artifact.
|
||||
|
||||
Reachable sequence from normal `_start`:
|
||||
|
||||
```text
|
||||
_start
|
||||
-> clear BSS
|
||||
-> payload_init
|
||||
-> __crt_syscall_init
|
||||
-> __kernel_init
|
||||
-> __klog_init
|
||||
-> write __isthreaded
|
||||
-> __patch_init
|
||||
-> patch_kernel_ucred
|
||||
-> kernel_set_ucred_caps
|
||||
-> kernel_set_ucred_attrs
|
||||
-> patch_syscall_permissions
|
||||
-> kernel_copyin syscall low bound
|
||||
-> kernel_copyin syscall high bound
|
||||
-> __rtld_init
|
||||
-> payload_run
|
||||
-> constructors
|
||||
-> main
|
||||
-> destructors
|
||||
-> payload_terminate
|
||||
```
|
||||
|
||||
Result: **UNSAFE** for the Phase-0.9B kernelwrite-free contract.
|
||||
|
||||
### Custom entry
|
||||
|
||||
`-nostartfiles -nodefaultlibs` can remove `crt1.o` and default libraries.
|
||||
However, compile/link capability alone does not establish safe behavior.
|
||||
elfldr `elfldr_prepare_exec()` shows `RDI=args`, `RIP=entry`, and the old RIP
|
||||
stored on the adjusted stack. No source establishes the complete observer
|
||||
post-return cleanup, process-exit, crash, or resource-lifetime contract for a
|
||||
new bare entry. Result: **UNPROVEN**.
|
||||
|
||||
## Output audit
|
||||
|
||||
Controlled elfldr call path:
|
||||
|
||||
```text
|
||||
controlled manager
|
||||
-> connect_loopback
|
||||
-> send_all(control header)
|
||||
-> send_all(ELF bytes)
|
||||
-> close_socket
|
||||
|
||||
elfldr controlled route
|
||||
-> payload_read_controlled
|
||||
-> payload_spawn
|
||||
-> elfldr_spawn(stdio = -1)
|
||||
-> no stdio duplication
|
||||
-> watchdog/reap
|
||||
-> fixed "Controlled payload exited" loader response
|
||||
```
|
||||
|
||||
There is no manager receive callback and no payload-provided response body.
|
||||
Result: **NO PROVEN NON-PERSISTENT OUTPUT CHANNEL**.
|
||||
|
||||
## Existing loader effects versus observer effects
|
||||
|
||||
The hardened loader performs ptrace, credential, mapping, socket-overlap,
|
||||
breakpoint, protection and cleanup operations before and around entry. Those
|
||||
are existing loader effects, not code introduced by an observer artifact.
|
||||
They are still relevant to the risk of a later execution and do not make the
|
||||
observer’s own startup kernelwrite-free.
|
||||
|
||||
Because no observer was built:
|
||||
|
||||
- observer imports: none to report;
|
||||
- observer filesystem reads: none implemented;
|
||||
- observer network functions: none implemented;
|
||||
- observer threads or loops: none implemented;
|
||||
- observer prohibited capabilities: none implemented; and
|
||||
- absence of an artifact is not hardware-safety proof.
|
||||
|
||||
## Reproducibility
|
||||
|
||||
Build 1 hash: `null`.
|
||||
|
||||
Build 2 hash: `null`.
|
||||
|
||||
Final artifact hash/size: `null` / `null`.
|
||||
|
||||
Result: `NOT_PERFORMED_BLOCKED_BEFORE_BUILD`, not
|
||||
`REPRODUCIBILITY_PASSED`.
|
||||
@@ -0,0 +1,103 @@
|
||||
# Phase 0.9C capability closure
|
||||
|
||||
Status: **NO TARGET CAPABILITY CLOSED**.
|
||||
|
||||
“Host evidence” below means a deterministic model or source validator. It is
|
||||
not PS5 evidence. `implementation allowed` and `execution allowed` are false
|
||||
for every capability because the startup/exit, output, firmware-source, and
|
||||
side-effect gates fail before target implementation.
|
||||
|
||||
## Closure matrix
|
||||
|
||||
| Capability | Source evidence | Host evidence | Target evidence | Implement allowed | Execute allowed | Remaining blocker |
|
||||
|---|---|---|---|---:|---:|---|
|
||||
| runtime self-identity | future protocol binds observer version and artifact SHA-256 | framing validates both | absent | false | false | no target artifact or runtime self-binding |
|
||||
| firmware source 1 | SDK `kernel_get_fw_version`, `crt/kernel.c:148-170` | protocol binds raw value | absent | false | false | depends on prohibited runtime and is not independent system identity |
|
||||
| firmware source 2 | export-stub name only, no accepted signature/semantics | missing/conflict tests fail closed | absent | false | false | independent accepted source absent |
|
||||
| mount query | SDK `samples/mntinfo` and libc wrapper | unsupported can be represented | absent | false | false | ABI, completeness, runtime behavior and effects unproven |
|
||||
| metadata | controlled manager no-follow pattern | result framing can represent error | absent | false | false | target metadata/no-follow semantics and effects unproven |
|
||||
| object ID | manager compares `st_dev/st_ino` | completeness rules modeled | absent | false | false | stable target identity and race contract unproven |
|
||||
| size | manager compares exact `st_size` | checked result length modeled | absent | false | false | current object and stable-read evidence absent |
|
||||
| SHA-256 | bounded same-FD manager implementation | checksum corruption is rejected | absent | false | false | target read effects, current paths and stable object absent |
|
||||
| processes | SDK `samples/ps` partial snapshot | unsupported result modeled | absent | false | false | complete ABI, bounds and semantics absent |
|
||||
| services | no complete source/API mapping | unsupported result modeled | absent | false | false | service inventory and ownership semantics absent |
|
||||
| listeners | no accepted snapshot/owner API | unsupported result modeled | absent | false | false | listener API, ownership and side effects absent |
|
||||
| autoload/startup/retry | stock manager readers/HTTP are incomplete or side-effecting | missing source remains blocked | absent | false | false | complete authoritative sources and safe collector absent |
|
||||
| rollback objects | Phase 0.8R/0.9A evidence contract only | no false promotion in validators | absent | false | false | current exact backups absent; manager backup is hard blocker |
|
||||
| monotonic time | hardened loader uses `CLOCK_MONOTONIC` | deadline expiry is rejected | absent in observer ABI | false | false | loader exposes no clock callback; freestanding callable ABI absent |
|
||||
| startup | SDK and hardened loader callgraphs | startup classifications validated | absent | false | false | normal CRT writes; freestanding dependency closure incomplete |
|
||||
| output | current route proven send-only; D1 host contract defined | 4096-byte framing and negative tests | absent | false | false | no caller-owned target buffer/copy-out/manager delivery |
|
||||
| normal exit | loader has wait/reap; status discarded | no safe exit terminal modeled | absent | false | false | return/exit semantics and teardown unproven |
|
||||
| error exit | CRT error/longjmp/trap and loader reap reviewed | observer error cannot equal empty success | absent | false | false | partial unwind, status and cleanup unproven |
|
||||
| timeout | loader SIGTERM/SIGKILL watchdog reviewed | timeout record is rejected | absent | false | false | kill/timeout is not an admissible safe exit |
|
||||
| cleanup | pre-detach cleanup state exists; post-detach relies on process lifetime | failed/incomplete cleanup rejected | absent | false | false | mappings, FDs, buffers, loader and manager cleanup not jointly proven |
|
||||
| recovery independence | Phase 0.9A contract | blocker preserved | absent | false | false | recovery executor and exact rollback objects unproven |
|
||||
|
||||
## Firmware-source closure
|
||||
|
||||
Current source 1 reads a process-parameter field associated with
|
||||
`libSceLibcInternal`; its own comment says it is chosen because some payloads
|
||||
modify the kernel-reported value. That makes it useful source evidence, but
|
||||
not an independent second current device identity.
|
||||
|
||||
The SDK stubs contain
|
||||
`sceKernelGetProsperoSystemSwVersion`, but a stub exports only a name/NID
|
||||
surface. The repository has no reviewed public prototype, result layout,
|
||||
return semantics, side-effect contract, or firmware-9.60 observation. It is
|
||||
not callable evidence and is not source 2.
|
||||
|
||||
A future source 2 must:
|
||||
|
||||
1. be official/reproducible public platform evidence or a separately reviewed
|
||||
locally obtained runtime value;
|
||||
2. have exact function/data ABI and side-effect evidence;
|
||||
3. identify the current system, not the observer's compiled SDK requirement;
|
||||
4. produce an exact raw value under the same deadline;
|
||||
5. be independent of source 1's data origin;
|
||||
6. bind source identity, raw result, nonce, request ID, observer artifact hash
|
||||
and deadline into the result record; and
|
||||
7. fail closed if absent, ambiguous, stale, or conflicting.
|
||||
|
||||
The host protocol returns
|
||||
`BLOCKED_FIRMWARE_SOURCE_2_ABSENT` for absence and
|
||||
`BLOCKED_FIRMWARE_CONFLICT` for disagreement. It never normalizes a conflict
|
||||
away or prefers one source.
|
||||
|
||||
## Cross-gate closure
|
||||
|
||||
The following dependencies form one conjunctive gate:
|
||||
|
||||
```text
|
||||
kernelwrite-free usable startup
|
||||
+ proven stack/relocation/BSS/TLS closure
|
||||
+ callable bounded observation primitives
|
||||
+ two bound firmware sources
|
||||
+ bounded transient output
|
||||
+ normal/error/deadline exit without kill
|
||||
+ complete cleanup and unambiguous status
|
||||
+ bounded accepted observation effects
|
||||
= target implementation may be reconsidered
|
||||
```
|
||||
|
||||
Every term is required. A passing host protocol cannot compensate for a
|
||||
missing exit ABI. A proven read algorithm cannot compensate for an absent
|
||||
output channel. Two firmware strings cannot compensate for an unreviewed ABI
|
||||
or stale execution binding.
|
||||
|
||||
## Decision
|
||||
|
||||
Closed for host design:
|
||||
|
||||
- startup graph classifications are explicit;
|
||||
- the freestanding missing dependencies are explicit;
|
||||
- D1 framing is fixed at 4096 bytes and fails closed;
|
||||
- stale, duplicate, incomplete, corrupt, timed-out and conflicting records
|
||||
are rejected; and
|
||||
- every capability has an explicit blocker.
|
||||
|
||||
Not closed for target implementation:
|
||||
|
||||
- all 21 capabilities in the matrix.
|
||||
|
||||
The capability result contributes to
|
||||
`BLOCKED_MULTIPLE_FOUNDATIONAL_CONTRACTS`.
|
||||
@@ -0,0 +1,268 @@
|
||||
# Phase 0.9C output-channel feasibility
|
||||
|
||||
Status: **HOST CONTRACT ONLY — NO CURRENT OUTPUT CHANNEL**.
|
||||
|
||||
This document evaluates the four requested architectures in order. It defines
|
||||
a finite host protocol because D1 is conceptually coherent, but it does not
|
||||
claim that hardened elfldr, the controlled Payload Manager, or any target
|
||||
implements that protocol. No production runtime was changed.
|
||||
|
||||
## D1 — caller-owned bounded result buffer
|
||||
|
||||
### Current architecture
|
||||
|
||||
The current `payload_args_t.payloadout` is not a caller-owned observer result
|
||||
buffer:
|
||||
|
||||
1. hardened elfldr maps the argument page **inside the child process**
|
||||
(`elfldr.c:273-287`);
|
||||
2. `payloadout` is `args_mapping + 0x300`
|
||||
(`elfldr.c:349-367`);
|
||||
3. after detach, elfldr clears its tracked cleanup bitmap and does not read
|
||||
`payloadout` (`elfldr.c:538-545`);
|
||||
4. on process exit, the controlled waiter discards the `waitpid` status
|
||||
(`ps5_controlled.c:36-59`); and
|
||||
5. the controlled connection writes only fixed loader text
|
||||
(`socksrv.c:361-365`).
|
||||
|
||||
The current field is therefore child-owned mapped storage whose useful
|
||||
post-exit lifetime and consumption are absent. It cannot be relabelled as D1.
|
||||
|
||||
### Future concept
|
||||
|
||||
A D1 implementation could be reviewed only if a future loader revision:
|
||||
|
||||
- allocates exactly 4096 bytes under caller ownership;
|
||||
- zero-initializes that buffer;
|
||||
- makes one bounded view available for one execution;
|
||||
- retains ownership outside the observer process;
|
||||
- binds it to a 128-bit execution nonce and 128-bit request ID;
|
||||
- prevents concurrent or reused writers;
|
||||
- obtains a proven normal return/exit indication;
|
||||
- validates the observer body before accepting it;
|
||||
- records cleanup outcome after the observer can no longer write;
|
||||
- writes the final checksum and completion marker last;
|
||||
- reads it once and rejects duplicate consumption; and
|
||||
- destroys the transient object without filesystem, listener, log, or
|
||||
persistent shared-memory state.
|
||||
|
||||
That design requires a loader ABI and implementation change in a later phase.
|
||||
It also depends on the startup/exit contract that Phase 0.9C did not prove.
|
||||
Classification:
|
||||
`CONCEPT_FEASIBLE_REQUIRES_LOADER_CHANGE_AND_EXIT_PROOF`.
|
||||
|
||||
## D2 — existing request/response channel
|
||||
|
||||
The controlled manager's transport interface contains exactly:
|
||||
|
||||
```text
|
||||
connect_loopback
|
||||
send_all
|
||||
close_socket
|
||||
```
|
||||
|
||||
Source: controlled manager `include/verified_launcher.h:38-42` and
|
||||
`src/ps5_launcher.c:18-69`. `verified_launcher.c:153-183` sends the header and
|
||||
artifact bytes, then closes the socket. There is no receive callback, response
|
||||
buffer, length framing, result deadline, or result validation.
|
||||
|
||||
The elfldr side can write a fixed text line after the child is reaped, but the
|
||||
controlled manager has already closed and never reads it. The text carries no
|
||||
nonce, request ID, process status, capability data, checksum, truncation flag,
|
||||
or cleanup status. It also cannot distinguish a normal exit from a reaped
|
||||
crash because the waiter discards status.
|
||||
|
||||
Classification: `REJECTED_SEND_ONLY_NO_RESULT_RECEIVE`.
|
||||
|
||||
## D3 — loader-owned fixed status record
|
||||
|
||||
Hardened elfldr has transient local variables for child PID, watchdog return,
|
||||
and `waitpid` status, but no persistent or returned per-request status record.
|
||||
The current `wait_reaped` discards the status and the connection response is
|
||||
fixed.
|
||||
|
||||
A small loader-owned record would still require:
|
||||
|
||||
- per-request storage and nonce binding;
|
||||
- preservation of actual wait status;
|
||||
- an exact normal/error/crash mapping;
|
||||
- a proven way for the observer to supply bounded data;
|
||||
- a manager receive operation and response framing; and
|
||||
- lifecycle rules preventing stale reuse or a race between completion and
|
||||
cleanup.
|
||||
|
||||
Those are production loader/manager changes and were forbidden in this task.
|
||||
Classification:
|
||||
`UNPROVEN_REQUIRES_LOADER_STATE_AND_PROPAGATION_CHANGE`.
|
||||
|
||||
## D4 — process exit status
|
||||
|
||||
`waitpid` supplies an integer status to the loader, but
|
||||
`ps5_controlled.c:36-59` does not retain or return it. The manager receives no
|
||||
status. The same fixed text can follow a normal exit or a crash, and the
|
||||
watchdog result distinguishes only its own high-level completion/timeout path.
|
||||
|
||||
Even if later propagated, a conventional exit status has too little space for
|
||||
the required observations and needs an exact mapping for success, unsupported,
|
||||
observer error, crash, signal, timeout, and cleanup failure. None exists.
|
||||
|
||||
Classification: `REJECTED_WAIT_STATUS_DISCARDED_AND_AMBIGUOUS`.
|
||||
|
||||
## Rejected output mechanisms
|
||||
|
||||
The following remain inadmissible:
|
||||
|
||||
- target filesystem or target logs;
|
||||
- a new socket, listener, server, debug service, or callback;
|
||||
- notification, klog, stdout, stderr, crash dump, or audit log;
|
||||
- kernel buffer or persistent shared memory;
|
||||
- autoload or service state;
|
||||
- graphics, VideoOut, SDL, GNM, or RetroArch;
|
||||
- timing or another covert channel; and
|
||||
- the legacy stdio route.
|
||||
|
||||
The controlled route passes `stdio=-1` at `socksrv.c:139-145`. Stdio
|
||||
duplication occurs only for `stdio > 0` at `elfldr.c:499-520`.
|
||||
|
||||
## Host-only D1 protocol
|
||||
|
||||
The protocol model is `tests/phase09c_feasibility_model.py`. It performs no
|
||||
filesystem, network, compiler, or target operation.
|
||||
|
||||
### Ownership and completion
|
||||
|
||||
The conceptual write sequence is:
|
||||
|
||||
```text
|
||||
caller:
|
||||
allocate and zero exactly 4096 bytes
|
||||
bind nonce, request ID, exact artifact hash and deadline
|
||||
|
||||
observer:
|
||||
fill fixed fields and at most 3840 body bytes
|
||||
write explicit status and observed/unsupported bitmaps
|
||||
write body SHA-256
|
||||
return through the still-unproven safe ABI
|
||||
|
||||
caller after proven return and cleanup:
|
||||
validate request binding and body
|
||||
write cleanup status
|
||||
compute final result SHA-256
|
||||
write completion marker last
|
||||
|
||||
consumer:
|
||||
validate once
|
||||
reject stale, duplicate, incomplete, timed-out or inconsistent records
|
||||
```
|
||||
|
||||
The caller-finalization step is essential: an observer cannot truthfully
|
||||
attest loader cleanup that occurs only after it returns. The current loader has
|
||||
no such step.
|
||||
|
||||
### Fixed framing
|
||||
|
||||
All integers are unsigned big-endian. There are no pointers, offsets supplied
|
||||
by the observer, variable headers, dynamic growth, or nested lengths.
|
||||
|
||||
| Offset | Size | Field |
|
||||
|---:|---:|---|
|
||||
| 0 | 8 | magic `CHG09C01` |
|
||||
| 8 | 2 | protocol version `1` |
|
||||
| 10 | 2 | header size `256` |
|
||||
| 12 | 4 | maximum output size `4096` |
|
||||
| 16 | 4 | actual output size, inclusive of header |
|
||||
| 20 | 4 | observer version |
|
||||
| 24 | 4 | status |
|
||||
| 28 | 4 | flags; bit 0 means truncation |
|
||||
| 32 | 4 | caller-recorded cleanup status |
|
||||
| 36 | 4 | reserved zero |
|
||||
| 40 | 8 | requested capability bitmap |
|
||||
| 48 | 8 | observed capability bitmap |
|
||||
| 56 | 8 | unsupported capability bitmap |
|
||||
| 64 | 8 | monotonic deadline in nanoseconds |
|
||||
| 72 | 16 | execution nonce |
|
||||
| 88 | 16 | request ID |
|
||||
| 104 | 8 | firmware source 1, canonical NUL-padded ASCII |
|
||||
| 112 | 8 | firmware source 2, canonical NUL-padded ASCII |
|
||||
| 120 | 32 | exact future observer artifact SHA-256 |
|
||||
| 152 | 32 | SHA-256 of body bytes |
|
||||
| 184 | 32 | SHA-256 of header and body with this field and completion zero |
|
||||
| 216 | 8 | completion marker `COMPLETE`, written last |
|
||||
| 224 | 32 | reserved zero |
|
||||
| 256 | 0–3840 | bounded body |
|
||||
| actual–4096 | remainder | required zero |
|
||||
|
||||
`actual_output_size` must be in `[256, 4096]`; subtraction and addition are
|
||||
checked before any slice is accepted. The body size is exactly
|
||||
`actual_output_size - 256`. A body larger than 3840 bytes is rejected unless
|
||||
the model deliberately produces a truncated record, and every truncated
|
||||
record is blocked.
|
||||
|
||||
### Status and bitmap rules
|
||||
|
||||
- only explicit `SUCCESS` can yield a valid completed record;
|
||||
- observer error, timeout, firmware conflict, or any unknown status is
|
||||
blocked;
|
||||
- `observed & unsupported` must be zero;
|
||||
- `observed | unsupported` must exactly equal the requested bitmap;
|
||||
- unrequested bits are forbidden;
|
||||
- explicit unsupported bits preserve evidence but do not prove the
|
||||
corresponding capability;
|
||||
- an empty successful body is valid only when the requested bitmap is also
|
||||
fully accounted for;
|
||||
- an empty observer-error body is still failure, never empty success.
|
||||
|
||||
### Fail-closed validation
|
||||
|
||||
The consumer rejects:
|
||||
|
||||
- wrong magic, unknown protocol version, header size, or maximum;
|
||||
- invalid or overflowed actual size;
|
||||
- nonzero reserved or unused bytes;
|
||||
- missing completion marker;
|
||||
- stale nonce or request ID;
|
||||
- duplicate consumption;
|
||||
- observer version, deadline, artifact hash, or firmware binding mismatch;
|
||||
- absent second firmware source or conflicting firmware sources;
|
||||
- expired deadline;
|
||||
- body or final checksum failure;
|
||||
- unknown flags or truncation;
|
||||
- incomplete or failed cleanup;
|
||||
- observer failure;
|
||||
- incomplete, overlapping, or unrequested capability bitmaps.
|
||||
|
||||
The completion marker is not itself an integrity proof. It is accepted only
|
||||
after both checksums and every binding validate.
|
||||
|
||||
## Firmware binding
|
||||
|
||||
Source 1 is SDK `kernel_get_fw_version()` at `crt/kernel.c:148-170`. It reads
|
||||
the `sdk_ps5_ver` field from the `libSceLibcInternal` process parameter and is
|
||||
not independent device evidence. The SDK export stubs contain the symbol name
|
||||
`sceKernelGetProsperoSystemSwVersion` at
|
||||
`sce_stubs/libkernel_web.c:2358-2360`, but no reviewed public header,
|
||||
signature, layout, semantics, side-effect contract, or firmware-9.60 runtime
|
||||
evidence accompanies that name. A symbol name is not an ABI and is not source
|
||||
2.
|
||||
|
||||
A future source 2 must be independently sourced, publicly reviewable or
|
||||
locally cryptographically bound, current for the same execution, exact rather
|
||||
than normalized from an ambiguous value, and bound into the same nonce and
|
||||
request record. Absence yields `BLOCKED_FIRMWARE_SOURCE_2_ABSENT`; disagreement
|
||||
yields `BLOCKED_FIRMWARE_CONFLICT`. Source 1 is never silently preferred.
|
||||
|
||||
## Feasibility decision
|
||||
|
||||
The 4096-byte D1 framing is internally closed and host-testable. That proves
|
||||
only the data contract. It does not prove:
|
||||
|
||||
- a caller-owned target buffer;
|
||||
- a shared mapping or copy-out ABI;
|
||||
- an observer write boundary;
|
||||
- a safe return or process exit;
|
||||
- caller finalization after real cleanup;
|
||||
- manager delivery; or
|
||||
- firmware 9.60 runtime behavior.
|
||||
|
||||
No current bounded non-persistent output channel exists. The output result is
|
||||
therefore `BLOCKED_NO_BOUNDED_OUTPUT_CHANNEL` despite the passing host model.
|
||||
@@ -0,0 +1,108 @@
|
||||
# Phase 0.9C observation side-effect model
|
||||
|
||||
Status: **OBSERVATION SIDE EFFECTS UNBOUNDED**.
|
||||
|
||||
This is an offline classification. No observation ran on a PS5. A source-level
|
||||
`read`, `O_RDONLY`, metadata query, syscall, or manager request is never
|
||||
promoted to side-effect-free merely because project code does not write file
|
||||
content.
|
||||
|
||||
## Distinct effect dimensions
|
||||
|
||||
| Dimension | Meaning in this review | Required proof for absence |
|
||||
|---|---|---|
|
||||
| content | bytes of the observed object do not change | exact operation and all callees contain no content mutation |
|
||||
| metadata | timestamps, flags, ownership, allocation or namespace state do not change | target filesystem and syscall semantics for the exact mount |
|
||||
| atime | access time is not updated immediately or lazily | exact mount policy plus operation semantics |
|
||||
| audit | platform audit/security/logging does not record the access | complete platform policy and service path |
|
||||
| cache | page, name, attribute, service or network caches do not change | complete kernel/service implementation or an accepted bounded effect |
|
||||
| counters | syscall, network, service, kernel or security counters do not change | complete implementation and counter inventory |
|
||||
| service state | flags, wakeups, queues, worker state or functional service state do not change | exact service source and all invoked dependencies |
|
||||
| security monitoring | access does not trigger security/accounting observation | exact policy and monitor implementation |
|
||||
| open bookkeeping | descriptor tables, vnode references, locks, access records and reference counts remain unchanged | exact open/query semantics and close cleanup |
|
||||
| process accounting | CPU time, scheduler data, resource usage and process records remain unchanged | platform accounting contract |
|
||||
| object lifetime | an open/reference cannot delay deletion, replacement, unmount or cleanup | exact reference and namespace semantics |
|
||||
| races | the observed identity cannot change between validation and read | stable-handle and concurrent-mutation contract |
|
||||
|
||||
Absence of a persistent content write proves none of the other rows.
|
||||
|
||||
## Classification vocabulary
|
||||
|
||||
Every proposed observation is labelled with one or more of:
|
||||
|
||||
- `SEMANTICALLY_READONLY`;
|
||||
- `METADATA_EFFECT_POSSIBLE`;
|
||||
- `ATIME_EFFECT_POSSIBLE`;
|
||||
- `AUDIT_EFFECT_POSSIBLE`;
|
||||
- `CACHE_EFFECT_POSSIBLE`;
|
||||
- `COUNTER_EFFECT_POSSIBLE`;
|
||||
- `SERVICE_STATE_EFFECT_POSSIBLE`;
|
||||
- `SECURITY_MONITORING_EFFECT_POSSIBLE`;
|
||||
- `OPEN_BOOKKEEPING_EFFECT_POSSIBLE`;
|
||||
- `PROCESS_ACCOUNTING_EFFECT_POSSIBLE`;
|
||||
- `OBJECT_LIFETIME_EFFECT_POSSIBLE`;
|
||||
- `OBJECT_RACE_POSSIBLE`;
|
||||
- `NOT_PROVABLY_SIDE_EFFECT_FREE`.
|
||||
|
||||
`SEMANTICALLY_READONLY` means only that the requested information flow does
|
||||
not intentionally alter the observed value. Every row below remains
|
||||
`NOT_PROVABLY_SIDE_EFFECT_FREE`.
|
||||
|
||||
## Observation matrix
|
||||
|
||||
| Observation | Application intent | Possible effects | Source boundary | Result |
|
||||
|---|---|---|---|---|
|
||||
| runtime self-identity | compare in-memory fixed identity | cache, audit, process accounting, loader mapping already exists | no target implementation | `NOT_PROVABLY_SIDE_EFFECT_FREE` |
|
||||
| firmware source 1 | read `sdk_ps5_ver` process parameter | syscall/dynamic-member lookup, cache, audit, counters, process accounting | SDK `crt/kernel.c:148-170`; requires prohibited normal runtime dependencies | `NOT_PROVABLY_SIDE_EFFECT_FREE` |
|
||||
| firmware source 2 | independently query current system firmware | all query ABI and effects unknown | only an export name exists; no accepted ABI | `UNPROVEN` |
|
||||
| mount query | enumerate mount state | cache, audit, counters, locks, reference lifetime, snapshot races | SDK sample only; runtime semantics unproven | `NOT_PROVABLY_SIDE_EFFECT_FREE` |
|
||||
| file metadata | no-follow stable-object metadata | metadata/access bookkeeping, cache, audit, reference lifetime, races | manager host/source pattern only | `NOT_PROVABLY_SIDE_EFFECT_FREE` |
|
||||
| object ID and size | compare pre/post identity | same as metadata plus concurrent replacement race | manager `verified_launcher.c:26-29,83-115,174-176` | `NOT_PROVABLY_SIDE_EFFECT_FREE` |
|
||||
| file SHA-256 | bounded descriptor read | atime, metadata, page cache, audit, counters, open bookkeeping, lifetime, races | manager `verified_launcher.c:31-55`; PS5 semantics unproven | `NOT_PROVABLY_SIDE_EFFECT_FREE` |
|
||||
| process snapshot | enumerate process records | kernel allocation/cache/counters, scheduler/accounting, snapshot races | SDK process sample is partial | `NOT_PROVABLY_SIDE_EFFECT_FREE` |
|
||||
| service snapshot | map services and supervisors | service queries, queues/counters/cache/audit and races | no complete API or mapping | `UNPROVEN` |
|
||||
| listener snapshot | enumerate sockets and owners | network counters/cache/locks, service state, owner mapping races | no accepted API | `UNPROVEN` |
|
||||
| autoload/startup/retry | read all authoritative sources | atime/metadata/cache/audit/open state; stock HTTP also changes global/autoload state | Phase 0.8R source audit | `NOT_PROVABLY_SIDE_EFFECT_FREE`; stock route is side-effecting |
|
||||
| rollback objects | metadata and hash existing backups | same filesystem effects plus object lifetime and target/backup race | no current paths or objects | `UNPROVEN` |
|
||||
| monotonic time | enforce deadline | clock/syscall counters, vDSO/runtime dependencies, accounting | only loader-owned clock use is source-proven | `NOT_PROVABLY_SIDE_EFFECT_FREE` for a future observer |
|
||||
| result publication | write caller-owned transient buffer | caller memory mutation, cache, accounting, synchronization and lifetime | host-only concept; no target owner | `UNPROVEN` |
|
||||
|
||||
## Stock Payload Manager remains inadmissible
|
||||
|
||||
Phase 0.8R already proves that non-`OPTIONS` requests set
|
||||
`server_active_flag`, `/autoload_status` sets `autoload_triggered`, and several
|
||||
routes read configuration or mutate logging state. `OPTIONS` does not provide
|
||||
the needed data and still has unproven network, allocation, audit, cache,
|
||||
scheduler and counter effects.
|
||||
|
||||
Phase 0.9C does not reinterpret those endpoints as a collector. A persistent
|
||||
listener or HTTP response is also forbidden as observer output.
|
||||
|
||||
## Filesystem-specific conclusion
|
||||
|
||||
The controlled manager demonstrates a useful source pattern:
|
||||
|
||||
```text
|
||||
open(O_RDONLY | O_NOFOLLOW | O_CLOEXEC)
|
||||
-> fstat
|
||||
-> bounded read
|
||||
-> fstat
|
||||
-> lstat path
|
||||
-> compare identity/size
|
||||
-> close
|
||||
```
|
||||
|
||||
That pattern can detect several races in the reviewed source. It does not
|
||||
prove no atime update, no audit record, no page-cache fill, no vnode/reference
|
||||
bookkeeping, no process accounting, or no platform-specific service effect.
|
||||
It also cannot make a hash atomic with respect to every target namespace race
|
||||
without proven filesystem and stable-object semantics.
|
||||
|
||||
## Decision
|
||||
|
||||
No planned observation is proven side-effect-free on firmware 9.60. A later
|
||||
phase would need an explicit bounded-effect budget rather than an absolute
|
||||
zero-effect claim, plus exact public ABI/source evidence and separately
|
||||
authorized runtime observation. Phase 0.9C grants neither.
|
||||
|
||||
Current blocker: `BLOCKED_OBSERVATION_SIDE_EFFECTS_UNBOUNDED`.
|
||||
@@ -0,0 +1,289 @@
|
||||
# Phase 0.9C startup and exit feasibility
|
||||
|
||||
Status: **BLOCKED**. This is a source-bound offline analysis. It does not add
|
||||
an observer, target source, PS5 object, ELF, linker map, installation package,
|
||||
lifecycle package, transfer path, or execution authority.
|
||||
|
||||
## Evidence boundary
|
||||
|
||||
The exact reviewed sources are:
|
||||
|
||||
| Component | Commit | Relevant file identity |
|
||||
|---|---|---|
|
||||
| hardened elfldr | `197623058f509eddde18868dafcb92fdcac66464` | `elfldr.c` SHA-256 `9949f8e4037984d10f1f5aa498e4665593d1fac8a33614d7f2141349839bb803` |
|
||||
| hardened elfldr controlled route | same | `socksrv.c` SHA-256 `d642ced3e9b4a296dd15e355050ebe956f53a6dfdaa6ac10109cd067a3bba3d7` |
|
||||
| hardened cleanup model | same | `controlled_runtime.c` SHA-256 `10145f3bbb3b54e3d715b1667e45c6f12d3c7f52a04342ab104ec8dd49e384c9` |
|
||||
| hardened PS5 cleanup adapter | same | `ps5_controlled.c` SHA-256 `68717ef1cc31c483743c5af325c59e73a90f66e93b880b989e349a4ddc748772` |
|
||||
| controlled Payload Manager | `e23d94ff91233aa770e2342800c1467875bdef44` | `verified_launcher.c` SHA-256 `066100ca4917c7acc560e2e85666ca136cd7ccfd9094417377048f41106dd56e` |
|
||||
| controlled manager adapter | same | `ps5_launcher.c` SHA-256 `29c1a5fd01784a59e88b3698940f120cb03020071bc2b7d74a1da1a51524ef59` |
|
||||
| PS5 Payload SDK v0.41 | `d2e2e585740362976a39fdd5ccf390f199a7bc37` | `crt/crt.c` SHA-256 `3875f4739ec40b33f1f4967a1acbb585a527d2c281a360153e1f69c8b945932a` |
|
||||
| SDK patch implementation | same | `crt/patch.c` SHA-256 `4f76a677bba54f4641e1cf2755768c29afb7464a35b2f21e85db2aa2785eceac` |
|
||||
| SDK CRT object set | same | `crt/Makefile` SHA-256 `6a62f777f32ab05cbe7bff81c00cfd6639ba8bf440aba611a40ff0b62732568b` |
|
||||
| SDK compiler wrapper | same | `host/bin/prospero-clang` SHA-256 `0cf49ae43d6110a7606c0ee4d702fc4b5d5e1c3ae9a722945a48b80294e295ba` |
|
||||
| SDK linker script | same | `host/elf_x86_64.x` SHA-256 `169b80d01da601ef96bbc584986608dec1d9c01397eae81eccd4e1a66b0a6c6a` |
|
||||
|
||||
The public bases remain elfldr
|
||||
`699e8bcff03e91e8d6ca6eba281af25c5a58d8c2` and Payload Manager
|
||||
`cfbc70f30f419b09bf2b52283f7409e2d3117ee1`. The lifecycle source remains
|
||||
bound to commit `fe08300339a13f899fb78ea404ada381a5cba87c`; its unchanged
|
||||
`samples/lifecycle_probe/main.c` is
|
||||
`1ae7df1fe921ccab2a252f77975d3d441ef7725e34535b024580c0d4a242d766`.
|
||||
None of these historical target sources was modified.
|
||||
|
||||
Classifications in this document mean:
|
||||
|
||||
- `PROVEN_SAFE`: the cited source proves the narrow property stated;
|
||||
- `PROVEN_SIDE_EFFECTING`: the cited source proves a state change or external
|
||||
operation, whether or not an earlier phase accepted it;
|
||||
- `UNPROVEN`: evidence required for the claimed contract is absent;
|
||||
- `NOT_APPLICABLE`: the path deliberately excludes the facility.
|
||||
|
||||
`PROVEN_SAFE` never means hardware-tested.
|
||||
|
||||
## Loader-to-entry call graph
|
||||
|
||||
The controlled route has this source-proven graph:
|
||||
|
||||
```text
|
||||
controlled manager
|
||||
|- open_verified
|
||||
| |- open(O_RDONLY | O_NOFOLLOW | O_CLOEXEC)
|
||||
| |- fstat -> bounded read/SHA-256 -> fstat
|
||||
| `- lseek(fd, 0)
|
||||
|- connect_loopback
|
||||
|- send_all(control header)
|
||||
|- send_all(exact ELF bytes)
|
||||
`- close_socket
|
||||
|
||||
hardened elfldr on_connection
|
||||
|- recv/validate controlled header
|
||||
|- recv exact payload bytes -> independent SHA-256
|
||||
|- payload_spawn(route=CONTROLLED)
|
||||
| `- elfldr_spawn(stdio=-1)
|
||||
| |- rfork_thread -> child execve(SceSpZeroConf)
|
||||
| |- wait for exec/stop under finite preparation waits
|
||||
| |- pt_syscall(process-needed-and-relocate)
|
||||
| |- change child heap-size parameter
|
||||
| |- make entry page RWX
|
||||
| |- install INT3 -> continue -> stop
|
||||
| |- restore byte and RX protection
|
||||
| |- map payload PT_LOAD image
|
||||
| |- apply R_X86_64_RELATIVE relocations
|
||||
| |- map payload_args_t page
|
||||
| |- create two IPv6 sockets, overlap them, and create a pipe
|
||||
| |- back up child credentials
|
||||
| |- raise child credentials
|
||||
| |- write saved RIP to [RSP-8]
|
||||
| |- set RSP=RSP-8, RIP=ELF entry, RDI=payload_args_t*
|
||||
| |- restore all five credential fields
|
||||
| `- ptrace detach
|
||||
|- watchdog wait/reap
|
||||
| `- on timeout: SIGTERM -> grace -> SIGKILL -> reap
|
||||
`- write fixed loader-generated exit text
|
||||
```
|
||||
|
||||
Sources: hardened elfldr `socksrv.c:129-157,162-215,289-375`;
|
||||
`elfldr.c:80-265,273-415,480-545,643-769`;
|
||||
`controlled_runtime.c:60-92,95-143,146-220,223-250`; and
|
||||
`ps5_controlled.c:26-59,132-220`. The manager side is
|
||||
`verified_launcher.c:31-184`, `include/verified_launcher.h:38-42`, and
|
||||
`ps5_launcher.c:18-69`.
|
||||
|
||||
### Entry contract classification
|
||||
|
||||
| Property | Classification | Evidence and consequence |
|
||||
|---|---|---|
|
||||
| entry symbol comes from `e_entry` | `PROVEN_SAFE` | `elfldr.c:143-265` returns `base + e_entry`. |
|
||||
| first argument in `RDI` | `PROVEN_SAFE` | `elfldr.c:401-409` sets `r_rdi` to the loader-created argument page. |
|
||||
| synthetic return address | `PROVEN_SIDE_EFFECTING` | `elfldr.c:401-407` writes the observed RIP at `RSP-8` and moves `RSP`; the child stack is changed. |
|
||||
| x86-64 stack alignment at entry | `UNPROVEN` | the loader subtracts eight but never validates the trapped `RSP` alignment. |
|
||||
| meaning and safety of saved RIP | `UNPROVEN` | it is the RIP observed at the breakpoint; no reviewed contract proves the post-`ret` continuation. |
|
||||
| preserved general/SIMD register set | `UNPROVEN` | source changes `RSP`, `RIP`, and `RDI` but defines no caller/callee preservation contract for a custom entry. |
|
||||
| argument layout | `PROVEN_SAFE` | SDK `include/ps5/payload.h:27-36` and elfldr `elfldr.c:349-367` agree on six x86-64 fields. |
|
||||
| argument ownership | `PROVEN_SIDE_EFFECTING` | elfldr maps and populates the page in the child at `elfldr.c:273-372`. |
|
||||
| argument lifetime after return or exit | `UNPROVEN` | success clears the loader cleanup bitmap at `elfldr.c:538-545`; the mapping then relies on child lifetime/OS teardown. |
|
||||
| image mapping | `PROVEN_SIDE_EFFECTING` | elfldr allocates child mappings, copies bytes, changes protection, and calls `msync` at `elfldr.c:143-265`. |
|
||||
| relocation support | `PROVEN_SAFE` only for `R_X86_64_RELATIVE` | `elfldr.c:208-222`; no complete freestanding artifact exists whose relocations can be checked. |
|
||||
| BSS zero-fill by loader | `UNPROVEN` and source-negative | `base_mirror` comes from `malloc`; `data_load` copies only `p_filesz`, then the entire mirror is copied. No zero-fill is visible at `elfldr.c:96-109,183-224`. |
|
||||
| TLS setup | `UNPROVEN` | elfldr has no reviewed TLS setup in this path; no future observer layout exists. |
|
||||
| constructors/destructors | `NOT_APPLICABLE` to a proposed freestanding entry | they are a stock CRT facility and are forbidden for the proposed path. |
|
||||
|
||||
## Normal SDK v0.41 startup
|
||||
|
||||
The exact normal graph is:
|
||||
|
||||
```text
|
||||
_start(payload_args_t *)
|
||||
|- clear [__bss_start, __bss_end)
|
||||
|- store payload_args
|
||||
|- payload_init
|
||||
| |- __crt_syscall_init
|
||||
| |- __kernel_init
|
||||
| |- __klog_init
|
||||
| |- resolve __isthreaded and write 1
|
||||
| |- __patch_init
|
||||
| | |- get process/ucred state
|
||||
| | |- write credential capability bytes
|
||||
| | |- write credential attribute bytes
|
||||
| | |- write syscall lower bound 0
|
||||
| | `- write syscall upper bound -1
|
||||
| `- __rtld_init
|
||||
|- setjmp
|
||||
|- payload_run
|
||||
| |- resolve argc/argv/environ/progname
|
||||
| |- create/open payload rtld object
|
||||
| |- load DT_NEEDED dependencies and relocate
|
||||
| |- run init array
|
||||
| |- main
|
||||
| |- run fini array
|
||||
| `- close/destroy rtld object
|
||||
`- payload_terminate
|
||||
|- return 0 for the runtime's detected hijacked-process case
|
||||
|- resolve and call exit(payloadout)
|
||||
`- trap if exit resolution/call returns
|
||||
```
|
||||
|
||||
Sources: SDK `crt/crt.c:30-44,51-80,88-146,154-180,197-220`;
|
||||
`crt/patch.c:27-100`; `crt/rtld_payload.c:51-60,203-260`; and
|
||||
`crt/Makefile:19-26,50-54`.
|
||||
|
||||
| Step | Classification | Reason |
|
||||
|---|---|---|
|
||||
| BSS clear | `PROVEN_SIDE_EFFECTING` | writes every byte in the payload BSS; deterministic and process-local, but still a mutation. |
|
||||
| global argument/setjmp state | `PROVEN_SIDE_EFFECTING` | writes CRT BSS state. |
|
||||
| syscall/kernel/klog bootstrap | `PROVEN_SIDE_EFFECTING` | consumes loader-provided kernel transport and initializes global function/state. |
|
||||
| `__isthreaded = 1` | `PROVEN_SIDE_EFFECTING` | writes resolved libc state at `crt.c:65-69`. |
|
||||
| `__patch_init` | `PROVEN_SIDE_EFFECTING` and prohibited | exact capability, attribute, and syscall-bound kernel writes occur before `main`. |
|
||||
| rtld initialization | `PROVEN_SIDE_EFFECTING` | resolves functions, allocates bookkeeping, and can load/start Sce modules. |
|
||||
| relocation and `DT_NEEDED` processing | `PROVEN_SIDE_EFFECTING` | writes relocations and opens dependencies. |
|
||||
| constructors | `PROVEN_SIDE_EFFECTING` | arbitrary linked constructor effects are permitted by this path. |
|
||||
| heap use | `PROVEN_SIDE_EFFECTING` | stock rtld resolves and uses allocation functions. |
|
||||
| `main` | `UNPROVEN` for an observer | no Phase-0.9C target implementation exists. |
|
||||
| destructors and rtld close | `PROVEN_SAFE` only as attempted normal-path calls | no proof covers partial initialization, longjmp, trap, crash, or module-internal cleanup. |
|
||||
| `payload_terminate` branch selection | `UNPROVEN` | the actual branch and its platform semantics are not bound to an observer execution. |
|
||||
|
||||
The normal SDK startup is therefore **not kernelwrite-free** and is unsuitable
|
||||
for Phase 0.9C. The fact that Phase 0.7 accepted its bounded, process-local
|
||||
effects for a different lifecycle profile does not satisfy this phase's
|
||||
stricter contract.
|
||||
|
||||
## Error and abnormal paths
|
||||
|
||||
### Initialization error
|
||||
|
||||
`_start` writes the error to `payloadout` and calls `payload_terminate`
|
||||
(`crt.c:207-210`). A failure after credential capabilities were written but
|
||||
before all patch writes finish has no CRT restoration path. A failure during
|
||||
rtld initialization has no demonstrated full unwind in `_start`.
|
||||
|
||||
Classification: `PROVEN_SIDE_EFFECTING` for partial startup and `UNPROVEN` for
|
||||
complete restoration and termination.
|
||||
|
||||
### Runtime error
|
||||
|
||||
`payload_run` attempts close/destroy on some open/init/fini failures
|
||||
(`crt.c:116-146`). These are source-proven calls, not proof of module, heap,
|
||||
TLS, file-descriptor, or process cleanup on firmware 9.60.
|
||||
|
||||
Classification: `PROVEN_SAFE` for the presence of the attempted calls;
|
||||
`UNPROVEN` for complete cleanup.
|
||||
|
||||
### `payload_exit`
|
||||
|
||||
`payload_exit` writes `payloadout` and longjmps to `_start`
|
||||
(`crt.c:175-180`). The longjmp leaves `payload_run`; `_start` proceeds directly
|
||||
to `payload_terminate`, so the normal fini/close/destroy sequence is not on
|
||||
that control path.
|
||||
|
||||
Classification: `PROVEN_SIDE_EFFECTING`; full cleanup is `UNPROVEN`.
|
||||
|
||||
### Trap, crash, unexpected return, and timeout
|
||||
|
||||
- `payload_terminate` deliberately traps if its resolved `exit` path returns
|
||||
or cannot be used (`crt.c:162-170`).
|
||||
- The controlled watchdog treats any reaped child as completion but discards
|
||||
the `waitpid` status (`ps5_controlled.c:36-59`).
|
||||
- If the child remains alive, the watchdog uses `SIGTERM`, then `SIGKILL`, and
|
||||
reaps it (`controlled_runtime.c:223-250`).
|
||||
- The connection handler emits the same fixed success text after
|
||||
`payload_spawn` returns a nonnegative value (`socksrv.c:361-365`).
|
||||
|
||||
A trap/crash can therefore be indistinguishable from a normal exit to the
|
||||
manager, and timeout termination is not a safe exit under the Phase-0.9C
|
||||
rules. Classification: `UNPROVEN` for crash cleanup and status meaning;
|
||||
`PROVEN_SIDE_EFFECTING` and **inadmissible** for signal termination.
|
||||
|
||||
## Freestanding feasibility without target implementation
|
||||
|
||||
`prospero-clang` omits `crt1.o` for `-nostartfiles` and omits libc,
|
||||
`libkernel_web`, `libSceLibcInternal`, and `libSceNet` for `-nodefaultlibs`
|
||||
(`host/bin/prospero-clang:25-46,69-84`). This proves driver suppression only.
|
||||
No custom entry source or target was assembled or linked.
|
||||
|
||||
| Required facility | Theoretical availability | Classification |
|
||||
|---|---|---|
|
||||
| entry address | ELF `e_entry` is transferred to `RIP` | `PROVEN_SAFE` narrow loader fact |
|
||||
| valid stack memory | an existing child stack is used | `UNPROVEN` size, alignment, guard, and post-return contract |
|
||||
| small automatic buffers | mechanically possible if the stack contract holds | `UNPROVEN` |
|
||||
| read-only constants | PT_LOAD bytes can be mapped and protected | `PROVEN_SAFE` only for loader mapping; relocation closure is artifact-dependent |
|
||||
| BSS | loader does not prove zero-fill; a custom clear is mechanically possible | `UNPROVEN` until a reviewed entry and map exist |
|
||||
| TLS | no freestanding TLS contract | `UNPROVEN` |
|
||||
| constructors/destructors | excluded | `NOT_APPLICABLE` |
|
||||
| heap | excluded | `NOT_APPLICABLE` |
|
||||
| libc/stdio | excluded by design | `NOT_APPLICABLE` |
|
||||
| raw syscalls | no callable observer syscall ABI is supplied by `payload_args_t` | `UNPROVEN` |
|
||||
| system calls from injected text | SDK patch widens permitted syscall address bounds | `UNPROVEN` without the prohibited patch |
|
||||
| monotonic time | hardened loader has a clock, but exposes no clock callback to the payload | `UNPROVEN` in the entry |
|
||||
| filesystem `open/read/fstat/close` | requires unresolved imports, a proven raw-syscall ABI, or another supplied callback | `UNPROVEN` |
|
||||
| process/service/listener queries | no freestanding callable ABI is supplied | `UNPROVEN` |
|
||||
| normal `ret` | mechanically reaches the saved RIP | `UNPROVEN` continuation and cleanup |
|
||||
| direct process exit | would require a proven import/raw syscall and exact teardown contract | `UNPROVEN` |
|
||||
| exit status | current waiter discards it | `UNPROVEN` delivery |
|
||||
| output | current `payloadout` is inside the child mapping and never read by the controlled caller | `UNPROVEN` |
|
||||
|
||||
The important closure result is negative: removing the CRT also removes the
|
||||
only reviewed syscall, kernel, rtld, import, time, and libc initialization
|
||||
machinery. The loader supplies a dynamic-symbol function pointer and kernel
|
||||
transport fields, but using them would reintroduce dynamic resolution or
|
||||
kernel-access dependencies that this phase excludes. No useful observation
|
||||
primitive is proven available to a zero-import freestanding entry.
|
||||
|
||||
## Return, exit, and cleanup contract
|
||||
|
||||
| Resource/state | Normal `ret` | process exit | error/crash | timeout |
|
||||
|---|---|---|---|---|
|
||||
| saved stack continuation | resumes the observed RIP; meaning unproven | not used | may be bypassed | bypassed |
|
||||
| ELF and argument mappings | remain in child after detach | OS reclamation expected but not source-proven for this exact contract | unproven | child is killed/reaped, which is not safe exit |
|
||||
| loader-created pipe/sockets | remain in child after detach | same unproven teardown dependency | unproven | same inadmissible kill path |
|
||||
| observer local buffers | stack lifetime follows unproven continuation/process semantics | teardown semantics unproven | unproven | forcibly discarded |
|
||||
| file descriptors opened by a future observer | no implementation or cleanup contract | no implementation or exact teardown proof | unproven | forcibly discarded |
|
||||
| threads | a future observer forbids them; existing child/runtime state remains | no target observer exists | unproven | signals affect the whole child |
|
||||
| credentials | loader restores five fields before detach | source-proven attempted and checked restore | pre-detach cleanup is tracked; post-detach crash remains dependent on process teardown | watchdog does not prove observer cleanup |
|
||||
| breakpoint/page | restored before payload entry | already restored | preparation failures use cleanup | already restored |
|
||||
| loader bookkeeping | returns from watchdog on reap | `waitpid` status is discarded | status is ambiguous | returns timeout/failure |
|
||||
| manager bookkeeping | send-only function closes its socket before a result | no result is received | indistinguishable | no result is received |
|
||||
| exit status | no defined status | locally available to `waitpid` but discarded | discarded | timeout result is loader-local |
|
||||
| output availability | none | child mapping gone; no copy-out | none | none |
|
||||
|
||||
The current normal return path is especially unsuitable: `ret` resumes the
|
||||
SceSpZeroConf continuation rather than proving process termination. The
|
||||
controlled watchdog waits for process exit; if that continuation remains
|
||||
alive, the only bounded endpoint is signal termination. The user explicitly
|
||||
forbids treating kill, crash, timeout, or disconnect as a safe exit.
|
||||
|
||||
## Decision
|
||||
|
||||
No reviewed path proves all of:
|
||||
|
||||
1. kernelwrite-free entry with usable observation dependencies;
|
||||
2. correct stack and register ABI;
|
||||
3. deterministic BSS/relocation/TLS closure;
|
||||
4. normal return or process exit with exact status semantics;
|
||||
5. cleanup of mappings, descriptors, stack, loader and manager state;
|
||||
6. a safe error path;
|
||||
7. a safe deadline path that does not rely on kill; and
|
||||
8. result availability after cleanup.
|
||||
|
||||
Startup is therefore `BLOCKED_STARTUP_ABI_UNPROVEN`, exit and cleanup are
|
||||
`BLOCKED_EXIT_CLEANUP_UNPROVEN`, and the combined Phase-0.9C decision cannot be
|
||||
positive.
|
||||
@@ -0,0 +1,147 @@
|
||||
# Phase 0.9C static audit
|
||||
|
||||
Date: 2026-07-18. Final classification:
|
||||
**BLOCKED_MULTIPLE_FOUNDATIONAL_CONTRACTS**.
|
||||
|
||||
This audit stops before target implementation. No observer source, assembly,
|
||||
object, ELF, map, target build, lifecycle package, installation package,
|
||||
autoload package, transfer template, device address, device path, or
|
||||
authorization exists.
|
||||
|
||||
## Exact source basis
|
||||
|
||||
| Source | Commit | Tree |
|
||||
|---|---|---|
|
||||
| hardened elfldr | `197623058f509eddde18868dafcb92fdcac66464` | clean |
|
||||
| controlled Payload Manager | `e23d94ff91233aa770e2342800c1467875bdef44` | clean |
|
||||
| public elfldr v0.23 | `699e8bcff03e91e8d6ca6eba281af25c5a58d8c2` | clean |
|
||||
| public Payload Manager v0.3.1 | `cfbc70f30f419b09bf2b52283f7409e2d3117ee1` | clean |
|
||||
| PS5 Payload SDK v0.41 | `d2e2e585740362976a39fdd5ccf390f199a7bc37` | clean |
|
||||
| lifecycle source identity | `fe08300339a13f899fb78ea404ada381a5cba87c` | unchanged file hash |
|
||||
|
||||
Every reviewed file hash is recorded in
|
||||
`manifests/runtime/phase-0.9c-feasibility.json`. The validator rehashes the
|
||||
files and verifies all five external Git trees without network access.
|
||||
|
||||
## Immutable evidence
|
||||
|
||||
| Evidence | SHA-256 |
|
||||
|---|---|
|
||||
| Phase-0.8 document | `3fbe086175a6048176075f447ec1482074928e3b5282db97ea2169395fe1d508` |
|
||||
| Phase-0.8 manifest | `47d7f452f8799979fe99b3e6d56859f03544112725bf7e5b349eba5ed81b3322` |
|
||||
| Phase-0.8 original test | `8a4ad7c70de28ffe3148fd3fd1f68c36a872c53c691c9068e1ff163970863c48` |
|
||||
| Phase-0.9A manifest | `39fd7c70cae998d9d74e7caf1ff3c19f9f76f7de2e5a50bc09baede4ba53e9e9` |
|
||||
| Phase-0.9B manifest | `104c4a667ad17f9827fc7276852c6faeef96effb8e3561a5ebc19a62c7d51634` |
|
||||
| Phase-0.9B schema | `efcea3b0001ef5b2da65c372ceb93ee2fec09c9331b2e4cbb6008212504c0918` |
|
||||
|
||||
Phase 0.9B remains a truthful historical blocked audit. It was not rewritten
|
||||
as if Phase 0.9C evidence existed earlier.
|
||||
|
||||
## Startup and transitive code result
|
||||
|
||||
### Normal SDK path
|
||||
|
||||
`crt1.o` transitively includes `crt`, `syscall`, `klog`, `nid`, `kernel`,
|
||||
`rtld`, `rtld_so`, `rtld_sprx`, `rtld_payload`, `rtld_dlfcn`, `mdbg`, and
|
||||
`patch`. `_start` reaches `__patch_init` before `main`; credential
|
||||
capabilities/attributes and syscall bounds are written. It also initializes
|
||||
rtld, permits DT_NEEDED processing, relocations, constructors, heap
|
||||
bookkeeping and module loading.
|
||||
|
||||
Result: `PROVEN_SIDE_EFFECTING`, unsuitable for the kernelwrite-free contract.
|
||||
|
||||
### Freestanding theoretical path
|
||||
|
||||
The compiler can suppress CRT/default libraries, and the loader can transfer
|
||||
`e_entry` and `RDI`. The reviewed source does not close:
|
||||
|
||||
- stack alignment and saved-RIP continuation;
|
||||
- BSS zero-fill, complete relocations, TLS, or register preservation;
|
||||
- a callable read/syscall ABI without prohibited patch/runtime setup;
|
||||
- monotonic time in the observer;
|
||||
- normal return or process exit;
|
||||
- error/deadline exit without crash/kill;
|
||||
- mapping, descriptor, buffer, loader and manager cleanup; or
|
||||
- result copy-out.
|
||||
|
||||
Result: `BLOCKED_STARTUP_ABI_UNPROVEN` and
|
||||
`BLOCKED_EXIT_CLEANUP_UNPROVEN`.
|
||||
|
||||
## Output result
|
||||
|
||||
| Architecture | Audit result |
|
||||
|---|---|
|
||||
| D1 caller-owned buffer | coherent 4096-byte host contract; no current loader buffer, return finalizer, copy-out, or manager delivery |
|
||||
| D2 existing request/response | rejected; manager is connect/send/close only |
|
||||
| D3 loader-owned status | unproven; wait status is discarded and no record propagates |
|
||||
| D4 process status | rejected; ambiguous, discarded, and too small |
|
||||
|
||||
The D1 host model validates magic/version, nonce, request ID, two firmware
|
||||
fields, observer version, fixed/actual sizes, status, requested/observed/
|
||||
unsupported bitmaps, truncation, artifact hash, body/final checksums, deadline,
|
||||
completion, cleanup, zero padding and one-time consumption. No target code
|
||||
implements it.
|
||||
|
||||
Result: `BLOCKED_NO_BOUNDED_OUTPUT_CHANNEL`.
|
||||
|
||||
## Firmware and side-effect result
|
||||
|
||||
SDK `kernel_get_fw_version()` is source 1 but reads a process-parameter SDK
|
||||
field and is runtime-unobserved. A system-version export name in the SDK stub
|
||||
has no accepted prototype or semantics and is not source 2. Result:
|
||||
`BLOCKED_FIRMWARE_SOURCE_INCOMPLETE`.
|
||||
|
||||
No planned observation is proven free of metadata, atime, audit, cache,
|
||||
counter, service/security, open-bookkeeping, process-accounting,
|
||||
object-lifetime, or race effects. Result:
|
||||
`BLOCKED_OBSERVATION_SIDE_EFFECTS_UNBOUNDED`.
|
||||
|
||||
## Target artifact audit disposition
|
||||
|
||||
| Audit item | Result |
|
||||
|---|---|
|
||||
| target source/assembly | `NOT_CREATED` |
|
||||
| target compile/link | `NOT_PERFORMED` |
|
||||
| ELF headers/program headers/sections | `NOT_APPLICABLE_NO_ARTIFACT` |
|
||||
| imports/undefined symbols/DT_NEEDED | `NOT_APPLICABLE_NO_ARTIFACT` |
|
||||
| relocations/init/fini/TLS | `NOT_APPLICABLE_NO_ARTIFACT` |
|
||||
| linker map | `NOT_CREATED` |
|
||||
| target reachable callgraph | `NOT_CREATED` |
|
||||
| target disassembly | `NOT_CREATED` |
|
||||
| double target build/hash | `NOT_PERFORMED` |
|
||||
| lifecycle/install/autoload package | `NOT_CREATED` |
|
||||
| execution eligibility | `false` |
|
||||
| execution authority | `false` |
|
||||
|
||||
These are nonexistence results, not evidence that hypothetical bytes would be
|
||||
safe.
|
||||
|
||||
## Offline verification
|
||||
|
||||
The final verification run is recorded as:
|
||||
|
||||
| Check | Result |
|
||||
|---|---|
|
||||
| Phase-0.9A host tests | `PASS` — 41 guardrails, 33 fault types for each of 2 components, and 14 power-loss boundaries |
|
||||
| Phase-0.9A hardened-elfldr virtual fault suite | `PASS` — 33 fault results and 14 power-loss results; host simulation only, no hardware evidence, connection, or execution |
|
||||
| Phase-0.9A controlled-manager virtual fault suite | `PASS` — 33 fault results and 14 power-loss results; host simulation only, no hardware evidence, connection, or execution |
|
||||
| Phase-0.9B validator and host tests | `PASS` — blocked-audit validator and artifact guardrails |
|
||||
| Phase-0.9C protocol cases | `PASS` — 21/21 |
|
||||
| Phase-0.9C feasibility cases | `PASS` — 12/12 |
|
||||
| full host configure/build/CTest | `PASS` — 22/22 |
|
||||
| manifests/schema/safety/denylist/secrets/immutable/checksums | `PASS` — all dedicated validators and regression guards |
|
||||
| `git diff --check` | `PASS` — no output |
|
||||
|
||||
The committed version of this document must contain no pending result.
|
||||
|
||||
## Decision
|
||||
|
||||
The only permitted positive classification required every foundational
|
||||
contract to be proven. Five independent blocker families remain. The exact
|
||||
decision is:
|
||||
|
||||
`BLOCKED_MULTIPLE_FOUNDATIONAL_CONTRACTS`
|
||||
|
||||
No automatic Phase 0.9D transition is permitted. Reconsideration requires new
|
||||
public, commit-bound evidence; it does not authorize an experimental target
|
||||
run to discover the missing contracts.
|
||||
@@ -0,0 +1,107 @@
|
||||
# Phase 0.9D bootstrap and recovery chain
|
||||
|
||||
Date: 2026-07-18
|
||||
Status: `DESIGN_ONLY`
|
||||
|
||||
This is an offline source audit. It does not establish current device state,
|
||||
firmware behavior, persistence, a live path, or recovery success.
|
||||
No PS5 was contacted.
|
||||
|
||||
## Source-bound chain
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["External jailbreak / exploit host<br/>source absent from audited trees"]
|
||||
B["Rudimentary exploit ELF loader<br/>port 9020 per elfldr README"]
|
||||
C["elfldr bootstrap<br/>bdj.elf -> SceRedisServer"]
|
||||
D["elfldr socket service<br/>elfldr.elf, port 9021"]
|
||||
E["Payload Manager ELF<br/>manual or external autoloader"]
|
||||
F["Payload Manager HTTP service"]
|
||||
|
||||
A --> B --> C --> D --> E --> F
|
||||
```
|
||||
|
||||
The public and hardened elfldr `README.md:3-19` describe host-to-console
|
||||
delivery to a rudimentary exploit loader on port 9020. The exploit and its host
|
||||
implementation are not present in any audited tree, so its repeatability and
|
||||
recovery behavior are unproven. Hardened elfldr `main.c:28-89` enters through
|
||||
`bdj.elf`, temporarily attaches to `SceRedisServer`, and
|
||||
`bootstrap.c:38-81` starts the socket server. `socksrv.c:477-507` names that
|
||||
service `elfldr.elf`, removes an already running process with that name, and
|
||||
listens on port 9021.
|
||||
|
||||
The Payload Manager README describes either manual loading or placement by an
|
||||
external autoloader. Its `deploy.sh` only sends an ELF to elfldr; it does not
|
||||
install, read back, or recover a device file. The external autoloader,
|
||||
jailbreak host, browser exploit, and any USB recovery implementation are absent
|
||||
from the audited sources.
|
||||
|
||||
## Dependency and recovery graph
|
||||
|
||||
| Component | Commit | Persistence | Start mechanism | Boot critical | Failure impact | Recovery executor | Self-dependent | Depends on elfldr | Depends on Manager | After reboot | Evidence / classification |
|
||||
|---|---|---|---|---|---|---|---:|---:|---:|---|---|
|
||||
| Jailbreak/exploit host | not present | `UNPROVEN` | user/browser/host, details absent | `UNPROVEN` | bootstrap unavailable if absent | itself/external | unknown | no | no | `UNPROVEN` | README description only; `UNPROVEN` |
|
||||
| Rudimentary port-9020 loader | not present | session behavior `UNPROVEN` | exploit chain | `UNPROVEN` | elfldr cannot be bootstrapped through the described route | external exploit chain | unknown | no | no | `UNPROVEN` | README description only; `UNPROVEN` |
|
||||
| Hardened elfldr bootstrap | `197623058f509eddde18868dafcb92fdcac66464` | source shows process injection, not filesystem installation | sent to port 9020 | no source proof | no port-9021 service | port-9020 chain, if still available | no | no | no | `UNPROVEN` | source plus missing upstream executor; `PARTIAL` |
|
||||
| elfldr socket service | same | process-local in source | bootstrap creates `elfldr.elf` | no source proof | no normal Payload Manager launch transport | bootstrap | no | no | no | `UNPROVEN` | source; `PARTIAL` |
|
||||
| Public/full Payload Manager | public base `cfbc70f30f419b09bf2b52283f7409e2d3117ee1` | external autoloader or manual, exact current deployment unknown | elfldr or external autoloader | `UNPROVEN` | management UI/listener unavailable | elfldr/manual route | no | yes | no | `UNPROVEN` | README/source; `PARTIAL` |
|
||||
| Controlled minimal Manager source | `e23d94ff91233aa770e2342800c1467875bdef44` | explicitly not installed by the Phase-0.7 record | would require a separately authorized transfer and launch | no | no impact on current device because installation is unproven | none in this phase | no | yes | no | not installed | source/offline record; `UNPROVEN` as device runtime |
|
||||
|
||||
## Bootstrap questions
|
||||
|
||||
1. **Original exploit start:** only described as a BD-J or WebKit-style host
|
||||
route to a rudimentary loader; implementation and current operator sequence
|
||||
are absent. `UNPROVEN`.
|
||||
2. **Direct browser/exploit delivery:** the elfldr README proves only that an
|
||||
elfldr ELF is sent host-to-console. Exact browser assets are absent.
|
||||
3. **elfldr storage:** source proves a process service, not a persistent
|
||||
filesystem installation. Current storage is `UNPROVEN`.
|
||||
4. **Payload Manager storage:** README permits manual or external-autoloader
|
||||
use; actual current storage is `UNPROVEN`.
|
||||
5. **Automatic start:** controlled by an external autoloader and/or Manager
|
||||
configuration not present as current device evidence.
|
||||
6. **Manual-only files:** any ELF sent to elfldr can be manually launched in
|
||||
principle; current availability is not proven.
|
||||
7. **Gone after reboot:** process state and volatile flags are source-local,
|
||||
but device restart behavior of the complete chain is `UNPROVEN`.
|
||||
8. **Persistent after reboot:** no current artifact or configuration is proven
|
||||
persistent.
|
||||
9. **Exploit after broken elfldr:** conceptually independent in the README,
|
||||
but source and current operability of the original exploit are absent:
|
||||
`PARTIAL`.
|
||||
10. **Exploit after broken Manager:** same `PARTIAL` result.
|
||||
11. **Independent recovery payload:** the README permits sending another ELF
|
||||
through port 9020, but neither the executor nor a recovery payload is
|
||||
audited: `PARTIAL`, not recovery proof.
|
||||
12. **Write-back through original chain:** no source-bound file-write contract
|
||||
is present: `UNPROVEN`.
|
||||
13. **Ignore a wrong non-autoload file:** plausible, but live path and
|
||||
configuration are unobserved: `UNPROVEN`.
|
||||
14. **Boot-loop potential:** depends on unknown persistent autoload state:
|
||||
`UNPROVEN`.
|
||||
15. **Automatic-start configuration:** external autoloader configuration is
|
||||
absent. Manager uses `/data/pldmgr/autoload.txt` and
|
||||
`/data/pldmgr/pldmgr_config.txt`, but this does not prove the current
|
||||
bootstrap configuration.
|
||||
16. **Keep automatic start disabled:** design policy requires it; actual
|
||||
current state has no non-mutating source-bound attestation.
|
||||
17. **Recovery after reboot:** external exploit restart is only described:
|
||||
`PARTIAL`.
|
||||
18. **Recovery after crash/hang:** elfldr source restarts its accept loop and
|
||||
uses a controlled watchdog, but recovery of a broken persistent file is
|
||||
absent.
|
||||
19. **USB/browser/host independent path:** upload and launch paths exist;
|
||||
no audited PS5-to-host readback or independent restore path exists.
|
||||
20. **Unproven answers:** current persistence, live paths, installed versions,
|
||||
autoload state, exploit repeatability, boot-loop behavior, write-back,
|
||||
power-loss recovery, and post-reboot recovery all remain hardware facts.
|
||||
|
||||
## Recovery classification
|
||||
|
||||
- elfldr: `PARTIAL`. The described port-9020 bootstrap does not depend on the
|
||||
port-9021 elfldr service, but its implementation and current operability are
|
||||
missing.
|
||||
- Payload Manager: `PARTIAL` with a `CROSS_DEPENDENT` restore shape. Manual
|
||||
launch through elfldr is described, but durable restoration and verification
|
||||
are absent.
|
||||
- Byte-exact file recovery for either component: `UNPROVEN`.
|
||||
@@ -0,0 +1,123 @@
|
||||
# Phase 0.9D existing-stack endpoint matrix
|
||||
|
||||
Date: 2026-07-18
|
||||
Status: `DESIGN_ONLY`
|
||||
|
||||
## Scope and common behavior
|
||||
|
||||
The full-profile matrix is bound to controlled Payload Manager commit
|
||||
`e23d94ff91233aa770e2342800c1467875bdef44`,
|
||||
`include/pldmgr.h:8-40` and `src/http_server.c:188-1181`. Its public-base
|
||||
equivalent is commit `cfbc70f30f419b09bf2b52283f7409e2d3117ee1`;
|
||||
the public base lacks the two `chimera` routes. The separately compiled minimal
|
||||
controlled profile is in `src/controlled_manager.c:181-334`.
|
||||
|
||||
Unless a row says otherwise:
|
||||
|
||||
- authentication is absent and full-profile responses add permissive CORS;
|
||||
- every non-`OPTIONS` full-profile request writes the process-local
|
||||
`server_active_flag` (`http_server.c:207-208`);
|
||||
- non-noisy requests also append stdout/ring log state
|
||||
(`http_server.c:638-641`);
|
||||
- handler responses are bounded in-memory text/JSON/static assets, not an
|
||||
arbitrary-file response;
|
||||
- there is no automatic server-side retry, but client/UI retry is not a safe
|
||||
property of the route;
|
||||
- exact timeouts and maximum request/response sizes are `UNPROVEN` unless
|
||||
explicitly bounded in the handler;
|
||||
- no row is a readback candidate.
|
||||
|
||||
`ANY` means the handler branch itself does not enforce a verb. This is not a
|
||||
recommendation to call it.
|
||||
|
||||
## Full-profile routes
|
||||
|
||||
| Method | Exact endpoint | Handler lines | Parameters / response | File and functional effects | Classification |
|
||||
|---|---|---:|---|---|---|
|
||||
| `OPTIONS` | any | 193-205 | empty CORS preflight | no active flag; sockets/counters only | observation false; not file readback |
|
||||
| `ANY` | `/`, `/index.html`, `/cache.appcache`, `/favicon.svg`, `/icon.png` | 709-733 | compiled static bytes | no file open; active flag | `LOW_VOLATILE`, observation partial |
|
||||
| `POST` | `/chimera:upload-controlled` | 212-252, 481-537 | query filename plus identity headers; text | exclusive write flags, then verified `O_RDONLY|O_NOFOLLOW|O_CLOEXEC` reopen/hash, fsync, rename, metadata write | forbidden: create/write/rename |
|
||||
| `ANY` | `/manage:upload` | 254-286, 540-585 | query filename, request body; text | `fopen("wb")`, write, rename/import, metadata | forbidden: create/truncate/write/rename |
|
||||
| `POST` | `/set_config` | 288-295, 363-398 | form body; text | reads current config, then config/autoload files can use `fopen("w")` | forbidden: configuration write |
|
||||
| `POST` | `/repository_push` | 297-304, 401-443 | JSON body; text | temp/cache write, remove on error, rename, config timestamp | forbidden: write/remove/rename |
|
||||
| `POST` | `/sources_set` | 306-313, 446-478 | JSON body; text | sources file replacement | forbidden: configuration write |
|
||||
| `POST` | `/repository_install_push` | 315-356, 588-636 | filename/repo URL plus body; text | `fopen("wb")`, write, install rename/metadata | forbidden: create/truncate/write/rename |
|
||||
| `ANY` | `/usb_move_check` | 648-674 | query `path`; JSON includes USB size | directory/stat reads only; path resolve | not binary response; observation partial |
|
||||
| `ANY` | `/usb_move_perform` | 676-706 | path, overwrite, keep; JSON | reads USB, writes internal copy, optionally removes source | forbidden: write/remove |
|
||||
| `ANY` | `/manage:check` | 735-759 | filename; existence JSON | `stat` directory and file | no bytes/size/hash; observation partial |
|
||||
| `ANY` | `/list_payloads` | 760-767 | JSON list | directory traversal, `stat`, metadata-sidecar reads | no file bytes/size/hash attestation; observation partial |
|
||||
| `ANY` | `/processes_list` | 768-775 | process JSON | process enumeration | functional observation only; not readback |
|
||||
| `ANY` | `/process_kill` | 776-796 | pid query; text | sends process signal | forbidden: process action |
|
||||
| `ANY` | `/repository_payloads` | 797-810 | JSON cache/list | cache/config reads; multi-source path can refresh/write | forbidden: possible network/cache write |
|
||||
| `ANY` | `/repository_refresh` | 811-824 | JSON | network download, cache/temp/config writes and renames | forbidden: network/write/rename |
|
||||
| `ANY` | `/repository_install` | 825-865 | filename/source/detail; JSON | network or cache reads, temp/final write and rename | forbidden: install/write/rename |
|
||||
| `ANY` | `/sources_list` | 866-873 | JSON | reads sources configuration | configuration disclosure; no binary file framing |
|
||||
| `ANY` | `/sources_add` | 874-900 | URL query; JSON | sources configuration write | forbidden: configuration write |
|
||||
| `ANY` | `/sources_remove` | 901-921 | index query; JSON | sources configuration write | forbidden: configuration write |
|
||||
| `ANY` | `/chimera:load-controlled` | 922-951 | filename plus identity headers; text | `O_RDONLY|O_NOFOLLOW|O_CLOEXEC`, stat/hash/read, sends to elfldr and launches | forbidden: payload launch |
|
||||
| `ANY` | `/loadpayload:<path>` | 952-983 | path suffix; text | `open(O_RDONLY)`, stat/read, sends to elfldr and launches | forbidden: payload launch |
|
||||
| `ANY` | `/manage:delete` | 984-1008 | filename query; text | unlinks payload/metadata, may update autoload | forbidden: delete/configuration |
|
||||
| `ANY` | `/shutdown` | 1009-1015 | text | changes server run state | forbidden: service action |
|
||||
| `ANY` | `/log` | 1016-1024 | log JSON | reads ring; active flag and connection state | observation partial |
|
||||
| `ANY` | `/version` | 1025-1028 | text version | no file open; active flag | observation partial |
|
||||
| `ANY` | `/getip` | 1029-1036 | text address | interface/socket query; active flag | observation partial; device/network metadata |
|
||||
| `ANY` | `/autoload_status` | 1037-1091 | JSON | reads config/autoload; **sets `autoload_triggered=1`** | forbidden in Windows 1 and 2 |
|
||||
| `ANY` | `/autoload_clear` | 1092-1097 | text | resets process-local autoload counters/trigger state; no file write in this call | forbidden: functional autoload mutation |
|
||||
| `ANY` | `/abort` | 1098-1103 | text | changes autoload abort state | forbidden: functional mutation |
|
||||
| unreachable | `/autoload_status` | 1104-1111 | short JSON | duplicate branch shadowed by 1037 | never independently callable |
|
||||
| `ANY` | `/get_config` | 1112-1155 | JSON | `fopen("r")` config/autoload | no arbitrary file bytes; observation partial |
|
||||
| `ANY` | `/events` | 1156-1165 | server-sent log stream | connection allocation and log reads | indefinite stream; not file readback |
|
||||
|
||||
## Minimal controlled-profile routes
|
||||
|
||||
This source defines a different listener/profile, not extra routes proven to be
|
||||
installed beside the full profile.
|
||||
|
||||
| Method | Exact endpoint | Handler lines | Parameters / response | Effects | Classification |
|
||||
|---|---|---:|---|---|---|
|
||||
| `POST` | `/chimera/upload` | 181-303, 322-324 | required identity headers and filename; text status | exclusive temp create/write, then verified read/hash, fsync/rename | forbidden: device write |
|
||||
| `POST` | `/chimera/launch` | 305-309, 324-326 | filename and identity headers; text status | verified local read/hash, sends and launches | forbidden: payload launch |
|
||||
| `DELETE` | `/chimera/artifact` | 311-327 | filename; text status | unlink | forbidden: delete |
|
||||
|
||||
## Requested capability inventory
|
||||
|
||||
| Capability | Existing route | Result |
|
||||
|---|---|---|
|
||||
| Directory listing | `/list_payloads` | yes, filtered payload listing |
|
||||
| File stat | `/manage:check`, `/usb_move_check`, listing internals | partial/fixed-purpose; no general stat identity |
|
||||
| File read | internal only | no arbitrary bytes returned |
|
||||
| File download | none | absent |
|
||||
| File hash | internal controlled-launch verification only | no hash response route |
|
||||
| File size | `/usb_move_check` for allowed USB source | no general live component size route |
|
||||
| Upload | both upload routes and minimal `/chimera/upload` | present and forbidden |
|
||||
| Rename | internal upload/install commits | present and forbidden; no standalone route |
|
||||
| Delete | `/manage:delete`, minimal `/chimera/artifact` | present and forbidden |
|
||||
| Process listing | `/processes_list` | present |
|
||||
| Service listing | none | absent |
|
||||
| Listener listing | none | absent |
|
||||
| Firmware | none | absent |
|
||||
| Configuration | `/get_config` | present, but request has functional active-flag effect |
|
||||
| Autoload | status/clear/config routes | present and excluded |
|
||||
| Payload launch | both load routes and minimal `/chimera/launch` | present and forbidden |
|
||||
|
||||
## File-open evidence
|
||||
|
||||
Filesystem reads occur in listing, configuration, repository/source handling,
|
||||
USB checking, self-update discovery, and launch verification. The only
|
||||
launch-side exact flags are controlled
|
||||
`O_RDONLY|O_NOFOLLOW|O_CLOEXEC` (`verified_launcher.c:83-99`) and legacy
|
||||
`O_RDONLY` (`ps5_launcher.c:77-84`). Upload paths use the write/create flags
|
||||
shown above. None of these internal reads is wired to an HTTP binary-body
|
||||
response.
|
||||
|
||||
Consequently:
|
||||
|
||||
- `readback_candidate=false` for every existing route;
|
||||
- binary framing, remote EOF, returned byte count, partial-transfer detection,
|
||||
and end-to-end integrity are absent;
|
||||
- a local file read for launch is not evidence of host readback;
|
||||
- a general HTTP response is not evidence of file streaming.
|
||||
|
||||
The machine-readable matrix in
|
||||
`manifests/runtime/phase-0.9d-existing-stack-readback.json` records the
|
||||
per-route booleans and hard-stop reasons used by the validator.
|
||||
@@ -0,0 +1,71 @@
|
||||
# Phase 0.9D independent recovery analysis
|
||||
|
||||
Date: 2026-07-18
|
||||
Status: `UNPROVEN`
|
||||
|
||||
## elfldr
|
||||
|
||||
| Question | Source-bound answer |
|
||||
|---|---|
|
||||
| Write mechanism | none in audited source |
|
||||
| Executor | original external exploit/rudimentary loader could launch an ELF, but its source is absent |
|
||||
| Works if elfldr is broken | bootstrap independence is described, not demonstrated: `PARTIAL` |
|
||||
| Works if Manager is broken | bootstrap path does not name Manager: `PARTIAL` |
|
||||
| Works after reboot | `UNPROVEN` |
|
||||
| Works without autoload | manual host send is described: `PARTIAL` |
|
||||
| Works without defective listener | port 9020 is described as distinct from elfldr port 9021: `PARTIAL` |
|
||||
| Exact restore target selectable | no live target mapping or write contract |
|
||||
| Write then verify | absent |
|
||||
| Old file remains intact | no restore transaction exists |
|
||||
| Power-loss behavior | `UNPROVEN`; no atomic restoration contract |
|
||||
| Second route | none source-bound |
|
||||
|
||||
Top-level required classification: `PARTIAL`. Detailed restore classifications:
|
||||
`UNPROVEN` and `ABSENT`; no `INDEPENDENT_RECOVERY_CANDIDATE` is established.
|
||||
|
||||
## Payload Manager
|
||||
|
||||
| Question | Source-bound answer |
|
||||
|---|---|
|
||||
| Write mechanism | full Manager upload/install routes write files, but using a Manager to restore that same Manager is self-dependent and is not authorized |
|
||||
| Executor | elfldr can launch a Manager ELF sent from a host, according to README/deploy source |
|
||||
| Works if elfldr is broken | no; described manual Manager route depends on elfldr: `CROSS_DEPENDENT` |
|
||||
| Works if Manager is broken | a separately supplied candidate could be launched through elfldr, but persistent restoration is absent: `PARTIAL` |
|
||||
| Works after reboot | original exploit and elfldr repeatability are `UNPROVEN` |
|
||||
| Works without autoload | manual send is described: `PARTIAL` |
|
||||
| Works without normal Manager listener | host-to-elfldr launch is structurally separate: `PARTIAL` |
|
||||
| Exact restore target selectable | no current live mapping |
|
||||
| Write then verify | absent |
|
||||
| Old file remains intact | upload/install paths are not an audited self-recovery transaction |
|
||||
| Power-loss behavior | existing writes/renames are not proven safe for the current live Manager object |
|
||||
| Second route | absent |
|
||||
|
||||
Top-level required classification: `PARTIAL`. Detailed classifications:
|
||||
`CROSS_DEPENDENT`, `SELF_DEPENDENT`, and `POWER_LOSS_UNSAFE` for the available
|
||||
shapes. None is recovery proof.
|
||||
|
||||
## Failure matrix
|
||||
|
||||
| Failed component | Still source-plausible | Not proven / unavailable |
|
||||
|---|---|---|
|
||||
| elfldr | original port-9020 exploit bootstrap, if the absent external chain remains usable | current exploit availability, persistent rewrite, exact target, verification, power-loss recovery |
|
||||
| Payload Manager | elfldr remains capable of accepting and launching a separately supplied ELF in source | Manager live path, durable replacement, independent verification, recovery when elfldr also fails |
|
||||
|
||||
The current byte-exact Payload Manager backup remains
|
||||
`HARD_BLOCKER_FOR_INSTALLATION`. Lack of independent recovery remains
|
||||
`HARD_BLOCKER_FOR_EVERY_DEVICE_WRITE`.
|
||||
|
||||
## Side-by-side feasibility
|
||||
|
||||
elfldr `socksrv.c:477-507` terminates an already running `elfldr.elf` service
|
||||
before creating another one. Payload Manager `main.c:81-103` terminates another
|
||||
`pldmgr.elf` instance during startup. Both therefore have process/listener
|
||||
overlap and global-state risks.
|
||||
|
||||
The controlled Manager source uses a separate profile/port but is not installed
|
||||
or runtime-proven. Any candidate would require transfer and execution, a
|
||||
source-bound non-live path, collision review, a timeout/cleanup contract, and
|
||||
independent recovery. None exists here.
|
||||
|
||||
Classification: `BLOCKED` / `RECOVERY_UNPROVEN`. This is not staging,
|
||||
installation, or execution approval.
|
||||
@@ -0,0 +1,81 @@
|
||||
# Phase 0.9D off-device backup contract
|
||||
|
||||
Date: 2026-07-18
|
||||
Status: `DESIGN_ONLY`; no readback route currently satisfies this contract.
|
||||
|
||||
## Invariants
|
||||
|
||||
A future host workflow shall process one component per separately authorized
|
||||
session. It shall contain no upload, create-on-device, rename, unlink, delete,
|
||||
chmod, chown, launch, process/service action, mount action, configuration
|
||||
change, `/autoload_status`, automatic resume, or automatic retry.
|
||||
|
||||
The host must:
|
||||
|
||||
1. record an approved literal source path without inference;
|
||||
2. record non-secret device identity, session identity, route, raw
|
||||
request/response metadata, and exact client source commit;
|
||||
3. create a new local temporary output exclusively and refuse overwrite;
|
||||
4. receive in binary mode while counting every byte;
|
||||
5. reject timeout, protocol error, unexpected EOF, short transfer, surplus
|
||||
bytes, missing expected length, or any partial output as
|
||||
`TRANSFER_INCOMPLETE` then `INVALID`;
|
||||
6. close the file, reopen it, record its exact size, and compute SHA-256;
|
||||
7. start a new connection and session for a second new exclusive local
|
||||
temporary file, with no reused partial bytes;
|
||||
8. close, reopen, size, and hash the second file;
|
||||
9. compare exact sizes, SHA-256 values, and every byte;
|
||||
10. make no automatic third attempt when the copies differ.
|
||||
|
||||
If a transport cannot provide a trustworthy expected byte count, the host may
|
||||
save an exploratory copy only as `SOURCE_MAPPING_PARTIAL`; it cannot classify
|
||||
the transfer as byte-exact source attestation. The current stack has the
|
||||
stronger blocker that it does not return arbitrary file bytes at all.
|
||||
|
||||
## State machine
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> TRANSFER_NOT_STARTED
|
||||
TRANSFER_NOT_STARTED --> TRANSFER_INCOMPLETE: first byte accepted
|
||||
TRANSFER_INCOMPLETE --> INVALID: timeout / short read / framing error
|
||||
TRANSFER_INCOMPLETE --> HOST_COPY_RECEIVED: exact complete response
|
||||
HOST_COPY_RECEIVED --> HOST_COPY_REOPENED: close + reopen
|
||||
HOST_COPY_REOPENED --> HOST_COPY_HASHED: size + SHA-256
|
||||
HOST_COPY_HASHED --> SECOND_COPY_CREATED: new session/output
|
||||
SECOND_COPY_CREATED --> SECOND_COPY_REOPENED: exact receive + close/reopen
|
||||
SECOND_COPY_REOPENED --> SECOND_COPY_HASHED: size + SHA-256
|
||||
SECOND_COPY_HASHED --> INVALID: size/hash/byte mismatch
|
||||
SECOND_COPY_HASHED --> COPIES_MATCH: size/hash/all bytes equal
|
||||
COPIES_MATCH --> SOURCE_MAPPING_PARTIAL: path/object identity incomplete
|
||||
COPIES_MATCH --> SOURCE_MAPPING_VERIFIED: independent source mapping proven
|
||||
```
|
||||
|
||||
Required status vocabulary:
|
||||
|
||||
- `TRANSFER_NOT_STARTED`
|
||||
- `TRANSFER_INCOMPLETE`
|
||||
- `HOST_COPY_RECEIVED`
|
||||
- `HOST_COPY_REOPENED`
|
||||
- `HOST_COPY_HASHED`
|
||||
- `SECOND_COPY_CREATED`
|
||||
- `SECOND_COPY_REOPENED`
|
||||
- `SECOND_COPY_HASHED`
|
||||
- `COPIES_MATCH`
|
||||
- `SOURCE_MAPPING_PARTIAL`
|
||||
- `SOURCE_MAPPING_VERIFIED`
|
||||
- `INVALID`
|
||||
|
||||
## Classification boundaries
|
||||
|
||||
`OFF_DEVICE_BACKUP_VALID` is allowed only after the two closed-and-reopened
|
||||
local copies have identical sizes, SHA-256 values, and bytes. It says nothing
|
||||
about the current live source path unless source mapping was independently
|
||||
proven.
|
||||
|
||||
`RECOVERY_PROVEN` is forbidden in this phase. A matching host backup is not
|
||||
proof that any actor can safely restore it, survive power loss, retain the old
|
||||
live file, or recover without the component being replaced.
|
||||
|
||||
The contract is intentionally descriptive. Phase 0.9D creates no client,
|
||||
script, device command, backup, or transfer package.
|
||||
@@ -0,0 +1,91 @@
|
||||
# Phase 0.9D operational windows
|
||||
|
||||
Date: 2026-07-18
|
||||
Status: future review design only
|
||||
|
||||
No window is authorized by this document. Because the existing stack has no
|
||||
file readback route, Window 2 is currently blocked and the later windows cannot
|
||||
open.
|
||||
|
||||
## Window 1 — manual fact collection
|
||||
|
||||
Proposed content:
|
||||
|
||||
- firmware text exactly as displayed in the PS5 interface;
|
||||
- visible exploit, loader, and Manager status/version strings;
|
||||
- non-secret device/session identifier;
|
||||
- operator photograph or literal transcript;
|
||||
- autoload state only if it is visible without a request or mutation.
|
||||
|
||||
Prohibitions: network request to Manager unless separately justified, file
|
||||
transfer, `/autoload_status`, payload launch, configuration change, USB
|
||||
operation, retry.
|
||||
|
||||
Current outcome: `PARTIAL`, then `BLOCKED_WINDOW1` until a concrete
|
||||
non-mutating operator procedure is reviewed. It can become
|
||||
`READY_FOR_WINDOW2_REVIEW` only through a new exact authorization.
|
||||
|
||||
## Window 2 — single off-device readback
|
||||
|
||||
Intended constraints:
|
||||
|
||||
- one existing component and one literal proven live source path;
|
||||
- PS5-to-host only;
|
||||
- no write/create/truncate/rename/unlink/delete/upload/launch/autoload/config,
|
||||
no automatic retry or resume;
|
||||
- new exclusive local output, binary framing, exact byte count, short-read and
|
||||
timeout rejection;
|
||||
- any accepted `server_active_flag`, logging, socket, buffer, counter, cache,
|
||||
atime, scheduling, audit, accounting, or network-counter effect must be named
|
||||
by the future permission.
|
||||
|
||||
Current outcome: `BLOCKED_NO_READBACK_PATH`. There is no first component to
|
||||
recommend. No route satisfies binary response, exact length, EOF, short-read,
|
||||
and partial-output rejection.
|
||||
|
||||
## Window 3 — independent repeat readback
|
||||
|
||||
Would require a new connection/session and output, no reused bytes, no
|
||||
resume/retry, full size/hash/byte comparison, and no automatic third attempt.
|
||||
A mismatch means `SOURCE_UNSTABLE_OR_READBACK_INVALID`.
|
||||
|
||||
Current outcome: `BLOCKED` because Window 2 is blocked.
|
||||
|
||||
## Window 4 — second component
|
||||
|
||||
Would require separate permission, session, and files after successful Windows
|
||||
2 and 3. A combined backup-all operation is forbidden.
|
||||
|
||||
Current outcome: `BLOCKED`.
|
||||
|
||||
## Window 5 — recovery contract review
|
||||
|
||||
Offline only. A matching pair of host copies may establish
|
||||
`OFF_DEVICE_BACKUP_VALID`, never `RECOVERY_PROVEN`. Exact write executor,
|
||||
non-self-dependence, target selection, write-then-verify, old-file retention,
|
||||
and power-loss behavior must be proven.
|
||||
|
||||
Current outcome: `UNPROVEN`.
|
||||
|
||||
## Window 6 — non-live staging
|
||||
|
||||
Outside Phase 0.9D and blocked until both readbacks match, live target mapping
|
||||
is proven, independent recovery is sufficient, a non-live staging path is
|
||||
proven, and a separate permission exists.
|
||||
|
||||
## Window 7 — side-by-side execution
|
||||
|
||||
Outside Phase 0.9D. No autoload, retry, live replacement, or combined lifecycle
|
||||
probe is permitted. Current classification: `BLOCKED`.
|
||||
|
||||
## Hard stops
|
||||
|
||||
- no existing PS5-to-host file transport;
|
||||
- no runtime-observed live component path;
|
||||
- current installed identity and persistence are unproven;
|
||||
- exploit/port-9020 executor source and repeatability are absent;
|
||||
- independent byte-exact restore is absent;
|
||||
- power-loss-safe restore is unproven;
|
||||
- current Payload Manager backup is still the installation blocker;
|
||||
- every device write is blocked by missing independent recovery;
|
||||
- all authorization fields remain false.
|
||||
@@ -0,0 +1,115 @@
|
||||
# Phase 0.9D existing-stack readback feasibility
|
||||
|
||||
Date: 2026-07-18
|
||||
Decision: `BLOCKED_NO_READBACK_PATH`
|
||||
|
||||
## Route search, in required order
|
||||
|
||||
| Order | Candidate | Source result | Binary framing | Short-read / EOF / size | Decision |
|
||||
|---:|---|---|---|---|---|
|
||||
| 1 | Payload Manager download | no endpoint exists | absent | absent | `ABSENT` |
|
||||
| 2 | Payload Manager file read | internal reads are not returned to HTTP client | absent | absent | `ABSENT` |
|
||||
| 3 | elfldr response or host pipe | controlled route returns fixed status text and disables payload stdio; legacy stdio requires a payload process | no file protocol | no file completeness contract | rejected |
|
||||
| 4 | exploit host | README sends host-to-PS5; implementation absent | no reverse framing | unproven | rejected |
|
||||
| 5 | browser/USB host | browser uploads toward PS5; USB move writes device storage | reverse direction or mutating | no host-copy contract | rejected |
|
||||
| 6 | repository tools | deploy scripts send through port 9021 only | no reverse framing | absent | rejected |
|
||||
| 7 | no route | all audited paths exhausted | — | — | selected |
|
||||
|
||||
Hardened elfldr `socksrv.c:288-375` sends only rejection, error, or
|
||||
`Controlled payload exited` status. The payload data is discarded after
|
||||
loading and controlled stdio is `-1`. Controlled Manager
|
||||
`verified_launcher.c:31-184` verifies and sends a descriptor to elfldr and then
|
||||
closes; `ps5_launcher.c:18-69` exposes connect/send/close only. Neither side
|
||||
contains a receive path for component bytes.
|
||||
|
||||
## Flag semantics
|
||||
|
||||
### `server_active_flag`
|
||||
|
||||
- Declaration and initial value: static volatile integer initialized to zero,
|
||||
`src/log_server.c:20-23`.
|
||||
- Sole writer: `log_server_set_active()` assigns one.
|
||||
- Sole reader: `pldmgr_server_is_active()`, used by
|
||||
`src/autoload.c:101` only to suppress fallback notification behavior while a
|
||||
browser/server request has occurred.
|
||||
- Reset: none in the process.
|
||||
- Lifetime: process-local; it cannot persist as this variable after process
|
||||
exit or reboot. Exact manager process lifetime on hardware is unobserved.
|
||||
- No source path connects it to filesystem writes, autoload enablement,
|
||||
payload launch, request authorization, shutdown, or boot configuration.
|
||||
- Disconnect does not reset it; a crash/process exit destroys the process
|
||||
state.
|
||||
|
||||
Classification: `LOW_VOLATILE`, not `ANTI_BRICK_CRITICAL`. Because there is no
|
||||
reset semantic within the running process, any otherwise observational route
|
||||
remains `PARTIAL` and a future permission must explicitly accept this effect,
|
||||
log-ring changes, connection state, buffers, sockets, and counters.
|
||||
|
||||
### `autoload_triggered`
|
||||
|
||||
- Declaration/initial value: static volatile integer zero,
|
||||
`src/autoload.c:31`.
|
||||
- Writers: `pldmgr_autoload_get_status()` sets one (`:45`);
|
||||
`pldmgr_autoload_reset()` sets zero (`:235`).
|
||||
- Readers: autoload worker wait logic at `:82-86`.
|
||||
- `/autoload_status` calls the mutating getter before building its response
|
||||
(`src/http_server.c:1037-1041`).
|
||||
- Reset is explicit clear/resume logic, not disconnect cleanup.
|
||||
- It is process-local, but can change worker timing and therefore launch
|
||||
behavior while that process exists.
|
||||
|
||||
Classification: `HIGH_FUNCTIONAL`. `/autoload_status` is excluded from
|
||||
Windows 1 and 2. The later duplicate route at `http_server.c:1104-1111` is
|
||||
unreachable because the first identical comparison already matches.
|
||||
|
||||
## Path inventory
|
||||
|
||||
| Literal path | Source | Meaning | Live status | Evidence |
|
||||
|---|---|---|---|---|
|
||||
| `/data/pldmgr` | controlled Manager `include/pldmgr.h:8` | base device directory | configured default only | source literal |
|
||||
| `/data/pldmgr/payloads` | same `:12` | payload storage | configured default only | source literal |
|
||||
| `/data/pldmgr/autoload.txt` | same `:9` | Manager autoload list | configured default only | source literal |
|
||||
| `/data/pldmgr/pldmgr_config.txt` | same `:10` | Manager config | configured default only | source literal |
|
||||
| `/data/pldmgr/repository_cache.json` | same `:11` | repository cache | configured default only | source literal |
|
||||
| `/data/pldmgr/sources.json` | same `:14` | repository sources | configured default only | source literal |
|
||||
| `/mnt/usb0/pldmgr` … `/mnt/usb7/pldmgr` | `payload_mgr.c:201-218` | USB scan roots | possible source directories | source literal/pattern |
|
||||
| `/data/pldmgr/payloads/chimera-controlled` | controlled Manager source/profile | controlled staging directory | explicitly not installed | offline candidate only |
|
||||
| `/data/pldmgr/payloads/elfldr/elfldr_v0.23.elf` | historical Phase-0.6 manifest/tool input | stock identity reference | not runtime-observed | `reference_only` |
|
||||
| `/data/pldmgr/payloads/pldmgr/pldmgr_v0.3.1.elf` | historical Phase-0.6 manifest/tool input | stock identity reference | not runtime-observed | `reference_only` |
|
||||
| `/data/payload.elf` | elfldr README example | generic manual launch example | not a current mapping | documentation example |
|
||||
| `/user/temp/payload_<pid>.self` | elfldr self-loader source | temporary converted image | runtime-generated, not component live path | source template |
|
||||
| `/system/vsh/app/NPXS40112/eboot.bin` | elfldr bootstrap source | injection victim executable | not an elfldr installation path | source literal |
|
||||
|
||||
No audited input binds an actual live elfldr or Manager object to a current
|
||||
path. The package/reference paths and configured defaults therefore produce
|
||||
`PATH_CONFLICT`; no future readback window may guess.
|
||||
|
||||
## Readback decision matrix
|
||||
|
||||
- `NEW_OBSERVER_FEASIBILITY`: `BLOCKED`
|
||||
- `EXISTING_STACK_MANUAL_FACT_COLLECTION`: `PARTIAL`
|
||||
- `EXISTING_STACK_SINGLE_READBACK`: `BLOCKED_NO_READBACK_PATH`
|
||||
- `EXISTING_STACK_REPEAT_READBACK`: `BLOCKED`
|
||||
- `ELFLDR_INDEPENDENT_RECOVERY`: `PARTIAL`
|
||||
- `PAYLOAD_MANAGER_INDEPENDENT_RECOVERY`: `PARTIAL`
|
||||
- `SIDE_BY_SIDE_FEASIBILITY`: `BLOCKED`
|
||||
- `DEVICE_WRITE`: `NOT_AUTHORIZED`
|
||||
- `TARGET_EXECUTION`: `NOT_AUTHORIZED`
|
||||
- `INSTALLATION`: `NOT_AUTHORIZED`
|
||||
|
||||
There is no possible first readback component: the component-risk order cannot
|
||||
override an absent transport. A missing metadata query would merely reduce a
|
||||
copy to `SOURCE_MAPPING_PARTIAL`; here the earlier condition—getting complete
|
||||
binary bytes—already fails.
|
||||
|
||||
## Explicitly acceptable only after later consent
|
||||
|
||||
A future read-only request could reasonably entail sockets, temporary buffers,
|
||||
heap allocation, connection/request counters, scheduler activity, cache or
|
||||
atime effects, audit/process/network accounting, stdout logging, ring logging,
|
||||
and a process-local `server_active_flag=1`. These effects are not claimed
|
||||
absent. They are acceptable only if the chosen route has no device-file write,
|
||||
launch, autoload, service, or persistent configuration effect and the
|
||||
artifact-specific permission names them.
|
||||
|
||||
No such permission is requested in Phase 0.9D.
|
||||
@@ -0,0 +1,109 @@
|
||||
# Phase 0.9E bootstrap provenance
|
||||
|
||||
Date: 2026-07-18
|
||||
|
||||
Status: `BOOTSTRAP_IMPLEMENTATION_MISSING`
|
||||
|
||||
This is an offline inventory. No internet operation, package installation,
|
||||
target build, device request, transfer, execution, or PS5 connection occurred.
|
||||
Y2JB was used only as a filename/search hint.
|
||||
|
||||
## Search boundary
|
||||
|
||||
The search was limited to:
|
||||
|
||||
- this `chimera-gfx` tree and its existing `work/upstream` trees;
|
||||
- the existing `chimera-elfldr` and `chimera-ps5-payload-manager` siblings;
|
||||
- exact-name checks in the user Downloads directory and supplied Codex
|
||||
attachments;
|
||||
- existing repository manifests, scripts, audit records, and ignored local
|
||||
Phase-0.6/0.7 evidence.
|
||||
|
||||
No other sibling project exists in the dated project directory. No BD-J SDK,
|
||||
WebKit exploit tree, Y2JB source tree, 9020-loader tree, or external-autoloader
|
||||
tree is present under the allowed source roots.
|
||||
|
||||
## Candidate archive
|
||||
|
||||
`~/Downloads/Y2JB-Autoloader-403-1240.zip` exactly matches the candidate
|
||||
recorded by Phase 0.6:
|
||||
|
||||
- size: `504159435`;
|
||||
- SHA-256:
|
||||
`805e3f87f0c371223619ffc7d3a7b3c0d41a1fae8a8b1171d9e2f162659e8291`;
|
||||
- ZIP integrity: valid central directory and CRC;
|
||||
- entries: four directories plus
|
||||
`PS5/EXPORT/BACKUP/202606102126_00/archive.dat`;
|
||||
- no ZIP comment and no source/version manifest.
|
||||
|
||||
The inner object has:
|
||||
|
||||
- size: `504365056`;
|
||||
- SHA-256:
|
||||
`6439834e8856d45b6d6fe699b74c35ca6985a199ea8ecf3e398c018d37be2d55`;
|
||||
- leading bytes: `SIECAF`;
|
||||
- measured byte entropy: `7.999987` bits/byte;
|
||||
- zero literal matches for `Y2JB`, `y2jb`, `9020`, `elfldr`, `autoload`,
|
||||
`<html`, `.wasm`, or ELF magic.
|
||||
|
||||
The container is not a standard nested archive and no acceptable local parser
|
||||
or source definition exists. It was not decrypted, unpacked through
|
||||
proprietary tooling, or treated as source. Its filename and equal hash prove
|
||||
only that this is the same local backup candidate as Phase 0.6. They do not
|
||||
prove that it is deployed, that its opaque content is Y2JB, or that it is the
|
||||
package currently used on the PS5.
|
||||
|
||||
## Artifact inventory
|
||||
|
||||
| Logical artifact | Size | SHA-256 | Provenance | Use evidence |
|
||||
|---|---:|---|---|---|
|
||||
| Y2JB-named outer ZIP | 504159435 | `805e3f87...659e8291` | `POSSIBLE` | historical local candidate only |
|
||||
| inner `archive.dat` | 504365056 | `6439834e...37be2d55` | `UNKNOWN` | opaque `SIECAF` object |
|
||||
| hardened `elfldr-ps5.elf` | 397000 | `63e81098...400b561` | `REFERENCE_ONLY` for this device chain | exact local Phase-0.7 build; manifest says not transferred/executed |
|
||||
| hardened elfldr map | 142905 | `2ea5ff73...813124f` | `REFERENCE_ONLY` | local build evidence |
|
||||
| embedded bootstrap map | 143081 | `ec4ae17a...5b3323` | `REFERENCE_ONLY` | source/build design only; intermediate ELF absent |
|
||||
| embedded socket-service map | 145072 | `bf74db6e...5447c1` | `REFERENCE_ONLY` | source/build design only; intermediate ELF absent |
|
||||
| hardened elfldr `Makefile` | 1902 | `3df93b48...783384` | `REFERENCE_ONLY` | exact commit-bound build source |
|
||||
| hardened elfldr `README.md` | 2821 | `372aeb28...1eadb` | `REFERENCE_ONLY` | describes, but does not implement, port 9020 |
|
||||
| hardened elfldr `main.c` | 2473 | `876389a2...2b4d1` | `REFERENCE_ONLY` | exact post-9020 bootstrap source |
|
||||
| hardened elfldr `bootstrap.c` | 2081 | `5a8072ec...45381` | `REFERENCE_ONLY` | exact embedded-stage source |
|
||||
| hardened elfldr `socksrv.c` | 11556 | `d642ced3...ba3d7` | `REFERENCE_ONLY` | exact port-9021 source, not port 9020 |
|
||||
| public elfldr v0.23 asset | 397000 | `092d16ee...703e8` | `REFERENCE_ONLY` | historical public release identity |
|
||||
| controlled Manager ELF | 99560 | `8fecf824...e5e5b1` | `REFERENCE_ONLY` | exact offline build, explicitly not installed |
|
||||
|
||||
Full hashes and source/build fields are in
|
||||
`manifests/runtime/phase-0.9e-bootstrap-provenance.json`.
|
||||
|
||||
## Confidence decision
|
||||
|
||||
No artifact is classified `EXACT_USED` or `STRONG_MATCH`.
|
||||
|
||||
- The Y2JB-named ZIP is `POSSIBLE`: exact local identity, no deployed-use
|
||||
identity.
|
||||
- The opaque inner container is `UNKNOWN`.
|
||||
- elfldr/Manager binaries and source are `REFERENCE_ONLY` for the external
|
||||
pre-elfldr bootstrap question.
|
||||
- public URLs in the elfldr README are architectural references only. No
|
||||
public upstream was silently substituted for the used implementation.
|
||||
|
||||
Therefore:
|
||||
|
||||
- `actual_bootstrap_package_available=false`;
|
||||
- `actual_bootstrap_identity=null`;
|
||||
- `bootstrap_provenance=POSSIBLE`;
|
||||
- exact used artifact set: empty.
|
||||
|
||||
## Missing exact objects
|
||||
|
||||
The minimum missing evidence is:
|
||||
|
||||
1. the actual Y2JB/exploit host directory or exported package with readable
|
||||
HTML, JavaScript, WebAssembly, payload data, configuration, cache/service
|
||||
worker, manifest, and version identity;
|
||||
2. the port-9020 listener source or exact binary plus a source/release or
|
||||
reproducible build match;
|
||||
3. its build script and linker input;
|
||||
4. the exact host sender/client and configuration used by the operator;
|
||||
5. the external autoloader source/configuration, if one exists;
|
||||
6. non-secret operator evidence binding those exact hashes to the current
|
||||
firmware-9.60 workflow.
|
||||
@@ -0,0 +1,64 @@
|
||||
# Phase 0.9E future rescue payload contract
|
||||
|
||||
Date: 2026-07-18
|
||||
|
||||
This is a contract for a possible later Phase 0.9F. It is not target source,
|
||||
build authorization, transfer authorization, or execution authorization.
|
||||
Phase 0.9F design remains blocked while the exact bootstrap implementation and
|
||||
output contract are missing.
|
||||
|
||||
## Requirements
|
||||
|
||||
| # | Requirement | Bootstrap support now |
|
||||
|---:|---|---|
|
||||
| 1 | loaded only through an independently proven bootstrap | `UNPROVEN` |
|
||||
| 2 | never installed | payload policy can require it; bootstrap staging unknown |
|
||||
| 3 | never added to autoload | payload policy can require it; actual trigger config unknown |
|
||||
| 4 | never modifies elfldr or Manager | payload policy can require it |
|
||||
| 5 | creates no device file | bootstrap behavior `UNKNOWN` |
|
||||
| 6 | opens targets read-only | future payload requirement |
|
||||
| 7 | sends only PS5-to-host file bytes | no current output channel |
|
||||
| 8 | binary-safe framing | must be designed |
|
||||
| 9 | exact byte count | must be designed |
|
||||
| 10 | SHA-256 or complete host hashing | must be designed |
|
||||
| 11 | rejects partial transfer | must be designed |
|
||||
| 12 | no automatic retry | mandatory; current authorization false |
|
||||
| 13 | one file per session | mandatory |
|
||||
| 14 | no rename/unlink/upload/install/other-launch/autoload/mount/reboot/service control | mandatory |
|
||||
| 15 | hard deadline | missing |
|
||||
| 16 | host abort | missing |
|
||||
| 17 | live installation untouched | bootstrap and payload both must prove this |
|
||||
| 18 | separate output derived from exact bootstrap | missing |
|
||||
| 19 | explicit crash/hang model | missing |
|
||||
| 20 | no side-effect-free execution claim | mandatory disclosure |
|
||||
|
||||
## Required framing properties
|
||||
|
||||
A future design must bind:
|
||||
|
||||
- protocol version and request identifier;
|
||||
- literal source path and component identity;
|
||||
- expected exact byte count before accepting output;
|
||||
- monotonically increasing chunk offset and bounded chunk length;
|
||||
- final byte count and SHA-256;
|
||||
- explicit success, rejection, timeout, abort, and short-read terminal states;
|
||||
- no resume, reconnect retry, or third attempt;
|
||||
- one connection/session and one component;
|
||||
- host-side exclusive temporary output, close, reopen, size/hash, and partial
|
||||
deletion/quarantine policy.
|
||||
|
||||
## Safety gates before any target source
|
||||
|
||||
Target source may not be created merely from this contract. A new phase must
|
||||
first provide:
|
||||
|
||||
1. exact used bootstrap package and source/binary identity;
|
||||
2. proof of independence from both components being recovered;
|
||||
3. source-backed host-to-memory or safe temporary-staging semantics;
|
||||
4. a bounded, binary-safe result channel;
|
||||
5. a restart/reboot model;
|
||||
6. a reviewed startup, deadline, abort, crash, and cleanup contract;
|
||||
7. separate explicit authority to design target code.
|
||||
|
||||
Current machine decision:
|
||||
`phase09f_rescue_payload_design_allowed=false`.
|
||||
@@ -0,0 +1,80 @@
|
||||
# Phase 0.9E independent rescue chain
|
||||
|
||||
Date: 2026-07-18
|
||||
|
||||
Decision: `BOOTSTRAP_IMPLEMENTATION_MISSING`
|
||||
|
||||
## Dependency graph
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Operator trigger<br/>exact artifact missing"]
|
||||
B["Y2JB/browser exploit host<br/>opaque candidate only"]
|
||||
C["Rudimentary port-9020 listener<br/>implementation missing"]
|
||||
D["Host sender<br/>README concept only"]
|
||||
E["hardened elfldr-ps5.elf<br/>local reference build"]
|
||||
F["embedded bootstrap<br/>source design"]
|
||||
G["elfldr service :9021<br/>source design"]
|
||||
H["controlled Payload Manager<br/>offline reference build"]
|
||||
|
||||
A --> B --> C
|
||||
D --> C
|
||||
C --> E --> F --> G --> H
|
||||
```
|
||||
|
||||
| Node | Environment / side | State | Start/input/output | Dependencies | Device file / autoload | Recovery role | Evidence |
|
||||
|---|---|---|---|---|---|---|---|
|
||||
| operator trigger | host/browser | unknown | unknown | exact package | unknown | begins jailbreak session | `UNKNOWN` |
|
||||
| Y2JB/exploit host | browser/host | unknown | opaque backup candidate | trigger/package | unknown | could recreate 9020 state | `POSSIBLE` |
|
||||
| rudimentary loader | PS5 process/kernel context unknown | unknown | presumed listener on 9020 | exploit | unknown | candidate rescue executor | implementation missing |
|
||||
| conceptual sender | host | temporary | host connects and streams an ELF per README | working listener | no sender-side device path | sends elfldr | architecture only |
|
||||
| hardened elfldr bootstrap | PS5 | temporary entry, then background service design | final ELF embeds bootstrap and service | 9020 execution | source itself does not install, but performs documented process/kernel changes | creates port 9021 | exact local source, not deployed-use proof |
|
||||
| elfldr service | PS5 process | background design | listens TCP 9021 | hardened bootstrap | no autoload source path | later payload executor | exact source, hardware unproven |
|
||||
| controlled Manager | PS5 process | not installed in evidence | separate launch via elfldr | elfldr 9021 | controlled storage if used; no autoload | management layer | offline reference only |
|
||||
|
||||
No node before hardened elfldr has a source-bound executable identity.
|
||||
|
||||
## Required questions
|
||||
|
||||
1. **Who listens on 9020?** Unknown. The elfldr README calls it a
|
||||
“rudimentary ELF loader”; no implementation is present.
|
||||
2. **Who starts it?** Presumably the exploit chain, but exact trigger and
|
||||
process are unknown.
|
||||
3. **Before elfldr?** Architecturally yes; exact implementation proof is
|
||||
absent.
|
||||
4. **Available again after reboot?** Plausible for a repeatable jailbreak, not
|
||||
proven for the used package.
|
||||
5. **Requires working elfldr on filesystem?** Architecture says no; exact
|
||||
loader proof is absent, so `independent_from_elfldr=unproven`.
|
||||
6. **Requires Payload Manager?** Architecture says no; exact proof is absent,
|
||||
so `independent_from_payload_manager=unproven`.
|
||||
7. **Can it receive a payload directly?** The README assumes an elfldr ELF can
|
||||
be sent; limits and exact acceptance are unknown.
|
||||
8. **Accepted format?** The sender streams ELF bytes. Server validation,
|
||||
container rules, and truncation behavior are unknown.
|
||||
9. **Automatic execution?** Required by the described bootstrap, but no server
|
||||
source proves it.
|
||||
10. **Writes a device file first?** Unknown.
|
||||
11. **Can it execute without live replacement?** Plausible, not proven.
|
||||
12. **Restart after a payload crash?** Unknown.
|
||||
13. **Does reboot remove temporary state?** Plausible, not proven.
|
||||
14. **Depends on autoload?** No architectural requirement is documented, but
|
||||
actual configuration is absent.
|
||||
15. **Works with both later components absent?** Conceptual chain says yes;
|
||||
exact implementation is missing.
|
||||
16. **Rescue without filesystem write?** Unknown.
|
||||
17. **Independent result channel?** No exact result/output contract exists.
|
||||
18. **Hardware-unproven aspects:** all process identities, boot persistence,
|
||||
port behavior, parser behavior, mapping/entry, file writes, cleanup,
|
||||
crash/hang response, and reboot recovery.
|
||||
|
||||
## Independence decision
|
||||
|
||||
An architectural diagram alone permits at most
|
||||
`PARTIAL_RESCUE_EXECUTOR`. Here, the actual executable implementation itself
|
||||
is unavailable, so the more precise required classification is:
|
||||
|
||||
`BOOTSTRAP_IMPLEMENTATION_MISSING`
|
||||
|
||||
This does not mean the chain is dependent; it means independence cannot be
|
||||
audited. `phase09f_rescue_payload_design_allowed=false`.
|
||||
@@ -0,0 +1,63 @@
|
||||
# Phase 0.9E port-9020 protocol
|
||||
|
||||
Date: 2026-07-18
|
||||
|
||||
Protocol status: `UNPROVEN_IMPLEMENTATION_MISSING`
|
||||
|
||||
## Available evidence
|
||||
|
||||
Hardened elfldr `README.md:11-19` describes a host connecting to port 9020 and
|
||||
piping `elfldr-ps5.elf` bytes through a generic TCP stream tool. Its Makefile
|
||||
defines `PS5_PORT ?= 9020`, but contains no deploy target or protocol client.
|
||||
The README names external BD-J and WebKit projects; neither project nor the
|
||||
used Y2JB implementation exists in the allowed local source trees.
|
||||
|
||||
This proves only the expected sender shape. It does not prove the listener
|
||||
implementation or actual deployed package.
|
||||
|
||||
| Field | Offline result |
|
||||
|---|---|
|
||||
| server role | PS5-side rudimentary loader, description only |
|
||||
| client role | host-side generic stream sender, no exact client artifact |
|
||||
| transport | TCP is strongly indicated by the documented stream tool |
|
||||
| port | 9020 in README/Makefile |
|
||||
| bind address | unknown |
|
||||
| direction | host connects to PS5 |
|
||||
| handshake / magic / version | unknown |
|
||||
| endianness / headers / length fields | unknown |
|
||||
| maximum payload size | unknown |
|
||||
| chunking | TCP fragmentation behavior only; application contract unknown |
|
||||
| EOF | sender closes after input; listener EOF semantics unknown |
|
||||
| acknowledgement / error frame | unknown |
|
||||
| checksum / hash | none documented; listener behavior unknown |
|
||||
| timeout / retry / reconnect | unknown |
|
||||
| upload direction | host to PS5 |
|
||||
| response direction | unknown |
|
||||
| accepted object | ELF assumed by documentation; validation unknown |
|
||||
| parser / bounds / overflow | implementation missing |
|
||||
| partial recv/send detection | implementation missing |
|
||||
| allocation / mapping / permissions | implementation missing |
|
||||
| entrypoint selection | implementation missing |
|
||||
| filesystem staging | implementation missing |
|
||||
| cleanup / crash behavior | implementation missing |
|
||||
|
||||
The exact source-backed port-9021 protocol is deliberately not substituted for
|
||||
port 9020. Port 9021 belongs to `socksrv.c`; it has different parser and
|
||||
lifecycle code.
|
||||
|
||||
## Host model decision
|
||||
|
||||
No parser/emulator was created. A model derived from the README would invent
|
||||
server framing, maximum length, EOF, mapping, and error semantics. The
|
||||
machine-readable result is
|
||||
`manifests/runtime/phase-0.9e-loader-protocol.json`.
|
||||
|
||||
Minimum input needed to build a host-only model:
|
||||
|
||||
- exact 9020 listener source or a fully audited exact binary;
|
||||
- exact sender/client implementation;
|
||||
- maximum length and allocation rules;
|
||||
- complete recv/EOF/short-read state machine;
|
||||
- accepted format and entrypoint validation;
|
||||
- response/error/close behavior;
|
||||
- timeout and retry rules.
|
||||
@@ -0,0 +1,30 @@
|
||||
# Phase 0.9E output architecture options
|
||||
|
||||
Date: 2026-07-18
|
||||
|
||||
No output architecture is selected. The actual bootstrap implementation is
|
||||
missing, so `output_channel_for_future_rescue=UNKNOWN`.
|
||||
|
||||
| Option | Exists now | Changes required | Device file | Cleanup/crash model | Risk / feasibility |
|
||||
|---|---|---|---|---|---|
|
||||
| A. same 9020 connection, duplex | unknown | exact server and host protocol may need change; payload result propagation required | not inherently | unknown socket ownership, EOF and abort | potentially low persistent risk, feasibility unknown |
|
||||
| B. temporary PS5-to-approved-host outbound connection | absent | host receiver and target payload required | no | bounded connect/send/close and deadline required | temporary socket is not automatically brick-relevant; network policy and cleanup unproven |
|
||||
| C. temporary one-connection listener | absent | target listener and host client required | no | bind/listen/accept deadline and guaranteed close required | listener lifetime/session collision risk; not automatically a brick risk |
|
||||
| D. caller-owned host buffer | absent | exact loader ABI, buffer ownership, copy-out and post-exit delivery required | no | caller finalization and crash-safe ownership required | Phase-0.9C already shows current elfldr has no such output path |
|
||||
| E. no usable output | consistent with current evidence | none | no | no recovery result possible | only defensible current operational assumption |
|
||||
|
||||
Options A through D are designs, not claims. A generic TCP connection can be
|
||||
duplex at transport level, but that does not prove that the 9020 listener keeps
|
||||
the socket, passes it to a payload, accepts response bytes, or returns them to
|
||||
the host.
|
||||
|
||||
No option may:
|
||||
|
||||
- create or replace a live device file;
|
||||
- enable autoload;
|
||||
- retry automatically;
|
||||
- combine recovery of both components;
|
||||
- persist a listener or configuration across sessions.
|
||||
|
||||
The missing exact listener source prevents selection and prevents a
|
||||
source-derived host-only emulator.
|
||||
@@ -0,0 +1,56 @@
|
||||
# Phase 0.9E-R official Y2JB host sender audit
|
||||
|
||||
Date: 2026-07-18
|
||||
|
||||
Official sender:
|
||||
`Gezine/Y2JB@0dbbf4e7e0203af7e5d101a3256c634edf4e3ba2:payload_sender.py`
|
||||
|
||||
Identity:
|
||||
|
||||
- size: 1064 bytes;
|
||||
- SHA-256:
|
||||
`8c87920c41dbdbd66b9f36ca9509f0d6bef9170f351dd97ff831cfb98e642ec6`;
|
||||
- Git blob: `4ad80085bd8f2cf9ca3520d8ff1353b9c764fb75`;
|
||||
- same blob in all five official tags;
|
||||
- originating commit:
|
||||
`edf0d631dd6e4dbd5a3db54ebdae47934d8bd994`.
|
||||
|
||||
The file was inspected statically and was never run against any network
|
||||
target.
|
||||
|
||||
## Contract
|
||||
|
||||
| Lines | Behavior |
|
||||
|---|---|
|
||||
| 2 | `send_payload(path, host, port=50000)` |
|
||||
| 3–4 | opens the selected local file `rb` and reads it completely |
|
||||
| 6 | creates IPv4 TCP socket |
|
||||
| 7 | blocking connect to caller-supplied host/port |
|
||||
| 8 | `sendall(data)`; CPython manages short sends or raises |
|
||||
| 9 | closes after successful `sendall` |
|
||||
| 10 | reports local byte count, not peer acknowledgement |
|
||||
| 14–22 | accepts `host file` or `host port file`; explicit port uses `int()` |
|
||||
| 23–29 | prints usage/examples, including non-binding 9020 example |
|
||||
|
||||
Findings:
|
||||
|
||||
- binary mode: yes;
|
||||
- default port: 50000;
|
||||
- explicit port selection: yes;
|
||||
- maximum input size: absent;
|
||||
- timeout: absent;
|
||||
- automatic retry/resume: absent;
|
||||
- response read: absent;
|
||||
- acknowledgement, remote byte count, checksum, or hash: absent;
|
||||
- exception handling: absent; file/socket errors propagate;
|
||||
- success exit: implicit zero;
|
||||
- usage error exit: also implicit zero;
|
||||
- local mutation: none; selected file is read-only;
|
||||
- duplex classification: false.
|
||||
|
||||
The server added same-connection log writes in Y2JB 1.4, but this official
|
||||
sender closes after `sendall` and never reads. Transport-level duplex
|
||||
capability is not an end-to-end duplex sender contract.
|
||||
|
||||
No claim is made that this official sender is the one actually used by the
|
||||
operator. That requires the separate operator attestation.
|
||||
@@ -0,0 +1,125 @@
|
||||
# Phase 0.9E-R official Y2JB release correlation
|
||||
|
||||
Date: 2026-07-18
|
||||
|
||||
Result: `OFFICIAL_RELEASE_NO_MATCH`
|
||||
|
||||
Overall classification: `LOCAL_BACKUP_NOT_CORRELATED`
|
||||
|
||||
This was a bounded host-side investigation. Public network access was limited
|
||||
to official `Gezine/Y2JB` GitHub repository, API, tag, release, asset metadata,
|
||||
and source-archive URLs. No PS5 address, request, connection, transfer,
|
||||
payload, target build, restore, or execution was used.
|
||||
|
||||
## Local evidence captured before network access
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| path | `<local-download>/Y2JB-Autoloader-403-1240.zip` |
|
||||
| size | `504159435` |
|
||||
| SHA-256 | `805e3f87f0c371223619ffc7d3a7b3c0d41a1fae8a8b1171d9e2f162659e8291` |
|
||||
| creation UTC | `2026-06-23T14:10:39.0466596Z` |
|
||||
| modification UTC | `2026-06-23T14:11:10.6992328Z` |
|
||||
| ZIP comment | empty |
|
||||
| first 64 bytes | `504b030414000000000041abca5c000000000000000000000000040000005053352f504b030414000000000041abca5c0000000000000000000000000b000000` |
|
||||
| last 64 bytes | `76652e6461740a0020000000000001001800c065678d17f9dc0100000000000000000000000000000000504b050600000000050005000a020000abda0c1e0000` |
|
||||
| Zone.Identifier | 327 bytes; SHA-256 `70928a3d66cbb9f584596414c4fe535b498dd5ed7c5f55bbeae4efeb146ea841` |
|
||||
| local download indication | `ReferrerUrl` and `HostUrl` are MediaFire; exact volatile signed URL is retained only in the original ADS |
|
||||
| browser records | exact filename absent from five bounded Chrome/Edge/Brave/Firefox history candidates |
|
||||
|
||||
The MediaFire marker is local provenance evidence, not evidence about the
|
||||
bytes hosted there and not an official-source match.
|
||||
|
||||
### ZIP entries
|
||||
|
||||
The four directory entries use method 0, CRC `00000000`, flag bits 0, and
|
||||
zero sizes. Central-directory metadata was captured without normalization:
|
||||
|
||||
| Name | Method | Compressed | Uncompressed | CRC32 | DOS timestamp | Header offset | External attr |
|
||||
|---|---:|---:|---:|---|---|---:|---:|
|
||||
| `PS5/` | 0 | 0 | 0 | `00000000` | `2026-06-10 21:26:02` | 0 | 16 |
|
||||
| `PS5/EXPORT/` | 0 | 0 | 0 | `00000000` | `2026-06-10 21:26:02` | 34 | 16 |
|
||||
| `PS5/EXPORT/BACKUP/` | 0 | 0 | 0 | `00000000` | `2026-06-10 21:26:54` | 75 | 16 |
|
||||
| `PS5/EXPORT/BACKUP/202606102126_00/` | 0 | 0 | 0 | `00000000` | `2026-06-10 21:27:24` | 123 | 16 |
|
||||
| `PS5/EXPORT/BACKUP/202606102126_00/archive.dat` | 8 | 504158629 | 504365056 | `522808c8` | `2026-06-10 21:27:28` | 187 | 32 |
|
||||
|
||||
All five entries use general-purpose flag bits 0. The archive entry reports
|
||||
create system 0, create version 63, and extraction version 20.
|
||||
|
||||
The inner first 64 bytes are
|
||||
`5349454341460000010000000000000001000000000000000300000000000000c6ff138694ca1d2701779aae67de1525e5158700e6158700e715870000000000`.
|
||||
Only the `SIECAF` magic and bounded header were inspected. No new parsing,
|
||||
decryption, or reverse engineering was attempted. Its previously established
|
||||
SHA-256 remains
|
||||
`6439834e8856d45b6d6fe699b74c35ca6985a199ea8ecf3e398c018d37be2d55`.
|
||||
|
||||
## Official inventory
|
||||
|
||||
Metadata came from:
|
||||
|
||||
- `https://api.github.com/repos/Gezine/Y2JB`;
|
||||
- `https://api.github.com/repos/Gezine/Y2JB/releases?per_page=100`;
|
||||
- `https://api.github.com/repos/Gezine/Y2JB/tags?per_page=100`.
|
||||
|
||||
The official API returned three releases and five tags.
|
||||
|
||||
| Version | Official state | Tag commit | Release publication | Source tree |
|
||||
|---|---|---|---|---|
|
||||
| 1.2 | changelog text only; no current tag or release | unknown; not guessed | none | no exact release tree |
|
||||
| 1.2.1 | tag `Y2JB-1.2.1`; no current release | `6210f98c23552e6eb3c4c8981f72a200bb6121b2` | none | `928ceb979881a063457270dde4961ea4a06bc1fa` |
|
||||
| 1.3 | release `Y2JB 1.3 (deprecated)`, tag `1.3` | `82e6bbf1935d5f41c3bd5bd9e6598cf90bb2e022` | `2026-05-25T14:29:41Z` | `df29ffe4d8131b5f8b0da1874e34b95a41f0660d` |
|
||||
| 1.4 | tag `1.4`; no current release | `02eda2e772df629ecfe5a46459769bd8c994ef3e` | none | `ec06403b45f7b68e01eb5053f81277dee4910dd2` |
|
||||
| 1.5 | release `Y2JB 1.5 (deprecated)`, tag `1.5` | `5fa556e6281229057dace3254b099f95261df386` | `2026-05-22T15:06:30Z` | `db364529c347f34b8ddb186f57bb61dab91113db` |
|
||||
| 1.6 | release `Y2JB 1.6`, tag `1.6` | `0dbbf4e7e0203af7e5d101a3256c634edf4e3ba2` | `2026-06-09T14:54:35Z` | `c4344f43af7c268337437e6419548dba6f6bc211` |
|
||||
|
||||
The 1.6 release body contains the historical 1.2 through 1.5 changelogs. That
|
||||
does not create missing release objects or identify an exact 1.2 commit.
|
||||
|
||||
## Metadata-first asset comparison
|
||||
|
||||
GitHub supplied SHA-256 digests for every current official asset. Each digest
|
||||
and size excludes the local outer ZIP, so no large release asset was
|
||||
downloaded.
|
||||
|
||||
| Tag | Asset ID | Official asset | Official size | Size delta vs local | Official SHA-256 | Result |
|
||||
|---|---:|---|---:|---:|---|---|
|
||||
| 1.6 | 442805805 | `Y2JB_backup_1.6.12.20.zip` | 498991521 | -5167914 | `9c097ed9000792507bcf307eff0802f40ee64dc047ab6de3d38acccc62d39dcc` | `NO_MATCH` |
|
||||
| 1.6 | 442358421 | `Y2JB_backup_1.6.4.03.zip` | 504395044 | +235609 | `b01b4f442327f9eca90ffc4506dfa58249e4ac70cb9d7488c856c9e8dfaf37b4` | `NO_MATCH` |
|
||||
| 1.6 | 442358388 | `Y2JB_download0_1.6.zip` | 315229037 | -188930398 | `d032954033c17acda47c41179a22fa09016ddd40a274f4e9afbb051e5d08d3bd` | `NO_MATCH` |
|
||||
| 1.5 | 429350761 | `Y2JB_backup_1.5.zip` | 503863926 | -295509 | `91bc9fb38e62d2b34d0009dbfd6a46dffb379277eef3915dd0a1956f65462a45` | `NO_MATCH` |
|
||||
| 1.5 | 429351154 | `Y2JB_download0_1.5.zip` | 336514975 | -167644460 | `f7e5debb2e4c6b3fe7224e549c4aaf9b273a178543cd0bfe84e37bc0521d590a` | `NO_MATCH` |
|
||||
| 1.3 | 429415428 | `Y2JB_backup_1.3.7z` | 488117068 | -16042367 | `e63a6b8fe134ad93b8a6a3b332b98810598aff7dfb6703a226523143c3844dfb` | `NO_MATCH` |
|
||||
| 1.3 | 429415862 | `Y2JB_download0_1.3.zip` | 336789664 | -167369771 | `c64ef5bc508e4d81395928a8a54b2832f2b37c9cd1603ec9e7e3bd6f5ad6b526` | `NO_MATCH` |
|
||||
|
||||
Asset creation/update times recorded by GitHub were:
|
||||
|
||||
- 1.6 `12.20`: `2026-06-09T14:52:35Z` / `14:53:10Z`;
|
||||
- 1.6 `4.03`: `2026-06-09T03:33:57Z` / `03:34:40Z`;
|
||||
- 1.6 `download0`: `2026-06-09T03:33:55Z` / `03:34:30Z`;
|
||||
- 1.5 backup: `2026-05-25T12:46:49Z` / `12:47:34Z`;
|
||||
- 1.5 `download0`: `2026-05-25T12:47:34Z` / `12:47:56Z`;
|
||||
- 1.3 backup: `2026-05-25T14:27:41Z` / `14:28:29Z`;
|
||||
- 1.3 `download0`: `2026-05-25T14:28:29Z` / `14:29:18Z`.
|
||||
|
||||
The 1.6 release labels its `4.03` backup for firmware 4.03 through 12.40 and
|
||||
its `12.20`-named backup for 12.60 and later. Releases 1.3 and 1.5 are marked
|
||||
deprecated. Their release bodies, and the 1.6 historical changelog, were
|
||||
retained as descriptive metadata only; they do not establish local identity.
|
||||
|
||||
No asset has the local name, size, or SHA-256. An exact byte match is therefore
|
||||
mathematically impossible for the inventoried assets without downloading
|
||||
them. Downloading a digest-excluded 315–504 MB object would add no evidence and
|
||||
would violate the metadata-first rule.
|
||||
|
||||
## Decision
|
||||
|
||||
- correlation: `OFFICIAL_RELEASE_NO_MATCH`;
|
||||
- identified local release: none;
|
||||
- local outer-to-release association: none;
|
||||
- large backup assets downloaded: zero;
|
||||
- local backup classification: `LOCAL_BACKUP_NOT_CORRELATED`;
|
||||
- Phase 0.9F offline design allowed: `false`.
|
||||
|
||||
This does not prove that the local package contains no official-derived
|
||||
content. It proves that its outer bytes are not any current official
|
||||
`Gezine/Y2JB` release asset.
|
||||
@@ -0,0 +1,148 @@
|
||||
# Phase 0.9E-R official Y2JB port audit
|
||||
|
||||
Date: 2026-07-18
|
||||
|
||||
Port-9020 classification: `PORT_9020_REFERENCE_ONLY`
|
||||
|
||||
## Exact 9020 search
|
||||
|
||||
Every official tag (`Y2JB-1.2.1`, `1.3`, `1.4`, `1.5`, `1.6`) has exactly two
|
||||
9020 text references:
|
||||
|
||||
- `README.md`: a `payload_sender.py ... 9020 payload.bin` example;
|
||||
- `payload_sender.py:29`: the same usage example.
|
||||
|
||||
No tag contains a socket bind, listen, connect target, parser, mapper, ELF
|
||||
loader, or dispatch function fixed to port 9020. Therefore the example cannot
|
||||
be promoted to an implementation.
|
||||
|
||||
## Actual Remote JS Loader
|
||||
|
||||
At release 1.6 commit
|
||||
`0dbbf4e7e0203af7e5d101a3256c634edf4e3ba2`, the implementation is
|
||||
`download0/cache/splash_screen/aHR0cHM6Ly93d3cueW91dHViZS5jb20vdHY=/remotejsloader.js`.
|
||||
|
||||
| Lines | Function / block | Contract |
|
||||
|---|---|---|
|
||||
| 2–8 | allocation | fixed `MAXSIZE = 500 * 1024`; one 512000-byte receive buffer |
|
||||
| 10–39 | `create_socket` | TCP/IPv4, `SO_REUSEADDR`, `INADDR_ANY`, port 0, backlog 3 |
|
||||
| 41–47 | `get_port` | reads assigned ephemeral port |
|
||||
| 49–88 | `setup_socket_until_port_50000` | creates/closes up to 60000 sockets seeking assigned port 50000; falls back to last port |
|
||||
| 90–105 | `recreate_socket` | creates a new ephemeral listener after accept failure |
|
||||
| 107–119 | initial setup | reports actual IP and port |
|
||||
| 122–209 | accept loop | infinite accept/read/decode/eval loop |
|
||||
| 145–164 | receive loop | reads until EOF or 512000 bytes; partial reads accumulate |
|
||||
| 168–188 | validation | rejects empty/error; 1.6 rejects ELF magic only |
|
||||
| 190–203 | dispatch | UTF-8 decode, `eval`, same-connection log writes, close in `finally` |
|
||||
|
||||
Protocol properties:
|
||||
|
||||
- server: PS5-side JavaScript listener;
|
||||
- expected port: normally 50000, but explicitly dynamic;
|
||||
- framing: TCP connection close/EOF;
|
||||
- maximum accepted prefix: 512000 bytes;
|
||||
- content: JavaScript; 1.6 rejects only `7f 45 4c 46`;
|
||||
- authentication: none;
|
||||
- declared length, version, checksum, or hash: none;
|
||||
- timeout: none;
|
||||
- full-limit rejection: absent; reaching 512000 bytes can dispatch the prefix
|
||||
without proving EOF;
|
||||
- native mapping/entrypoint: absent; received bytes are text-decoded and
|
||||
evaluated;
|
||||
- filesystem write: none in this receive function;
|
||||
- retry behavior: internal listener allocation/recreation loops exist;
|
||||
- crash/hang risk: untrusted JavaScript evaluation, unbounded accept lifetime,
|
||||
blocking reads, and no deadline.
|
||||
|
||||
The 1.2.1/1.3 loader uses Git blob
|
||||
`21663be4a0fab6b6a829824946f54706fb1be839`; 1.4/1.5 use
|
||||
`decb42ba0bbd2bdc8d1568d33b6d772f9fe24d8e`; 1.6 uses
|
||||
`dd4957530e7a88c889877a7dcb3433642a71e019`. Release 1.6 added ELF-magic
|
||||
rejection. Release 1.4 added streaming logs over the accepted connection.
|
||||
|
||||
This is a concrete official implementation, but it is not a port-9020
|
||||
implementation.
|
||||
|
||||
## Lapse and port 9021
|
||||
|
||||
The official chain is:
|
||||
|
||||
`Remote JS Loader (~50000) → lapse.js → load_aioshellcode → embedded kexp + elfldr bytes → elfldr listener 9021`
|
||||
|
||||
Relevant source:
|
||||
|
||||
- `payloads/lapse.js:1707-1717` requires `load_aioshellcode` and rejects
|
||||
firmware above 10.01;
|
||||
- `payloads/lapse.js:1725-1734` creates a per-run `lapse.fail` marker;
|
||||
- `payloads/lapse.js:1639` calls `load_aioshellcode` after exploit setup;
|
||||
- `aioshellcode.js:12-24` locates embedded files in sandbox slots;
|
||||
- `aioshellcode.js:26-45` maps the kexp binary with JIT shared executable
|
||||
memory;
|
||||
- `aioshellcode.js:47-76` starts and joins its thread;
|
||||
- `aioshellcode.js:78-90` reads the embedded elfldr into process memory;
|
||||
- `aioshellcode.js:107-117` passes pipe state, `allproc`, elfldr address, and
|
||||
size to the embedded binary;
|
||||
- `misc.js:262-302` treats a successful loopback connection to 9021 as a
|
||||
jailbroken/elfldr-running signal;
|
||||
- `README.md:127-137` tells the host to send an ELF to 9021 after Lapse.
|
||||
|
||||
The port-9021 listener itself is contained in an ELF binary. Y2JB contains no
|
||||
generator or listener source for the 1.6 ELF. Release 1.5 embeds the already
|
||||
pinned public elfldr v0.23 asset byte-for-byte; release 1.6 embeds a distinct
|
||||
binary. No 1.6 elfldr source commit is invented.
|
||||
|
||||
## Safety classification
|
||||
|
||||
The Remote JS Loader is independent of an already running elfldr and Payload
|
||||
Manager at source-architecture level, but deployed use is unbound because the
|
||||
local backup is not an official outer asset. It also uses ~50000, not 9020.
|
||||
|
||||
Consequently:
|
||||
|
||||
- `PORT_9020_IMPLEMENTATION_FOUND`: false;
|
||||
- `PORT_9020_IMPLEMENTATION_PARTIAL`: false;
|
||||
- `PORT_9020_REFERENCE_ONLY`: true;
|
||||
- Phase 0.9F offline design allowed: false.
|
||||
|
||||
## Security and robustness findings
|
||||
|
||||
| Finding | Classification | Evidence and consequence |
|
||||
|---|---|---|
|
||||
| Receiver dispatches UTF-8 through `eval` | `SESSION_CRASH_RISK` | arbitrary JavaScript can hang or terminate the current exploit session |
|
||||
| No receiver deadline; infinite accept loop | `SESSION_CRASH_RISK` | blocked reads and repeated listener lifetime have no bounded cleanup |
|
||||
| Buffer limit can dispatch without proven EOF | `PROTOCOL_INTEGRITY_RISK` | a 512000-byte prefix can be treated as complete |
|
||||
| No length, authentication, checksum, or hash | `PROTOCOL_INTEGRITY_RISK` | source does not bind received bytes to an intended request |
|
||||
| Sender has no timeout, acknowledgement, response read, or hash | `PROTOCOL_INTEGRITY_RISK` | local `sendall` completion is not peer receipt or execution proof |
|
||||
| Lapse creates `common_temp/lapse.fail` | `UNKNOWN` | source proves a filesystem side effect, but deployed persistence and reboot semantics remain unobserved |
|
||||
| Lapse/kexp intentionally changes kernel state | `BRICK_RELEVANT` | it is outside every authorization in this phase and cannot be treated as read-only |
|
||||
| Embedded 1.6 elfldr has no source/generator | `UNKNOWN` | listener bounds, parser, mapping, cleanup, and crash behavior cannot be source-audited here |
|
||||
| Sender usage errors return implicit success | `HOST_ONLY` | automation could misread a local invocation error; no device action occurred |
|
||||
|
||||
A session crash is not automatically a brick: the reviewed Remote JS receive
|
||||
function does not itself replace a live file or enable autoload. However, the
|
||||
local backup is unbound and the subsequent Lapse path contains explicit kernel
|
||||
and filesystem effects, so no device-risk conclusion or recovery guarantee is
|
||||
promoted from that source architecture.
|
||||
|
||||
## Firmware selection and reboot boundary
|
||||
|
||||
At release 1.6:
|
||||
|
||||
- `main.js:681-729` identifies supported YouTube app layouts and labels
|
||||
versions `01.000.003`, `01.000.030`, and `01.009.202` with minimum firmware
|
||||
4.03, 12.20, and 13.20 respectively;
|
||||
- `misc.js:92-108` obtains `kern.sdk_version` and formats the firmware value;
|
||||
- `main.js:967-971` assigns and reports that value;
|
||||
- `payloads/lapse.js:1707-1717` requires `load_aioshellcode` and rejects
|
||||
versions above 10.01.
|
||||
|
||||
Thus 9.60 passes the release-source comparison in Lapse. It does not prove
|
||||
that release 1.6 is deployed, that its masks match the device, or that the
|
||||
runtime chain succeeds.
|
||||
|
||||
Listener sockets, JavaScript state, mappings, threads, and loaded code are
|
||||
process- or kernel-resident in source architecture. The Y2JB cache and
|
||||
`lapse.fail` path are filesystem state. Source alone does not prove which
|
||||
state a reboot removes, whether the original trigger remains usable, or
|
||||
whether a crash permits clean restart. The classification stays
|
||||
`REBOOT_RECOVERY_UNPROVEN`.
|
||||
@@ -0,0 +1,63 @@
|
||||
# Phase 0.9E-R remaining provenance gaps
|
||||
|
||||
Date: 2026-07-18
|
||||
|
||||
Overall decision: `LOCAL_BACKUP_NOT_CORRELATED`
|
||||
|
||||
## Closed questions
|
||||
|
||||
- The local outer ZIP retains its Phase-0.9E size and SHA-256.
|
||||
- The official current inventory consists of releases 1.3, 1.5, and 1.6 and
|
||||
tags `Y2JB-1.2.1`, 1.3, 1.4, 1.5, and 1.6.
|
||||
- All seven current official release assets have official SHA-256 digests,
|
||||
names, and sizes different from the local outer ZIP.
|
||||
- Official tag commits, trees, source archives, and host sender are bound.
|
||||
- Official Y2JB does not implement a port-9020 listener in the inspected tags.
|
||||
- Its Remote JS Loader is a dynamic port listener normally seeking 50000.
|
||||
- Port 9021 belongs to an embedded elfldr path reached after Lapse/kexp.
|
||||
|
||||
## Remaining gaps
|
||||
|
||||
1. The source, author, version, and construction procedure for
|
||||
`Y2JB-Autoloader-403-1240.zip` are unknown.
|
||||
2. The MediaFire download marker does not identify an official release asset.
|
||||
3. The local opaque `SIECAF` content cannot be matched to official source.
|
||||
4. No evidence binds the local outer ZIP to what was restored on the PS5.
|
||||
5. No evidence shows whether `download0.dat` or app data was later replaced.
|
||||
6. No evidence identifies the operator's actual host sender.
|
||||
7. No evidence explains the previously assumed port-9020 listener.
|
||||
8. The source/generator identity of the 1.6 embedded elfldr and kexp blobs is
|
||||
not present in Y2JB.
|
||||
9. Runtime behavior on firmware 9.60 remains unobserved.
|
||||
10. Independent recovery and the current Payload Manager backup remain
|
||||
unresolved installation blockers.
|
||||
11. The exact requested official source-archive URLs are recorded, but the
|
||||
transient GitHub redirect URLs were not retained.
|
||||
|
||||
The official sender is one-way. The JavaScript server can write log bytes on
|
||||
its accepted socket, but `payload_sender.py` never receives them. Therefore no
|
||||
existing end-to-end duplex result channel is established. Reusing that
|
||||
connection would require a different host contract; an outbound connection or
|
||||
temporary listener would require new target design. No output architecture is
|
||||
selected while the exact-used bootstrap remains unbound.
|
||||
|
||||
## Phase 0.9F gate
|
||||
|
||||
`phase09f_offline_design_allowed=false`.
|
||||
|
||||
The mandatory official outer-asset byte match is absent and the inspected
|
||||
official source has only a 9020 reference, not a found or partial 9020
|
||||
implementation. Device observation cannot be used to repair these facts in
|
||||
this phase.
|
||||
|
||||
Minimum safe next evidence:
|
||||
|
||||
- a verifiable publisher/provenance record for the exact MediaFire-marked
|
||||
outer ZIP, or a different operator-provided exact outer ZIP that matches an
|
||||
official asset;
|
||||
- a completed non-runtime operator attestation;
|
||||
- exact identification of any external autoloader or 9020 implementation and
|
||||
sender used in the real workflow.
|
||||
|
||||
Supplying evidence grants no connection, transfer, installation, execution,
|
||||
autoload, device-write, or retry authority.
|
||||
@@ -0,0 +1,93 @@
|
||||
# Phase 0.9E-R Y2JB release-to-source binding
|
||||
|
||||
Date: 2026-07-18
|
||||
|
||||
## Official source acquisition
|
||||
|
||||
The official repository was acquired from
|
||||
`https://github.com/Gezine/Y2JB.git` into ignored host-only path
|
||||
`work/upstream/Y2JB-official`. It is detached at tag `1.6`:
|
||||
|
||||
- commit: `0dbbf4e7e0203af7e5d101a3256c634edf4e3ba2`;
|
||||
- tree: `c4344f43af7c268337437e6419548dba6f6bc211`;
|
||||
- status: clean;
|
||||
- submodules: none;
|
||||
- Git LFS pointers: none;
|
||||
- tracked files at 1.6: 19;
|
||||
- license: MIT.
|
||||
|
||||
No project file from that tree was executed and no dependency was installed.
|
||||
The upstream tree remains ignored and is not vendored.
|
||||
|
||||
## Source archives
|
||||
|
||||
Each official GitHub tag source archive was downloaded outside tracked paths,
|
||||
closed, hashed locally, and compared byte-for-byte by pathname with the exact
|
||||
Git tree. All regular files match their tag tree.
|
||||
|
||||
The requested URLs were the official GitHub API form
|
||||
`https://api.github.com/repos/Gezine/Y2JB/zipball/<tag>` for each exact tag in
|
||||
the table. GitHub's redirect target was not retained as provenance and is
|
||||
listed as a gap rather than reconstructed.
|
||||
|
||||
| Tag | Commit | Tree | Archive bytes | Locally computed SHA-256 | Archive ↔ tree |
|
||||
|---|---|---|---:|---|---|
|
||||
| `Y2JB-1.2.1` | `6210f98c23552e6eb3c4c8981f72a200bb6121b2` | `928ceb979881a063457270dde4961ea4a06bc1fa` | 142038 | `dd7b05234aec35696b6d00ea4420f7bc1e09d57a4fe64363fdaa6728a37b7201` | 20/20 files exact |
|
||||
| `1.3` | `82e6bbf1935d5f41c3bd5bd9e6598cf90bb2e022` | `df29ffe4d8131b5f8b0da1874e34b95a41f0660d` | 185243 | `661993fbeec566bdfc0c5d9b89eeddc4a1f21f4a8c0b7392fddea4f73ce636d6` | 22/22 files exact |
|
||||
| `1.4` | `02eda2e772df629ecfe5a46459769bd8c994ef3e` | `ec06403b45f7b68e01eb5053f81277dee4910dd2` | 151619 | `53d7fb1e665d0534d446cfe980841a0b8eed7eda35424c2f9c4abad32d5aaec5` | 19/19 files exact |
|
||||
| `1.5` | `5fa556e6281229057dace3254b099f95261df386` | `db364529c347f34b8ddb186f57bb61dab91113db` | 149934 | `5d964faaf1b941c2fc8a006b10ae909b15d8f2c27d120e08b37196f1e464ad6d` | 19/19 files exact |
|
||||
| `1.6` | `0dbbf4e7e0203af7e5d101a3256c634edf4e3ba2` | `c4344f43af7c268337437e6419548dba6f6bc211` | 150964 | `8385c439458c6954fd1198760ab0ef8245543235c83db90d041591362027cae4` | 19/19 files exact |
|
||||
|
||||
This establishes `REPRODUCIBLE_CONTENT_BINDING` between each downloaded source
|
||||
archive and its official Git tree. It establishes no relationship between the
|
||||
local MediaFire-marked backup and any tag.
|
||||
|
||||
## Static 1.6 inventory
|
||||
|
||||
The 1.6 tree contains one HTML file, ten JavaScript files, three Python host
|
||||
tools, one embedded kexp binary, and one embedded ELF. It contains no WASM,
|
||||
service worker, web manifest, submodule, LFS pointer, loader generator, or
|
||||
build script for the embedded blobs.
|
||||
|
||||
Important 1.6 file identities:
|
||||
|
||||
| Path | Bytes | SHA-256 |
|
||||
|---|---:|---|
|
||||
| `README.md` | 7500 | `16bfdaa624b8b04f4a6a4a7d512ca8473ad2db73e80df39a974267403e34f751` |
|
||||
| `payload_sender.py` | 1064 | `8c87920c41dbdbd66b9f36ca9509f0d6bef9170f351dd97ff831cfb98e642ec6` |
|
||||
| `log_server.py` | 929 | `463114fd46479a7286706de13beb3f52221f36f3cbe37dc5a27bdb6104787a98` |
|
||||
| `appinfo_editor.py` | 2008 | `c1bcb453660f597cbc9026dba76519a4929fc3e967c183deec8a1ca56912e2e8` |
|
||||
| `splash.html` | 596 | `0060fce48b104d57025399814e29e9db83923068e7fce899c6235ff7da2e72ef` |
|
||||
| `main.js` | 44909 | `4f2a87a4550e453b13ada660136d9e7019230bf8fdf7016e855911bd38f0e3d5` |
|
||||
| `global.js` | 8760 | `1b39c3fe7576f80f6ff3cd32fcb5eef2cbb972b574897f80a28370fb1afceb1d` |
|
||||
| `kernel.js` | 9113 | `631aac816ed674dce6460cea49fa62961b06ed9446b14f6340416bb98d0326de` |
|
||||
| `misc.js` | 16308 | `05df5102239af19a9f5a28fb6994dc213db8ab54c7bd7120243b92409c8f8407` |
|
||||
| `remotejsloader.js` | 7132 | `30cc6d1535549b2a49b47a9e0c85a3444cf84177be54398691694b7c6505f38e` |
|
||||
| `aioshellcode.js` | 3870 | `feb50f1a7596dfde61611ae347fc7d2ec2ca34e75d05fa5d91340df2d762d310` |
|
||||
| `kexp_2026_05_25.bin` | 18912 | `618f4b121cd26f2b259ade4fc3a69b3bdb631667758ae63fb9d316b4362015eb` |
|
||||
| `elfldr-ps5-1340.elf` | 397000 | `30478bcadb6439e1247451c4ac706b6e1385044dd0f12d6486b6d7057929453b` |
|
||||
|
||||
The embedded 1.6 ELF is an x86-64 PIE with entry `0x4700` and `DT_NEEDED`
|
||||
entries for `libkernel_web.sprx`, `libSceLibcInternal.sprx`, and
|
||||
`libSceNet.sprx`. It has no source or generator in Y2JB; its commit identity is
|
||||
therefore the containing Y2JB blob only, not a claimed elfldr source commit.
|
||||
|
||||
Across tags the embedded elfldr identities are:
|
||||
|
||||
| Tag | Embedded file | SHA-256 | Binding |
|
||||
|---|---|---|---|
|
||||
| 1.2.1 / 1.3 | `elfldr.elf` | `00ce93eb217b3720f40f18f47221ed25702847c570593e468823abffbcadd562` | binary only |
|
||||
| 1.4 | `elfldr_1320_v5.elf` | `5839049ca949462c9e8cb40be35afd783ac07d50a290857a5558ceeb81fb90fe` | binary only |
|
||||
| 1.5 | `elfldr-ps5-0.23.elf` | `092d16ee0ede0c494947efd38d1a17bbd7cc4b022d3858ea898833c188c703e8` | byte-equal to the already pinned public v0.23 asset |
|
||||
| 1.6 | `elfldr-ps5-1340.elf` | `30478bcadb6439e1247451c4ac706b6e1385044dd0f12d6486b6d7057929453b` | binary only |
|
||||
|
||||
## Binding decision
|
||||
|
||||
- official tag source archive → Git tree:
|
||||
`REPRODUCIBLE_CONTENT_BINDING`;
|
||||
- official release → same-tag source: `OFFICIAL_RELEASE_ASSOCIATION`;
|
||||
- local outer ZIP → official release: no association;
|
||||
- local inner `SIECAF` → source: `UNBOUND`;
|
||||
- local backup overall: `LOCAL_BACKUP_NOT_CORRELATED`.
|
||||
|
||||
No official source association was promoted into a local inner-content match.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Phase 0.9E-R2 community backup correlation
|
||||
|
||||
Date: 2026-07-19
|
||||
|
||||
Only the three named official GitHub repositories and their release metadata
|
||||
were inspected. No mirror or general scene download was used. Metadata,
|
||||
source trees, and release assets were read statically; downloaded archives
|
||||
were not executed.
|
||||
|
||||
## Candidate matrix
|
||||
|
||||
| Family | Relevant release identity | Firmware statement | Public system backup | Components/autoload | Decision |
|
||||
|---|---|---|---|---|---|
|
||||
| `itsPLK/ps5-y2jb-autoloader` | `v0.8-a0146a2`, commit `a0146a2a9229fa5df5b5127257bf2e11ffc6d2de` | 4.03–12.70 | no; README explicitly says the project does not distribute preconfigured system backups | Lapse blob `190996c…`, P2JB blob `510bf4b…`, elfldr submodule `148b71c…`, Payload Manager submodule `5d33ce1…`; exploit and localhost elfldr auto-load, later payloads use `autoload.txt` | `THIRD_PARTY_BUILD_FROM_PUBLIC_SOURCE_POSSIBLE`, but unbound |
|
||||
| `owendswang/Y2JB-P2JB-bdj_unpatch` | `v1.4-autoloader`, commit `9990e917cdb24c249ce24f4ff18e6e869e99cf51` | tag README says 9.00–12.40 disc; downloaded backup name says 7.61 | yes | Gezine Y2JB base declared; Lapse/P2JB blobs and embedded elfldr are identifiable; no Payload Manager identity at this tag | downloaded candidate inner and structure do not match |
|
||||
| `lz-anonz/Y2X` | `v1.3`, commit `2ae881259be647738713b83a6a91ffe693ccf9af` | 4.03–12.70 | no current large release asset despite README backup wording | P2JB/Lapse, v1/v2 embedded elfldr, Payload Manager 0.3.1 and FTP; v2 auto-loads Manager/FTP and warns against kstuff in autoload | excluded by asset inventory; no large download |
|
||||
|
||||
## itsPLK
|
||||
|
||||
The relevant tag was published 2026-06-10 09:05:51Z, before the local inner
|
||||
ZIP timestamp. Its official assets are only:
|
||||
|
||||
- `download0.dat`, 336789504 bytes,
|
||||
SHA-256 `268c82f7a8f581c804949a86c259c982953ff479c13a3dc9f9da02c354b32d6e`;
|
||||
- `y2jb_update.zip`, 1152857 bytes,
|
||||
SHA-256 `301599b05e7eb7224025ef9ed6ebc896d86d2c14bba5c32ced5a88bdf2c3517e`.
|
||||
|
||||
Its README's firmware range, “Autoloader” naming, timing, and credit to Rush
|
||||
for creating a backup make the family plausible. The same README explicitly
|
||||
says itsPLK does not distribute such backups. No public hash, backup asset,
|
||||
MediaFire link, or maker attestation binds this source to the local bytes.
|
||||
Accordingly it is not an official itsPLK release and is not promoted to
|
||||
`THIRD_PARTY_REPACK_PROVENANCE_BOUND`.
|
||||
|
||||
## owendswang
|
||||
|
||||
Release `v1.4-autoloader` published 2026-06-10 09:01:19Z includes:
|
||||
|
||||
- `download0_Y2JB+autoloader-20260609.zip`, 333151616 bytes;
|
||||
- `PS5-12.20-backup-Y2JB+autoloader-20260609-en.zip`, 498991549 bytes;
|
||||
- `PS5-7.61-backup-Y2JB+autoloader-20260609-en.zip`, 504425435 bytes.
|
||||
|
||||
The 7.61 backup was the sole downloaded community candidate because its
|
||||
family, date, and size were concrete matches. Its local download exactly
|
||||
matched GitHub size and SHA-256
|
||||
`8552d7c3c7bb3f078d967f56dfe1b488b37e3ed13e10c5fe97ae222482d56897`.
|
||||
Its inner is 504627200 bytes with SHA-256
|
||||
`d4f9b1ba4e32af175a3431a7734085d5420370ebb79f9a32852eb824a90e190e`.
|
||||
The local inner is 262144 bytes smaller, has a different full hash, differs
|
||||
byte-for-byte, and has version/count 3/62 rather than 6/58. Normalized
|
||||
segment layout and section hashes also differ.
|
||||
|
||||
Classification: no `COMMUNITY_INNER_BYTE_MATCH`.
|
||||
|
||||
## lz-anonz
|
||||
|
||||
Release `v1.3` published 2026-06-10 21:58:27Z has only:
|
||||
|
||||
- `USB-ps5_autoloader.rar`, 904337 bytes;
|
||||
- `v1.3-download0-Y2X-P2JB+Lapse.rar`, 521801 bytes.
|
||||
|
||||
The source contains autoload and embedded components, but the current release
|
||||
does not expose a system-backup object to compare. README language is not a
|
||||
byte identity. No large asset was downloaded.
|
||||
|
||||
## Download bound
|
||||
|
||||
One of the maximum three allowed community backups was downloaded. It used one
|
||||
attempt, no resume, and no retry. The other two families had no public large
|
||||
candidate justified by their own release metadata.
|
||||
@@ -0,0 +1,67 @@
|
||||
# Phase 0.9E-R2 final provenance decision
|
||||
|
||||
Date: 2026-07-19
|
||||
|
||||
Primary classification: `LOCAL_BACKUP_UNCORRELATED`
|
||||
|
||||
## Decision chain
|
||||
|
||||
1. The complete local ADS establishes `MEDIAFIRE_URL_EXACT` for file key
|
||||
`jq3fcutuwbb1mrb` and the exact local filename.
|
||||
2. The exact MediaFire page is still present and establishes
|
||||
`MEDIAFIRE_OBJECT_METADATA_BOUND`, but exposes no server digest, exact byte
|
||||
count, public uploader, maker, tutorial, or source.
|
||||
3. The mandatory official Gezine/Y2JB 1.6 4.03 inner differs in size,
|
||||
SHA-256, complete bytes, normalized layout, and section hashes.
|
||||
4. The one justified community backup from owendswang also differs on every
|
||||
inner and structural measure.
|
||||
5. itsPLK is a plausible public source family, but explicitly does not publish
|
||||
system backups and supplies no binding to this MediaFire object.
|
||||
6. Y2X has no current large system-backup asset at its relevant release.
|
||||
|
||||
Therefore:
|
||||
|
||||
- `OFFICIAL_INNER_BYTE_MATCH`: false;
|
||||
- `COMMUNITY_INNER_BYTE_MATCH`: false;
|
||||
- `THIRD_PARTY_REPACK_PROVENANCE_BOUND`: false;
|
||||
- `SIECAF_STRUCTURAL_RELATION_ONLY`: false;
|
||||
- `LOCAL_BACKUP_UNCORRELATED`: true.
|
||||
|
||||
`LOCAL_BACKUP_NOT_CORRELATED` from Phase 0.9E-R remains historically correct
|
||||
for the outer-asset analysis. R2 refines the current fail-closed result after
|
||||
inner, structure, origin, and community correlation; it does not silently
|
||||
replace the prior record.
|
||||
|
||||
## Separate identities
|
||||
|
||||
| Question | Result |
|
||||
|---|---|
|
||||
| Is the outer ZIP official? | no |
|
||||
| Is the MediaFire object metadata-bound? | yes |
|
||||
| Is its maker/source bound? | no |
|
||||
| Is the inner official/community byte-bound? | no |
|
||||
| Is even a normalized structural relation established? | no |
|
||||
| Was this backup restored to the PS5? | `UNPROVEN` |
|
||||
| Are current PS5 bytes known? | `UNPROVEN` |
|
||||
| Is firmware-9.60 runtime behavior known? | `UNPROVEN` |
|
||||
|
||||
## Phase 0.9F
|
||||
|
||||
Phase 0.9F offline design may not be reconsidered. Neither of the entry
|
||||
conditions is met:
|
||||
|
||||
- the inner is not byte-exactly bound to an auditable source family;
|
||||
- the MediaFire backup is not bound to an auditable maker/release with a
|
||||
complete actual bootstrap implementation.
|
||||
|
||||
The actual deployed bootstrap, embedded listener closure, autoloader component
|
||||
manifest, independent recovery, and current device contents remain unproven.
|
||||
The byte-exact Payload Manager backup remains
|
||||
`HARD_BLOCKER_FOR_INSTALLATION`.
|
||||
|
||||
## Authorization
|
||||
|
||||
All device, target-build, transfer, execution, installation, lifecycle,
|
||||
autoload, device-write, rescue-design, and retry fields remain false. No PS5
|
||||
action, target code, target artifact, payload, device client, restore, or
|
||||
execution occurred.
|
||||
@@ -0,0 +1,68 @@
|
||||
# Phase 0.9E-R2 inner archive correlation
|
||||
|
||||
Date: 2026-07-19
|
||||
|
||||
Result: `INNER_ARCHIVE_HASH_MISMATCH`
|
||||
|
||||
Phase 0.9E-R excluded an outer byte match. R2 separately tests the plausible
|
||||
repack case by comparing complete inner `archive.dat` bytes.
|
||||
|
||||
## Local identity
|
||||
|
||||
| Object | Size | SHA-256 |
|
||||
|---|---:|---|
|
||||
| local outer ZIP | 504159435 | `805e3f87f0c371223619ffc7d3a7b3c0d41a1fae8a8b1171d9e2f162659e8291` |
|
||||
| local `PS5/EXPORT/BACKUP/202606102126_00/archive.dat` | 504365056 | `6439834e8856d45b6d6fe699b74c35ca6985a199ea8ecf3e398c018d37be2d55` |
|
||||
|
||||
## Mandatory official candidate
|
||||
|
||||
The exact official Gezine/Y2JB 1.6 asset
|
||||
`Y2JB_backup_1.6.4.03.zip` was downloaded once from its GitHub release URL.
|
||||
Resume and retry were disabled. The closed and reopened file was 504395044
|
||||
bytes and its locally calculated SHA-256 was
|
||||
`b01b4f442327f9eca90ffc4506dfa58249e4ac70cb9d7488c856c9e8dfaf37b4`,
|
||||
equal to GitHub's official digest.
|
||||
|
||||
It was not executed or restored. Static ZIP inventory:
|
||||
|
||||
| Entry | Method | Compressed | Uncompressed | CRC32 | Timestamp | Entry SHA-256 |
|
||||
|---|---:|---:|---:|---|---|---|
|
||||
| `PS5/` | 0 | 0 | 0 | `00000000` | `2026-06-09 04:15:20` | empty SHA-256 |
|
||||
| `PS5/EXPORT/` | 0 | 0 | 0 | `00000000` | `2026-06-09 04:15:20` | empty SHA-256 |
|
||||
| `PS5/EXPORT/BACKUP/` | 0 | 0 | 0 | `00000000` | `2026-06-09 04:15:20` | empty SHA-256 |
|
||||
| `PS5/EXPORT/BACKUP/202606090510_00/` | 0 | 0 | 0 | `00000000` | `2026-06-09 04:15:20` | empty SHA-256 |
|
||||
| `PS5/EXPORT/BACKUP/202606090510_00/archive.dat` | 8 | 504394122 | 504496128 | `7db3b89a` | `2026-06-09 05:15:58` | `3e1f0867d5d8362cbf722d51d0e68c26243d6b33d78460d978580b510c854212` |
|
||||
|
||||
The four directory entries use Unix create-system 3, create/extract version
|
||||
20, external attributes 1107230720, and empty comments. The inner entry uses
|
||||
create system/version 3/20, extract version 20, flag bits 8, external
|
||||
attributes 2176188416, header offset 315, and an empty comment.
|
||||
|
||||
## Full inner comparison
|
||||
|
||||
| Property | Local inner | Official inner |
|
||||
|---|---:|---:|
|
||||
| size | 504365056 | 504496128 |
|
||||
| SHA-256 | `6439834e...37be2d55` | `3e1f0867...0c854212` |
|
||||
| complete bytes equal | no | no |
|
||||
|
||||
The size differs by 131072 bytes. Complete streaming comparison and both
|
||||
hashes disagree. Classification is `INNER_ARCHIVE_HASH_MISMATCH`, so the
|
||||
local outer cannot be classified `REPACKAGED_OFFICIAL_BACKUP`.
|
||||
|
||||
## Community comparison performed
|
||||
|
||||
The one source-motivated community download was
|
||||
owendswang/Y2JB-P2JB-bdj_unpatch release `v1.4-autoloader`,
|
||||
`PS5-7.61-backup-Y2JB+autoloader-20260609-en.zip`. GitHub and local size were
|
||||
504425435 bytes; both SHA-256 values were
|
||||
`8552d7c3c7bb3f078d967f56dfe1b488b37e3ed13e10c5fe97ae222482d56897`.
|
||||
|
||||
Its inner `PS5/EXPORT/BACKUP/202606100638_00/archive.dat` is 504627200 bytes,
|
||||
CRC32 `cf138df3`, and SHA-256
|
||||
`d4f9b1ba4e32af175a3431a7734085d5420370ebb79f9a32852eb824a90e190e`.
|
||||
It is neither the same size, hash, nor bytes as the local inner:
|
||||
`INNER_ARCHIVE_HASH_MISMATCH`.
|
||||
|
||||
Outer mismatch did not substitute for inner analysis. The negative inner
|
||||
results now independently exclude both downloaded candidates.
|
||||
@@ -0,0 +1,78 @@
|
||||
# Phase 0.9E-R2 local download provenance
|
||||
|
||||
Date: 2026-07-19
|
||||
|
||||
Result: `MEDIAFIRE_URL_EXACT`
|
||||
|
||||
This evidence is host-only. No PS5 address, request, connection, transfer,
|
||||
restore, target build, or execution was used.
|
||||
|
||||
## Local object
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| name | `Y2JB-Autoloader-403-1240.zip` |
|
||||
| size | `504159435` |
|
||||
| SHA-256 | `805e3f87f0c371223619ffc7d3a7b3c0d41a1fae8a8b1171d9e2f162659e8291` |
|
||||
| creation UTC | `2026-06-23T14:10:39.0466596Z` |
|
||||
| modification UTC | `2026-06-23T14:11:10.6992328Z` |
|
||||
|
||||
The file was read without changing it. Its `Zone.Identifier` alternate data
|
||||
stream is 327 bytes and has SHA-256
|
||||
`70928a3d66cbb9f584596414c4fe535b498dd5ed7c5f55bbeae4efeb146ea841`.
|
||||
It contains exactly the `ZoneTransfer` section and these fields:
|
||||
|
||||
| Field | Safe evidence |
|
||||
|---|---|
|
||||
| `ZoneId` | `3` |
|
||||
| `ReferrerUrl` | host `www.mediafire.com`, path `/`, no query; full-value SHA-256 `9a0ff5a3e34286b2e53192003fca8b6c7b00ad6df3c681765da04ccaa54c0919` |
|
||||
| `HostUrl` | host `download2434.mediafire.com`, file key `jq3fcutuwbb1mrb`, filename `Y2JB-Autoloader-403-1240.zip`; full-value SHA-256 `a39f05923d0a5368ea5138c1974ac109bb09f8ab795c6edb8e470d8dfe4d784c` |
|
||||
| `LastWriterPackageFamilyName` | absent |
|
||||
| `AppZoneId` | absent |
|
||||
| other fields | none |
|
||||
|
||||
The transient signed path component is deliberately redacted. It was neither
|
||||
committed nor reproduced here. The complete value remains only in the
|
||||
unchanged local ADS.
|
||||
|
||||
## Browser metadata
|
||||
|
||||
The bounded search covered existing Chrome Default, Chrome System Profile,
|
||||
and Edge Default Chromium History databases. The query was limited to the
|
||||
exact filename, size, filesystem-date window, MediaFire host, and file key.
|
||||
Brave, standalone Chromium, Opera, and Opera GX profiles were absent.
|
||||
|
||||
Three read-only database copies were made because browser databases can be
|
||||
live-locked. Chrome Default, Chrome System Profile, and Edge Default each
|
||||
returned `NO_MATCH`; no download rows were exported and the originals were
|
||||
not changed. The temporary copies were removed with the rest of the research
|
||||
directory.
|
||||
|
||||
Browser classification: `NO_BROWSER_HISTORY_MATCH`.
|
||||
|
||||
## Exact MediaFire page
|
||||
|
||||
Only
|
||||
`https://www.mediafire.com/file/jq3fcutuwbb1mrb/Y2JB-Autoloader-403-1240.zip/file`
|
||||
was requested. Static HTML was 333321 bytes with SHA-256
|
||||
`655e4c3c2e5c423019b0195ca863ee8906f7ca02601b773b39688a590bf7fcb7`.
|
||||
It displayed:
|
||||
|
||||
- filename `Y2JB-Autoloader-403-1240.zip`;
|
||||
- size `480.8MB`;
|
||||
- uploaded value `2026-06-11 15:32:16`;
|
||||
- upload country `United Kingdom`;
|
||||
- the same MediaFire file key.
|
||||
|
||||
No public account/uploader, user description, tutorial, maker, server digest,
|
||||
or exact server byte count was exposed. The download object was not
|
||||
downloaded again. The local ADS plus page provide
|
||||
`MEDIAFIRE_OBJECT_METADATA_BOUND`, not `MEDIAFIRE_OBJECT_BYTE_BOUND` and not
|
||||
maker/source provenance.
|
||||
|
||||
## Boundary
|
||||
|
||||
The download-origin classification is `MEDIAFIRE_URL_EXACT`. That describes
|
||||
where the local bytes were downloaded from. It does not prove who created
|
||||
them, which public source generated them, whether they were restored, or what
|
||||
is currently on the PS5.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Phase 0.9E-R2 SIECAF structural analysis
|
||||
|
||||
Date: 2026-07-19
|
||||
|
||||
Result: all pairwise comparisons are `SIECAF_LAYOUT_DIFFERENT`.
|
||||
|
||||
## Evidence and scope
|
||||
|
||||
`tools/inspect_siecaf_header.py` is a host-only read-only parser. Its fixed
|
||||
little-endian layouts are bound to:
|
||||
|
||||
- PS5 DevWiki `Archive.dat` structure documentation;
|
||||
- `c0w-ar/ps5-bar-tool` commit
|
||||
`36d014672bc87577a6e0d750c2cccadc3fae0854`, tree
|
||||
`d3e973b60432fdc32bd16e3b7424e82dcc38a23f`;
|
||||
- public `include/bar_file.h` blob
|
||||
`fdbc368353a7797464873ada306f0297257eb95e`.
|
||||
|
||||
The public header names the 64-bit value after the magic `unknown`, and the
|
||||
later signed 32-bit field `version`. Versions 3 and 6 were observed and are
|
||||
parsed using that same public fixed-width layout. Other versions fail closed.
|
||||
|
||||
The parser reads only the 0x58-byte header, 0x40-byte metadata records, and
|
||||
0x30-byte hash records. It never decrypts, guesses keys, extracts content,
|
||||
executes `ps5-bar-tool`, writes output files, or opens a network connection.
|
||||
The 16-byte header field named `key` by the public source and the complete raw
|
||||
header are not emitted; only their SHA-256 fingerprints are recorded. This
|
||||
preserves exact structural comparison without committing cryptographic header
|
||||
material.
|
||||
|
||||
It checks exact magic, table arithmetic with uint64 overflow guards, table and
|
||||
declared-data bounds, 64 KiB alignment, coherent aligned/unaligned sizes,
|
||||
metadata `(section_id, part_number)` identity, hash-table index coverage,
|
||||
duplicates, overlaps, gaps, and trailing data. Repeated section IDs with
|
||||
different part numbers are reported but are valid multipart records.
|
||||
|
||||
## Header comparison
|
||||
|
||||
| Field | Local | Official Y2JB 1.6 4.03 | owendswang v1.4 autoloader 7.61 |
|
||||
|---|---:|---:|---:|
|
||||
| inner size | 504365056 | 504496128 | 504627200 |
|
||||
| version | 3 | 3 | 6 |
|
||||
| segment count | 62 | 64 | 58 |
|
||||
| data offset | 65536 | 65536 | 65536 |
|
||||
| declared data size | 504299520 | 504430592 | 504561664 |
|
||||
| header SHA-256 | `4454809c9831770901491368f08b648129aef7ee3148aff17df8716ff3a5cd76` | `1af2bd937e5b6a2386331893f7ea1295661858cb91c90ee728141a4fec2dbf9b` | `db2a9677f051b372e208261d767ac45f653374426a5594ce3306568138ebd3ae` |
|
||||
|
||||
All three parse as `SIECAF_VALID_STRUCTURE`. None has gaps, overlaps, trailing
|
||||
data, duplicate metadata composite keys, or duplicate hash-table IDs.
|
||||
|
||||
## Normalized fingerprints
|
||||
|
||||
| Object | Segment table SHA-256 | Hash blocks SHA-256 | Layout SHA-256 | Structural SHA-256 |
|
||||
|---|---|---|---|---|
|
||||
| local | `ee35a92fe5e46c307310715fc5bd0edb9ac46c2046b7d77e9c1c437446e399ea` | `6e052f186dc8e683d501e376d79dcec1ba0d3268c257b6071e96eae738a7be24` | `c6dac8313ef99accba68b4a36871f0d8ae99676df0b721d4447ecb05a12a6539` | `7bb1b70187d1f48370b9bae218429af79105585bd043307824c0d84982e6922f` |
|
||||
| official | `d31def8e731d7bba0eaf23177f7c7245ef17f5d37ade53c9ca18744154bc8e25` | `c3236f5d85a4d7741be5a1fda5ce96d2bb7f005b0e48fed043af5ea48fb045d2` | `de6cc47686e5e301b725267b9b777c80a07a788e51f214cfb6e9d7f6e2e11110` | `9c453e1fa99ef1f1e6fe1d992f9b0a2ede4dbd4b9a2ad8551c08c8c61ed9be2a` |
|
||||
| community | `f0aed4ae115866010902671a511983c3e6e21d1a7ab187bae7f36566979beb89` | `434b209865af8c5815b1277073db59348fddf65086908b2fd00dee5324459bcb` | `be7fdf87361c17fa52d3b4b263f4ee0cce69e924f8dab0ab66c554b4d9557549` | `4884c54e280969371ae1d0b84533be5a7c50a61dff6931cf595fdb5862655218` |
|
||||
|
||||
Pairwise outcomes:
|
||||
|
||||
- local versus official: `SIECAF_LAYOUT_DIFFERENT`;
|
||||
- local versus community: `SIECAF_LAYOUT_DIFFERENT`;
|
||||
- official versus community: `SIECAF_LAYOUT_DIFFERENT`.
|
||||
|
||||
`manifests/runtime/phase-0.9e-r2-siecaf-fingerprints.json` contains every
|
||||
non-secret normalized input field, metadata record, section hash, redacted
|
||||
header-field hashes, parser warning/error array, and comparison. Structural
|
||||
hashes are non-authorizing fingerprints:
|
||||
even `SIECAF_STRUCTURAL_EXACT` would not prove decrypted-content identity or
|
||||
deployment. Here, not even normalized layout equality exists.
|
||||
@@ -0,0 +1,57 @@
|
||||
# Phase 0.9E reboot and crash model
|
||||
|
||||
Date: 2026-07-18
|
||||
|
||||
Classification: `REBOOT_RECOVERY_UNPROVEN`
|
||||
|
||||
## State model
|
||||
|
||||
| State | Evidence | Expected lifetime | Reboot statement |
|
||||
|---|---|---|---|
|
||||
| exact exploit/browser state | implementation absent | unknown | `UNPROVEN` |
|
||||
| exact port-9020 listener state | implementation absent | unknown | `UNPROVEN` |
|
||||
| hardened elfldr entry process | `main.c` source | temporary by design | hardware behavior unproven |
|
||||
| embedded bootstrap in `SceRedisServer` | `main.c`/`bootstrap.c` | temporary injection stage | likely process/kernel state, not a proven recovery mechanism |
|
||||
| `elfldr.elf` port-9021 service | `socksrv.c` | process-local background service by design | README says rest-mode resume, not reboot persistence |
|
||||
| controlled Manager | source/offline artifact | process-local when launched | explicitly not installed in current controlled-runtime evidence |
|
||||
| Manager configuration/autoload files | source paths only | filesystem-persistent if actually present | current device values and use unobserved |
|
||||
| Y2JB-named `SIECAF` backup | host file | host-persistent | not proof of device installation |
|
||||
|
||||
The hardened elfldr README states that the port-9021 service survives payload
|
||||
crashes and resumes after rest mode. It does not say that the service survives
|
||||
a full reboot. Source creates process state and does not install a boot item,
|
||||
but the complete device bootstrap/autoload environment is not available.
|
||||
|
||||
## Crash cases
|
||||
|
||||
- A payload crash under hardened port 9021 is isolated by design from the
|
||||
service process. That is source architecture, not a tested firmware-9.60
|
||||
guarantee.
|
||||
- A crash in the unknown port-9020 listener may terminate a process, exploit
|
||||
state, or more. No cleanup, watchdog, retry, or restart path is available for
|
||||
audit.
|
||||
- A malformed or truncated 9020 transfer has unknown allocation, mapping,
|
||||
execution, and close behavior.
|
||||
- A hang has no proven host abort, deadline, or recovery response.
|
||||
- No source proves that a bad payload cannot create persistent state; a future
|
||||
rescue contract must explicitly prohibit such writes.
|
||||
|
||||
## Anti-brick boundary
|
||||
|
||||
A session crash is not automatically brick-relevant if live files, autoload,
|
||||
configuration, mounts, and boot state remain unchanged and a reboot or fresh
|
||||
jailbreak session restores the executor. Those premises are not yet proven for
|
||||
the actual chain.
|
||||
|
||||
Consequently:
|
||||
|
||||
- `restartable_after_reboot=unproven`;
|
||||
- no guarantee is made that reboot always restores access;
|
||||
- no automatic retry is permitted;
|
||||
- no future device phase may rely on reboot recovery until the exact package
|
||||
and its state transitions are audited.
|
||||
|
||||
Minimum evidence to promote to `REBOOT_RECOVERY_SUPPORTED_BY_DESIGN` is an
|
||||
exact source-bound trigger/listener implementation proving that all bootstrap
|
||||
state is session-local or safely reproducible, plus an exact operator procedure
|
||||
that does not rely on a live component or autoload.
|
||||
@@ -0,0 +1,198 @@
|
||||
# SDK v0.41 startup call graph
|
||||
|
||||
This is an offline source, relocation, and disassembly audit of the installed
|
||||
SDK v0.41 `target/lib/crt1.o`. It describes the unsafe stock startup, not a new
|
||||
Chimera GFX artifact. The complete machine-readable reachable graph contains
|
||||
31 functions and 182 call or tail-call edges in
|
||||
`manifests/runtime/phase-0.5-startup-audit.json`.
|
||||
|
||||
## Transitive startup objects
|
||||
|
||||
`crt/Makefile` compiles and partially links exactly these objects into one
|
||||
relocatable `crt1.o` with `prospero-lld -r`:
|
||||
|
||||
| Object | Public source | Role |
|
||||
|---|---|---|
|
||||
| `crt.o` | `crt/crt.c` | entry, BSS, init/run/terminate |
|
||||
| `syscall.o` | `crt/syscall.c` | syscall bootstrap |
|
||||
| `klog.o` | `crt/klog.c` | kernel log helpers |
|
||||
| `nid.o` | `crt/nid.c` | symbol-name encoding |
|
||||
| `kernel.o` | `crt/kernel.c` | kernel transport and process helpers |
|
||||
| `rtld.o` | `crt/rtld.c` | runtime-loader core |
|
||||
| `rtld_so.o` | `crt/rtld_so.c` | shared-object mapping and relocation |
|
||||
| `rtld_sprx.o` | `crt/rtld_sprx.c` | Sce module load/start/stop/unload |
|
||||
| `rtld_payload.o` | `crt/rtld_payload.c` | payload relocation and arrays |
|
||||
| `rtld_dlfcn.o` | `crt/rtld_dlfcn.c` | `dlopen`/`dlsym` facade |
|
||||
| `mdbg.o` | `crt/mdbg.c` | memory-debug transport helpers |
|
||||
| `patch.o` | `crt/patch.c` | credentials and syscall-bound patches |
|
||||
|
||||
The files named `crti.o`, `crtn.o`, `crtbegin.o`, `crtend.o`, `crtbeginS.o`,
|
||||
and `crtendS.o` are empty `ar` archives at the installed release. The audit
|
||||
enumerates them rather than assuming their filename implies contents.
|
||||
|
||||
## Reachable startup paths
|
||||
|
||||
The important conservative paths from source, relocations, and disassembly are:
|
||||
|
||||
```text
|
||||
_start
|
||||
|- zero [__bss_start, __bss_end)
|
||||
|- __crt_syscall_init
|
||||
|- __kernel_init
|
||||
| `- kernel_copyout (reachable in compiled object)
|
||||
|- __klog_init
|
||||
|- kernel_dynlib_dlsym -> set __isthreaded = 1
|
||||
|- __patch_init UNSAFE
|
||||
| |- kernel_get_ucred_caps -> kernel_copyout
|
||||
| |- kernel_get_ucred_attrs -> kernel_copyout
|
||||
| |- kernel_set_ucred_caps -> kernel_copyin KERNEL WRITE
|
||||
| |- kernel_set_ucred_attrs -> kernel_copyin KERNEL WRITE
|
||||
| `- kernel_copyin at process offsets 0xf0/0xf8 KERNEL WRITE
|
||||
|- __rtld_init UNSAFE
|
||||
| |- __rtld_sprx_init -> sceKernelLoadStartModule
|
||||
| |- __rtld_so_init
|
||||
| |- __rtld_payload_init
|
||||
| `- __rtld_dlfcn_init
|
||||
|- __rtld_payload_new/open/init
|
||||
| `- constructors
|
||||
|- main
|
||||
|- __rtld_lib_fini/close/destroy
|
||||
| `- destructors
|
||||
`- payload_terminate
|
||||
|- ret for the CRT's detected hijacked-process case
|
||||
|- resolved exit for another case
|
||||
`- trap when exit cannot be resolved
|
||||
```
|
||||
|
||||
Indirect calls are retained as `INDIRECT:<operand>` in the JSON graph rather
|
||||
than guessed. A relocation to the `sceKernelLoadStartModule` function-pointer
|
||||
slot is retained explicitly. This makes the graph conservative without
|
||||
inventing a firmware ABI.
|
||||
|
||||
## Linked but not startup-reachable
|
||||
|
||||
The monolithic `crt1.o` also contains `__dlopen`, `__dlsym`,
|
||||
`kernel_mprotect`, `kernel_overlap_sockets`, and
|
||||
`kernel_set_vmem_protection`, although the disassembly graph did not find them
|
||||
reachable from the stock `_start`. Their presence demonstrates why an import
|
||||
inventory alone would be insufficient: prohibited-capability code can be
|
||||
statically linked without appearing as an undefined symbol.
|
||||
|
||||
## Driver and linker behavior
|
||||
|
||||
The `prospero-clang` wrapper normally adds `crt1.o`, `libc`, `libkernel_web`,
|
||||
`libSceLibcInternal`, and `libSceNet`. A no-output `-###` trace with both
|
||||
`-nostartfiles` and `-nodefaultlibs` adds none of them. The linker wrapper still
|
||||
selects the public `elf_x86_64.x` script, PIE mode, an ELF x86-64 emulation,
|
||||
0x4000 maximum page size, emulated TLS support, and GNU hashing unless the
|
||||
caller overrides applicable options.
|
||||
|
||||
The linker script retains preinit/init/fini arrays and a dynamic segment. It
|
||||
also declares the text load segment with flags `0x7`; that is a source fact,
|
||||
not a claim about final loader-enforced permissions.
|
||||
|
||||
## Why there is no custom linker map
|
||||
|
||||
The loader return contract failed before the build gate. In accordance with
|
||||
the task rule, no custom `_start` source or PS5 ELF was created. Therefore a
|
||||
custom linker map, imports, `DT_NEEDED`, relocations, arrays, TLS inventory,
|
||||
double-build hash, and artifact disassembly are all explicitly recorded as
|
||||
`NOT_PERFORMED_BLOCKED_BEFORE_BUILD`, not silently treated as passing.
|
||||
|
||||
## Phase 0.6 exact runtime chain
|
||||
|
||||
This addendum is the reviewed source call graph for the installed chain. No new
|
||||
probe artifact exists, so there is no probe disassembly call graph to report.
|
||||
|
||||
```text
|
||||
Payload Manager /loadpayload:<path>
|
||||
`- ps5_launch_elf(path)
|
||||
|- open(path, O_RDONLY)
|
||||
|- connect(127.0.0.1:9021)
|
||||
`- send(ELF bytes)
|
||||
|
||||
elfldr serve_elfldr
|
||||
`- elfldr_spawn
|
||||
|- rfork_thread
|
||||
| `- child: elfldr_rfork_entry
|
||||
| |- sys_budget_set(0)
|
||||
| |- open(/dev/deci_{stdin,stdout,stderr})
|
||||
| |- ptrace(PT_TRACE_ME)
|
||||
| `- execve(SceSpZeroConf)
|
||||
|- parent: pt_syscall(599)
|
||||
| `- pt_syscall -> unbounded pt_step loop
|
||||
|- elfldr_set_heap_size(-1)
|
||||
|- kernel_mprotect(eboot entry page, RWX)
|
||||
|- install INT3 -> continue -> wait -> restore byte
|
||||
`- elfldr_exec
|
||||
|- backup jaildir/rootdir/caps/authid
|
||||
|- elfldr_raise_privileges
|
||||
| `- set rootdir/jaildir/UID/caps
|
||||
|- elfldr_prepare_exec
|
||||
| |- elfldr_load
|
||||
| | |- mmap/copy/RELATIVE relocations
|
||||
| | `- per-segment mprotect + msync
|
||||
| |- elfldr_payload_args
|
||||
| | |- mmap page
|
||||
| | |- two IPv6 sockets + overlap
|
||||
| | `- pipe + six payload_args_t fields
|
||||
| `- [RSP-8]=old RIP; RIP=entry; RDI=args
|
||||
|- restore jaildir/rootdir/caps/authid (not UID)
|
||||
`- ptrace(PT_DETACH)
|
||||
|
||||
SDK v0.41 payload _start
|
||||
|- clear BSS
|
||||
|- initialize syscall/kernel/klog
|
||||
|- __patch_init
|
||||
|- initialize rtld and constructors
|
||||
|- main
|
||||
|- destructors and rtld cleanup
|
||||
`- payload_terminate
|
||||
`- return OR exit OR trap (exact child branch unproven)
|
||||
```
|
||||
|
||||
The exact elfldr release binary is stripped, so the source graph is bound to
|
||||
the release by source commit and release-asset SHA-256. Static binary evidence
|
||||
records entry `0x4700`, 164 relocations, 24 undefined dynamic symbols, three
|
||||
`DT_NEEDED` modules, zero-byte init/fini arrays, no TLS, and hashes of the
|
||||
complete readelf report and disassembly in
|
||||
`manifests/runtime/phase-0.6-loader-runtime-audit.json`.
|
||||
|
||||
## Phase 0.7 hardened callgraph addendum
|
||||
|
||||
Phase 0.7 uses new hardened elfldr and controlled Payload Manager binaries;
|
||||
the graph above remains the historical stock Phase-0.6 chain.
|
||||
|
||||
The lifecycle source-level action is deliberately narrow:
|
||||
|
||||
```text
|
||||
SDK _start
|
||||
|- BSS and stock SDK v0.41 runtime initialization
|
||||
|- __patch_init
|
||||
|- main
|
||||
| |- sceKernelSendNotificationRequest
|
||||
| `- _exit
|
||||
`- payload_terminate [not reached from main]
|
||||
```
|
||||
|
||||
The hardened loader retains its required first-stage and ptrace operations,
|
||||
but each single-step operation now has both a one-second monotonic deadline
|
||||
and a 65,536-step ceiling. Cleanup tracks the child, breakpoint, mappings, and
|
||||
descriptors in one state. The success and failure paths restore all five
|
||||
credential fields and verify every restoration. The runtime supervisor waits
|
||||
at most 2000 ms, then uses a bounded SIGTERM/SIGKILL/reap sequence.
|
||||
|
||||
The controlled manager opens, hashes, rewinds, and streams one no-follow file
|
||||
descriptor. The hardened receiver independently rehashes the received bytes
|
||||
and checks the exact versioned header and permanent denylist.
|
||||
|
||||
The committed machine audit contains every extracted call edge, not a sample:
|
||||
|
||||
- lifecycle: 499 edges;
|
||||
- hardened elfldr: 1032 edges;
|
||||
- controlled manager: 478 edges.
|
||||
|
||||
Full disassembly, normalized linker maps, symbol/relocation/section reports,
|
||||
and text callgraphs are in the ignored `outputs/phase07/audit/` package. Their
|
||||
hashes and the complete edge arrays are committed in
|
||||
`manifests/runtime/phase-0.7-offline-audit.json`.
|
||||
Reference in New Issue
Block a user