Files
Tushar Rohilla e5295f36aa Add Afterglow 1.0.6, a PS5 internet radio and music visualizer
222 stations in 17 genres, 56 visualizer scenes, Ogg and Opus playback, station logos, crossfade, My Music from USB, a command box and live BPM sync.
2026-10-16 00:59:10 -04:00

5.8 KiB

Lapy sandbox elevation

This optional example embeds the exact-title one-shot helper from upstream PS5-Lapy-JB-Daemon. The boilerplate does not fork or reimplement Lapy's kernel backend. Its build fetches a pinned upstream commit, invokes Lapy's own owned-helper target, checks the generated manifest and packages the resulting ELF and MIT license.

The old boilerplate raw-pointer helper and its later copied Lapy backend remain deleted. Kernel ownership, runtime layout checks and firmware behavior stay in one upstream implementation.

Build integration

Set APP_LAPY_HELPER=1 for an application that compiles the client:

APP_SOURCE_DIR=examples/sandbox-elevation/src \
APP_PARAM=examples/sandbox-elevation/sce_sys/param.json \
APP_SCE_SYS=sce_sys APP_ASSETS= APP_LAPY_HELPER=1 \
bash tools/build.sh Folder

Or build the included proof title:

make sandbox-elevation-example

The helper title is read from the selected param.json; wildcard helpers are not built. The package contains:

lapy.elf
lapy-manifest.json
licenses/Lapy-MIT.txt

The build verifies the manifest schema, exact title, one-request helper mode, ELF and protocol hashes, and root_layout_probe_retry feature before copying those files. Lapy, its ps5log build input and the compatible Payload SDK are cached under ignored .deps/lapy/.

Application API

Compile examples/sandbox-elevation/src/elevation.cpp, keep elevation.hpp and protocol.hpp beside it, and call the client once during single-threaded startup:

const auto result = elevation::request(elevation::Capability::filesystem);
if (result == elevation::Status::ok)
{
    // /data write/read was verified; privileged initialization may continue.
}

elevation::path() reports existing, resident, helper, or none for diagnostics.

The runtime sequence is:

  1. Probe /data; return immediately when access already exists. Access means a file can be created, written and read back and /data can be listed. ShadowMountPlus 1.7 mounts /data into a sandboxed app: files open and write there, but listing a folder or lstat is refused (EPERM), the app still runs as uid 1, and libcurl can't start. That is not elevation, so the request goes on to Lapy: Lapy runs only when it is needed.
  2. Publish the cooperative resident request through /download0/elevate_proc and wait 1.5 seconds.
  3. If a resident service claimed the marker, never launch a second helper for that title launch.
  4. Otherwise cancel the marker, observe one final grace interval, stream /app0/lapy.elf to the local ELF loader on TCP port 9021 and complete upstream's request/prepare/prepared/response exchange on that connection.
  5. Return Status::ok only after creating, writing, reading, comparing and removing a PID-specific probe under /data, and listing /data.

The jailbreak environment must provide the local ELF loader on port 9021 when a resident Lapy service is not already running. downloadDataSize must be positive in sce_sys/param.json. A missing loader, rejection, timeout or failed /data proof never authorizes privileged work.

Pinned upstream inputs

tools/build-lapy-helper.py pins:

  • Lapy commit 57fcc19b7f57e46c823d6f2a6c6233ebf3288079, in BlackBearReloaded's fork, which carries the changes proposed upstream in PRs #48, #49 and #50;
  • official PS5 Payload SDK v0.42, used only for the helper; it knows firmware 13.40 to 13.60; and
  • the pinned ps5log/1 header used by upstream's build.

The normal boilerplate application build continues to use Payload SDK v0.42. The two toolchains are deliberately separate.

Validation and firmware caveats

Run the host exchange tests with:

make test-elevation

The tests cover resident success, resident claim without fallback, partial socket transfers, helper rejection, client preparation failure, corrupt data proof and the fixed 24-byte wire ABI. Host tests cannot establish kernel or firmware safety.

Upstream documents console validation of the helper lifecycle on firmware 12.02. The exact pinned helper was also qualified through this boilerplate on firmware 6.02 and 12.70 on 2026-10-04. Each console completed five consecutive launch/elevate/close cycles. All ten runs:

  • used the embedded one-shot helper (build ID a91ff858a91effc48c2b62f0f4e92f7b92c2015b3a3d20a793a9946ff4c208e1);
  • reached UID/GID 0 and completed a PID-specific write/read/remove proof under /data;
  • reported exactly two donor processes and reaped both; and
  • left FTP, the kernel-log service and elfldr responsive, with no fatal signal, app-crash, coredump, nonsleeping-lock, trap or panic marker in the captured kernel logs.

That is strong functional evidence for those two tested environments, not a universal or long-term kernel-stability guarantee. Other firmware, jailbreak and elfldr combinations remain experimental and need the same qualification. Never fall back to a raw-pointer helper when Lapy rejects a target.

Credits and licenses

Lapy was created by ArkSama / Team PHU. The cooperative exact-title helper used here is maintained in mpereiraesaa's fork. Credit belongs to both projects and their contributors.

Lapy is MIT licensed; its published shared protocol header is LGPL-2.1-or-later. The pinned ps5log build input is GPL-3.0-or-later. Their source references and roles are recorded in THIRD_PARTY_NOTICES.md.