From nobody Tue Jun 16 10:12:15 2026 Received: from mail-pj1-f54.google.com (mail-pj1-f54.google.com [209.85.216.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E3C5537649D for ; Sat, 18 Apr 2026 13:30:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776519022; cv=none; b=dXUtLbLeGOGY9tzrcosgNCKa9e9eS6kkJynkLLtw6mkNUlDvHPn6P80a8dZSg4QZJ+CWPvJSblkkCe0bVd1C1ls+OBAMx4Q3XANn68qh7SRBv7pJc+uY17dJKrxEm7d6bJtb2RsKVp7kRM0AxIKDyE1vQPrQAySom7B+QjQJqZg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776519022; c=relaxed/simple; bh=FSw9T+IBDfp7hvGNXwhUDw2Z2ayVOPz6zaav9EQJDoA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=OSjNE9Js669rmDuxfPe0yFJ7WD9ZDKTGZQXRPa4Mh7thERCikSPNowX9e8V3SnutS6Ros8H5lnh/Yovwz5u4KHabualv4IFDxFug9T8hfnR+riP+7H1kjaX6/wYqg+iS7ClS0rOymgEiv8Z9LxXvin64IJPha1X/7D5Zr4Zwq3w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=snu.ac.kr; spf=pass smtp.mailfrom=snu.ac.kr; dkim=pass (1024-bit key) header.d=snu.ac.kr header.i=@snu.ac.kr header.b=FhbPxN/S; arc=none smtp.client-ip=209.85.216.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=snu.ac.kr Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=snu.ac.kr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=snu.ac.kr header.i=@snu.ac.kr header.b="FhbPxN/S" Received: by mail-pj1-f54.google.com with SMTP id 98e67ed59e1d1-35d90833cacso1036638a91.2 for ; Sat, 18 Apr 2026 06:30:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=snu.ac.kr; s=google; t=1776519018; x=1777123818; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=sMB6KXkkm0c0b8EnPP7cQVspQAzGNbeaZSme+aUt7G0=; b=FhbPxN/SoMPaj6tB3y4E6sEDS4yHdfHnLIlAT+0YXvrgPbi81ur/lp/a9kGSMh8SsD 1j8ypvj5GtZaUs8xOfAzG221uocvciX6/rF8OBwaVq5KF1xwWf9MZlX1BMrhkCFl3XrD t4VuJL0hRJni1C+Nv7gjwRwaOcCX3da5Irvmc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776519018; x=1777123818; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=sMB6KXkkm0c0b8EnPP7cQVspQAzGNbeaZSme+aUt7G0=; b=XVcDqaYYZV5q55ZFXbuMtV+rW++A+Ipo372FtsHJMncXb8oibiu2IoSkqbaV75ta0p 1+iUe2qYWph1LMsGo3ciohqVOPNY0GI8A5Giy8tpYFjFWkTfCJKND1EmLthaqmQC0V7W sDSiwc3dVt/x9rYlbwtc4GgfPcQIRIrP6bzcaqLM8/z5g0d1HguP5PSGWqRqobzAAPCy Mc3i9IBR6pJi2aMO5RI9jD4X9AROXbKGOSJELYoqPNPqbpeQ9ThStKu5FYh1R3cJM8Ir XF0iDoSk7Z9QpRpJ1NZWFk+p0bnYg0gqY+i379UOy1eMsvzaqCIC9r4Lb0SwYwdmyPAM y2Xw== X-Forwarded-Encrypted: i=1; AFNElJ/37arsPHiP2dC4jKfnqxjHG57EYkTXCQdcxxEEXzGQ2MbKeamF3gRpc5OxCLQs9Lkdgr7y0rt0XSB7MWc=@vger.kernel.org X-Gm-Message-State: AOJu0YxSXIw61wYulxj/YBqBhIOxIpGL/Kwb5M89RoaX4ED1HM0PYKv4 1e4O9UjUTdtXmPBtnkgXu1dZ5NHQicb+cCwoc1Ay927MFKrg+zitgrfjNK/HKunGBv4= X-Gm-Gg: AeBDietmcB/QSpVBJ6mQtZI2fZaI92bk7gix+2Meb68GKWd1KsPMOfpGpv2HZy3Hdp+ RhBRbPvkYHMfY15CbQ9NzJIldRVkLh+9ixWfCpjcHkD6X7p38l7qWrreD4E5E3D1Tkf0IZp//X1 FQBSvb3oh3RSYkp8gXgeiihoiLDpTptYiPrKDe4mz1oVFmKnHwFIhVFu/tgMa5mZtxWKE748oIb OVlQbDmjk5rQyOJl9/Wn03F0hPOMlU/RuLaURfeG6NXRHGmOzdQxR+jl8mhCGFJC4iey4JQVDjZ nQzllxW+5zV5PVZ901vs8ntkKputOCiKbLdX3UXYQGdWDSFJFM30JJlL806+aL35dPWDZlbNh02 6QhUGQt3Pg2gEX8ERzOPH0NbVWYnb7XouePdLqjx/yWP5ig0/uUFa/3QZX9dSaObGs2RKW/evxn ysI7J3nyl0P+YsNetvclLr4fNkdw+px0/Pl0+LHAR3+HcS1vXyQGdDA6LJdEltbE4K5lCNng== X-Received: by 2002:a17:90b:3f47:b0:35b:a7be:ae47 with SMTP id 98e67ed59e1d1-3614048ee93mr8074585a91.21.1776519018335; Sat, 18 Apr 2026 06:30:18 -0700 (PDT) Received: from nunu.. (nunu.snu.ac.kr. [147.46.112.82]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3614195a9fbsm6843001a91.11.2026.04.18.06.30.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Apr 2026 06:30:18 -0700 (PDT) From: Sangyun Kim To: "Martin K . Petersen" Cc: "James E . J . Bottomley" , Duoming Zhou , linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] scsi: mvsas: drain delayed work before unmapping MMIO in mvs_free() Date: Sat, 18 Apr 2026 22:30:02 +0900 Message-Id: <20260418133003.2462460-2-sangyun.kim@snu.ac.kr> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260418133003.2462460-1-sangyun.kim@snu.ac.kr> References: <20260418133003.2462460-1-sangyun.kim@snu.ac.kr> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" mvs_free() currently calls MVS_CHIP_DISP->chip_iounmap(mvi) before the loop that cancels pending mwq->work_q delayed work items. If a mvs_work_queue() callback starts executing between chip_iounmap() and cancel_delayed_work_sync(), it dereferences the now-unmapped MMIO region via MVS_CHIP_DISP->read_phy_ctl() and faults. Move the cancel_delayed_work_sync() loop above chip_iounmap() so that all pending and running callbacks have completed before the MMIO BARs are torn down. scsi_host_put() is also deferred past the cancel loop so that no callback can touch host state that has already been released. Signed-off-by: Sangyun Kim --- drivers/scsi/mvsas/mv_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index 5abc17a2e261..0c9c62c25987 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -120,11 +120,11 @@ static void mvs_free(struct mvs_info *mvi) dma_free_coherent(mvi->dev, TRASH_BUCKET_SIZE, mvi->bulk_buffer1, mvi->bulk_buffer_dma1); =20 + list_for_each_entry(mwq, &mvi->wq_list, entry) + cancel_delayed_work_sync(&mwq->work_q); MVS_CHIP_DISP->chip_iounmap(mvi); if (mvi->shost) scsi_host_put(mvi->shost); - list_for_each_entry(mwq, &mvi->wq_list, entry) - cancel_delayed_work_sync(&mwq->work_q); kfree(mvi->rsvd_tags); kfree(mvi); } --=20 2.34.1 From nobody Tue Jun 16 10:12:15 2026 Received: from mail-pj1-f51.google.com (mail-pj1-f51.google.com [209.85.216.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1D26B37701B for ; Sat, 18 Apr 2026 13:30:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776519023; cv=none; b=NfVHP7W7g6iqTiGALThRmkCMee0ThRWlKxl6B2nCSJmA/AeRx1zHs8+0uWgm7ZCzrV61GMI72gKmtG2FeTduKbvJMIaCa3n1i/odN/6/zh5M6OopiEDLayqyn95rxGh4toxfLAb+kDXhAqh5189mBakstpPePYgyyWeqcxmiO8c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776519023; c=relaxed/simple; bh=qZvlNuK8tH4BDyFywnoaGtb4DYHdxKKSUg7PjuGMihs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KSOFlLxAQ5hoe4sjdUolUekExD3V/wrisNY5il0KTEO1WRYQsd3UrojnID61ZTABjocMUQ2H0vQnkYRMsL8n2M78ghKLxrTYF2CiFgMQRaZo+UdA5c4c4jsZbmV9gC42Yhsp2gsnu1FpqylIfOTfN8ILIUGtxrSl8FLxY87J+UA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=snu.ac.kr; spf=pass smtp.mailfrom=snu.ac.kr; dkim=pass (1024-bit key) header.d=snu.ac.kr header.i=@snu.ac.kr header.b=uD7y9f7+; arc=none smtp.client-ip=209.85.216.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=snu.ac.kr Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=snu.ac.kr Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=snu.ac.kr header.i=@snu.ac.kr header.b="uD7y9f7+" Received: by mail-pj1-f51.google.com with SMTP id 98e67ed59e1d1-35d99bae2ebso1555568a91.3 for ; Sat, 18 Apr 2026 06:30:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=snu.ac.kr; s=google; t=1776519020; x=1777123820; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=QOsocMkxtjKD9j9zvFgGCM2TULz401mQWwIAVfMJ00Q=; b=uD7y9f7+FN3iScyGlJiTniaRz+hw6/gkMxSY5CpK+kF6zfzlTfiE5P9gMeVp8m5FKG q9CIyrqxBZO7mV/cHNRXshKgLRW5Ih3JM9rczlROi5mR94Ol+CkvIE7daHh+v/bIwfMc AyBogQavbe01NxbxChCgD3RdQrex7Iu9oWkHY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1776519020; x=1777123820; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=QOsocMkxtjKD9j9zvFgGCM2TULz401mQWwIAVfMJ00Q=; b=b7UxLAwjnv8m+LhO0rvl/m4TWhv9/pTcKoWHJVgY4seywq/7tJlydWFlcVZZMWVG4t tMF5sKm+K/CFDvtDw4kz82PKq9DHvcvscK6pYDjcaYP0l7+yLO3hcsumdQgAzlRXA6gn YiShm/agJfb2qtQWgK+DLXPw1hkDFn5TvB2BXukm3Knrb0SzDpFwU7KIeEgdUGs2/YnJ C8vbOZCLyOVf2rtPJNJ2ilTc5J74gbokfT4hm+lImMXzlvgUsonpgYCQ6T3I6F0uGmZZ 2JejB4bueeoGK/SCRLvIybLBs5hIZHtbnZpMnatR1ThOxLr1JLuy7H5mYwXxxhI/UxDJ Z7kg== X-Forwarded-Encrypted: i=1; AFNElJ/LPariwhHFMXjVjUs0Uzku6C4uccoHDmIOzpHEQWcoWuT/+O2P3WE/3egrWUdbfP7pTWo9mHXVPlbQnsM=@vger.kernel.org X-Gm-Message-State: AOJu0YygRzTKXVPqIyy1R9caAwXzmdrlrAWUGIOChyK8O/RLOG/dlCxt clVF6skUx1nsgGk+eRtppevzziuhFZ+2tadJ0TnKjH4M22T/K2GdhGYyzQVDwVt0sTM= X-Gm-Gg: AeBDieuUtxgPYyYdSioqAeXIF2d/LbEO2H+4cbYu58YtF60/6XrML2s9ET7p844YsJZ L/wRrcgmYL7opRjQjlcQOzKiBg3RghLB/Lj7pVq3cIT7cCgnE+E/Ubw8hTH5YtweqTsYdUmHNHu m6gTEXkPerh1eTxEfYQ8CalElk1QTODa0PKTmCGbkYkc7uoCRHI5andXp5/1j7FYoKXxwKZ+Igb Viz4pY0BPTEBNv2O1SeC7Gw1zhbKLN4Pbbeck95tg1dBIVTikpEZsxOBlZhN/ZOMQgenuVM/++h +qz9+qyp4HsxEzUvlSzM5rPhlpGvzCk5aM9ROjHiblDDhA86HSs5lMn6CFoQoyhS+I49yEUZS7w fFxcIGVUyr+bCcdUviASewJ1GhCeRCwxbtYQoBJfErzndzM4sXzDARGWIlPb5TqDjsExrdV8Uh6 pp36/ZN5iUjnS2uD8ZA6nzX20cnf185B3YaA2PCVejgUd2+/IW24CVtSOlTSjfbbudBFWwbA== X-Received: by 2002:a17:90a:da83:b0:35b:9ab6:1d4b with SMTP id 98e67ed59e1d1-3614048e368mr7488746a91.20.1776519020536; Sat, 18 Apr 2026 06:30:20 -0700 (PDT) Received: from nunu.. (nunu.snu.ac.kr. [147.46.112.82]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-3614195a9fbsm6843001a91.11.2026.04.18.06.30.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 18 Apr 2026 06:30:20 -0700 (PDT) From: Sangyun Kim To: "Martin K . Petersen" Cc: "James E . J . Bottomley" , Duoming Zhou , linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/2] scsi: mvsas: fix iterator use-after-free in mvs_free() wq drain loop Date: Sat, 18 Apr 2026 22:30:03 +0900 Message-Id: <20260418133003.2462460-3-sangyun.kim@snu.ac.kr> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260418133003.2462460-1-sangyun.kim@snu.ac.kr> References: <20260418133003.2462460-1-sangyun.kim@snu.ac.kr> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" mvs_free() walks mvi->wq_list with list_for_each_entry() and calls cancel_delayed_work_sync(&mwq->work_q) for each element. If the callback for the current node is already executing, the sync wait allows mvs_work_queue() to remove its own list entry and kfree() the mvs_wq: list_del(&mwq->entry); spin_unlock_irqrestore(&mvi->lock, flags); kfree(mwq); When cancel_delayed_work_sync() returns, list_for_each_entry() in mvs_free() advances with list_next_entry(mwq, entry), which reads mwq->entry.next from the already-freed node. This is a read use-after-free in the remove path. Switching the iterator to list_for_each_entry_safe() is not enough, because any saved "next" cursor can itself be freed by its own callback once cancel_delayed_work_sync() drops mvi->lock. Drain wq_list one entry at a time under mvi->lock: - mvs_free() uses list_first_entry() + list_del_init() to detach the head, drops the lock, calls cancel_delayed_work_sync(), then kfree()s the entry, and retakes the lock for the next iteration. - mvs_work_queue() checks list_empty(&mwq->entry) under mvi->lock before doing its own list_del_init() + kfree(). If mvs_free() has already detached the entry, the callback skips the final free and teardown owns it. This gives teardown and the callback a single-owner rule for the struct mvs_wq free. Fixes: 60cd16a3b743 ("scsi: mvsas: Fix use-after-free bugs in mvs_work_queu= e") Signed-off-by: Sangyun Kim --- drivers/scsi/mvsas/mv_init.c | 11 ++++++++++- drivers/scsi/mvsas/mv_sas.c | 10 +++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/mvsas/mv_init.c b/drivers/scsi/mvsas/mv_init.c index 0c9c62c25987..c32f645deef3 100644 --- a/drivers/scsi/mvsas/mv_init.c +++ b/drivers/scsi/mvsas/mv_init.c @@ -85,6 +85,7 @@ static void mvs_phy_init(struct mvs_info *mvi, int phy_id) static void mvs_free(struct mvs_info *mvi) { struct mvs_wq *mwq; + unsigned long flags; int slot_nr; =20 if (!mvi) @@ -120,8 +121,16 @@ static void mvs_free(struct mvs_info *mvi) dma_free_coherent(mvi->dev, TRASH_BUCKET_SIZE, mvi->bulk_buffer1, mvi->bulk_buffer_dma1); =20 - list_for_each_entry(mwq, &mvi->wq_list, entry) + spin_lock_irqsave(&mvi->lock, flags); + while (!list_empty(&mvi->wq_list)) { + mwq =3D list_first_entry(&mvi->wq_list, struct mvs_wq, entry); + list_del_init(&mwq->entry); + spin_unlock_irqrestore(&mvi->lock, flags); cancel_delayed_work_sync(&mwq->work_q); + kfree(mwq); + spin_lock_irqsave(&mvi->lock, flags); + } + spin_unlock_irqrestore(&mvi->lock, flags); MVS_CHIP_DISP->chip_iounmap(mvi); if (mvi->shost) scsi_host_put(mvi->shost); diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index 359226e80eae..7df6964a76e8 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -1729,9 +1729,13 @@ static void mvs_work_queue(struct work_struct *work) PORTE_BROADCAST_RCVD, GFP_ATOMIC); mv_dprintk("phy%d Got Broadcast Change\n", phy_no); } - list_del(&mwq->entry); - spin_unlock_irqrestore(&mvi->lock, flags); - kfree(mwq); + if (!list_empty(&mwq->entry)) { + list_del_init(&mwq->entry); + spin_unlock_irqrestore(&mvi->lock, flags); + kfree(mwq); + } else { + spin_unlock_irqrestore(&mvi->lock, flags); + } } =20 static int mvs_handle_event(struct mvs_info *mvi, void *data, int handler) --=20 2.34.1