Yahallo: Free memory access

The Yahallo exploit uses a security vulnerability in the NVIDIA Tegra 3 / Tegra 4 UEFI firmware to disable the SMMU memory protection. As a result you can access all memory.
Disclaimer Most information only applies to SurfaceRT, but some yahallo information applies to Surface RT 2 too.

The exploit

Background story

Because NVIDIA/Microsoft didn't implement a check for maximum buffer size when using a SMC instruction to register a new shared buffer, it is possible to create a buffer overflow, which is then used to overwrite the area where a BootServices->SetMem UEFI call writes its memory.

Understand the formular

// Register a new shared memory buffer at 0x4000_0000 (IRAM) with size // 0x6001_e0e0. The following algorithm is used to determine the end address // that the QueryVariable call will write over: // response_area = (request_area + (area_slice >> 1));
Ret = ArmCallSmcHelper(0x03, 0x06, 0x40000000, 0x6001e0e0);
This is from the yahallo source code. It gives a brief overview about the parameters, but here is more detail about them:
First, you need to know which values are used from the SMC in the calculation, we don't care about parameters 1 and 2. Parameter 3 is request_area, so in yahallo source 0x40000000. Parameter 4 is area_slice, so in yahallo source 0x6001e0e0.

Calculation of the addresses

The calculation has the following formular: response_area = (request_area + (area_slice >> 1)) Examples: 0x7000_f070 = (0x4000_0000 + (0x6001_e0e0 >> 1) 0x7000_f010 = (0x4000_0000 + (0x6001_e020 >> 1))

Use the exploit to disable the SMMU

Tegra 3 SOC: Important information

The Tegra 3 Technical Reference Manual (TRM) has important information about virtual addressing and configuration registers in section 18. You can download it here, but downloading requires a NVIDIA developer account.
The SMMU (System Memory Managment Unit) is part of the SOC, and not part of the Cortex-A9 cores. The CPU cores have a MMU too, you can simply disable it with a ArmDisableMmu() call in the edk2 source tree. Yahallo reconfigures the SMMU, so all SMMU memory protection is gone. The CPU MMU still protects this memory, but you can easily disable it.

Disable SMMU

To disable the SMMU, you need to write 0's to the SMMU Enable Register (0x7000f010). This can only be done when you are in secure mode, so it doesn't work if you just disable the CPU MMU. With the help of the Yahallo exploit we can write to all memory locations in secure mode, because the BootServices->SetMem call executes in secure mode. (UEFI firmware operates in secure mode generally)

What Yahallo does

Yahallo writes 32 bytes of 0's to 0x7000f070, so it writes the Secure Region Configuration Base register, Secure Region Configuration Bound register and the Protected Region Configuration Bound register.
This makes the Trustzone 0MB in size (SMMU side), so you have access to non-trustzone-secured* memory, when CPU doesn't restrict memory access. The CPU restrictions can be removed by disabling the MMU.
* Some registers are restricted to be only accessible from Trustzone-secured CPU memory access. (e.g. from the SMMU_ENABLE register from TRM: This register can only be accessed by Trustzone-Secured accesses from the CPU.)