Switch 2 jailbreak: the ns2jb FS flaw explained
How ns2jb gets from SmileBASIC into the Switch 2's file system: an integer overflow, a buffer overflow and a signature check sidestepped.
Three steps, from a Switch 1 game to the fs module
In his write-up dated 18 October 2026, published with the jailbreak on the 22nd, pepsipu (Sammy Hajhamid) describes the whole ns2jb chain. The author had Codex, OpenAI's coding agent, hunt for the flaws, and says the jailbreak took him two weeks of work. In short:
1. SmileBASIC: a calculation that overflows
pepsipu ruled out the Switch 2's browser: WebKit there is protected by execute-only memory, signed pointers (PAC) and call checks (CFI). A Switch 1 game is more vulnerable, since the Switch 1 has no PAC, and its code can be decrypted because that console is fully hacked. SmileBASIC had already been exploited on the 3DS (smilehax).
The flaw is in the REMOVE command, which removes elements from an array. It checks that “position + count” does not exceed the array's size, but the sum is computed on 32 bits and can wrap into a negative number. With REMOVE R,&H60000000,&H3FFFFFFF, the check passes, and the copy that follows pulls into the array the 8 bytes located just before it in memory. Those 8 bytes hold a pointer to the array itself: the first element becomes a string of enormous length, which allows reading and writing outside the array. That is the “Out of memory” you see while ns2jb launches: the error comes after the copy.
2. The fs module: a 0x301-byte buffer
fs handles every file access, and it is the one that serves the programs' decrypted code to the loader. Its flaw is in path normalisation. When a path contains a parent-directory component written with a backslash, such as “/..\”, a function allocates a temporary buffer of 0x301 bytes (769) and copies the path into it without checking its length. pepsipu's summary: “lol”.
The overflow reaches a neighbouring structure: the cache of an open file (BufferedStorage). By rewriting that cache's pointer, the file's reads and writes go wherever you want: that is read and write access to all of fs's memory. pepsipu then finds SmileBASIC's connection in that memory and changes its process ID to 1. From then on, fs treats it with “ FullPermission ”: the whole file system is accessible. That is what let him copy the internal storage, and what makes possible today the first game dumps.
3. The signature sidestepped by a swap
To launch a program, the loader (ldr) asks fs to open its “ExeFS” file system, which holds the executable and its permissions (main.npdm). It checks two signatures: Nintendo's on the permissions, and the developer's on the package header. The chain is sound on one condition: that fs really serves the files matching that header.
But fs is under control. ns2jb lets fs send the header and signature of a genuine program, then, at the right moment, swaps the file system served to the loader for its own: the genuine main.npdm, but an executable of its choosing. So that the swap lands between the loader's two requests, it also replaces the event fs waits on with an event SmileBASIC triggers itself.
Finally, pepsipu borrows the permissions of ro, the only ordinary module allowed to create executable code. His program then opens a writable view of fs's code and patches it live.
What is still missing
Sources: pepsipu's write-up · ns2jb (GitLab)
Three steps, from a Switch 1 game to the fs module
In his write-up dated 18 October 2026, published with the jailbreak on the 22nd, pepsipu (Sammy Hajhamid) describes the whole ns2jb chain. The author had Codex, OpenAI's coding agent, hunt for the flaws, and says the jailbreak took him two weeks of work. In short:
- run code inside SmileBASIC 4, a Switch 1 program that also runs on the Switch 2;
- corrupt the memory of the fs system module, which handles the console's files;
- use it to launch his own code with a system module's rights.
1. SmileBASIC: a calculation that overflows
pepsipu ruled out the Switch 2's browser: WebKit there is protected by execute-only memory, signed pointers (PAC) and call checks (CFI). A Switch 1 game is more vulnerable, since the Switch 1 has no PAC, and its code can be decrypted because that console is fully hacked. SmileBASIC had already been exploited on the 3DS (smilehax).
The flaw is in the REMOVE command, which removes elements from an array. It checks that “position + count” does not exceed the array's size, but the sum is computed on 32 bits and can wrap into a negative number. With REMOVE R,&H60000000,&H3FFFFFFF, the check passes, and the copy that follows pulls into the array the 8 bytes located just before it in memory. Those 8 bytes hold a pointer to the array itself: the first element becomes a string of enormous length, which allows reading and writing outside the array. That is the “Out of memory” you see while ns2jb launches: the error comes after the copy.
2. The fs module: a 0x301-byte buffer
fs handles every file access, and it is the one that serves the programs' decrypted code to the loader. Its flaw is in path normalisation. When a path contains a parent-directory component written with a backslash, such as “/..\”, a function allocates a temporary buffer of 0x301 bytes (769) and copies the path into it without checking its length. pepsipu's summary: “lol”.
The overflow reaches a neighbouring structure: the cache of an open file (BufferedStorage). By rewriting that cache's pointer, the file's reads and writes go wherever you want: that is read and write access to all of fs's memory. pepsipu then finds SmileBASIC's connection in that memory and changes its process ID to 1. From then on, fs treats it with “ FullPermission ”: the whole file system is accessible. That is what let him copy the internal storage, and what makes possible today the first game dumps.
3. The signature sidestepped by a swap
To launch a program, the loader (ldr) asks fs to open its “ExeFS” file system, which holds the executable and its permissions (main.npdm). It checks two signatures: Nintendo's on the permissions, and the developer's on the package header. The chain is sound on one condition: that fs really serves the files matching that header.
But fs is under control. ns2jb lets fs send the header and signature of a genuine program, then, at the right moment, swaps the file system served to the loader for its own: the genuine main.npdm, but an executable of its choosing. So that the swap lands between the loader's two requests, it also replaces the event fs waits on with an event SmileBASIC triggers itself.
Finally, pepsipu borrows the permissions of ro, the only ordinary module allowed to create executable code. His program then opens a writable view of fs's code and patches it live.
What is still missing
- the jailbreak is tethered: everything must be redone at every boot, from SmileBASIC and a computer;
- only fs is compromised among the system's built-in modules: there is no custom firmware;
- the fs flaw itself does not depend on SmileBASIC. pepsipu suggests exploiting it from the browser, which Nintendo cannot withdraw like an eShop game;
- the chain also works on the Switch 1, with no added hardware, but the author has not released it for that console yet.
Sources: pepsipu's write-up · ns2jb (GitLab)
No comments