[REPORT] tee: tee_ioctl_supp_recv() missing tee_shm_put() cleanup for memref params
Qihang <[email protected]> Wed, 29 Apr 2026 11:07:22 +0800
| Newsgroups | org.trustedfirmware.lists.op-tee |
|---|---|
| Message-ID | <CAH78Gvtd_reUt1mCasR=grZuLWWHcn4-ox3bXWXNEvbTOV3UGA@mail.gmail.com> |
Hi,
I would like to report a likely shared-memory reference leak in
drivers/tee/tee_core.c, in tee_ioctl_supp_recv().
The issue is that tee_ioctl_supp_recv() calls params_from_user(), which
acquires references for MEMREF-type parameters via tee_shm_get_from_id(),
but the cleanup path only frees the params array and does not drop the
acquired shm references.
Relevant code in tee_ioctl_supp_recv():
rc = params_from_user(ctx, params, num_params, uarg->params);
if (rc)
goto out;
rc = ctx->teedev->desc->ops->supp_recv(ctx, &func, &num_params, params);
if (rc)
goto out;
...
out:
kfree(params);
return rc;
By contrast, other callers of params_from_user() in tee_core.c do release
MEMREF references on cleanup, for example:
- tee_ioctl_open_session()
- tee_ioctl_invoke()
- tee_ioctl_object_invoke()
The helper comment in param_from_user_memref() also states that the caller
is responsible for calling tee_shm_put() on all resolved pointers.
Reachability / trigger paths:
1. qcomtee backend:
qcomtee registers .supp_recv = qcomtee_supp_recv on a non-privileged
tee device path. qcomtee_supp_recv() rejects any non-meta parameter
after the first one:
for (i = 1; i < *num_params; i++)
if (params[i].attr)
return -EINVAL;
This allows a path where params_from_user() has already acquired a shm
reference for a MEMREF parameter, then qcomtee_supp_recv() returns an
error, and tee_ioctl_supp_recv() exits without tee_shm_put().
2. Partial failure before backend callback:
if params_from_user() successfully resolves an earlier MEMREF parameter
and then fails on a later parameter, tee_ioctl_supp_recv() still goes
to the same cleanup path without dropping already acquired shm refs.
This means the issue is not just a backend-specific quirk: the core ioctl
cleanup path itself is missing tee_shm_put() handling.
Impact:
- leaked shared-memory references
- shared-memory objects may remain pinned and never reach final release
- repeated triggering can cause resource exhaustion / DoS
This does not appear to be a UAF, since refcount_t saturation prevents
wraparound. The impact looks limited to resource leakage and availability.
If useful, I can also prepare a patch.
Thanks,
Qihang