The function thread_rpc_alloc()
(used by functions thread_rpc_alloc_payload()
, thread_rpc_alloc_global_payload()
) allocates shared memory buffer via RPC. The required size is copied to the RPC’s thread shared memory arg[]
from internal TEE memory params[]
in get_rpc_arg()
. Then thread_rpc_alloc()
calls thread_rpc()
to send the request to the REE.
The REE then process the request, update shared memory arg[]
at will, when the RPC is completed, thread_rpc()
returns. thread_rpc_alloc()
then call get_rpc_alloc_res()
to parse result from the REE and allocate corresponding memory object (mobj
) in case of success (using buf_ptr
and size
from arg[]
).
Consequences: Resulting allocated memory could be smaller than requested: Returned memory [PA, SIZE] could be inside shared memory "NSEC", but if caller does not check mobj->size
, this could be leverage to access invalid or restricted memory beyond the shared "NSEC" intended memory; consequence of doing so depends on memory arrangement and memory map. This could also have other side effects in the case of attribute OPTEE_MSG_ATTR_NONCONTIG
, like mapping less pages than expected.
E.g.#1: gprof_send_rpc()
uses thread_rpc_alloc_payload(SIZE)
, then use returned mobj
to get the virtual address, but assume the requested SIZE
is served, and does not check the actual size of the allocated memory object, and uses memcpy()
over it.
E.g.#2: ta_load()
uses thread_rpc_alloc_payload()
to allocate space for a TA binary, then get the virtual address (ta_buf
) from the associated mobj
without further checks on the size. ta_buf
is later used assumed to be of a given size.
E.g.#3: tee_fs_rpc_cache_alloc()
uses thread_rpc_alloc_payload()
, then get the va
from the mobj
, but the size is the one given in argument, and could be smaller than the one in the mobj. This API is used in various places.
E.g.#4 teerpmb*()->tee_rpmb_alloc()->thread_rpc_alloc_payload()
, the va
from the mobj
could point to a smaller allocated block than required.
Patches
optee_os.git
- core: verify size of allocated shared memory (cc6bc5f)
Workarounds
N/A
References
N/A
OP-TEE ID
OP-TEE-2019-0001
Reported by
Netflix (Bastien Simondi)
For more information
For more information regarding the security incident process in OP-TEE, please read the information that can be found when going to the "Security" page at https://www.trustedfirmware.org.
The function
thread_rpc_alloc()
(used by functionsthread_rpc_alloc_payload()
,thread_rpc_alloc_global_payload()
) allocates shared memory buffer via RPC. The required size is copied to the RPC’s thread shared memoryarg[]
from internal TEE memoryparams[]
inget_rpc_arg()
. Thenthread_rpc_alloc()
callsthread_rpc()
to send the request to the REE.The REE then process the request, update shared memory
arg[]
at will, when the RPC is completed,thread_rpc()
returns.thread_rpc_alloc()
then callget_rpc_alloc_res()
to parse result from the REE and allocate corresponding memory object (mobj
) in case of success (usingbuf_ptr
andsize
fromarg[]
).Consequences: Resulting allocated memory could be smaller than requested: Returned memory [PA, SIZE] could be inside shared memory "NSEC", but if caller does not check
mobj->size
, this could be leverage to access invalid or restricted memory beyond the shared "NSEC" intended memory; consequence of doing so depends on memory arrangement and memory map. This could also have other side effects in the case of attributeOPTEE_MSG_ATTR_NONCONTIG
, like mapping less pages than expected.E.g.#1:
gprof_send_rpc()
usesthread_rpc_alloc_payload(SIZE)
, then use returnedmobj
to get the virtual address, but assume the requestedSIZE
is served, and does not check the actual size of the allocated memory object, and usesmemcpy()
over it.E.g.#2:
ta_load()
usesthread_rpc_alloc_payload()
to allocate space for a TA binary, then get the virtual address (ta_buf
) from the associatedmobj
without further checks on the size.ta_buf
is later used assumed to be of a given size.E.g.#3:
tee_fs_rpc_cache_alloc()
usesthread_rpc_alloc_payload()
, then get theva
from themobj
, but the size is the one given in argument, and could be smaller than the one in the mobj. This API is used in various places.E.g.#4
teerpmb*()->tee_rpmb_alloc()->thread_rpc_alloc_payload()
, theva
from themobj
could point to a smaller allocated block than required.Patches
optee_os.git
Workarounds
N/A
References
N/A
OP-TEE ID
OP-TEE-2019-0001
Reported by
Netflix (Bastien Simondi)
For more information
For more information regarding the security incident process in OP-TEE, please read the information that can be found when going to the "Security" page at https://www.trustedfirmware.org.