With
10.0.0-X the following functions were updated: svcGetThreadAffinityMask, svcGetProcessAffinityMask, svcSetProcessAffinityMask, and svcCreateThread. The code changes for all but svcCreateThread are identical.
The original code with the first 3 did the following:
- if(u32_processorcount > ~0x80000001)return 0xe0e01bfd;
- if(s32_processorcount > <total_cores>)return 0xd8e007fd;
The following code replaced the above:
- if(u32_processorcount >= <total_cores+1>)return 0xd8e007fd;
In theory the latter should catch everything that the former did, so it's unknown if this was really a security issue.
The svcCreateThread changes with
10.0.0-X definitely did fix a security issue.
- Original code: "if(s32_processorid > <total_cores>)return 0xd8e007fd;"
- New code: "if(s32_processorid >= <total_cores> || s32_processorid <= -4)return 0xd8e007fd;"
This fixed an off-by-one issue: if one would use processorid=total_cores, which isn't actually a valid value, svcCreateThread would accept that value on <
10.0.0-X. This results in data being written out-of-bounds(baseaddr = arrayaddr + entrysize*processorid), which has the following result:
- Old3DS: Useless kernel-mode crash due to accessing unmapped memory.
- New3DS: uncontrolled data write into a kernel-mode L1 MMU-table. This isn't really useful: the data can't be controlled, and the data which gets overwritten is all-zero anyway(this isn't anywhere near MMU L1 entries for actually mapped memory).