diff --git a/patches.kernel.org/6.2.12-109-scsi-ses-Handle-enclosure-with-just-a-primary-.patch b/patches.kernel.org/6.2.12-109-scsi-ses-Handle-enclosure-with-just-a-primary-.patch new file mode 100644 index 0000000..e5c8633 --- /dev/null +++ b/patches.kernel.org/6.2.12-109-scsi-ses-Handle-enclosure-with-just-a-primary-.patch @@ -0,0 +1,148 @@ +From: Jiri Kosina +Date: Tue, 4 Apr 2023 21:23:42 +0200 +Subject: [PATCH] scsi: ses: Handle enclosure with just a primary component + gracefully +References: bsc#1012628 +Patch-mainline: 6.2.12 +Git-commit: c8e22b7a1694bb8d025ea636816472739d859145 + +commit c8e22b7a1694bb8d025ea636816472739d859145 upstream. + +This reverts commit 3fe97ff3d949 ("scsi: ses: Don't attach if enclosure +has no components") and introduces proper handling of case where there are +no detected secondary components, but primary component (enumerated in +num_enclosures) does exist. That fix was originally proposed by Ding Hui +. + +Completely ignoring devices that have one primary enclosure and no +secondary one results in ses_intf_add() bailing completely + + scsi 2:0:0:254: enclosure has no enumerated components + scsi 2:0:0:254: Failed to bind enclosure -12ven in valid configurations such + +even on valid configurations with 1 primary and 0 secondary enclosures as +below: + + # sg_ses /dev/sg0 + 3PARdata SES 3321 + Supported diagnostic pages: + Supported Diagnostic Pages [sdp] [0x0] + Configuration (SES) [cf] [0x1] + Short Enclosure Status (SES) [ses] [0x8] + # sg_ses -p cf /dev/sg0 + 3PARdata SES 3321 + Configuration diagnostic page: + number of secondary subenclosures: 0 + generation code: 0x0 + enclosure descriptor list + Subenclosure identifier: 0 [primary] + relative ES process id: 0, number of ES processes: 1 + number of type descriptor headers: 1 + enclosure logical identifier (hex): 20000002ac02068d + enclosure vendor: 3PARdata product: VV rev: 3321 + type descriptor header and text list + Element type: Unspecified, subenclosure id: 0 + number of possible elements: 1 + +The changelog for the original fix follows + +===== +We can get a crash when disconnecting the iSCSI session, +the call trace like this: + + [ffff00002a00fb70] kfree at ffff00000830e224 + [ffff00002a00fba0] ses_intf_remove at ffff000001f200e4 + [ffff00002a00fbd0] device_del at ffff0000086b6a98 + [ffff00002a00fc50] device_unregister at ffff0000086b6d58 + [ffff00002a00fc70] __scsi_remove_device at ffff00000870608c + [ffff00002a00fca0] scsi_remove_device at ffff000008706134 + [ffff00002a00fcc0] __scsi_remove_target at ffff0000087062e4 + [ffff00002a00fd10] scsi_remove_target at ffff0000087064c0 + [ffff00002a00fd70] __iscsi_unbind_session at ffff000001c872c4 + [ffff00002a00fdb0] process_one_work at ffff00000810f35c + [ffff00002a00fe00] worker_thread at ffff00000810f648 + [ffff00002a00fe70] kthread at ffff000008116e98 + +In ses_intf_add, components count could be 0, and kcalloc 0 size scomp, +but not saved in edev->component[i].scratch + +In this situation, edev->component[0].scratch is an invalid pointer, +when kfree it in ses_intf_remove_enclosure, a crash like above would happen +The call trace also could be other random cases when kfree cannot catch +the invalid pointer + +We should not use edev->component[] array when the components count is 0 +We also need check index when use edev->component[] array in +ses_enclosure_data_process +===== + +Reported-by: Michal Kolar +Originally-by: Ding Hui +Cc: stable@vger.kernel.org +Fixes: 3fe97ff3d949 ("scsi: ses: Don't attach if enclosure has no components") +Signed-off-by: Jiri Kosina +Link: https://lore.kernel.org/r/nycvar.YFH.7.76.2304042122270.29760@cbobk.fhfr.pm +Tested-by: Michal Kolar +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Jiri Slaby +--- + drivers/scsi/ses.c | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c +index 1707d6d1..6a1428d4 100644 +--- a/drivers/scsi/ses.c ++++ b/drivers/scsi/ses.c +@@ -503,9 +503,6 @@ static int ses_enclosure_find_by_addr(struct enclosure_device *edev, + int i; + struct ses_component *scomp; + +- if (!edev->component[0].scratch) +- return 0; +- + for (i = 0; i < edev->components; i++) { + scomp = edev->component[i].scratch; + if (scomp->addr != efd->addr) +@@ -596,8 +593,10 @@ static void ses_enclosure_data_process(struct enclosure_device *edev, + components++, + type_ptr[0], + name); +- else ++ else if (components < edev->components) + ecomp = &edev->component[components++]; ++ else ++ ecomp = ERR_PTR(-EINVAL); + + if (!IS_ERR(ecomp)) { + if (addl_desc_ptr) { +@@ -728,11 +727,6 @@ static int ses_intf_add(struct device *cdev, + components += type_ptr[1]; + } + +- if (components == 0) { +- sdev_printk(KERN_WARNING, sdev, "enclosure has no enumerated components\n"); +- goto err_free; +- } +- + ses_dev->page1 = buf; + ses_dev->page1_len = len; + buf = NULL; +@@ -774,9 +768,11 @@ static int ses_intf_add(struct device *cdev, + buf = NULL; + } + page2_not_supported: +- scomp = kcalloc(components, sizeof(struct ses_component), GFP_KERNEL); +- if (!scomp) +- goto err_free; ++ if (components > 0) { ++ scomp = kcalloc(components, sizeof(struct ses_component), GFP_KERNEL); ++ if (!scomp) ++ goto err_free; ++ } + + edev = enclosure_register(cdev->parent, dev_name(&sdev->sdev_gendev), + components, &ses_enclosure_callbacks); +-- +2.35.3 + diff --git a/series.conf b/series.conf index 1a7e0ec..57a54e4 100644 --- a/series.conf +++ b/series.conf @@ -2336,6 +2336,7 @@ patches.kernel.org/6.2.12-106-net-sfp-initialize-sfp-i2c_block_size-at-sfp-a.patch patches.kernel.org/6.2.12-107-net-phy-nxp-c45-tja11xx-add-remove-callback.patch patches.kernel.org/6.2.12-108-net-phy-nxp-c45-tja11xx-fix-unsigned-long-mult.patch + patches.kernel.org/6.2.12-109-scsi-ses-Handle-enclosure-with-just-a-primary-.patch ######################################################## # Build fixes that apply to the vanilla kernel too.