Re: [REPORT] tee: tee_ioctl_supp_recv() missing tee_shm_put() cleanup for memref params

Jens Wiklander <[email protected]> Wed, 29 Apr 2026 08:34:36 +0200
Newsgroups org.trustedfirmware.lists.op-tee
Message-ID <CAHUa44E+b9SmT++XrrzSansAjMMhgxQLwCA-LmS-GMEugSmhSw@mail.gmail.com>
Hi Qihang,

On Wed, Apr 29, 2026 at 5:07 AM Qihang <[email protected]> wrote:
>
> 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 for the detailed report. If possible, please prepare a patch to fix this.

Cheers,
Jens

>
> Thanks,
> Qihang