dmaengine: idxd: Fix possible Use-After-Free in irq_process_work_list
authorLi RongQing <lirongqing@baidu.com>
Mon, 3 Jun 2024 01:24:44 +0000 (09:24 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Jun 2024 11:49:08 +0000 (13:49 +0200)
[ Upstream commit e3215deca4520773cd2b155bed164c12365149a7 ]

Use list_for_each_entry_safe() to allow iterating through the list and
deleting the entry in the iteration process. The descriptor is freed via
idxd_desc_complete() and there's a slight chance may cause issue for
the list iterator when the descriptor is reused by another thread
without it being deleted from the list.

Fixes: 16e19e11228b ("dmaengine: idxd: Fix list corruption in description completion")
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Reviewed-by: Dave Jiang <dave.jiang@intel.com>
Reviewed-by: Fenghua Yu <fenghua.yu@intel.com>
Link: https://lore.kernel.org/r/20240603012444.11902-1-lirongqing@baidu.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/dma/idxd/irq.c

index b2ca9c1f194c91645afe82ad778739480a95bdad..7efc85b5bad9e91d38cd914cadd0051a04423e16 100644 (file)
@@ -611,11 +611,13 @@ static void irq_process_work_list(struct idxd_irq_entry *irq_entry)
 
        spin_unlock(&irq_entry->list_lock);
 
-       list_for_each_entry(desc, &flist, list) {
+       list_for_each_entry_safe(desc, n, &flist, list) {
                /*
                 * Check against the original status as ABORT is software defined
                 * and 0xff, which DSA_COMP_STATUS_MASK can mask out.
                 */
+               list_del(&desc->list);
+
                if (unlikely(desc->completion->status == IDXD_COMP_DESC_ABORT)) {
                        idxd_dma_complete_txd(desc, IDXD_COMPLETE_ABORT, true);
                        continue;