From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793211630; b=ZhO1XyblRmKxSVlTgPbpNXSXnn3DlgwgPBjjlwEN+ycLs7rMQQigvkXnZ6tjqVNCnEsg HLxkbFx4GuAa8hEIBJyNEe8jDAc4kVy5EuKTz5tGuOlo1WxFH+rq67AYZOkz/dDEArzc4 DkejaIgKyN2yLkrLzQs3dQSWkxxPgrU7v9PJCVkDybW7JnqZiPKxE6prahQZKkiSj0u0W YChccaJvMc1k78w8lupD8NRbEree9gaGBPsx+o52dO1KJgaAZ1gpD7fuJFib2LjnfuLEw 5ohgPZ7v+HSX3mUU8ZLetiRT7aJBViIOHYQ60AWdeWnEDKRtft2Z5Blvf1lnVFuvIBw== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793211630; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Transfer-Encoding; bh=j/IUFtU3p8cKthyxzb0/zO5j9ciB4Fg9MN2y6i2MTCo=; b=GCeYFpXNKQhVVjFkVbaCspulC2XOUEF6JyGHAtI695rjyeFZlV3cKjbGRCDH6Sn9UkDF cuYwcok3PnglNlBop0vaqV9KJddtKiSc2hzW2OFmyt2dlcGA/6S2m1NrstKsPYGramMB2 YM1kogsCzOYnkv7AMSaQD6HEC+uUGfAGJQphawfMWwB/KkB9NPZ7CkhCfbWlmZB0BFj5u vqDVLlMxHuwJRAAYXjGctoxXfuc1G29nFHk/tNX1yIsTQN6nb6A13hdZMOfgO0dsxq/mf 5HsLHWBO0Y0yoM4ZkdE+W3l0NDAK0q7jy8pe12rzGaOvlykRUQwpiiqKwTQn5k0nHlA== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=yYJSmYTn; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D01BE606A31A; Wed, 28 Oct 2026 18:20:29 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key, unprotected) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=yYJSmYTn Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2D0B31F01825; Wed, 28 Oct 2026 18:20:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1793211629; bh=j/IUFtU3p8cKthyxzb0/zO5j9ciB4Fg9MN2y6i2MTCo=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=yYJSmYTnY/iCNLkHQ3zroHgN/scuAWo6c+b+pq/RyeUsz8MAL50xs3NiEvJo22hfm Fwxh9prrAaQWi/gKBIoFSlF8jGUAagsn3I+5GpbkgsFHEoLrM6GJgsSUbfw2TSaIvD DMNt+NOD6ECBK9ikHYZwlUX+B7gd3msctWUiUh9Q= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Ahmed Abdelhaleem Ahmed , Laurence Oberman , "Martin K. Petersen (Oracle)" , Sasha Levin Subject: [PATCH 5.15 444/571] scsi: ch: Do not keep references to data transfer element devices Date: Wed, 28 Oct 2026 17:59:51 +0100 Message-ID: <20261028170018.561404781@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261028170008.009143722@linuxfoundation.org> References: <20261028170008.009143722@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: patches@lists.linux.dev List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 5.15-stable review patch. If anyone has any objections, please let me know. ------------------ From: Ahmed Abdelhaleem Ahmed [ Upstream commit 27c0f718d3b3c99e6d315308e95d987d0382a8a8 ] ch_readconfig() looks up the scsi_device of every data transfer element whose SCSI id the changer reports in READ ELEMENT STATUS, and stores it in ch->dt[]. scsi_device_lookup() takes a reference, and nothing ever drops it: ch_destroy() frees the array with kfree(). ch->dt[] is read nowhere else - it only supplies the vendor, model and revision printed in the same loop. Once such a drive is removed, its scsi_device can never be released. It stays on the host's device list at its address, so a new device there is refused by anything that walks the list - target_core_pscsi reports "scsi_device_get() failed for H:C:T:L" - and the low-level driver's module can no longer be unloaded. Only a reboot recovers. It shows with any changer that reports its drives' ids; with the mhvtl virtual library (IBM 3573-TL personality), each create and remove of a library with four drives leaves four references behind, counted by the module's use count in lsmod. With ch not bound the count is unchanged, and with this patch applied it is unchanged too. Drop the reference as soon as the name has been printed, and remove the now unused dt[] array. That also removes the array leaked when ch_probe() fails after ch_readconfig(). The same leak was reported with an RFC patch in 2022, which was not merged. Fixes: daa6eda65a53 ("[SCSI] add scsi changer driver") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/linux-scsi/20220719075442.6215-1-yanghao_ht@163.com/ Signed-off-by: Ahmed Abdelhaleem Ahmed Reviewed-by: Laurence Oberman Fixes: daa6eda65a53 ("[SCSI] add scsi changer driver") Link: https://patch.msgid.link/20260929-ch-dt-leak-v2-1-ddda8d635dca@gmail.com Signed-off-by: Martin K. Petersen (Oracle) [ sashal: Adapted the allocation-removal hunk for kcalloc() instead of kzalloc_objs(). ] Signed-off-by: Sasha Levin --- drivers/scsi/ch.c | 30 +++++++++--------------------- 1 file changed, 9 insertions(+), 21 deletions(-) diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index 27012908b5861..c1f714664bfc5 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -110,7 +110,6 @@ typedef struct { int minor; char name[8]; struct scsi_device *device; - struct scsi_device **dt; /* ptrs to data transfer elements */ u_int firsts[CH_TYPES]; u_int counts[CH_TYPES]; u_int unit_attention; @@ -357,16 +356,10 @@ ch_readconfig(scsi_changer *ch) vendor_labels[i]); } - /* look up the devices of the data transfer elements */ - ch->dt = kcalloc(ch->counts[CHET_DT], sizeof(*ch->dt), - GFP_KERNEL); - - if (!ch->dt) { - kfree(buffer); - return -ENOMEM; - } - + /* report the devices of the data transfer elements */ for (elem = 0; elem < ch->counts[CHET_DT]; elem++) { + struct scsi_device *sdev; + id = -1; lun = 0; if (elem < CH_DT_MAX && -1 != dt_id[elem]) { @@ -382,10 +375,8 @@ ch_readconfig(scsi_changer *ch) VPRINTK(KERN_INFO, "dt 0x%x: ",elem+ch->firsts[CHET_DT]); if (data[6] & 0x80) { VPRINTK(KERN_CONT, "not this SCSI bus\n"); - ch->dt[elem] = NULL; } else if (0 == (data[6] & 0x30)) { VPRINTK(KERN_CONT, "ID/LUN unknown\n"); - ch->dt[elem] = NULL; } else { id = ch->device->id; lun = 0; @@ -395,18 +386,16 @@ ch_readconfig(scsi_changer *ch) } if (-1 != id) { VPRINTK(KERN_CONT, "ID %i, LUN %i, ",id,lun); - ch->dt[elem] = - scsi_device_lookup(ch->device->host, - ch->device->channel, - id,lun); - if (!ch->dt[elem]) { + sdev = scsi_device_lookup(ch->device->host, + ch->device->channel, + id, lun); + if (!sdev) { /* should not happen */ VPRINTK(KERN_CONT, "Huh? device not found!\n"); } else { VPRINTK(KERN_CONT, "name: %8.8s %16.16s %4.4s\n", - ch->dt[elem]->vendor, - ch->dt[elem]->model, - ch->dt[elem]->rev); + sdev->vendor, sdev->model, sdev->rev); + scsi_device_put(sdev); } } } @@ -570,7 +559,6 @@ static void ch_destroy(struct kref *ref) scsi_changer *ch = container_of(ref, scsi_changer, ref); ch->device = NULL; - kfree(ch->dt); kfree(ch); } -- 2.53.0