All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Ekansh Gupta" <ekansh.gupta@oss.qualcomm.com>
Cc: dri-devel@lists.freedesktop.org, media-ci@linuxtv.org
Subject: Re: [PATCH v4 22/25] accel/qda: Add remote session attach to the legacy shim
Date: Sun, 01 Nov 2026 23:00:06 +0000	[thread overview]
Message-ID: <sashiko-outbox-192746@kernel.org> (raw)
In-Reply-To: <20261102-v4-v4-22-88f2f24a5f0b@qti.qualcomm.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] accel/qda: race between qda_session_attach() and qda_session_init_create()
- [High] accel/qda: use-after-free in qda_session_attach() during rpmsg removal
- [Medium] accel/qda: interrupted wait in qda_attach_audio_pd() resends remote heap
--

commit ae4f1060dc81ff84d55ddf1c5fd82d79333077f8
Author: Ekansh Gupta <ekangupt@qti.qualcomm.com>

accel/qda: Add remote session attach to the legacy shim

This commit wires FASTRPC_IOCTL_INIT_ATTACH, FASTRPC_IOCTL_INIT_ATTACH_SNS,
and FASTRPC_IOCTL_INIT_CREATE_STATIC into the legacy FastRPC compatibility
shim by extracting qda_session_attach() and exposing it via
qda_legacy_ops_table.

> diff --git a/drivers/accel/qda/qda_fastrpc_shim.c b/drivers/accel/qda/qda_fastrpc_shim.c
> index c46d2de4f5818..c1464b1adbc2c 100644
> --- a/drivers/accel/qda/qda_fastrpc_shim.c
> +++ b/drivers/accel/qda/qda_fastrpc_shim.c
[ ... ]
> @@ -295,6 +296,23 @@ static long qda_shim_init_create(struct qda_shim_file *sf, void __user *argp)
>  	return err;
>  }
>  
> +static long qda_shim_attach(struct qda_shim_file *sf, u32 pd_type)
> +{
> +	return qda_legacy_ops_table.attach(sf->session, pd_type, NULL, 0);
> +}
> +
> +/* memlen is ignored: the Audio PD heap size comes from the device tree */
> +static long qda_shim_init_create_static(struct qda_shim_file *sf, void __user *argp)
> +{
> +	struct fastrpc_init_create_static args;
> +
> +	if (copy_from_user(&args, argp, sizeof(args)))
> +		return -EFAULT;
> +
> +	return qda_legacy_ops_table.attach(sf->session, QDA_ATTACH_AUDIO_PD,
> +					   u64_to_user_ptr(args.name), args.namelen);
> +}

[Severity: High]
Can qda_shim_attach() and qda_shim_init_create_static() (as well as
qda_ioctl_attach()) trigger a use-after-free if the underlying rpmsg device
is removed while an attach ioctl is in flight?

Both qda_shim_ioctl() and drm_ioctl() only perform a point-in-time
drm_dev_is_unplugged() check on entry without entering a drm_dev_enter()
critical section:

drivers/accel/qda/qda_fastrpc_shim.c:qda_shim_ioctl() {
	if (drm_dev_is_unplugged(&sf->session->qda_dev->drm_dev))
		return -ENODEV;

	return qda_shim_dispatch(sf, cmd, (void __user *)arg);
}

If qda_rpmsg_remove() runs after that check passes (for example while
qda_shim_init_create_static() or qda_attach_audio_pd() sleeps in
copy_from_user() or memdup_user()), drm_dev_unplug() does not wait for the
in-flight qda_session_attach() call before tearing down the device:

drivers/accel/qda/qda_rpmsg.c:qda_rpmsg_remove() {
	drm_dev_unplug(&qdev->drm_dev);
	qdev->rpdev = NULL;
	qda_fastrpc_flush_pending(qdev);
	qda_cb_unpopulate(qdev);
	qda_deinit_device(qdev);
	qda_deinit_remote_heap(qdev);
}

qda_deinit_device() destroys qdev->iommu_mgr->assignment_lock and
qdev->ctx_xa, and devres teardown on &rpdev->dev frees qdev->iommu_mgr
(allocated with devm_kzalloc(qdev->dev, ...) in qda_init_device()). When the
in-flight qda_session_attach() proceeds into:

  qda_fastrpc_invoke()
    -> qda_fastrpc_context_alloc()
    -> qda_fastrpc_prepare_args()
      -> alloc_kernel_gem()
        -> qda_gem_create_object()
          -> qda_memory_manager_alloc()
            -> qda_memory_manager_assign_device()

wouldn't it access the destroyed qdev->ctx_xa and dereference the freed
qdev->iommu_mgr (or have its newly allocated ctx freed early if
qda_fastrpc_flush_pending() runs between qda_fastrpc_context_alloc() and
qda_rpmsg_send_msg())?

> diff --git a/drivers/accel/qda/qda_ioctl.c b/drivers/accel/qda/qda_ioctl.c
> index 41234fc576a9a..aaf3e5e6b5b18 100644
> --- a/drivers/accel/qda/qda_ioctl.c
> +++ b/drivers/accel/qda/qda_ioctl.c
> @@ -183,7 +183,7 @@ int qda_release_dsp_process(struct qda_dev *qdev, struct qda_session *session)
>   * so that a concurrent one cannot skip the heap while the first is still in
>   * flight, and the flag is set only once the DSP has accepted it.
>   */
> -static int qda_attach_audio_pd(struct qda_session *session, struct drm_qda_remote_attach *args)
> +static int qda_attach_audio_pd(struct qda_session *session, const char __user *uname, u32 namelen)
>  {
>  	struct qda_dev *qdev = session->qda_dev;
>  	struct qda_static_pd_args sargs = {};
> @@ -193,20 +193,20 @@ static int qda_attach_audio_pd(struct qda_session *session, struct drm_qda_remot
>  	if (strcmp(qdev->dsp_name, "adsp") || !qdev->remote_heap_size)
>  		return -ENODEV;
>  
> -	if (!args->namelen || args->namelen > QDA_FASTRPC_INIT_NAMELEN_MAX)
> +	if (!namelen || namelen > QDA_FASTRPC_INIT_NAMELEN_MAX)
>  		return -EINVAL;
>  
> -	name = memdup_user(u64_to_user_ptr(args->name), args->namelen);
> +	name = memdup_user(uname, namelen);
>  	if (IS_ERR(name))
>  		return PTR_ERR(name);
>  
> -	if (name[args->namelen - 1]) {
> +	if (name[namelen - 1]) {
>  		err = -EINVAL;
>  		goto out_free;
>  	}
>  
>  	sargs.name = name;
> -	sargs.namelen = args->namelen;
> +	sargs.namelen = namelen;
>  
>  	scoped_guard(mutex, &qdev->remote_heap_lock) {
>  		if (!qdev->audio_init_mem) {

[Severity: Medium]
What happens in qda_attach_audio_pd() if qda_fastrpc_invoke() is interrupted
by a signal after sending the request to the DSP?

Inside the qdev->remote_heap_lock guard:

	scoped_guard(mutex, &qdev->remote_heap_lock) {
		if (!qdev->audio_init_mem) {
			sargs.heap.addr = qdev->remote_heap_addr;
			sargs.heap.size = qdev->remote_heap_size;
		}

		err = qda_fastrpc_invoke(QDA_FASTRPC_RMID_INIT_CREATE_STATIC, &sargs, session);
		if (!err && sargs.heap.size)
			qdev->audio_init_mem = true;
	}

qda_fastrpc_invoke_common() calls qda_rpmsg_send_msg() and then blocks in
qda_rpmsg_wait_for_rsp() via wait_for_completion_interruptible(&ctx->work).
If a signal interrupts the wait before the DSP replies, qda_fastrpc_invoke()
returns -ERESTARTSYS while the first QDA_FASTRPC_RMID_INIT_CREATE_STATIC
request is still in flight on the DSP.

Because err is non-zero, qdev->audio_init_mem remains false when
qdev->remote_heap_lock is released. Could a concurrent or restarted
FASTRPC_IOCTL_INIT_CREATE_STATIC / DRM_IOCTL_QDA_REMOTE_SESSION_ATTACH call
then observe !qdev->audio_init_mem and hand the remote heap to the DSP a
second time?

> @@ -226,38 +226,60 @@ static int qda_attach_audio_pd(struct qda_session *session, struct drm_qda_remot
>  }
>  
>  /**
> - * qda_ioctl_attach() - Attach to a DSP-resident protection domain
> - * @dev: DRM device structure
> - * @data: User-space data (struct drm_qda_remote_attach)
> - * @file_priv: DRM file private data
> + * qda_session_attach() - Attach a session to a DSP-resident protection domain
> + * @session: Session to attach
> + * @pd_type: QDA_ATTACH_ROOT_PD, QDA_ATTACH_SENSORS_PD or QDA_ATTACH_AUDIO_PD
> + * @name: User pointer to the static PD name (QDA_ATTACH_AUDIO_PD only)
> + * @namelen: Length of @name including the NUL (QDA_ATTACH_AUDIO_PD only)
> + *
> + * Shared by the accel UAPI and the legacy shim, so the privilege check lives
> + * here rather than on the ioctl.
>   *
>   * Return: 0 on success, negative error code on failure
>   */
> -int qda_ioctl_attach(struct drm_device *dev, void *data, struct drm_file *file_priv)
> +int qda_session_attach(struct qda_session *session, u32 pd_type, const char __user *name,
> +		       u32 namelen)
>  {
> -	struct drm_qda_remote_attach *args = data;
> -	struct qda_session *session = file_priv->driver_priv;
>  	int pd;
>  
> +	if (!capable(CAP_SYS_ADMIN))
> +		return -EPERM;
> +
>  	if (READ_ONCE(session->init_mem_gem_obj))
>  		return -EBUSY;
>  
> -	switch (args->pd_type) {
> +	switch (pd_type) {
>  	case QDA_ATTACH_ROOT_PD:
>  	case QDA_ATTACH_SENSORS_PD:
> -		if (args->name || args->namelen)
> +		if (name || namelen)
>  			return -EINVAL;
>  
> -		pd = args->pd_type == QDA_ATTACH_ROOT_PD ? QDA_ROOT_PD : QDA_SENSORS_PD;
> +		pd = pd_type == QDA_ATTACH_ROOT_PD ? QDA_ROOT_PD : QDA_SENSORS_PD;
>  
>  		return qda_fastrpc_invoke(QDA_FASTRPC_RMID_INIT_ATTACH, &pd, session);
>  	case QDA_ATTACH_AUDIO_PD:
> -		return qda_attach_audio_pd(session, args);
> +		return qda_attach_audio_pd(session, name, namelen);
>  	default:
>  		return -EINVAL;
>  	}
>  }

[Severity: High]
Does qda_session_attach() race with concurrent qda_session_init_create()
calls on the same session?

Both the accel UAPI and the legacy shim allow concurrent ioctls on the same
open file without holding a per-session lock. In qda_session_attach(), the
check:

	if (READ_ONCE(session->init_mem_gem_obj))
		return -EBUSY;

runs unlocked before qda_fastrpc_invoke() sleeps waiting for the DSP
response, and qda_session_init_create() does not check whether the session
has already attached or is attaching. State updates only happen after the
DSP responds in qda_fastrpc_invoke():

	if (type == QDA_FASTRPC_RMID_INIT_CREATE) {
		qda_session_set_init_mem(session, ctx->init_mem_gem_obj);
		WRITE_ONCE(session->pd, QDA_USER_PD);
	} else if (type == QDA_FASTRPC_RMID_INIT_ATTACH ||
		   type == QDA_FASTRPC_RMID_INIT_CREATE_STATIC) {
		WRITE_ONCE(session->pd, ctx->pd);
	}

If one thread calls qda_session_attach() and another concurrently calls
qda_session_init_create() on the same file descriptor, both can pass
validation and send RPCs to the DSP. If QDA_FASTRPC_RMID_INIT_CREATE finishes
first (setting session->init_mem_gem_obj and session->pd = QDA_USER_PD) and
QDA_FASTRPC_RMID_INIT_ATTACH finishes second, session->pd is overwritten with
QDA_ROOT_PD or QDA_SENSORS_PD while session->init_mem_gem_obj remains
non-NULL.

When the file is later closed, legacy_release() or qda_postclose() sees
session->init_mem_gem_obj is non-NULL and calls qda_release_dsp_process(),
which sends QDA_FASTRPC_RMID_INIT_RELEASE directed at READ_ONCE(session->pd)
(now the attached PD instead of QDA_USER_PD). Wouldn't that leave the User PD
process running on the DSP while qda_session_release() frees
session->init_mem_gem_obj underneath it?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261102-v4-v4-0-88f2f24a5f0b@qti.qualcomm.com?part=22

  reply	other threads:[~2026-11-01 23:00 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-01 22:21 [PATCH v4 00/25] accel/qda: Qualcomm DSP Accelerator driver Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 01/25] accel/qda: Add QDA driver documentation Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 02/25] accel/qda: Add initial QDA DRM accelerator driver Ekansh Gupta
2026-11-01 22:39   ` sashiko-bot
2026-11-02  8:42   ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 03/25] accel/qda: Add compute context bank devices Ekansh Gupta
2026-11-01 22:52   ` sashiko-bot
2026-11-02  8:43   ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 04/25] accel/qda: Assign a context bank to each session Ekansh Gupta
2026-11-01 22:39   ` sashiko-bot
2026-11-02  8:45   ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 05/25] accel/qda: Add UAPI header and DSP query ioctl Ekansh Gupta
2026-11-01 22:21 ` [PATCH v4 06/25] accel/qda: Add buffer allocation for the DSP Ekansh Gupta
2026-11-01 22:51   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 07/25] accel/qda: Add DMA-BUF import Ekansh Gupta
2026-11-01 22:51   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 08/25] accel/qda: Add legacy ops base and auxiliary device Ekansh Gupta
2026-11-01 22:43   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 09/25] accel/qda: Add legacy FastRPC shim skeleton Ekansh Gupta
2026-11-01 22:42   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 10/25] accel/qda: Add FastRPC invocation contexts Ekansh Gupta
2026-11-01 22:44   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 11/25] accel/qda: Add RPMsg send and response dispatch Ekansh Gupta
2026-11-01 22:39   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 12/25] accel/qda: Add invocation argument validation and packing Ekansh Gupta
2026-11-01 22:44   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 13/25] accel/qda: Add the invocation ioctl and teardown on unplug Ekansh Gupta
2026-11-01 22:41   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 14/25] accel/qda: Add invocation through the legacy FastRPC shim Ekansh Gupta
2026-11-01 22:47   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 15/25] accel/qda: Add DSP process creation and release Ekansh Gupta
2026-11-01 22:50   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 16/25] accel/qda: Add DSP process creation and release to the legacy shim Ekansh Gupta
2026-11-01 22:48   ` sashiko-bot
2026-11-02  8:47   ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 17/25] accel/qda: Add remote memory mapping to the DSP address space Ekansh Gupta
2026-11-01 22:54   ` sashiko-bot
2026-11-02  9:24   ` Konrad Dybcio
2026-11-01 22:21 ` [PATCH v4 18/25] accel/qda: Add remote memory unmapping from " Ekansh Gupta
2026-11-01 22:49   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 19/25] accel/qda: Add remote memory map and unmap to the legacy shim Ekansh Gupta
2026-11-01 22:57   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 20/25] accel/qda: Add remote attach to root and sensors protection domains Ekansh Gupta
2026-11-01 22:49   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 21/25] accel/qda: Add Audio protection domain attach and its remote heap Ekansh Gupta
2026-11-01 23:00   ` sashiko-bot
2026-11-02  8:43   ` Arnd Bergmann
2026-11-02  8:50   ` Krzysztof Kozlowski
2026-11-01 22:21 ` [PATCH v4 22/25] accel/qda: Add remote session attach to the legacy shim Ekansh Gupta
2026-11-01 23:00   ` sashiko-bot [this message]
2026-11-01 22:21 ` [PATCH v4 23/25] accel/qda: Add DSP capability query Ekansh Gupta
2026-11-01 23:03   ` sashiko-bot
2026-11-02  8:46   ` Arnd Bergmann
2026-11-01 22:21 ` [PATCH v4 24/25] accel/qda: Add legacy shim support for " Ekansh Gupta
2026-11-01 23:05   ` sashiko-bot
2026-11-01 22:21 ` [PATCH v4 25/25] accel/qda: Add poll mode for invocation completion Ekansh Gupta
2026-11-01 23:02   ` sashiko-bot
2026-11-02  8:53 ` [PATCH v4 00/25] accel/qda: Qualcomm DSP Accelerator driver Krzysztof Kozlowski
2026-11-02 10:08   ` Ekansh Gupta
2026-11-02 10:12     ` Krzysztof Kozlowski
2026-11-02 10:52       ` Ekansh Gupta

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-192746@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=ekansh.gupta@oss.qualcomm.com \
    --cc=media-ci@linuxtv.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.