Summary

This is the second part of a blog series covering my security research into Samsung’s TrustZone.

This post is a companion to my talk from Ekoparty 2017, namely the reverse engineering process of T-base. The slides and video of the talk are both available online.

In fact, since both of those are available, for this part of the series I didn’t quite write a “storytelling” blog post. Instead, this post only does what the slide/video format does not accomplish: a more accessible enumeration of the most important results (code snippets, declarations of reversed functions/structures). So it’s more like a wiki then a blog post.

T-base Image Extraction

To extract all the T-base firmware parts that are embedded in the Sboot image (microkernel, Run Time Manager, tlLibrary, Crypto Driver, etc), find the extract table by the string marker “t-base”:

ROM:00147000 tbase_extract_table DCB "t-base ",0     ; descriptor struct:
ROM:00147000                                         ;     char name[8]
ROM:00147000                                         ;     int offset
ROM:00147000                                         ;     int size
ROM:00147000                                         ;     char padding[0x10]
ROM:00147000                                         ;
ROM:00147000                                         ; real start offset: 0x132000
ROM:00147000                                         ;
ROM:00147000                                         ; Mtk: 0->0x147000 -> the Microkernel image itself -> go back 0x15000 from "t-base"
ROM:00147000                                         ; Image_h: 0x147000 -> 0x148000 -> so that's this
ROM:00147000                                         ; Rtm: 0x148000 -> RTM is the Run-Time Manager (aka S0CB)
ROM:00147000                                         ;
ROM:00147000                                         ; drcrypt: 0x167000 -> MCLF file (Crypto Driver)
ROM:00147000                                         ; tlproxy: 0x17A000 -> MCLF file (SFS Trustlet)
ROM:00147000                                         ; sth2: 0x17B000    -> MCLF file (SFS Driver)
ROM:00147000                                         ; mclib: 0x183000   -> tlLib (runtime library for Trustlets and Drivers)
ROM:00147008                 DCD 0
ROM:0014700C                 DCD 0x5D000
ROM:00147010                 ALIGN 0x20
ROM:00147020 aMtk            DCB "mtk    ",0
ROM:00147028                 DCD 0
ROM:0014702C                 DCD 0x15000
ROM:00147030                 ALIGN 0x20
ROM:00147040 aImage_h        DCB "image_h",0
ROM:00147048                 DCD 0x15000
ROM:0014704C                 DCD unk_1000
ROM:00147050                 ALIGN 0x20
ROM:00147060 aRtm            DCB "rtm    ",0
ROM:00147068                 DCD 0x16000
ROM:0014706C                 DCD 0x1F000
ROM:00147070                 ALIGN 0x20
ROM:00147080 aDrcrypt        DCB "drcrypt",0
ROM:00147088                 DCD 0x35000
ROM:0014708C                 DCD 0x13000
ROM:00147090                 ALIGN 0x20
ROM:001470A0 aTlproxy        DCB "tlproxy",0
ROM:001470A8                 DCD 0x48000
ROM:001470AC                 DCD 0x1000
ROM:001470B0                 DCD 0
ROM:001470B4                 DCD 0
ROM:001470B8                 DCD 0
ROM:001470BC                 DCD 0
ROM:001470C0 aSth2           DCB "sth2   ",0
ROM:001470C8                 DCD 0x49000
ROM:001470CC                 DCD unk_8000
ROM:001470D0                 ALIGN 0x20
ROM:001470E0 aMclib          DCB "mclib  ",0
ROM:001470E8                 DCD 0x51000
ROM:001470EC                 DCD unk_C000
ROM:001470F0                 ALIGN 0x1000
ROM:00148000 S0CB_HDR        DCB "S0CB",0            ; Rtm offset points here
ROM:00148005                 DCB 0x10, 0, 0
ROM:00148008                 DCD unk_C000
ROM:0014800C                 DCD dword_D000
ROM:00148010                 DCD 0
ROM:00148014                 DCD 0x11960
ROM:00148018                 DCD 0xB295
ROM:0014801C                 DCD 0x3F
ROM:00148020                 DCD 0x6A
ROM:00148024 aMccb           DCB "MCCB",0
ROM:00148029                 DCD 0
ROM:0014802D                 DCD 0

T-base SMCs

I have identified the following T-base → ATF invocable SMCs:

  • 0x1: finished processing fastcall invoked from NWd, return to NWd via ATF
  • 0xB2000002: send the VBAR value to ATF (so ATF knows where the SMC handler is)
  • 0xB2000003: write character (for logging messages through ATF)
  • 0xB2000004: send the T-base initialization status to ATF
ROM:00133054 tbase_smc_send_VBAR                     ; CODE XREF: config_tbase_and_tell_aft_the_vbar+E↑p
ROM:00133054                 LDR             R0, =0xB2000002
ROM:00133058                 MOV             R1, #1
ROM:0013305C                 LDR             R2, =0x7F00000 ; normal VBAR address
ROM:00133060                 SMC             #0
ROM:00133064                 BX              LR
ROM:00133064 ; End of function tbase_smc_send_VBAR
ROM:00133064
ROM:00133068
ROM:00133068 ; =============== S U B R O U T I N E =======================================
ROM:00133068
ROM:00133068 ; Attributes: noreturn
ROM:00133068
ROM:00133068 tbase_smc_fastcall_status_then_ret_to_nonSW
ROM:00133068                                         ; CODE XREF: sub_1343AA:loc_1354C8↓p
ROM:00133068                                         ; translate_MSMBase_to_VA+46↓p
ROM:00133068                 LDR             R0, =0xB2000004
ROM:0013306C                 MOV             R1, #1
ROM:00133070                 MOV             R2, #1
ROM:00133074                 SMC             #0
ROM:00133078                 LDR             R0, =0x2000001
ROM:0013307C                 SMC             #0
ROM:00133080
ROM:00133080 loc_133080                              ; CODE XREF: tbase_smc_fastcall_status_then_ret_to_nonSW:loc_133080↓j
ROM:00133080                 B               loc_133080
ROM:00133080 ; End of function tbase_smc_fastcall_status_then_ret_to_nonSW
ROM:00133080
ROM:00133084
ROM:00133084 ; =============== S U B R O U T I N E =======================================
ROM:00133084
ROM:00133084
ROM:00133084 tbase_smc_fastcall_status               ; CODE XREF: sub_1343AA+31C6↓p
ROM:00133084                 LDR             R0, =0xB2000004
ROM:00133088                 MOV             R1, #1
ROM:0013308C                 MOV             R2, #3
ROM:00133090                 SMC             #0
ROM:00133094                 BX              LR
ROM:00133094 ; End of function tbase_smc_fastcall_status
ROM:00133094
ROM:00133098
ROM:00133098 ; =============== S U B R O U T I N E =======================================
ROM:00133098
ROM:00133098
ROM:00133098 tbase_smc_fastcall_print
ROM:00133098                 MOV             R2, R0
ROM:0013309C                 LDR             R0, =0xB2000003
ROM:001330A0                 MOV             R1, #1
ROM:001330A4                 SMC             #0
ROM:001330A8                 BX              LR
ROM:001330A8 ; End of function tbase_smc_fastcall_print

T-base syscalls

.tbase_mem_data:07F0D86C ; ===========================================================================
.tbase_mem_data:07F0D86C
.tbase_mem_data:07F0D86C ; Segment type: Pure data
.tbase_mem_data:07F0D86C                 AREA .tbase_mem_data, DATA, ALIGN=0
.tbase_mem_data:07F0D86C                 ; ORG 0x7F0D86C
.tbase_mem_data:07F0D86C syscall_table   DCD svc_0_nop+1         ; DATA XREF: invoke_syscall_from_table+40↑o
.tbase_mem_data:07F0D86C                                         ; invoke_syscall_from_table:syscall_table_ptr↑o
.tbase_mem_data:07F0D870                 DCD svc_1_init_process+1
.tbase_mem_data:07F0D874                 DCD svc_2_nop+1
.tbase_mem_data:07F0D878                 DCD svc_3_nop+1
.tbase_mem_data:07F0D87C                 DCD svc_4+1             ; Did not find this invoked anywhere in {RTM,tlLib}
.tbase_mem_data:07F0D880                 DCD svc_5_start_process+1
.tbase_mem_data:07F0D884                 DCD svc_exit+1
.tbase_mem_data:07F0D888                 DCD svc_mmap+1
.tbase_mem_data:07F0D88C                 DCD svc_8_munmap+1
.tbase_mem_data:07F0D890                 DCD svc_9_start_thread+1
.tbase_mem_data:07F0D894                 DCD svc_A_stop_thread+1
.tbase_mem_data:07F0D898                 DCD svc_B_return_0xD+1
.tbase_mem_data:07F0D89C                 DCD svc_C_modify_thread_registers+1
.tbase_mem_data:07F0D8A0                 DCD svc_D_mprotect+1
.tbase_mem_data:07F0D8A4                 DCD svc_E_resume_thread+1
.tbase_mem_data:07F0D8A8                 DCD svc_F+1
.tbase_mem_data:07F0D8AC                 DCD svc_10_set_thread_prio+1
.tbase_mem_data:07F0D8B0                 DCD svc_11_ipc+1
.tbase_mem_data:07F0D8B4                 DCD svc_12_int_attach+1
.tbase_mem_data:07F0D8B8                 DCD svc_13_int_detach+1
.tbase_mem_data:07F0D8BC                 DCD svc_14_sigwait+1
.tbase_mem_data:07F0D8C0                 DCD svc_15_signal+1
.tbase_mem_data:07F0D8C4                 DCD svc_16+1            ; Did not find this invoked anywhere in {RTM,tlLib}
.tbase_mem_data:07F0D8C8                 DCD svc_tbase_smc_fastcall_input+1
.tbase_mem_data:07F0D8CC                 DCD svc_18_log_char+1
.tbase_mem_data:07F0D8D0                 DCD svc_19_get_secure_timestamp+1
.tbase_mem_data:07F0D8D4                 DCD svc_1A_control+1    ; includes a lot, such as:
.tbase_mem_data:07F0D8D4                                         ; - driver shmem map/unmap
.tbase_mem_data:07F0D8D4                                         ; - get/set exception info
.tbase_mem_data:07F0D8D4                                         ; - get MCP queue info
.tbase_mem_data:07F0D8D4                                         ; - get IPCH phys address values
.tbase_mem_data:07F0D8D4                                         ; - cache control
.tbase_mem_data:07F0D8D4                                         ; - virt2phys, phys2virt translation
.tbase_mem_data:07F0D8D4                                         ; - set custom fastcall, call custom fastcall
.tbase_mem_data:07F0D8D4                                         ;
.tbase_mem_data:07F0D8D4                                         ; Known sub-handlers:
.tbase_mem_data:07F0D8D4                                         ;
.tbase_mem_data:07F0D8D4                                         ; -0x8F: getting/setting fastcall configuration values
.tbase_mem_data:07F0D8D4                                         ;     - 0xC: get S0CB PA
.tbase_mem_data:07F0D8D4                                         ;     - 0xA: notify (nSW - trigger interrupt)
.tbase_mem_data:07F0D8D4                                         ;     - 0xB: notify driver (drTriggerIntr)
.tbase_mem_data:07F0D8D4                                         ;     - 0xD: get fc_init perm flags
.tbase_mem_data:07F0D8D4                                         ;     - 0x1: set exception info
.tbase_mem_data:07F0D8D4                                         ;     - 0x2: get fault info
.tbase_mem_data:07F0D8D4                                         ;     - 0x4,0x5,0x6,0x7: get MCP queue info
.tbase_mem_data:07F0D8D4                                         ; (mci_buffer_addr, nq_length, mcp_queue_addr, mcp_queue_len)
.tbase_mem_data:07F0D8D4                                         ;     - 0x9: map mcp cmd queue (in kernel)
.tbase_mem_data:07F0D8D4                                         ; -0x90 -> more control
.tbase_mem_data:07F0D8D4                                         ;     - 5: read info for exception
.tbase_mem_data:07F0D8D4                                         ;     - 7: translate VA to PA
.tbase_mem_data:07F0D8D4                                         ; -0x91 virt-to-phys and also virt-to-phys64
.tbase_mem_data:07F0D8D4                                         ; -0x92 ->  I-cache clean/invalidate, D-cache clean/invalidate
.tbase_mem_data:07F0D8D4                                         ; -0x81:map, 0x83: unmap, 0x85:map.
.tbase_mem_data:07F0D8D4                                         ;  - Difference in 81/85: map into TA/driver or map into RTM
.tbase_mem_data:07F0D8D4                                         ; -0x94 -> set custom fastcall handler
.tbase_mem_data:07F0D8D4                                         ; -0x95 -> SMC fastcall 5 (unk)
.tbase_mem_data:07F0D8D4                                         ; -0x96 -> getPhysMemType
.tbase_mem_data:07F0D8D4                                         ; -0x98 -> exec f

RTM IPC

Note: The talk calls RTM “S0CB”, based on the magic value of its fileformat. Using the hint from the Sboot firmware, the probably more accurate name I now use for it instead is RTM (“Run Time Manager”).

This is a uniquely powerful user-space process in T-base, always started first, and tasked with starting and managing all other processes (trustlets). So similar to init on Linux. It servers three functions:

  • implements MCP,
  • implements the notification of trustlets when requests arrive from NWd,
  • implements the IPC mechanism of T-base.

The MCP commands were known from public sources. For IPC, the first 12 IPC command definitions can be found in source code here! I used the naming convention seen here for the rest that I was able to associate functionality with:

/** Possible message types/event types of the system. */
typedef enum {
    MSG_NULL = 0,  // Used for initializing state machines
    /***************/
    MSG_RQ                  = 1,  /**< Request; client -> server;  */
    MSG_RS                  = 2,  /**< Response; server -> client */
    MSG_RD                  = 3,  /**< Ready; server -> IPCH */
    MSG_NOT                 = 4,  /**< Notification; client -> IPCH; */
    MSG_CLOSE_TRUSTLET      = 5,  /**< Close Trustlet; MSH -> IPCH; IPCH -> all servers */
    MSG_CLOSE_TRUSTLET_ACK  = 6,  /**< Close Trustlet Ack; servers -> IPCH */
    MSG_MAP                 = 7,  /**< Map; driver <-> IPCH; */
    MSG_ERR_NOT             = 8,  /**< Error Notification;  EXCH/SIQH -> IPCH; */
    MSG_CLOSE_DRIVER        = 9,  /**< Close driver; MSH -> IPCH; IPCH -> driver */
    MSG_CLOSE_DRIVER_ACK    = 10, /**< Close driver Ack; driver -> IPCH; IPCH -> MSH */
    MSG_GET_DRIVER_VERSION  = 11, /**< GetDriverVersion; client <--> IPCH */
    MSG_GET_DRAPI_VERSION   = 12, /**< GetDrApiVersion; driver <--> IPCH */
    MSG_SET_NOTIFICATION_HANDLER    = 13, // Driver <-> IPCH
    MSG_DRV_NOT                     = 15, // Driver -> Trustlet
    MSG_SET_FASTCALL_HANDLER        = 16, // Driver <-> IPCH
    MSG_GET_CLIENT_ROOT_AND_SP_ID   = 17, // Driver <-> IPCH
    MSG_CALL_FASTCALL               = 25, // DRIVER -> IPCH -> Kernel
    MSG_GET_CLI_UUID                = 26, // Driver <-> IPCH
    MSG_RQ_2                        = 27, // Client -> Server
    MSG_MAP_VA_DIRECT               = 31, // DRIVER <-> IPCH
    MSG_MAP_PY_DIRECT               = 32, // DRIVER <-> IPCH
    MSG_UNMAP_PY_DIRECT             = 33, // DRIVER <-> IPCH
    MSG_GET_MEM_TYPE                = 34, // DRIVER <-> IPCH
    MSG_UNMAP_VA_DIRECT             = 35 // DRIVER <-> IPCH
} message_t;

tlApis

ROM:07D0BE38 tlApi_syscall_table DCD tlApiNOP+1          ; 0
ROM:07D0BE38                 DCD tlApiGetVersion+1   ; 1
ROM:07D0BE38                 DCD tlApiGetMobicoreVersion+1; 2
ROM:07D0BE38                 DCD tlApiGetPlatformInfo+1; 3
ROM:07D0BE38                 DCD tlApiExit+1         ; 4
ROM:07D0BE38                 DCD tlApiLogvPrintf+1   ; 5
ROM:07D0BE38                 DCD tlApiWaitNotification+1; 6
ROM:07D0BE38                 DCD tlApiNotify+1       ; 7
ROM:07D0BE38                 DCD tlApi_callDriver+1  ; 8
ROM:07D0BE38                 DCD tlApiWrapObjectExt+1; 9
ROM:07D0BE38                 DCD tlApiUnwrapObjectExt+1; 10
ROM:07D0BE38                 DCD tlApiGetSuid+1      ; 11
ROM:07D0BE38                 DCD tlApiSecSPICmd+1    ; 12
ROM:07D0BE38                 DCD tlApiCrAbort+1      ; 13
ROM:07D0BE38                 DCD tlApiRandomGenerateData+1; 14
ROM:07D0BE38                 DCD tlApiGenerateKeyPair+1; 15
ROM:07D0BE38                 DCD tlApiCipherInitWithData+1; 16
ROM:07D0BE38                 DCD tlApiCipherUpdate+1 ; 17
ROM:07D0BE38                 DCD tlApiCipherDoFinal+1; 18
ROM:07D0BE38                 DCD tlApiSignatureInitWithData+1; 19
ROM:07D0BE38                 DCD tlApiSignatureUpdate+1; 20
ROM:07D0BE38                 DCD tlApiSignatureSign+1; 21
ROM:07D0BE38                 DCD tlApiSignatureVerify+1; 22
ROM:07D0BE38                 DCD tpiApiMessageDigestInitWithData+1; 23
ROM:07D0BE38                 DCD tlApiMessageDigestUpdate+1; 24
ROM:07D0BE38                 DCD tlApiMessageDigestDoFinal+1; 25
ROM:07D0BE38                 DCD tlApiGetVirtMemType+1; 26
ROM:07D0BE38                 DCD tlApiDeriveKey+1    ; 27
ROM:07D0BE38                 DCD tlApiMalloc+1       ; 28
ROM:07D0BE38                 DCD tlApiRealloc+1      ; 29
ROM:07D0BE38                 DCD tlApiFree+1         ; 30
(...)
ROM:07D0BE38                 DCD tlApiGetIDs+1       ; 43
(...)
ROM:07D0BE38                 DCD tlApiRandomGenerateData_wrap+1; 83
ROM:07D0BE38                 DCD tlApiCrash+1        ; 84
ROM:07D0BE38                 DCD tlApiEndorse+1      ; 85
ROM:07D0BE38                 DCD tlApiTuiGetScreenInfo+1; 86
ROM:07D0BE38                 DCD tlApiTuiOpenSession+1; 87
ROM:07D0BE38                 DCD tlApiTuiCloseSession+1; 88
ROM:07D0BE38                 DCD tlApiTuiSetImage+1  ; 89
ROM:07D0BE38                 DCD tlApiTuiGetTouchEvent+1; 90
ROM:07D0BE38                 DCD tlApiTuiGetTouchEventsLoop+1; 91
ROM:07D0BE38                 DCD tlApiDrmProcessContent+1; 92
ROM:07D0BE38                 DCD tlApiDrmOpenSession+1; 93
ROM:07D0BE38                 DCD tlApiDrmCloseSession+1; 94
ROM:07D0BE38                 DCD tlApiDrmCheckLink+1 ; 95
ROM:07D0BE38                 DCD tlApiDeriveKey_wrapper+1; 96
ROM:07D0BE38                 DCD tlApiUnwrapObjectExt_wrapper+1; 97
ROM:07D0BE38                 DCD tlApiGetSecureTimestamp+1; 98

drApis

ROM:07D0C114 ; int drApi_syscall_table[62]
ROM:07D0C114 drApi_syscall_table DCD drApiGetVersion+1   ; 0
ROM:07D0C114                                         ; DATA XREF: get_syscall_fn+30↑o
ROM:07D0C114                                         ; ROM:off_7D0A9F8↑o
ROM:07D0C114                 DCD drApiExit+1         ; 1
ROM:07D0C114                 DCD drApiMapPhys+1      ; 2
ROM:07D0C114                 DCD drApiUnmap+1        ; 3
ROM:07D0C114                 DCD drApiMapPhysPage4KBWithHardware+1; 4
ROM:07D0C114                 DCD drApiMapClient+1    ; 5
ROM:07D0C114                 DCD drApiMapClientAndParams+1; 6
ROM:07D0C114                 DCD drApiAddrTranslateAndCheck+1; 7
ROM:07D0C114                 DCD drApiGetTaskid+1    ; 8
ROM:07D0C114                 DCD drApiTaskidGetThreadid+1; 9
ROM:07D0C114                 DCD drApiGetLocalThreadId+1; 10
ROM:07D0C114                 DCD drApiStartThread+1  ; 11
ROM:07D0C114                 DCD drApiStopThread+1   ; 12
ROM:07D0C114                 DCD drApiResumeThread+1 ; 13
ROM:07D0C114                 DCD drApiThreadSleep+1  ; 14
ROM:07D0C114                 DCD drApiSetThreadPriority+1; 15
ROM:07D0C114                 DCD drApiIntrAttach+1   ; 16
ROM:07D0C114                 DCD drApiIntrDetach+1   ; 17
ROM:07D0C114                 DCD drApiWaitForIntr+1  ; 18
ROM:07D0C114                 DCD drApiTriggerIntr+1  ; 19
ROM:07D0C114                 DCD drApiIpcWaitForMessage+1; 20
ROM:07D0C114                 DCD drApiIpcCallToIPCH+1; 21
ROM:07D0C114                 DCD drApiIpcSignal+1    ; 22
ROM:07D0C114                 DCD drApiIpcSigWait+1   ; 23
ROM:07D0C114                 DCD drApiNotify+1       ; 24
ROM:07D0C114                 DCD drApiSystemCtrl+1   ; 25
ROM:07D0C114                 DCD sub_7D0A2CE+1       ; 26
ROM:07D0C114                 DCD drApiVirt2Phys+1    ; 27
ROM:07D0C114                 DCD drApiCacheDataClean+1; 28
ROM:07D0C114                 DCD drApiCacheDataCleanAndInvalidate+1; 29
ROM:07D0C114                 DCD drApiNotifyClient+1 ; 30
ROM:07D0C114                 DCD drApiThreadExRegs+1 ; 31
ROM:07D0C114                 DCD drApiInstallFc+1    ; 32
ROM:07D0C114                 DCD drApiIpcUnknownMessage+1; 33
ROM:07D0C114                 DCD drApiIpcUnknownException+1; 34
ROM:07D0C114                 DCD drApiGetPhysMemType+1; 35
ROM:07D0C114                 DCD drApiGetClientRootAndSpId+1; 36
ROM:07D0C114                 DCD drApiCacheDataCleanRange+1; 37
ROM:07D0C114                 DCD drApiCacheDataCleanAndInvalidateRange+1; 38
ROM:07D0C114                 DCD drApiMapPhys64+1    ; 39
ROM:07D0C114                 DCD drApiMapPhys64_2+1  ; 40
ROM:07D0C114                 DCD drApiVirt2Phys64+1  ; 41
ROM:07D0C114                 DCD drApiGetPhysMemType64+1; 42
ROM:07D0C114                 DCD drApiUpdateNotificationThread+1; 43
ROM:07D0C114                 DCD drApiRestartThread+1; 44
ROM:07D0C114                 DCD drApiGetSecureTimestamp+1; 45
ROM:07D0C114                 DCD drApiFastCall+1     ; 46
ROM:07D0C114                 DCD drApiGetClientUuid+1; 47
ROM:07D0C114                 DCD sub_7D0A2AC+1       ; 48
ROM:07D0C114                 DCD drApiMapVirtBuf+1   ; 49
ROM:07D0C114                 DCD drApiUnmapPhys2+1   ; 50
ROM:07D0C114                 DCD drApiMapPhys2+1     ; 51
ROM:07D0C114                 DCD drApiUnmapVirtBuf2+1; 52
ROM:07D0C114                 DCD sub_7D07D76+1       ; 53
ROM:07D0C114                 DCD sub_7D0A558+1       ; 54
ROM:07D0C114                 DCD sub_7D0A574+1       ; 55
ROM:07D0C114                 DCD sub_7D0A5D6+1       ; 56
ROM:07D0C114                 DCD sub_7D0A738+1       ; 57
ROM:07D0C114                 DCD sub_7D0A1BA+1       ; 58
ROM:07D0C114                 DCD sub_7D0A1C8+1       ; 59
ROM:07D0C114                 DCD sub_7D0A5F4+1       ; 60
ROM:07D0C114                 DCD sub_7D0A60C+1       ; 61

Sandboxing Mechanisms

  • Kernel and RTM both maintain their own mappings of process instances to type (Trustlet/Driver) as well as the virtual address space mappings of processes.
  • Kernel checks caller type for SVCs that it restricts to drivers; RTM checks caller type for IPC calls that it restricts to drivers (not a central mechanism; has to be implemented correctly one-by-one for each case, similar to access_ok() checks in Linux).
  • These two together restrict the ability to map other Trustlets’ virtual memory or any physical memory (including NWd) to Drivers. Drivers are still restricted from mapping RWX memory, or mapping anything over their own code pages.
  • Drivers can use SVC to get from the kernel the UUID of the Trustlet that is making the current request; this can be used to filter what clients (Trustlets) are allowed to access what functionality of a Driver.
  • Drivers can use SVC to map NWd or SWd physical memory into their address space and also use SVC to register custom fastcall handlers, giving them the ability to directly executing code from SWd EL1. In effect, this makes Drivers as privileged as SWd EL1.

Exploit Mitigations (Trustlets and Drivers)

  • RX code pages and RW data pages
  • No boundaries between stack/bss/heap
  • WSMs mapped into Trustlets and Trustlet memory mapped into Drivers are in separate memory region from the above code+data regions
  • No stack canaries, no ASLR