All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Daniel Byrne" <daniel1.byrne@intel.com>
Cc: dmaengine@vger.kernel.org, vkoul@kernel.org, Frank.Li@kernel.org
Subject: Re: [PATCH 14/17] dmaengine: idxd: complete an iaa_crypto descriptor through its own driver on abort and flush
Date: Mon, 19 Oct 2026 18:56:18 +0000	[thread overview]
Message-ID: <sashiko-outbox-178117@kernel.org> (raw)
In-Reply-To: <20261019150630.4026341-15-daniel1.byrne@intel.com>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Critical] dmaengine: idxd: active DMA unmap and UAF in idxd_flush_pending_descs()
--

commit 17311ece6ccc1def94a5c98267c599339eae70ce
Author: Daniel Byrne <daniel1.byrne@intel.com>

dmaengine: idxd: complete an iaa_crypto descriptor through its own driver on abort and flush

This commit updates idxd_flush_pending_descs() and llist_abort_desc() to
complete or skip non-dmaengine descriptors via their own driver's completion
handler rather than treating them as dmaengine transactions, and avoids
blocking in idxd_alloc_desc() when a workqueue is permanently dying.

> diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c
> index 222c201669bdd..a33c4309f5d42 100644
> --- a/drivers/dma/idxd/device.c
> +++ b/drivers/dma/idxd/device.c
> @@ -1534,10 +1534,25 @@ static void idxd_flush_pending_descs(struct idxd_irq_entry *ie,
>  		list_del(&desc->list);
>  		ctype = desc->completion->status ? IDXD_COMPLETE_NORMAL : IDXD_COMPLETE_ABORT;
>  		/*
> -		 * wq is being disabled. Any remaining descriptors are
> -		 * likely to be stuck and can be dropped. callback could
> -		 * point to code that is no longer accessible, for example
> -		 * if dmatest module has been unloaded.
> +		 * Another driver's descriptor carries that driver's request
> +		 * in place of a txd, and a client may still wait for it, so it
> +		 * goes back through that driver's completion. The completion
> +		 * reads the outcome from the record, which the device never
> +		 * wrote for an unfinished descriptor. Only a dmaengine channel
> +		 * terminates, so nothing of such a queue is quarantined.
> +		 */
> +		if (!idxd_wq_has_txd(wq)) {
> +			if (ctype == IDXD_COMPLETE_ABORT)
> +				desc->completion->status = IDXD_COMP_DESC_ABORT;
> +			idxd_desc_complete(desc, ctype, true);
> +			continue;
> +		}

[Severity: Critical]
When an iaa_crypto workqueue with in-flight interrupt-armed requests is
disabled via iaa_crypto_remove() -> idxd_drv_disable_wq(), idxd_wq_free_irq()
calls idxd_flush_pending_descs() unconditionally even if idxd_wq_drain()
timed out:

drivers/dma/idxd/device.c:idxd_drv_disable_wq() {
	...
	idxd_wq_unmap_portal(wq);
	rc = idxd_wq_drain(wq);
	idxd_wq_free_irq(wq);
	rc |= idxd_wq_reset(wq);
	...
}

If idxd_wq_drain() returns -ETIMEDOUT (either because DRAIN_WQ timed out or
because an earlier command set IDXD_FLAG_CMD_TIMEDOUT), the hardware engine is
still active and processing unfinished descriptors when
idxd_flush_pending_descs() runs.

For an unfinished descriptor (ctype == IDXD_COMPLETE_ABORT), calling
idxd_desc_complete() invokes iaa_desc_complete():

drivers/crypto/intel/iaa/iaa_crypto_main.c:iaa_desc_complete() {
	...
err:
	dma_unmap_sg(dev, ctx->req->dst, sg_nents(ctx->req->dst), DMA_FROM_DEVICE);
	iaa_unmap_src(dev, ctx->req);
out:
	if (ret != 0)
		dev_dbg(dev, "asynchronous compress failed ret=%d\n", ret);

	if (ctx->req->base.complete)
		acomp_request_complete(ctx->req, err);

	if (free_desc)
		idxd_free_desc(idxd_desc->wq, idxd_desc);
	iaa_wq_put(idxd_desc->wq);
}

Doesn't completing an unfinished descriptor here while the device is still
active cause active DMA unmapping and use-after-free? Specifically:

1. iaa_desc_complete() unmaps ctx->req->dst and ctx->req->src (and via
iaa_unmap_src() unmaps req_ctx->bounce_src_dma and frees req_ctx->bounce_src
back to iaa_bounce_pool) while the hardware engine may still be DMA-reading
src1_addr and DMA-writing dst_addr.

2. acomp_request_complete() notifies the caller, which can free or reuse the
request and scatterlist buffers while hardware DMA is still in flight.

3. iaa_wq_put() drops the iaa_wq reference. During iaa_crypto_remove(),
iaa_wq->remove is set to true, so dropping the last reference calls
__free_iaa_wq() -> free_iaa_device() -> remove_device_compression_modes() ->
free_device_compression_mode(), freeing device_mode->aecs_comp_table via
dma_free_coherent() while an in-flight compression descriptor in hardware
still reads src2_addr (aecs_comp_table_dma_addr).

4. Because iaa_desc_complete() ignores comp_type and inspects
idxd_desc->iax_completion->status via check_completion(), can a concurrent
hardware completion write between setting desc->completion->status =
IDXD_COMP_DESC_ABORT and check_completion() overwrite IDXD_COMP_DESC_ABORT
with IAX_COMP_SUCCESS or IAA_ANALYTICS_ERROR, causing iaa_desc_complete() to
treat the aborted descriptor as succeeded or retryable during teardown?

>  		/*
> -		 * wq is being disabled. Any remaining descriptors are
[ ... ]
>  		tx = &desc->txd;
>  		tx->callback = NULL;

[ ... ]

>
> -- 
> 2.51.2
>

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261019150630.4026341-1-daniel1.byrne@intel.com?part=14

  reply	other threads:[~2026-10-19 18:56 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-19 15:06 [PATCH 00/17] [PATCH 00/17] dmaengine: idxd: fixes found by an in-kernel polling client Daniel Byrne
2026-10-19 15:06 ` [PATCH 01/17] dmaengine: idxd: don't queue EVL fault work for kernel WQs Daniel Byrne
2026-10-19 15:06 ` [PATCH 02/17] dmaengine: idxd: detach the user fault workqueue under the event log lock Daniel Byrne
2026-10-19 15:06 ` [PATCH 03/17] dmaengine: idxd: refuse a memcpy longer than the WQ max transfer size Daniel Byrne
2026-10-19 21:19   ` Frank Li
2026-10-19 15:06 ` [PATCH 04/17] dmaengine: idxd: list a new channel only once it is complete Daniel Byrne
2026-10-19 15:06 ` [PATCH 05/17] dmaengine: idxd: unbind the device driver before its work queues go away Daniel Byrne
2026-10-19 15:06 ` [PATCH 06/17] dmaengine: idxd: keep the interrupt handle across terminate_all Daniel Byrne
2026-10-19 15:06 ` [PATCH 07/17] dmaengine: idxd: bound device command waits and fail fast after a timeout Daniel Byrne
2026-10-19 17:05   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 08/17] dmaengine: idxd: compare the device disable status code whole Daniel Byrne
2026-10-19 15:06 ` [PATCH 09/17] dmaengine: idxd: quarantine terminate_all's descriptor slots until the device has drained Daniel Byrne
2026-10-19 17:26   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 10/17] dmaengine: idxd: return -ETIMEDOUT from drains and resets and leak what the device may still write Daniel Byrne
2026-10-19 17:50   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 11/17] dmaengine: idxd: disable the device before its work queues are unregistered Daniel Byrne
2026-10-19 18:09   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 12/17] dmaengine: idxd: hold device commands off while the reset re-creates its interrupts Daniel Byrne
2026-10-19 18:19   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 13/17] dmaengine: idxd: fix the double free of a descriptor whose submission failed Daniel Byrne
2026-10-19 15:06 ` [PATCH 14/17] dmaengine: idxd: complete an iaa_crypto descriptor through its own driver on abort and flush Daniel Byrne
2026-10-19 18:56   ` sashiko-bot [this message]
2026-10-19 15:06 ` [PATCH 15/17] dmaengine: idxd: flush the work queues on every halt type Daniel Byrne
2026-10-19 19:17   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 16/17] dmaengine: idxd: keep client callbacks on a halt flush and cancel resubmissions after a terminate Daniel Byrne
2026-10-19 19:36   ` sashiko-bot
2026-10-19 15:06 ` [PATCH 17/17] dmaengine: idxd: run the interrupt-handle revoke under the queue lock Daniel Byrne
2026-10-19 19:53   ` sashiko-bot
2026-10-19 19:09 ` [PATCH 00/17] [PATCH 00/17] dmaengine: idxd: fixes found by an in-kernel polling client Frank Li

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-178117@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=Frank.Li@kernel.org \
    --cc=daniel1.byrne@intel.com \
    --cc=dmaengine@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=vkoul@kernel.org \
    /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.