3DS System Flaws: Difference between revisions
New 0day. By the way this was fixed in Luma3DS's reimpl since 2017 →FIRM Sysmodules |
Disclose flaws following 11.14 release |
||
Line 326: | Line 326: | ||
| August 11, 2018 | | August 11, 2018 | ||
| smea | | smea | ||
|- | |||
| agbhax | |||
| This is the same issue as twlhax above. Legacy FIRMs share the same OS code (Arm9-side OS, Arm11 kernel), and therefore, the outdated AGB_FIRM can be tricked into executing the still vulnerable PrepareArm9ForTwl function. | |||
| ARM9 code execution (whilst still in 3DS mode) | |||
| None | |||
| [[11.14.0-46|11.14.0-X]] | |||
| | |||
| December 17, 2020 | |||
| Everyone | |||
|- | |- | ||
| safefirmhax | | safefirmhax | ||
Line 636: | Line 645: | ||
! Timeframe this was discovered | ! Timeframe this was discovered | ||
! Discovered by | ! Discovered by | ||
|- | |||
| [[SVC|svcUnbindInterrupt]] double free when irqId = 15 | |||
| svcBindInterrupt and svcUnbindInterrupt give special treatment to irqId 15 (FIQ helper): the access control list is bypassed and the provided KInterruptEvent (event or semaphore, via handle) is stored inside a singleton static object after having its refcount increased by 1. | |||
svcUnbindInterrupt assumes that the user-provided handle is what is stored in the singleton and will decref the user-provided KInterruptEvent twice, causing a use-after-free if the attacker didn't actually provide an handle to the same event or semaphore. | |||
This was "fixed" on [[11.14.0-46|11.14.0-X]] by preventing irqId 15 to be bound on retail units altogether (in both functions). | |||
| Arm11 kernel code execution | |||
| [[11.14.0-46|11.14.0-X]] (only on retail units) | |||
| [[11.14.0-46|11.14.0-X]] | |||
| 2019 | |||
| [[User:TuxSH|TuxSH]], maybe others | |||
|- | |||
| [[SVC|svcKernelSetState]] op=3 could map the NULL page | |||
| svcKernelSetState op=3 param1=1 maps the firmlaunch parameters page to the user-specified VA. | |||
It had previously no check, allowing the attacker to map data at VA 0. | |||
Starting from [[11.14.0-46|11.14.0-X]], the VA must be in the standard 0x10000000-0x14000000 address range. | |||
| Mapping the NULL page (as RW) to leverage other kernel vulnerabilities | |||
| [[11.14.0-46|11.14.0-X]] | |||
| [[11.14.0-46|11.14.0-X]] | |||
| 2019 | |||
| [[User:TuxSH|TuxSH]] | |||
|- | |||
| [[SVC|svcMapProcessMemory]] can map the NULL page | |||
| svcMapProcessMemory's destination VA is unchecked. | |||
By passing a big enough "size" parameter, an attacker can map chunks of data at VA 0 in the destination (caller) process. | |||
| Mapping the NULL page (as RW) to leverage other kernel vulnerabilities | |||
| None | |||
| [[11.14.0-46|11.14.0-X]] | |||
| 2020 | |||
| [[User:TuxSH|TuxSH]] | |||
|- | |||
| Resource limit use-after-free | |||
| When assigning a KResourceLimit to a KProcess, the reslimit's refcounter doesn't get incremented. This essentially means all KResourceLimit get freed if pm gets somehow terminated. | |||
It turns out it is possible to ask pm (via ns:s or pm:app) to terminate itself along all other KIPs simply by passing TID 0004000100001000. | |||
Calling [[SVC|svcGetResourceLimit]] afterwards triggers a use-after-free. This is rather difficult to exploit, however: there is one slot left in the reslimit slabheap. An attacker either has to map the NULL page as R(W)X (svcControlProcessMemory vuln fixed on [[11.8.0-41|11.8.0-X]]), or use one of the map-null exploits above while having access to svcCreateResourceLimit (with the only one that is easy enough to use in that context having been fixed on [[11.14.0-46|11.14.0-X]], anyway). | |||
| Arm11 kernel code execution | |||
| None (although near impossible to exploit on [[11.14.0-46|11.14.0-X]]) | |||
| [[11.14.0-46|11.14.0-X]] | |||
| 2020 | |||
| [[User:TuxSH|TuxSH]] | |||
|- | |- | ||
| [[SVC|svcSetProcessIdealProcessor]] reference count overflow and therefore use-after-free. | | [[SVC|svcSetProcessIdealProcessor]] reference count overflow and therefore use-after-free. |