OP-TEE / optee_os

Trusted side of the TEE
Other
1.51k stars 1.03k forks source link

ASID allocator can cause soft lock in virtualized builds #6904

Open lorc opened 1 week ago

lorc commented 1 week ago

The way how ASID allocator is defined:

static bitstr_t bit_decl(g_asid, MMU_NUM_ASID_PAIRS) __nex_bss;

Creates an issue in virtualized environment. As this bitmask is shared between all VMs:

  1. One VM can trick OP-TEE to use all ASIDs for self, denying other VMs of service
  2. Even when VM behaves correctly, it can be destroyed in midst of open TEE session, leaving ASID(s) allocated forever.

We encountered problem 2 while restarting Android VM multiple times. At some point new VM just can't open a session:

D/TC:? 0 tee_ta_init_session_with_context:573 Re-open TA 7011a688-ddde-4053-a5a9-7b3c4ddf13b8
D/TC:? 0 tee_ta_close_session:498 csess 0x441b1100 id 1
D/TC:? 0 tee_ta_close_session:518 Destroy session
D/TC:? 0 tee_ta_init_pseudo_ta_session:284 Lookup pseudo TA dba51a17-0563-11e7-93b1-6fa7b0071a51
D/TC:? 0 vm_info_init:787 Failed to allocate ASID
D/TC:? 0 tee_ta_open_session:684 init session failed 0xffff0000
D/TC:? 0 tee_ta_init_pseudo_ta_session:284 Lookup pseudo TA dba51a17-0563-11e7-93b1-6fa7b0071a51
D/TC:? 0 vm_info_init:787 Failed to allocate ASID
D/TC:? 0 tee_ta_open_session:684 init session failed 0xffff0000
D/TC:? 0 tee_ta_init_pseudo_ta_session:284 Lookup pseudo TA dba51a17-0563-11e7-93b1-6fa7b0071a51
D/TC:? 0 vm_info_init:787 Failed to allocate ASID
D/TC:? 0 tee_ta_open_session:684 init session failed 0xffff0000
D/TC:? 0 tee_ta_init_pseudo_ta_session:284 Lookup pseudo TA dba51a17-0563-11e7-93b1-6fa7b0071a51
D/TC:? 0 vm_info_init:787 Failed to allocate ASID
D/TC:? 0 tee_ta_open_session:684 init session failed 0xffff0000
D/TC:? 0 tee_ta_init_pseudo_ta_session:284 Lookup pseudo TA dba51a17-0563-11e7-93b1-6fa7b0071a51
D/TC:? 0 vm_info_init:787 Failed to allocate ASID
...

Correct solution is to allocate a block of ASIDs for each VM separately. But we can't move g_asid from nexus, because it is used in partition allocator itself. Looks like ASID allocator should be virtualization-aware.

jenswi-linaro commented 1 week ago

Correct solution is to allocate a block of ASIDs for each VM separately. But we can't move g_asid from nexus, because it is used in partition allocator itself. Looks like ASID allocator should be virtualization-aware.

Yes, that's the quickest solution. However, with a few partitions, we may end up with not so many ASIDs per partition so in the longer term we may need to look for a way of reusing ASIDs even before the different TAs have been terminated. Anyway, dividing the ASID ranges per partition is a good first step.