PS5 jailbreak via the Y2JB. Ports Gezine's p2jb kqueueex cr_ref overflow
JavaScript
277
20 commits
updated May 28, 2026
PlayStation 5 jailbreak (firmware 9.00 – 12.40)
— a port of Gezine / cheburek3000's
p2jb kernel exploit (cr_ref
overflow via kqueueex) from the luac0re (lua-loader) host to
Y2JB (YouTube / V8 JavaScript host).
Confirmed working: jailbreak end-to-end + GPU-DMA debug menu + ELF loader (delivered automatically by the Y2JB host) + persistent unpatcher delivery. Closing the YouTube host app after completion no longer kernel-panics the console.
Firmware support: works on 9.00 – 12.40.
The payload triggers a 32-bit cr_ref overflow in the PS5 kernel
(via ~2³² kqueueex syscalls, ~50 minutes), uses the resulting
use-after-free to build a kernel read/write primitive, escalates the
host process to root, enables the Debug Settings menu via GPU DMA
writes on the read-only kernel .data segment, then delivers an
ELF loader inside the YouTube process. The binary and delivery
mechanism depend on the installed Y2JB version (see
PS5 setup (Y2JB) below). Either way the loader
ends up listening on TCP :9021 for ELFs to run on the
jailbroken PS5.
This payload runs inside the Y2JB userland framework on the PS5 (the YouTube TV app modded to run arbitrary JavaScript). Before you can send anything to the console, you must restore Gezine's Y2JB system backup on the PS5 — see Gezine/Y2JB for the backup file and the restore procedure. Without Y2JB restored and the YouTube TV app launched, the PS5 has no listener for the payload and nothing will happen.
Y2JB 1.3 or newer. The ELF loader is delivered differently
depending on Y2JB version. The payload detects the framework
version at runtime (from Y2JB's version_string global) and picks
the matching path automatically — you don't need to configure
anything.
kexp
shellcode (load_aioshellcode), which loads
elfldr-ps5-0.23.elf from inside the framework. No USB, nothing
to provide.elfldr_1320_v5.elf directly
from the Y2JB sandbox slot — no USB needed.elfldr.elf that does
not work on the current kernels, so the payload reads
elfldr_1320.elf from a USB stick plugged into the PS5
(/mnt/usb0 ... /mnt/usb7). Grab elfldr_1320_v5.elf from this
repo, put it on the root of a FAT32/exFAT USB (you can rename it
to elfldr_1320.elf or elfldr.elf if you prefer — all three are
probed), and plug the USB in before launching the payload.At the very start the payload checks the framework helpers it needs are in scope: if anything is missing it aborts before touching the kernel (no leak, no stage 0).
elfldr_1320.elf
on its root. On Y2JB 1.4+ no USB is needed.payload_sender.py delivery tool from
Gezine/Y2JB (not included here).:9021.p2jb.js — the jailbreak payload (this repo).elfldr_1320_v5.elf — Gezine's ELF loader binary, included here
for Y2JB 1.3 users who need to provide it via USB. Y2JB 1.4 bundles
the same file inside the framework; Y2JB 1.5+ ships its own bundled
elfldr-ps5-0.23.elf instead. In either of those two cases you can
ignore this file.From the PC:
python payload_sender.py <ps5-ip> p2jb.js
The payload streams its log back to payload_sender.py's console.
The cr_ref leak dominates the runtime. The payload sender will stay
silent for the whole leak — no per-percentage progress is printed.
Don't assume it has crashed; the worker is internally checked for
liveness and a stall would surface as a FATAL log line. Do not
interact with the PS5 while it runs.
[p2jb] stage_elfldr: elfldr launched - listening on :9021
[p2jb] === p2jb complete ===
At this point you have an in-memory jailbreak and a generic ELF loader.
Any ELF you send to :9021 will run on the jailbroken PS5.
:9021A convenient tool for delivering ELFs to the loader is Al-Azif/hermes-link. It takes care of the TCP handshake the loader expects, so you don't have to write the byte protocol yourself.
The cr_ref leak runs across multiple pinned worker threads in
parallel. The default is 4 cores (cores 0–3; core 4 stays free for
the orchestrator):
// p2jb.js
const LEAK_CORES = [0, 1, 2, 3]; // ~48 min, default
On hardware that's unstable at 4 cores (kernel panics during the leak
phase, or runs that never reach Stage 0), dropping to fewer cores
trades wall-clock time for stability — fewer parallel workers means
less contention on the kernel kqueueex allocator and a markedly
higher chance of completing.
LEAK_CORES | wall time | notes |
|---|---|---|
[0, 1, 2, 3] | ~50 min | default — fastest, less stable |
[0, 1, 2] | ~1h | three-core (slightly more stable) |
[0, 1] | ~1h 30 min | middle ground |
[0] | ~2h | single-core — slowest, most stable |
To change it: open p2jb.js, search for LEAK_CORES, edit the array,
save the file, and run payload_sender.py as usual. Try the default
first; only fall back to fewer cores if you see kernel panics during
the leak or if Stage 0 doesn't appear after well over an hour.
p2jb.fail marker is dropped at stage 0 entry
to refuse re-runs without a reboot — the triple-free is a point of
no return.:9021. Keep YouTube open until your persistent
payload (e.g. BD-UN-JB) has
applied; afterwards you can close the app normally.I don't normally work on PS5 exploits or low-level reverse engineering. This repository is the result of a personal attempt to understand how the scene's techniques work — not a contribution from a scene developer. I'm publishing it in case it's useful to someone on firmware 11.60 who is stuck, but please don't read it as me claiming expertise on the topic. The real work is by the people credited below; I just tried to glue their primitives into a working flow on the Y2JB host and learn along the way.
p2jb kernel exploit (cr_ref overflow via kqueueex) —
Gezine / cheburek3000.
Luac0re.kexp post-jailbreak all-in-one shellcode — ufm42
(kexp), merged into Y2JB 1.4.remote_lua_loader p2jb port — notmaj0r.
Used as a secondary reference during the port.gpu.js debug-menu apply
flow; not the exploit itself (lapse exploits AIO, not kqueueex).cr_ref leak down from ~2 hours to ~48 minutes.MIT — see LICENSE.
JavaScript
100.0%
PS5 jailbreak via the Y2JB. Ports Gezine's p2jb kqueueex cr_ref overflow
JavaScript
277
20 commits
updated May 28, 2026
PlayStation 5 jailbreak (firmware 9.00 – 12.40)
— a port of Gezine / cheburek3000's
p2jb kernel exploit (cr_ref
overflow via kqueueex) from the luac0re (lua-loader) host to
Y2JB (YouTube / V8 JavaScript host).
Confirmed working: jailbreak end-to-end + GPU-DMA debug menu + ELF loader (delivered automatically by the Y2JB host) + persistent unpatcher delivery. Closing the YouTube host app after completion no longer kernel-panics the console.
Firmware support: works on 9.00 – 12.40.
The payload triggers a 32-bit cr_ref overflow in the PS5 kernel
(via ~2³² kqueueex syscalls, ~50 minutes), uses the resulting
use-after-free to build a kernel read/write primitive, escalates the
host process to root, enables the Debug Settings menu via GPU DMA
writes on the read-only kernel .data segment, then delivers an
ELF loader inside the YouTube process. The binary and delivery
mechanism depend on the installed Y2JB version (see
PS5 setup (Y2JB) below). Either way the loader
ends up listening on TCP :9021 for ELFs to run on the
jailbroken PS5.
This payload runs inside the Y2JB userland framework on the PS5 (the YouTube TV app modded to run arbitrary JavaScript). Before you can send anything to the console, you must restore Gezine's Y2JB system backup on the PS5 — see Gezine/Y2JB for the backup file and the restore procedure. Without Y2JB restored and the YouTube TV app launched, the PS5 has no listener for the payload and nothing will happen.
Y2JB 1.3 or newer. The ELF loader is delivered differently
depending on Y2JB version. The payload detects the framework
version at runtime (from Y2JB's version_string global) and picks
the matching path automatically — you don't need to configure
anything.
kexp
shellcode (load_aioshellcode), which loads
elfldr-ps5-0.23.elf from inside the framework. No USB, nothing
to provide.elfldr_1320_v5.elf directly
from the Y2JB sandbox slot — no USB needed.elfldr.elf that does
not work on the current kernels, so the payload reads
elfldr_1320.elf from a USB stick plugged into the PS5
(/mnt/usb0 ... /mnt/usb7). Grab elfldr_1320_v5.elf from this
repo, put it on the root of a FAT32/exFAT USB (you can rename it
to elfldr_1320.elf or elfldr.elf if you prefer — all three are
probed), and plug the USB in before launching the payload.At the very start the payload checks the framework helpers it needs are in scope: if anything is missing it aborts before touching the kernel (no leak, no stage 0).
elfldr_1320.elf
on its root. On Y2JB 1.4+ no USB is needed.payload_sender.py delivery tool from
Gezine/Y2JB (not included here).:9021.p2jb.js — the jailbreak payload (this repo).elfldr_1320_v5.elf — Gezine's ELF loader binary, included here
for Y2JB 1.3 users who need to provide it via USB. Y2JB 1.4 bundles
the same file inside the framework; Y2JB 1.5+ ships its own bundled
elfldr-ps5-0.23.elf instead. In either of those two cases you can
ignore this file.From the PC:
python payload_sender.py <ps5-ip> p2jb.js
The payload streams its log back to payload_sender.py's console.
The cr_ref leak dominates the runtime. The payload sender will stay
silent for the whole leak — no per-percentage progress is printed.
Don't assume it has crashed; the worker is internally checked for
liveness and a stall would surface as a FATAL log line. Do not
interact with the PS5 while it runs.
[p2jb] stage_elfldr: elfldr launched - listening on :9021
[p2jb] === p2jb complete ===
At this point you have an in-memory jailbreak and a generic ELF loader.
Any ELF you send to :9021 will run on the jailbroken PS5.
:9021A convenient tool for delivering ELFs to the loader is Al-Azif/hermes-link. It takes care of the TCP handshake the loader expects, so you don't have to write the byte protocol yourself.
The cr_ref leak runs across multiple pinned worker threads in
parallel. The default is 4 cores (cores 0–3; core 4 stays free for
the orchestrator):
// p2jb.js
const LEAK_CORES = [0, 1, 2, 3]; // ~48 min, default
On hardware that's unstable at 4 cores (kernel panics during the leak
phase, or runs that never reach Stage 0), dropping to fewer cores
trades wall-clock time for stability — fewer parallel workers means
less contention on the kernel kqueueex allocator and a markedly
higher chance of completing.
LEAK_CORES | wall time | notes |
|---|---|---|
[0, 1, 2, 3] | ~50 min | default — fastest, less stable |
[0, 1, 2] | ~1h | three-core (slightly more stable) |
[0, 1] | ~1h 30 min | middle ground |
[0] | ~2h | single-core — slowest, most stable |
To change it: open p2jb.js, search for LEAK_CORES, edit the array,
save the file, and run payload_sender.py as usual. Try the default
first; only fall back to fewer cores if you see kernel panics during
the leak or if Stage 0 doesn't appear after well over an hour.
p2jb.fail marker is dropped at stage 0 entry
to refuse re-runs without a reboot — the triple-free is a point of
no return.:9021. Keep YouTube open until your persistent
payload (e.g. BD-UN-JB) has
applied; afterwards you can close the app normally.I don't normally work on PS5 exploits or low-level reverse engineering. This repository is the result of a personal attempt to understand how the scene's techniques work — not a contribution from a scene developer. I'm publishing it in case it's useful to someone on firmware 11.60 who is stuck, but please don't read it as me claiming expertise on the topic. The real work is by the people credited below; I just tried to glue their primitives into a working flow on the Y2JB host and learn along the way.
p2jb kernel exploit (cr_ref overflow via kqueueex) —
Gezine / cheburek3000.
Luac0re.kexp post-jailbreak all-in-one shellcode — ufm42
(kexp), merged into Y2JB 1.4.remote_lua_loader p2jb port — notmaj0r.
Used as a secondary reference during the port.gpu.js debug-menu apply
flow; not the exploit itself (lapse exploits AIO, not kqueueex).cr_ref leak down from ~2 hours to ~48 minutes.MIT — see LICENSE.
JavaScript
100.0%