Switch System Flaws: Difference between revisions
(11 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
This page is a list of publicly known Switch flaws. | |||
= Hardware = | = Hardware = | ||
Line 464: | Line 464: | ||
|} | |} | ||
== | == BootImagePackage System Modules == | ||
Flaws in this category pertain to any of the [[Package2#Section_1|built-in system modules]]. | Flaws in this category pertain to any of the [[Package2#Section_1|built-in system modules]]. | ||
Line 1,004: | Line 1,004: | ||
| February 25, 2022 | | February 25, 2022 | ||
| October 24, 2023 | | October 24, 2023 | ||
| [[User:Yellows8|yellows8]] | |||
|- | |||
| [[Audio_services|audctl]] GetTargetDeviceInfo infoleak | |||
| audctl GetTargetDeviceInfo calls an impl func with a ptr to a stackbuf, then if successful memcpys the 0x100-bytes from that buffer to output. This stackbuf is not memset. This func (after doing various state checks) copies a string to output, other than always writing a NUL-terminator there's no clearing of the buffer. | |||
This will leak audio-sysmodule stack into the output buffer as long as the state/input checks pass (for the remainder of the buffer following the string NUL-terminator). | |||
With [18.0.0+] data is written directly to the outbuf instead of the stack tmpbuf. | |||
| audio-sysmodule infoleak, which allows defeating ASLR. | |||
| [[18.0.0]] | |||
| [[18.0.0]] | |||
| December 24, 2022 | |||
| March 26, 2024 | |||
| [[User:Yellows8|yellows8]] | |||
|- | |||
| [[Audio_services|audctl]] GetSystemInformationForDebug infoleak / buffer overflow | |||
| audctl GetSystemInformationForDebug calls a func with a 0x1000-byte stack tmpbuf, then afterwards that buffer is memcpy'd into the cmd outbuf. This called func doesn't clear the buffer. This func eventually uses [[BTM_services|btm]] cmd75 with outarray={global ptr} and count=10. Then if the outcount is s32 >=1, it loops through the output using the outcount, without validating it besides the <1 check. Data from that outarray is copied into the array in the func output buffer (tmpbuf above). | |||
With btm comprimised, one could return a large output count and trigger a stack buffer overflow with data following that global array, however exploiting this would be difficult since that data would be uncontrolled (can't directly control it from this cmd at least). | |||
A stack infoleak can be obtained with this as well (assuming the above output array isn't full). | |||
Even though the name has "ForDebug", there's no checks which would trigger an error / return early (this also always returns 0). | |||
[18.0.0+] now clears the output buffer, and also now prints strings into the buffer instead of writing binary data (overflow no longer possible). | |||
| audio-sysmodule infoleak, which allows defeating ASLR. Also audio-sysmodule memory corruption, likely not useful unless there's a way to control the data. | |||
| [[18.0.0]] | |||
| [[18.0.0]] | |||
| December 7, 2022 | |||
| March 27, 2024 | |||
| [[User:Yellows8|yellows8]] | |||
|- | |||
| [[Migration_services|migration]] nn::migration::savedata::IServer cmd1 buffer overflow | |||
| nn::migration::savedata::IServer cmd1 with [18.0.0-18.0.1] copies data from an array to the output ptr. As the output is an u64 field for the IPC cmd output, this is a field on stack. Hence, if more than 1 entry (8-bytes) are copied a stack buffer overflow will occur. Note that cmd3 loads the same data, except this has a proper output array. | |||
It's unknown whether there's a way to actually control this data with a large enough enough size. | |||
See [[18.1.0]] for the diff/fix. | |||
| [[Migration_services|migration]] stack buffer overflow, only on [18.0.0-18.0.1]. | |||
| [[18.1.0]] | |||
| [[18.1.0]] | |||
| June 11, 2024 | |||
| June 11, 2024 | |||
| [[User:Yellows8|yellows8]] (sysupdate diff) | |||
|- | |||
| [[SSL_services|ssl]] broken RNG | |||
| [[SSL_services|ssl]] uses nn::os::GenerateRandomBytes, but not [[SPL_services|spl]] GenerateRandomBytes. See the RNG entries elsewhere. This is used to seed the NSS global RNG (drbg.c, RNG_GenerateGlobalRandomBytes etc). | |||
If one could somehow determine the data which was returned by nn::os::GenerateRandomBytes during seeding (which is likely difficult), the global RNG would be broken. | |||
With [19.0.0+] nn::os::GenerateRandomBytes usage was replaced with [[SPL_services|spl]] GenerateRandomBytes. | |||
| Breaking [[SSL_services|ssl]] global RNG -> potentially predict RNG data (keys(?)) during TLS comms. | |||
| [[19.0.0]] | |||
| [[19.0.0]] | |||
| December 14, 2021 | |||
| October 8, 2024 | |||
| [[User:Yellows8|yellows8]] | |||
|- | |||
| [[Audio_services|audren]] uncleared TransferMemory | |||
| audren OpenAudioRenderer uses the input tmem as workmem. The IAudioRenderer dtor doesn't clear the workmem properly. Depending on input params, certain objects stored here have vtables - hence infoleak. | |||
The exact location in the workmem will vary depending on the input params - these objects are dynamically allocated in the workmem. | |||
The following will leak vtables: Sink, Effect. | |||
If the initialization func fails, the tmem is unmapped without clearing it first. It's unknown whether there's a way to actually trigger an infoleak with this however. With [19.0.0+] it's now cleared on failure. | |||
With [19.0.0+] the dtor now clears the workmem when needed. | |||
| Reading leaked data/ptrs from TransferMemory -> defeating ASLR in [[Audio_services|audio]]-sysmodule. | |||
| [[19.0.0]] | |||
| [[19.0.0]] | |||
| December 17, 2022 | |||
| October 13, 2024 | |||
| [[User:Yellows8|yellows8]] | |||
|- | |||
| [[Audio_services|audren]] UpdateMixes OOB mem-copy | |||
| With nn::audio::server::InfoUpdater::UpdateMixes when nn::audio::server::BehaviorInfo::IsMixInParameterDirtyOnlyUpdateSupported() returns true (requires REV7, which is [7.0.0+]), the mix_id from user input is used without validation as input to <code><nn::audio::server::MixContext::GetInfo(int) const></code>, instead of the counter from the for-loop. This allows one to control the destination MixInfo index which the user-input data is written into. If too large, this will trigger OOB data-copy. Note that the u8 at dest_MixInfo+12 must be non-zero. | |||
Also note that a field is loaded from dest_MixInfo which is used as a splitter_id, so splitters need to be initialized where count is large enough for that id. | |||
With [19.0.0+] after getting the mix_id (loop-index/input) it now does: <code>if (mix_id < 0 || mix_id >= nn::audio::server::MixContext::GetCount()) continue;</code> | |||
| OOB mem-copy in [[Audio_services|audio]]-sysmodule, which for example can be used to overwrite a vtable used immediately after UpdateMixes. | |||
| [[19.0.0]] | |||
| [[19.0.0]] | |||
| December 19, 2022 | |||
| October 13, 2024 | |||
| [[User:Yellows8|yellows8]] | |||
|- | |||
| [[Bus_services|sasbus]] StartPeriodicReceiveMode infoleak | |||
| StartPeriodicReceiveMode writes a vtable ptr into the mapped tmem at +0. The tmem is mapped RW in the user-process. There is no clearing of tmem during tmem cleanup. Hence, the user-process can read the tmem to obtain a Bus-sysmodule codebin-region infoleak. This vtable-ptr seems to be unused - it's also empty after the first two entries (stubbed incref/decref). | |||
[20.0.0+] Removed the vtable ptr, with data intended for the user-process being moved from tmem+0x8 to +0x0. Also, instead of calling memset, funcs are called for manually clearing tmem. | |||
| Bus-sysmodule infoleak, which allows defeating ASLR. | |||
| [[20.0.0]] | |||
| [[20.0.0]] | |||
| February 22, 2022 | |||
| May 3, 2025 | |||
| [[User:Yellows8|yellows8]] | |||
|- | |||
| [[NFC_services|nfc]] SendCommandByPassThrough buffer overflow | |||
| SendCommandByPassThrough eventually copies the input buffer into a fixed-size heap buffer, without size validation. | |||
This was fixed with [20.0.0+] by clamping the size. | |||
| nfc-sysmodule heap buffer overflow. | |||
| [[20.0.0]] | |||
| [[20.0.0]] | |||
| Late November 2021 | |||
| May 3, 2025 | |||
| [[User:Yellows8|yellows8]] (maybe others?) | |||
|- | |||
| [[HID_services|hidbus]] EnableJoyPollingReceiveMode infoleak | |||
| The tmem initialized by hidbus EnableJoyPollingReceiveMode contains a vtable ptr (tmem+0x10), hence infoleak. With [20.0.0+] the vtable ptr write was removed, and tmem is now memset starting at tmem+0x10 instead of +0x20. | |||
| hid-sysmodule infoleak, which allows defeating ASLR. | |||
| [[20.0.0]] | |||
| [[20.0.0]] | |||
| March 2020 | |||
| May 4, 2025 | |||
| [[User:Yellows8|yellows8]] | | [[User:Yellows8|yellows8]] | ||
|} | |} | ||
Line 1,054: | Line 1,165: | ||
| | | | ||
| Everyone | | Everyone | ||
|- | |||
| Web-applets OpenSSL broken RNG | |||
| [[SPL_services|csrng]] access was added to web-applets with [12.1.0+]. Prior to that, csrng and nn::os::GenerateRandomBytes were not used (besides sdk heap code). | |||
nn::os::GetSystemTick is used to seed the OpenSSL RNG, among other data. Hence, it's probably (?) possible to bruteforce the RNG initial state, allowing predicting RNG output. | |||
The RNG code is wkcRandomNumbersPeer (peer_wkc nro), with the initialization code using GetSystemTick located in the func immediately before wkcGetTickCountPeer. The former is called from wkcOsslRandFilefReadPeer. wkcOsslRandFilefReadPeer is called for seeding the OpenSSL RNG. | |||
With [12.1.0+], wkcRandomNumberPeer/wkcRandomNumbersPeer wrap nn::os::GenerateRandomBytes. wkcCryptographicallyRandomValuesPeer was added which wraps nn::crypto::GenerateCryptographicallyRandomBytes. wkcOsslRandFilefReadPeer now calls nn::crypto::GenerateCryptographicallyRandomBytes instead of wkcRandomNumbersPeer. | |||
| Breaking web-applets OpenSSL RNG -> potentially predict RNG data (keys(?)) during TLS comms. | |||
| [[12.1.0]] | |||
| [[12.1.0]] | |||
| January 28, 2022 | |||
| October 8, 2024 | |||
| [[User:Yellows8|yellows8]], likely (?) others | |||
|} | |} | ||