Line 586: |
Line 586: |
| ! Discovered by | | ! Discovered by |
| |- | | |- |
− | | [[WLAN_services|wlan]] SetMulticastList heap buffer overflow | + | | OOB Read in NS system module (pl:utoohax, pl:utonium, maybe other names) |
− | | The [[WLAN_services#SetMulticastList|SetMulticastList]] command allocates a 0x31-bytes sized buffer and copies to it as much [[WLAN_services#MacAddress|MacAddress]] values from the input [[WLAN_services#MulticastList|MulticastList]] as specified by the "Count" field, but this field is never validated. | + | | Prior to [[3.0.0]], pl:u (Shared Font services implemented in the NS sysmodule) service commands 1,2,3 took in a signed 32-bit index and returned that index of an array but did not check that index at all. This allowed for an arbitrary read within a 34-bit range (33-bit signed) from NS .bss. In [[3.0.0]], sending out of range indexes causes error code 0x60A to be returned. |
| + | | Dumping full NS .text, .rodata and .data, infoleak, etc |
| + | | [[3.0.0]] |
| + | | [[3.0.0]] |
| + | | April 2017 |
| + | | June 19, 2017 |
| + | | [[User:qlutoo|qlutoo]], ReSwitched Team (independently) |
| + | |- |
| + | | Unchecked domain ID in common IPC code |
| + | | Prior to [[2.0.0]], object IDs in [[IPC_Marshalling#Domain_message|domain messages]] are not bounds checked. This out-of-bounds read could be exploited to brute-force ASLR and get PC control in some services that support domain messages. |
| + | | |
| + | | [[2.0.0]] |
| + | | [[2.0.0]] |
| + | | July 2017 |
| + | | July 20, 2017 |
| + | | [[User:hthh|hthh]] |
| + | |- |
| + | | Out-of-bounds array read for [[BCAT_Content_Container]] secret-data index |
| + | | The [[BCAT_Content_Container]] secret-data index is not validated at all. This is handled before the RSA-signature(?) is ever used. Since the field is an u8, a total of 0x800-bytes relative to the array start can be accessed. |
| + | This is not useful since the string loaded from this array is only involved with key-generation. |
| + | | |
| + | | Unknown |
| + | | [[2.0.0]] |
| + | | August 4, 2017 |
| + | | August 6, 2017 |
| + | | [[User: shinyquagsire23|Shiny Quagsire]], [[User:Yellows8|yellows8]] (independently) |
| + | |- |
| + | | expLDR (sysmodule handle table exhaustion) |
| + | | Most sysmodules share common template code to handle IPC control messages. The command DuplicateSession (type 5 command 2)'s template code will abort() if it fails to duplicate a session's handle for the requester. Because many sysmodules have limited handle table size (smaller than the browser/other entrypoints), repeatedly requesting to duplicate one's session will cause the sysmodule to run out of handle table space and abort, causing the service to release all its handles cleanly. |
| + | | Sysmodule crashes. Most usefully, crashing ldr allows access to fsp-ldr and crashing pm allows access to fsp-pr. Useless after [[4.0.0]], which mitigated a number of single-session service access issues. |
| + | | Unfixed |
| + | | [[4.1.0]] |
| + | | June 24, 2017 |
| + | | March 8, 2018 |
| + | | [[User:daeken|daeken]] |
| + | |- |
| + | | Transfer Memory leak in nvservices system module |
| + | | The nvservices sysmodule does not clear most of its transfer memory prior to release. |
| + | | The calling process can read key bits of memory, including breaking ASLR (by revealing the image base) and exposing the address of other transfer memory to set up attacks. More details here: [https://daeken.svbtle.com/nintendo-switch-nvservices-info-leak transfermeme (nvservices info leak)] by [[User:daeken|daeken]] |
| + | | [[6.0.0]] |
| + | | [[6.0.0]] |
| + | | June 2017 |
| + | | October 16, 2018 |
| + | | [[User:qlutoo|qlutoo]] and [[User:hexkyz|hexkyz]], |
| + | [[User:daeken|daeken]] (independently) |
| + | |- |
| + | | OOB write in audio system module |
| + | | Prior to [[2.0.0]], the [[Audio_services#audout:u|AppendAudioOutBuffer]] and [[Audio_services#audin:u|AppendAudioInBuffer]] IPC commands would blindly increment the appended buffers' count while using said count value as an index to where the user data should be copied into. This resulted in an 0x28 bytes, user controlled, out-of-bounds memory write into the [[Audio_services|audio]] sysmodule's memory space. |
| + | Combined with the [[Audio_services#audout:u|GetReleasedAudioOutBuffer]] or [[Audio_services#audin:u|GetReleasedAudioInBuffer]] commands, this could also be used as an 8 byte infoleak. |
| | | |
− | With [15.0.0+] error code 0x1906B is now returned if "Count" is larger than 8.
| + | In [[2.0.0]], the commands now return error code 0x1099 if the number of unreleased buffers exceeds 0x1F. |
− | | wlan-sysmodule heap buffer overflow. | + | | Code execution under audio sysmodule |
− | | [[15.0.0]] | + | | [[2.0.0]] |
− | | [[15.0.0]] | + | | [[2.0.0]] |
− | | June 6, 2022 | + | | |
− | | November 9, 2022 | + | | November 2, 2018 |
− | | [[User:Hexkyz|hexkyz]] | + | | [[User:hexkyz|hexkyz]], probably others (independently). |
| |- | | |- |
− | | [[Bluetooth_Driver_services|bluetooth]] BSA bsa_sv_av_cback stack buffer overflow | + | | Infoleak in nvservices system module |
− | | bsa_sv_av_cback checks for two input type values (0xC/0xD), on match it copies the input data to stack without size validation. Then it sends an internal request with this data (likewise when the type values don't match, except the input data is passed directly with a small size), then it returns. | + | | The [[NV_services|nvservices]] ioctl [[NV_services#NVMAP_IOC_ALLOC|NVMAP_IOC_ALLOC]] takes an optional argument "addr" which allows the calling process to pass a pointer to user allocated memory for backing a nvmap object. If "addr" is left as 0, nvservices uses the transfer memory region (donated by the user during initialization) instead, when allocating memory for the nvmap object. |
− | This requires the AV functionality added with [13.0.0+], however this func is only reachable with [14.0.0+] where the required functionality was enabled.
| + | By design, freeing the nvmap object by calling the ioctl [[NV_services#NVMAP_IOC_FREE|NVMAP_IOC_FREE]] returns, in its "refcount" argument, the user address previously supplied if the reference count reaches 0. |
| + | However, prior to [[6.2.0]], the case where the transfer memory region is used to allocate the nvmap object was not taken into account, thus resulting in [[NV_services#NVMAP_IOC_FREE|NVMAP_IOC_FREE]] leaking back an address from within the transfer memory region mapped in nvservices' memory space. |
| | | |
− | This requires message data that's larger than the MTU, so fragmentation must be used, or manually send the ACL data to bypass the MTU. | + | In [[6.2.0]], [[NV_services#NVMAP_IOC_FREE|NVMAP_IOC_FREE]] no longer returns the address when the transfer memory region is used instead of user supplied memory. |
| + | | Combined with other vulnerabilities: Defeating ASLR in nvservices sysmodule. |
| + | | [[6.2.0]] |
| + | | [[6.2.0]] |
| + | | April 2017 |
| + | | November 24, 2018 |
| + | | Everyone |
| + | |- |
| + | | nvhax (memory corruption in nvservices system module) |
| + | | Prior to [[6.2.0]], the [[NV_services|nvservices]] ioctl [[NV_services#.2Fdev.2Fnvhost-ctrl-gpu|NVGPU_GPU_IOCTL_WAIT_FOR_PAUSE]] would take a single "pwarpstate" argument which would be interpreted by nvservices as a memory pointer for writing 2 "warpstate" structs (one for each Streaming Multiprocessor). |
| + | This resulted in nvservices attempting to blindly memcpy into this user supplied address and trigger a crash. However, if paired with an infoleak, this could be used to arbitrarily write 0x30 bytes anywhere in nvservices' memory space. |
| + | Additionally, the "warpstate" struct itself was never initialized, which means nvservices would leak the 0x30 bytes from the stack. By invoking other ioctls it was also possible to partially control the stack contents and achieve a usable arbitrary memory write primitive. |
| | | |
− | This can be triggered via an AVRC message with opcode=0x0 (vendor). The above type 0xC is reached via AVRC ctype 0..4, while 0xD is reached with ctype>=0x9.
| + | In [[6.2.0]], [[NV_services#.2Fdev.2Fnvhost-ctrl-gpu|NVGPU_GPU_IOCTL_WAIT_FOR_PAUSE]] now takes 2 inline "warpstate" structs instead of a "pwarpstate" pointer, thus effectively avoiding the bad memcpy. |
− | | + | | Code execution under nvservices sysmodule |
− | With [15.0.0+] the size value for the memcpy (which is also written to the request struct) is clamped to a max value.
| + | | [[6.2.0]] |
− | | Bluetooth-sysmodule stack buffer overflow on [14.0.0-14.1.2], with data received from an AVRC bluetooth message with a bluetooth-audio device. | + | | [[6.2.0]] |
− | | [[15.0.0]] | + | | April 5, 2017 |
− | | [[15.0.0]] | + | | November 24, 2018 |
− | | November 2021 | + | | [[User:hexkyz|hexkyz]] |
− | | October 11, 2022 | |
− | | [[User:Yellows8|yellows8]] | |
| |- | | |- |
− | | Broken RNG used by [[NS_Services|ns]] | + | | [[Applet_Manager_services#IStorage|AM IStorage]] infoleak |
− | | The code generating the sd seed and the data for the [[SD_Filesystem|sd]] private/private1 file, all use nn::os::GenerateRandomBytes, not csrng. The sd-seed is generated first, then private, then private1. This allows deriving sd-seed from private since this uses TinyMT, as long as the system shipped from factory on [2.0.0+]. private1 is only useful if the system shipped with [4.0.0+]. | + | | Originally the buffer allocated by [[Applet_Manager_services#CreateStorage|CreateStorage]] using the specified input size was not cleared. With [8.0.0+] this was fixed by adding a memset() for the buffer after successful allocation. |
| | | |
− | There's various other code in ns using nn::os::GenerateRandomBytes as well. This includes the code generating ns_systemseed when it doesn't exist. ns_systemseed is generated at some point after the various sd-seed-related code (both are called from the same func). Hence, ns_systemseed can be recovered with the above method as well, if it wasn't recreated at some point without regenerating the above nand-save used with the above.
| + | Hence, IStorage->IStorageAccessor->Read will return uninitialized memory when the Write cmd was not previously used with the specified region. |
− | | + | | Infoleak from the main [[Applet_Manager_services#IStorage|AM]] heap, allowing defeating ASLR by reading addresses from previously allocated objects. |
− | With [15.0.0+] ns now uses csrng_GenerateRandomBytes for sd-seed/private and ns_systemseed, etc. This only matters when the file is newly generated, which is usually only for factory-fresh systems which ship with this version. This would also apply after being deleted during {System Settings -> Formatting Options -> Initialize Console}, and also with a refurbished console.
| + | | [[8.0.0]] |
− | | Generation of a system's sd-seed allowing decryption of the NAX0 layer of data on [[SD_Filesystem|SD]], derived using the private file from SD. Applies to systems which factory-shipped with a system-version prior to [[15.0.0]] (that is, [2.0.0-14.1.2]). | + | | [[8.1.0]] |
− | | [[15.0.0]], for newly generated files | + | | December 2018 |
− | | [[15.0.0]] | + | | August 9, 2019 |
− | | December ~12, 2021 | |
− | | October 11, 2022 | |
| | [[User:Yellows8|yellows8]] | | | [[User:Yellows8|yellows8]] |
| |- | | |- |
− | | Infoleak with [[Joy-Con]] HidCommand PairingIn | + | | [[HID_services#hid:sys|hid:sys]] ButtonConfig s32 array-index not validated |
− | | The joycon protocol handler for PairingIn copies data from stack to the response cmd-buf for sending PairingOut. Only the first byte is set to a type value, the rest is uninitialized stack data. | + | | The input s32 array-index for [[HID_services#hid:sys|hid:sys]] ButtonConfig cmds 1255-1270 was originally not validated. Using a negative or >=5 index results in accessing out-of-bounds data, with an array stored on stack. |
− | | + | [10.1.0-10.2.0] Each of these cmds will now Abort if the s32 is negative or >=5. [11.0.0+] Now an unsigned compare is used, with 0 or an error being immediately returned when the value is invalid. |
− | This was fixed with [15.0.0+] by directly writing to the response data without using stack data.
| + | | hid infoleak, out-of-bounds mem-write anywhere in hid address-space relative to the stack array (with constraints on the data). |
− | | Infoleak of hid stack via a bluetooth/uart message+response with a connected hid controller. This returns addrs for the main-codebin/stack, which allows defeating ASLR. | + | | [[10.1.0]] |
− | | [[15.0.0]] | + | | [[11.0.1]] |
− | | [[15.0.0]] | + | | April 18, 2020 |
− | | September 4, 2020 | + | | July 14, 2020 |
− | | October 10, 2022 | |
| | [[User:Yellows8|yellows8]] | | | [[User:Yellows8|yellows8]] |
| |- | | |- |
− | | [[Sockets_services|bsdsockets]] ioctl SIOCGIFMEDIA input can contain ptr | + | | [[Bluetooth_Driver_services|Bluetooth]] sdp_server.cc process_service_search() continuation request p_req validation |
− | | Originally bsd ioctl SIOCGIFMEDIA used the user-specified ifmediareq structure directly from the input buffer. This includes a ptr. This ptr probably isn't actually used? | + | | With [5.0.0+], the following was added to the if-block prior to loading cont_offset from p_req: <code>(p_req + sizeof(cont_offset) > p_req_end)</code> (which verifies that cont_offset is within message bounds). |
− | With [5.0.0+] the structure used as input for the ioctl was changed to using <code>int ifm_ulist[1]</code> instead of <code>int *ifm_ulist</code> (which is unused). The input structure is copied to a tmp struct which is used as the original ifmediareq structure, with ifm_ulist always NULL. The user can still specify a non-zero ifm_count value, however that's not useful with ifm_ulist being always NULL. | + | | Bluetooth-sysmodule out-of-bounds read from heap, probably not useful since the read value must match a state field, etc. |
− | | Useless?
| |
| | [[5.0.0]] | | | [[5.0.0]] |
− | | [[13.1.0]] | + | | [[11.0.0]] |
− | | February 14, 2022 | + | | Switch: December 2020 |
− | | February 14, 2022 | + | | Switch: December 25, 2020 |
− | | [[User:Yellows8|yellows8]], probably others | + | | Switch: [[User:Yellows8|yellows8]] |
| |- | | |- |
− | | [[Sockets_services|bsdsockets]] ioctl SIOCGIFCONF infoleak | + | | [[Bluetooth_Driver_services|Bluetooth]] A-63146698 |
− | | Originally bsd ioctl SIOCGIFCONF was handled by setting the data in IPC outbuf0 to the size/addr of IPC outbuf1. These buffers are HipcAutoSelect, so if buf1 is small enough for HipcPointer (otherwise it would be HipcMapAlias) the IPC-buf-ptr leaked into outbuf0 would be located in the codebin-region. Since this is done before the actual ioctl-handling, it doesn't matter whether the fd is valid. | + | | [https://android.googlesource.com/platform/system/bt/+/226ea26684d4cd609a5b456d3d2cc762453c2d75 A-63146698] / CVE-2017-0785. See also [https://info.armis.com/rs/645-PDC-047/images/BlueBorne%20Technical%20White%20Paper_20171130.pdf here]. |
− | This was fixed in [5.0.0+] by using a tmp struct on stack instead of buf0.
| + | | Bluetooth-sysmodule stack infoleak, which allows defeating ASLR (note: not tested on hw). |
− | | bsdsockets-sysmodule codebin-region addr infoleak, which allows defeating ASLR. | |
| | [[5.0.0]] | | | [[5.0.0]] |
− | | [[13.1.0]] | + | | [[11.0.0]] |
− | | February 14, 2022 (probably earlier) | + | | Switch: December 2020 |
− | | February 14, 2022 | + | | Switch: December 25, 2020 |
− | | [[User:Yellows8|yellows8]], probably others | + | | Switch: [[User:Yellows8|yellows8]] |
| |- | | |- |
− | | [[Bluetooth_Driver_services|bluetooth]] BSA gatt_process_notification stack buffer overflow | + | | [[Bluetooth_Driver_services|bluetooth]] GetAdapterProperty/SetAdapterProperty unchecked memcpy size |
− | | gatt_process_notification is the GATT handler for processing notification/indication messages. gatt_process_notification does memcpy to stack from the input bt msg data, without size validation. The input len param isn't validated in this func either - if the remaining len following op_code is less than 2, a negative value will be used for the data copy to stack.
| + | | GetAdapterProperty copies data from stack to the output buffer using the buffer size, without checking the size (when not handling the Name type). SetAdapterProperty copies data to stack from the input buffer using the buffer size, without checking the size. |
− | These were fixed by adding a bounds check for the size, size==0 is also checked for now.
| + | This requires access to the btdrv service, only hid and btm have access. |
− | | Bluetooth-sysmodule stack buffer overflow, with data received from a bluetooth message | + | |
− | | [[13.2.1]] | + | This was fixed with [[12.0.0]] by replacing the buffer data with a fixed-size-struct. |
− | | [[13.2.1]] | + | | Stack infoleak with GetAdapterProperty, stack buffer overflow (and hence ROP) with SetAdapterProperty. |
− | | November 2021 | + | | [[12.0.0]] |
− | | January 19, 2022 | + | | [[12.0.0]] |
| + | | July 17, 2020 |
| + | | April 7, 2021 |
| | [[User:Yellows8|yellows8]] | | | [[User:Yellows8|yellows8]] |
| |- | | |- |
− | | [[SSL_services|ssl]] CVE-2021-43527 | + | | [[Bluetooth_Driver_services|bluetooth]] stack buffer overflow with HID DATA packets |
− | | CVE-2021-43527, see also [https://bugs.chromium.org/p/project-zero/issues/detail?id=2237 here] and [https://googleprojectzero.blogspot.com/2021/12/this-shouldnt-have-happened.html here]. | + | | The BSA (bt-stack) func bta_hh_co_data copies data from a HID DATA packet to stack without checking the size, then sends it over Uipc. [7.0.0+] The user Uipc callback also copies the input data to stack without checking the size, then sends it to the sharedmem CircularBuffer. |
− | Using BigSig where the server cert sig is RSA-PSS results in the remote server throwing {no shared cipher} error when Switch connects. If however one creates a rootCA using BigSig (RSA-PSS), which then signs a server cert where the server key is RSA (not PSS), the vuln can be triggered (if the rootCA is trusted, via using the import service-cmd). It's unknown whether there's other ways to trigger the vuln.
| + | With [12.0.2+] this was fixed in bta_hh_co_data by clamping the size to a maximum of 0x2BB. The aforementioned buffer overflow in the Uipc callback can't be triggered since at that point the size was already clamped. |
| | | |
− | The crash occurs in VFY_Begin when using the previously overwritten data. A bitsize of <code>$((16384 + 32 + 64 + 64 + 64))</code> is only enough to overwrite cx->hashcx, to fully overwrite cx->hashobj an additional 0xC-bytes (additional 96 bits) is needed.
| + | Before this bta_hh_co_data func is reached, there is no validation of the size (such as comparing against the L2CAP MTU) when Basic Mode is being used. |
− | Note that partial overwrite isn't an option: this is the func that initializes those fields to begin with, it just does deinit first before initializing hashcx/hashobj (prior to that these fields would be all-zero when not overwritten by the buf-overflow).
| |
− | | Heap buffer overflow in [[SSL_services|ssl]], overwriting data including a ptr to an object which is later used to load a funcptr.
| |
− | | [[13.2.1]]
| |
− | | [[13.2.1]]
| |
− | | Switch: December 1-2, 2021
| |
− | | Switch: January 19, 2022
| |
− | |
| |
− | |-
| |
− | | [[Bluetooth_Driver_services|bluetooth]] EventInfo infoleak
| |
− | | The various funcs which send messages to the thread which handles writing to EventInfo, didn't clear the stack msgbuf. Hence, the various get-EventInfo cmds could return leaked stack data. This likely affected most (?) get-EventInfo cmds, besides CircularBuffer-GetHidReportEventInfo.
| |
| | | |
− | This only matters for events where there's uninitialized regions of the EventInfo, such as events with variable-size data without a memset. | + | Actually triggering this requires using a data-size larger than the normal L2CAP MTU. This can be done by for example, using raw HCI to send the packet from the remote bluetooth device. |
| | | |
− | This was fixed by clearing the msgbuf in a number of funcs.
| + | Note that when the remote device is configured as an audio device for [12.0.0+] where [[Settings_services#BluetoothDevicesSettings|BluetoothDevicesSettings]].TrustedServices was only ever set for audio since system-boot, it is not possible for the remote device to connect to the Switch for HID. |
− | | Bluetooth-sysmodule stack infoleak, which allows defeating ASLR
| + | | ROP under [[Bluetooth_Driver_services|bluetooth]] via HID DATA packet sent by a paired HID bluetooth device. This can be triggered at any time while not in sleep-mode, when not in airplane-mode. The earliest is while the Nintendo Switch logo screen is displayed during system boot. |
− | | [[13.0.0]]
| + | | [[12.0.2]] |
− | | [[13.1.0]]
| + | | [[12.0.2]] |
− | |
| + | | July-August 2020 |
− | | During initial [[13.0.0|diff]]. Added to this page on: December 12, 2021
| + | | May 11, 2021 |
− | | [[User:Yellows8|yellows8]] | |
− | |-
| |
− | | Infoleak with [[HID_services|hid:sys]] SetButtonConfigStorage{name}Deprecated
| |
− | | These cmds pass a stack ptr for the StorageName when calling the internal func. Nothing is written to this StorageName. Hence, stack infoleak (data is copied as a NUL-terminated string), which can be later read by the GetButtonConfigStorage{name} cmds.
| |
− | | |
− | This was fixed by removing the Deprecated cmds in [[13.0.0]].
| |
− | | Infoleak of hid stack from a StorageName readable via GetButtonConfigStorage{name}, up to the NUL-terminator.
| |
− | | [[13.0.0]] | |
− | | [[13.0.0]] | |
− | | December 11, 2020 | |
− | | September 27, 2021 | |
| | [[User:Yellows8|yellows8]] | | | [[User:Yellows8|yellows8]] |
| |- | | |- |
Line 716: |
Line 750: |
| | [[User:Yellows8|yellows8]] | | | [[User:Yellows8|yellows8]] |
| |- | | |- |
− | | [[Bluetooth_Driver_services|bluetooth]] stack buffer overflow with HID DATA packets | + | | Infoleak with [[HID_services|hid:sys]] SetButtonConfigStorage{name}Deprecated |
− | | The BSA (bt-stack) func bta_hh_co_data copies data from a HID DATA packet to stack without checking the size, then sends it over Uipc. [7.0.0+] The user Uipc callback also copies the input data to stack without checking the size, then sends it to the sharedmem CircularBuffer. | + | | These cmds pass a stack ptr for the StorageName when calling the internal func. Nothing is written to this StorageName. Hence, stack infoleak (data is copied as a NUL-terminated string), which can be later read by the GetButtonConfigStorage{name} cmds. |
− | With [12.0.2+] this was fixed in bta_hh_co_data by clamping the size to a maximum of 0x2BB. The aforementioned buffer overflow in the Uipc callback can't be triggered since at that point the size was already clamped.
| |
| | | |
− | Before this bta_hh_co_data func is reached, there is no validation of the size (such as comparing against the L2CAP MTU) when Basic Mode is being used.
| + | This was fixed by removing the Deprecated cmds in [[13.0.0]]. |
| + | | Infoleak of hid stack from a StorageName readable via GetButtonConfigStorage{name}, up to the NUL-terminator. |
| + | | [[13.0.0]] |
| + | | [[13.0.0]] |
| + | | December 11, 2020 |
| + | | September 27, 2021 |
| + | | [[User:Yellows8|yellows8]] |
| + | |- |
| + | | [[Bluetooth_Driver_services|bluetooth]] EventInfo infoleak |
| + | | The various funcs which send messages to the thread which handles writing to EventInfo, didn't clear the stack msgbuf. Hence, the various get-EventInfo cmds could return leaked stack data. This likely affected most (?) get-EventInfo cmds, besides CircularBuffer-GetHidReportEventInfo. |
| | | |
− | Actually triggering this requires using a data-size larger than the normal L2CAP MTU. This can be done by for example, using raw HCI to send the packet from the remote bluetooth device.
| + | This only matters for events where there's uninitialized regions of the EventInfo, such as events with variable-size data without a memset. |
| | | |
− | Note that when the remote device is configured as an audio device for [12.0.0+] where [[Settings_services#BluetoothDevicesSettings|BluetoothDevicesSettings]].TrustedServices was only ever set for audio since system-boot, it is not possible for the remote device to connect to the Switch for HID.
| + | This was fixed by clearing the msgbuf in a number of funcs. |
− | | ROP under [[Bluetooth_Driver_services|bluetooth]] via HID DATA packet sent by a paired HID bluetooth device. This can be triggered at any time while not in sleep-mode, when not in airplane-mode. The earliest is while the Nintendo Switch logo screen is displayed during system boot. | + | | Bluetooth-sysmodule stack infoleak, which allows defeating ASLR |
− | | [[12.0.2]] | + | | [[13.0.0]] |
− | | [[12.0.2]] | + | | [[13.1.0]] |
− | | July-August 2020
| + | | |
− | | May 11, 2021
| + | | During initial [[13.0.0|diff]]. Added to this page on: December 12, 2021 |
| | [[User:Yellows8|yellows8]] | | | [[User:Yellows8|yellows8]] |
| |- | | |- |
− | | [[Bluetooth_Driver_services|bluetooth]] GetAdapterProperty/SetAdapterProperty unchecked memcpy size | + | | [[SSL_services|ssl]] CVE-2021-43527 |
− | | GetAdapterProperty copies data from stack to the output buffer using the buffer size, without checking the size (when not handling the Name type). SetAdapterProperty copies data to stack from the input buffer using the buffer size, without checking the size.
| + | | CVE-2021-43527, see also [https://bugs.chromium.org/p/project-zero/issues/detail?id=2237 here] and [https://googleprojectzero.blogspot.com/2021/12/this-shouldnt-have-happened.html here]. |
− | This requires access to the btdrv service, only hid and btm have access.
| + | Using BigSig where the server cert sig is RSA-PSS results in the remote server throwing {no shared cipher} error when Switch connects. If however one creates a rootCA using BigSig (RSA-PSS), which then signs a server cert where the server key is RSA (not PSS), the vuln can be triggered (if the rootCA is trusted, via using the import service-cmd). It's unknown whether there's other ways to trigger the vuln. |
| | | |
− | This was fixed with [[12.0.0]] by replacing the buffer data with a fixed-size-struct.
| + | The crash occurs in VFY_Begin when using the previously overwritten data. A bitsize of <code>$((16384 + 32 + 64 + 64 + 64))</code> is only enough to overwrite cx->hashcx, to fully overwrite cx->hashobj an additional 0xC-bytes (additional 96 bits) is needed. |
− | | Stack infoleak with GetAdapterProperty, stack buffer overflow (and hence ROP) with SetAdapterProperty. | + | Note that partial overwrite isn't an option: this is the func that initializes those fields to begin with, it just does deinit first before initializing hashcx/hashobj (prior to that these fields would be all-zero when not overwritten by the buf-overflow). |
− | | [[12.0.0]] | + | | Heap buffer overflow in [[SSL_services|ssl]], overwriting data including a ptr to an object which is later used to load a funcptr. |
− | | [[12.0.0]] | + | | [[13.2.1]] |
− | | July 17, 2020 | + | | [[13.2.1]] |
− | | April 7, 2021 | + | | Switch: December 1-2, 2021 |
| + | | Switch: January 19, 2022 |
| + | | |
| + | |- |
| + | | [[Bluetooth_Driver_services|bluetooth]] BSA gatt_process_notification stack buffer overflow |
| + | | gatt_process_notification is the GATT handler for processing notification/indication messages. gatt_process_notification does memcpy to stack from the input bt msg data, without size validation. The input len param isn't validated in this func either - if the remaining len following op_code is less than 2, a negative value will be used for the data copy to stack. |
| + | These were fixed by adding a bounds check for the size, size==0 is also checked for now. |
| + | | Bluetooth-sysmodule stack buffer overflow, with data received from a bluetooth message |
| + | | [[13.2.1]] |
| + | | [[13.2.1]] |
| + | | November 2021 |
| + | | January 19, 2022 |
| | [[User:Yellows8|yellows8]] | | | [[User:Yellows8|yellows8]] |
| |- | | |- |
− | | [[Bluetooth_Driver_services|Bluetooth]] A-63146698 | + | | [[Applet_Manager_services#IDisplayController|AM IDisplayController]] TakeScreenShotOfOwnLayer OOB |
− | | [https://android.googlesource.com/platform/system/bt/+/226ea26684d4cd609a5b456d3d2cc762453c2d75 A-63146698] / CVE-2017-0785. See also [https://info.armis.com/rs/645-PDC-047/images/BlueBorne%20Technical%20White%20Paper_20171130.pdf here]. | + | | The captureBuf is used as an array index without validation. Data used from this array includes calling a funcptr from the array entry, if set. Eventually this is also used to write bools into this array, one of which is from the command input. |
− | | Bluetooth-sysmodule stack infoleak, which allows defeating ASLR (note: not tested on hw). | + | With [5.0.0+] a func is eventually called to get a ptr determined by the input captureBuf, with nullptr being returned for captureBuf>=0x10. The caller will Abort if nullptr was returned. |
| + | | OOB array access |
| | [[5.0.0]] | | | [[5.0.0]] |
− | | [[11.0.0]] | + | | [[13.1.0]] |
− | | Switch: December 2020
| + | | ~July 31, 2019 |
− | | Switch: December 25, 2020
| + | | January 26, 2022 |
− | | Switch: [[User:Yellows8|yellows8]]
| |
− | |-
| |
− | | [[Bluetooth_Driver_services|Bluetooth]] sdp_server.cc process_service_search() continuation request p_req validation
| |
− | | With [5.0.0+], the following was added to the if-block prior to loading cont_offset from p_req: <code>(p_req + sizeof(cont_offset) > p_req_end)</code> (which verifies that cont_offset is within message bounds).
| |
− | | Bluetooth-sysmodule out-of-bounds read from heap, probably not useful since the read value must match a state field, etc.
| |
− | | [[5.0.0]]
| |
− | | [[11.0.0]]
| |
− | | Switch: December 2020
| |
− | | Switch: December 25, 2020
| |
− | | Switch: [[User:Yellows8|yellows8]]
| |
− | |-
| |
− | | [[HID_services#hid:sys|hid:sys]] ButtonConfig s32 array-index not validated
| |
− | | The input s32 array-index for [[HID_services#hid:sys|hid:sys]] ButtonConfig cmds 1255-1270 was originally not validated. Using a negative or >=5 index results in accessing out-of-bounds data, with an array stored on stack.
| |
− | [10.1.0-10.2.0] Each of these cmds will now Abort if the s32 is negative or >=5. [11.0.0+] Now an unsigned compare is used, with 0 or an error being immediately returned when the value is invalid.
| |
− | | hid infoleak, out-of-bounds mem-write anywhere in hid address-space relative to the stack array (with constraints on the data).
| |
− | | [[10.1.0]]
| |
− | | [[11.0.1]] | |
− | | April 18, 2020
| |
− | | July 14, 2020 | |
| | [[User:Yellows8|yellows8]] | | | [[User:Yellows8|yellows8]] |
| |- | | |- |
Line 782: |
Line 817: |
| | [[User:Yellows8|yellows8]] | | | [[User:Yellows8|yellows8]] |
| |- | | |- |
− | | [[Applet_Manager_services#IDisplayController|AM IDisplayController]] TakeScreenShotOfOwnLayer OOB | + | | [[Sockets_services|bsdsockets]] ioctl SIOCGIFCONF infoleak |
− | | The captureBuf is used as an array index without validation. Data used from this array includes calling a funcptr from the array entry, if set. Eventually this is also used to write bools into this array, one of which is from the command input. | + | | Originally bsd ioctl SIOCGIFCONF was handled by setting the data in IPC outbuf0 to the size/addr of IPC outbuf1. These buffers are HipcAutoSelect, so if buf1 is small enough for HipcPointer (otherwise it would be HipcMapAlias) the IPC-buf-ptr leaked into outbuf0 would be located in the codebin-region. Since this is done before the actual ioctl-handling, it doesn't matter whether the fd is valid. |
− | With [5.0.0+] a func is eventually called to get a ptr determined by the input captureBuf, with nullptr being returned for captureBuf>=0x10. The caller will Abort if nullptr was returned. | + | This was fixed in [5.0.0+] by using a tmp struct on stack instead of buf0. |
− | | OOB array access | + | | bsdsockets-sysmodule codebin-region addr infoleak, which allows defeating ASLR. |
| + | | [[5.0.0]] |
| + | | [[13.1.0]] |
| + | | February 14, 2022 (probably earlier) |
| + | | February 14, 2022 |
| + | | [[User:Yellows8|yellows8]], probably others |
| + | |- |
| + | | [[Sockets_services|bsdsockets]] ioctl SIOCGIFMEDIA input can contain ptr |
| + | | Originally bsd ioctl SIOCGIFMEDIA used the user-specified ifmediareq structure directly from the input buffer. This includes a ptr. This ptr probably isn't actually used? |
| + | With [5.0.0+] the structure used as input for the ioctl was changed to using <code>int ifm_ulist[1]</code> instead of <code>int *ifm_ulist</code> (which is unused). The input structure is copied to a tmp struct which is used as the original ifmediareq structure, with ifm_ulist always NULL. The user can still specify a non-zero ifm_count value, however that's not useful with ifm_ulist being always NULL. |
| + | | Useless? |
| | [[5.0.0]] | | | [[5.0.0]] |
| | [[13.1.0]] | | | [[13.1.0]] |
− | | ~July 31, 2019 | + | | February 14, 2022 |
− | | January 26, 2022 | + | | February 14, 2022 |
− | | [[User:Yellows8|yellows8]] | + | | [[User:Yellows8|yellows8]], probably others |
| |- | | |- |
− | | [[Applet_Manager_services#IStorage|AM IStorage]] infoleak | + | | Infoleak with [[Joy-Con]] HidCommand PairingIn |
− | | Originally the buffer allocated by [[Applet_Manager_services#CreateStorage|CreateStorage]] using the specified input size was not cleared. With [8.0.0+] this was fixed by adding a memset() for the buffer after successful allocation. | + | | The joycon protocol handler for PairingIn copies data from stack to the response cmd-buf for sending PairingOut. Only the first byte is set to a type value, the rest is uninitialized stack data. |
| | | |
− | Hence, IStorage->IStorageAccessor->Read will return uninitialized memory when the Write cmd was not previously used with the specified region.
| + | This was fixed with [15.0.0+] by directly writing to the response data without using stack data. |
− | | Infoleak from the main [[Applet_Manager_services#IStorage|AM]] heap, allowing defeating ASLR by reading addresses from previously allocated objects. | + | | Infoleak of hid stack via a bluetooth/uart message+response with a connected hid controller. This returns addrs for the main-codebin/stack, which allows defeating ASLR. |
− | | [[8.0.0]] | + | | [[15.0.0]] |
− | | [[8.1.0]] | + | | [[15.0.0]] |
− | | December 2018 | + | | September 4, 2020 |
− | | August 9, 2019 | + | | October 10, 2022 |
| | [[User:Yellows8|yellows8]] | | | [[User:Yellows8|yellows8]] |
− | |-
| |
− | | Out-of-bounds array read for [[BCAT_Content_Container]] secret-data index
| |
− | | The [[BCAT_Content_Container]] secret-data index is not validated at all. This is handled before the RSA-signature(?) is ever used. Since the field is an u8, a total of 0x800-bytes relative to the array start can be accessed.
| |
− | This is not useful since the string loaded from this array is only involved with key-generation.
| |
− | |
| |
− | | Unknown
| |
− | | [[2.0.0]]
| |
− | | August 4, 2017
| |
− | | August 6, 2017
| |
− | | [[User: shinyquagsire23|Shiny Quagsire]], [[User:Yellows8|yellows8]] (independently)
| |
− | |-
| |
− | | OOB Read in NS system module (pl:utoohax, pl:utonium, maybe other names)
| |
− | | Prior to [[3.0.0]], pl:u (Shared Font services implemented in the NS sysmodule) service commands 1,2,3 took in a signed 32-bit index and returned that index of an array but did not check that index at all. This allowed for an arbitrary read within a 34-bit range (33-bit signed) from NS .bss. In [[3.0.0]], sending out of range indexes causes error code 0x60A to be returned.
| |
− | | Dumping full NS .text, .rodata and .data, infoleak, etc
| |
− | | [[3.0.0]]
| |
− | | [[3.0.0]]
| |
− | | April 2017
| |
− | | On exploit's fix in [[3.0.0]]
| |
− | | [[User:qlutoo|qlutoo]], ReSwitched Team (independently)
| |
− | |-
| |
− | | Unchecked domain ID in common IPC code
| |
− | | Prior to [[2.0.0]], object IDs in [[IPC_Marshalling#Domain_message|domain messages]] are not bounds checked. This out-of-bounds read could be exploited to brute-force ASLR and get PC control in some services that support domain messages.
| |
− | |
| |
− | | [[2.0.0]]
| |
− | | [[2.0.0]]
| |
− | | ~July 2017
| |
− | | 20 July 2017
| |
− | | [[User:hthh|hthh]]
| |
− | |-
| |
− | | expLDR (sysmodule handle table exhaustion)
| |
− | | Most sysmodules share common template code to handle IPC control messages. The command DuplicateSession (type 5 command 2)'s template code will abort() if it fails to duplicate a session's handle for the requester. Because many sysmodules have limited handle table size (smaller than the browser/other entrypoints), repeatedly requesting to duplicate one's session will cause the sysmodule to run out of handle table space and abort, causing the service to release all its handles cleanly.
| |
− | | Sysmodule crashes. Most usefully, crashing ldr allows access to fsp-ldr and crashing pm allows access to fsp-pr. Useless after [[4.0.0]], which mitigated a number of single-session service access issues.
| |
− | | Unfixed
| |
− | | [[4.1.0]]
| |
− | | 24 June 2017
| |
− | | 8 March 2018
| |
− | | [[User:daeken|daeken]]
| |
− | |-
| |
− | | Transfer Memory leak in nvservices system module
| |
− | | The nvservices sysmodule does not clear most of its transfer memory prior to release.
| |
− | | The calling process can read key bits of memory, including breaking ASLR (by revealing the image base) and exposing the address of other transfer memory to set up attacks. More details here: [https://daeken.svbtle.com/nintendo-switch-nvservices-info-leak transfermeme (nvservices info leak)] by [[User:daeken|daeken]]
| |
− | | [[6.0.0]]
| |
− | | [[6.0.0]]
| |
− | | June 2017
| |
− | | 16 October 2018
| |
− | | [[User:qlutoo|qlutoo]] and [[User:hexkyz|hexkyz]],
| |
− | [[User:daeken|daeken]] (independently)
| |
− | |-
| |
− | | OOB write in audio system module
| |
− | | Prior to [[2.0.0]], the [[Audio_services#audout:u|AppendAudioOutBuffer]] and [[Audio_services#audin:u|AppendAudioInBuffer]] IPC commands would blindly increment the appended buffers' count while using said count value as an index to where the user data should be copied into. This resulted in an 0x28 bytes, user controlled, out-of-bounds memory write into the [[Audio_services|audio]] sysmodule's memory space.
| |
− | Combined with the [[Audio_services#audout:u|GetReleasedAudioOutBuffer]] or [[Audio_services#audin:u|GetReleasedAudioInBuffer]] commands, this could also be used as an 8 byte infoleak.
| |
− |
| |
− | In [[2.0.0]], the commands now return error code 0x1099 if the number of unreleased buffers exceeds 0x1F.
| |
− | | Code execution under audio sysmodule
| |
− | | [[2.0.0]]
| |
− | | [[2.0.0]]
| |
− | |
| |
− | | November 2, 2018
| |
− | | [[User:hexkyz|hexkyz]], probably others (independently).
| |
− | |-
| |
− | | nvhax (memory corruption in nvservices system module)
| |
− | | Prior to [[6.2.0]], the [[NV_services|nvservices]] ioctl [[NV_services#.2Fdev.2Fnvhost-ctrl-gpu|NVGPU_GPU_IOCTL_WAIT_FOR_PAUSE]] would take a single "pwarpstate" argument which would be interpreted by nvservices as a memory pointer for writing 2 "warpstate" structs (one for each Streaming Multiprocessor).
| |
− | This resulted in nvservices attempting to blindly memcpy into this user supplied address and trigger a crash. However, if paired with an infoleak, this could be used to arbitrarily write 0x30 bytes anywhere in nvservices' memory space.
| |
− | Additionally, the "warpstate" struct itself was never initialized, which means nvservices would leak the 0x30 bytes from the stack. By invoking other ioctls it was also possible to partially control the stack contents and achieve a usable arbitrary memory write primitive.
| |
− |
| |
− | In [[6.2.0]], [[NV_services#.2Fdev.2Fnvhost-ctrl-gpu|NVGPU_GPU_IOCTL_WAIT_FOR_PAUSE]] now takes 2 inline "warpstate" structs instead of a "pwarpstate" pointer, thus effectively avoiding the bad memcpy.
| |
− | | Code execution under nvservices sysmodule
| |
− | | [[6.2.0]]
| |
− | | [[6.2.0]]
| |
− | | April 5, 2017
| |
− | | November 24, 2018
| |
− | | [[User:hexkyz|hexkyz]]
| |
− | |-
| |
− | | Infoleak in nvservices system module
| |
− | | The [[NV_services|nvservices]] ioctl [[NV_services#NVMAP_IOC_ALLOC|NVMAP_IOC_ALLOC]] takes an optional argument "addr" which allows the calling process to pass a pointer to user allocated memory for backing a nvmap object. If "addr" is left as 0, nvservices uses the transfer memory region (donated by the user during initialization) instead, when allocating memory for the nvmap object.
| |
− | By design, freeing the nvmap object by calling the ioctl [[NV_services#NVMAP_IOC_FREE|NVMAP_IOC_FREE]] returns, in its "refcount" argument, the user address previously supplied if the reference count reaches 0.
| |
− | However, prior to [[6.2.0]], the case where the transfer memory region is used to allocate the nvmap object was not taken into account, thus resulting in [[NV_services#NVMAP_IOC_FREE|NVMAP_IOC_FREE]] leaking back an address from within the transfer memory region mapped in nvservices' memory space.
| |
− |
| |
− | In [[6.2.0]], [[NV_services#NVMAP_IOC_FREE|NVMAP_IOC_FREE]] no longer returns the address when the transfer memory region is used instead of user supplied memory.
| |
− | | Combined with other vulnerabilities: Defeating ASLR in nvservices sysmodule.
| |
− | | [[6.2.0]]
| |
− | | [[6.2.0]]
| |
− | | April 2017
| |
− | | November 24, 2018
| |
− | | Everyone
| |
| |- | | |- |
| | Broken RNG for [[RO_services|ro]] ASLR | | | Broken RNG for [[RO_services|ro]] ASLR |
Line 900: |
Line 860: |
| | October 11, 2022 | | | October 11, 2022 |
| | Everyone | | | Everyone |
| + | |- |
| + | | Broken RNG used by [[NS_Services|ns]] |
| + | | The code generating the sd seed and the data for the [[SD_Filesystem|sd]] private/private1 file, all use nn::os::GenerateRandomBytes, not csrng. The sd-seed is generated first, then private, then private1. This allows deriving sd-seed from private since this uses TinyMT, as long as the system shipped from factory on [2.0.0+]. private1 is only useful if the system shipped with [4.0.0+]. |
| + | |
| + | There's various other code in ns using nn::os::GenerateRandomBytes as well. This includes the code generating ns_systemseed when it doesn't exist. ns_systemseed is generated at some point after the various sd-seed-related code (both are called from the same func). Hence, ns_systemseed can be recovered with the above method as well, if it wasn't recreated at some point without regenerating the above nand-save used with the above. |
| + | |
| + | With [15.0.0+] ns now uses csrng_GenerateRandomBytes for sd-seed/private and ns_systemseed, etc. This only matters when the file is newly generated, which is usually only for factory-fresh systems which ship with this version. This would also apply after being deleted during {System Settings -> Formatting Options -> Initialize Console}, and also with a refurbished console. |
| + | | Generation of a system's sd-seed allowing decryption of the NAX0 layer of data on [[SD_Filesystem|SD]], derived using the private file from SD. Applies to systems which factory-shipped with a system-version prior to [[15.0.0]] (that is, [2.0.0-14.1.2]). |
| + | | [[15.0.0]], for newly generated files |
| + | | [[15.0.0]] |
| + | | December ~12, 2021 |
| + | | October 11, 2022 |
| + | | [[User:Yellows8|yellows8]] |
| + | |- |
| + | | [[Bluetooth_Driver_services|bluetooth]] BSA bsa_sv_av_cback stack buffer overflow |
| + | | bsa_sv_av_cback checks for two input type values (0xC/0xD), on match it copies the input data to stack without size validation. Then it sends an internal request with this data (likewise when the type values don't match, except the input data is passed directly with a small size), then it returns. |
| + | This requires the AV functionality added with [13.0.0+], however this func is only reachable with [14.0.0+] where the required functionality was enabled. |
| + | |
| + | This requires message data that's larger than the MTU, so fragmentation must be used, or manually send the ACL data to bypass the MTU. |
| + | |
| + | This can be triggered via an AVRC message with opcode=0x0 (vendor). The above type 0xC is reached via AVRC ctype 0..4, while 0xD is reached with ctype>=0x9. |
| + | |
| + | With [15.0.0+] the size value for the memcpy (which is also written to the request struct) is clamped to a max value. |
| + | | Bluetooth-sysmodule stack buffer overflow on [14.0.0-14.1.2], with data received from an AVRC bluetooth message with a bluetooth-audio device. |
| + | | [[15.0.0]] |
| + | | [[15.0.0]] |
| + | | November 2021 |
| + | | October 11, 2022 |
| + | | [[User:Yellows8|yellows8]] |
| + | |- |
| + | | [[WLAN_services|wlan]] SetMulticastList heap buffer overflow |
| + | | The [[WLAN_services#SetMulticastList|SetMulticastList]] command allocates a 0x31-bytes sized buffer and copies to it as much [[WLAN_services#MacAddress|MacAddress]] values from the input [[WLAN_services#MulticastList|MulticastList]] as specified by the "Count" field, but this field is never validated. |
| + | |
| + | With [15.0.0+] error code 0x1906B is now returned if "Count" is larger than 8. |
| + | | wlan-sysmodule heap buffer overflow. |
| + | | [[15.0.0]] |
| + | | [[15.0.0]] |
| + | | June 6, 2022 |
| + | | November 9, 2022 |
| + | | [[User:Hexkyz|hexkyz]] |
| |} | | |} |