Thursday, December 18, 2014

[QPSIIR-80] Qualcomm TrustZone Integer Signedness bug

Qualcomm TrustZone is prone to an integer signedness bug that may allow to write NULL words to barely controllable locations in memory.

The vulnerability can be triggered from Non-Secure World through the TrustZone call "tzbsp_smmu_fault_regs_dump".

This issue has been discovered in Samsung Galaxy S5 firmware, but other devices can be affected as well.
This vulnerability has been discovered in TrustZone binary of Samsung Galaxy S5 firmware, version 4.4.2.
The tzbsp_smmu_fault_regs_dump function can be called from Non-Secure World through the SMC instruction. It takes 4 arguments passed in R0-R3 registers.
When called with argument R0 > 1, nested function subfunc_1 is called with arguments (R0 = 0xFFFFFFFF, R1) :

FE84B9B6 tzbsp_smmu_fault_regs_dump FE84B9B6 PUSH.W {R4-R8,LR} FE84B9BA MOVS R6, R2 FE84B9BC MOV R8, R1 FE84B9BE MOV R7, R3 FE84B9C0 MOV.W R4, #0xFFFFFFFF FE84B9C4 MOV R5, #0xFFFFFFEE FE84B9C8 BEQ loc_FE84BA1A FE84B9CA CBZ R0, loc_FE84B9D2 ; R0 > 1 : branch not taken FE84B9CC CMP R0, #1 FE84B9CE BEQ loc_FE84B9D6 ; R0 > 1 : branch not taken FE84B9D0 B loc_FE84B9D8 ; branch FE84B9D2 ; --------------------------------------------------------- FE84B9D2 loc_FE84B9D2 ; if R0 == 0 FE84B9D2 MOVS R4, #1 FE84B9D4 B loc_FE84B9D8 FE84B9D6 ; --------------------------------------------------------- FE84B9D6 loc_FE84B9D6 ; if R0 == 1 FE84B9D6 MOVS R4, #0 FE84B9D8 FE84B9D8 loc_FE84B9D8 ; for any value of R0 FE84B9D8 MOVS R0, #1 FE84B9DA BL subfunc_0 ; kind of "is retail hardware?" test FE84B9DE CBZ R0, loc_FE84B9EE ; not taken FE84B9E0 MOV R1, R8 FE84B9E2 MOV R0, R4 ; R4 == #0xFFFFFFFF FE84B9E4 BL subfunc_1
FE84B9E8 [...]

Then subfunc_1 checks if R0 value is valid. It will Branch and return if R0 is Greater than or Equal to 2. However, BGE instruction operates on signed integers. So R0 == -1 < 2 will pass the test and the execution will continue :
FE853124 subfunc_1 FE853124 CMP R0, #2 ; R0 == #0xFFFFFFFF FE853126 BGE locret_FE85314C ; signed comparison :
FE853126 ; R0(-1) < 2 so branch not taken FE853128 MOVW R2, #0x9EE0 FE85312C ADD.W R3, R0, R0,LSL#1 FE853130 MOVT.W R2, #0xFE82 FE853134 ADD.W R0, R3, R0,LSL#3 FE853138 LDR R2, [R2,#(dword_FE829EE4 - 0xFE829EE0)] FE85313A ADD.W R0, R2, R0,LSL#4 FE85313E LDRB R2, [R0,#4] FE853140 CMP R2, R1 ; with R1 < R2 FE853142 BLS locret_FE85314C FE853144 LDR R0, [R0] FE853146 MOVS R2, #0
FE853148 B.W sub_FE856C84 ; write NULL DWORD to a barely arbitrary address (derived from R1 value) FE85314C [...]

Finally, the last nested function could allow to write NULL words to a limited range of memory locations.
This bug is fixed in Lolipop version of the firmware. Several changes have been made. First, subfunc_1 function is not reachable anymore with an invalid R0 value:
FE84B970 tzbsp_smmu_fault_regs_dump
FE84B970 PUSH.W {R4-R8,LR} FE84B974 MOVS R6, R2 FE84B976 MOV R8, R1 FE84B978 MOV R7, R3 FE84B97A MOV R5, #0xFFFFFFEE FE84B97E BEQ loc_FE84B9D2 FE84B980 CBZ R0, loc_FE84B98A FE84B982 CMP R0, #1 FE84B984 BEQ loc_FE84B98E FE84B986 ADDS R0, R5, #2 FE84B988 B locret_FE84B7AA ; branch if R0 > 1 FE84B98A ; --------------------------------------------------------- FE84B98A loc_FE84B98A ; if R0 == 0 FE84B98A MOVS R4, #1 FE84B98C B loc_FE84B990 FE84B98E ; --------------------------------------------------------- FE84B98E loc_FE84B98E ; if R0 == 1 FE84B98E MOVS R4, #0 FE84B990 FE84B990 loc_FE84B990 ; if 0 <= R0 < 2 FE84B990 MOVS R0, #1 FE84B992 BL subfunc_0 ; kind of "is retail hardware?" test FE84B996 CBZ R0, loc_FE84B9A6 ; not taken FE84B998 MOV R1, R8 FE84B99A MOV R0, R4 ; R4 is either 0 or 1
FE84B99C BL subfunc_1 FE84B9A0 [...]

Then in (sub)subfunc_1, R0 value is now tested with an unsigned comparison:
FE852B94 (sub)subfunc_1 FE852B94 CMP R0, #2 FE852B96 BCS loc_FE852BBA ;unsigned comparison: branch if R0 > 1 FE852B98 MOVW R2, #0x9F38 FE852B9C [...]

The bug can no longer be triggered.
________________________________________________________________________ CVSS Version 2 Metrics: Access Vector: Local Access Complexity: High Authentication: Single Confidentiality Impact: Complete Integrity Impact: Complete Availability Impact: Complete ________________________________________________________________________ Disclosure Timeline: 2014-08-28 Intial vendor notification
2014-09-03 Vendor reply; severity of the issue rated as high 2014-00-00 Vendor has notified all OEMs 2014-12-18 Public advisory ________________________________________________________________________ References:

No comments:

Post a Comment