diff options
author | Thorsten Leemhuis <fedora@leemhuis.info> | 2018-04-19 09:11:11 +0200 |
---|---|---|
committer | Thorsten Leemhuis <fedora@leemhuis.info> | 2018-04-19 09:11:11 +0200 |
commit | 941994c0dadd4c08c79a6bd79bade85298a18497 (patch) | |
tree | 83d5a87f4ab828379be00e4cef1ad601e677c3fe | |
parent | bd8ce3d733265ef26fa9b3ba63100a60820b217c (diff) | |
parent | 2637ac8e11357063f4bf09c99b1d3ba8018a1ff3 (diff) | |
download | kernel-941994c0dadd4c08c79a6bd79bade85298a18497.tar.gz kernel-941994c0dadd4c08c79a6bd79bade85298a18497.tar.xz kernel-941994c0dadd4c08c79a6bd79bade85298a18497.zip |
Merge remote-tracking branch 'origin/f27' into f27-user-thl-vanilla-fedora
-rw-r--r-- | 0001-scsi-libsas-defer-ata-device-eh-commands-to-libata.patch | 130 | ||||
-rw-r--r-- | 0001-scsi-libsas-direct-call-probe-and-destruct.patch | 66 | ||||
-rw-r--r-- | 0001-scsi-libsas-fix-memory-leak-in-sas_smp_get_phy_event.patch | 40 | ||||
-rw-r--r-- | kernel.spec | 12 |
4 files changed, 172 insertions, 76 deletions
diff --git a/0001-scsi-libsas-defer-ata-device-eh-commands-to-libata.patch b/0001-scsi-libsas-defer-ata-device-eh-commands-to-libata.patch new file mode 100644 index 000000000..2e65d9b99 --- /dev/null +++ b/0001-scsi-libsas-defer-ata-device-eh-commands-to-libata.patch @@ -0,0 +1,130 @@ +From 318aaf34f1179b39fa9c30fa0f3288b645beee39 Mon Sep 17 00:00:00 2001 +From: Jason Yan <yanaijie@huawei.com> +Date: Thu, 8 Mar 2018 10:34:53 +0800 +Subject: [PATCH] scsi: libsas: defer ata device eh commands to libata + +When ata device doing EH, some commands still attached with tasks are +not passed to libata when abort failed or recover failed, so libata did +not handle these commands. After these commands done, sas task is freed, +but ata qc is not freed. This will cause ata qc leak and trigger a +warning like below: + +WARNING: CPU: 0 PID: 28512 at drivers/ata/libata-eh.c:4037 +ata_eh_finish+0xb4/0xcc +CPU: 0 PID: 28512 Comm: kworker/u32:2 Tainted: G W OE 4.14.0#1 +...... +Call trace: +[<ffff0000088b7bd0>] ata_eh_finish+0xb4/0xcc +[<ffff0000088b8420>] ata_do_eh+0xc4/0xd8 +[<ffff0000088b8478>] ata_std_error_handler+0x44/0x8c +[<ffff0000088b8068>] ata_scsi_port_error_handler+0x480/0x694 +[<ffff000008875fc4>] async_sas_ata_eh+0x4c/0x80 +[<ffff0000080f6be8>] async_run_entry_fn+0x4c/0x170 +[<ffff0000080ebd70>] process_one_work+0x144/0x390 +[<ffff0000080ec100>] worker_thread+0x144/0x418 +[<ffff0000080f2c98>] kthread+0x10c/0x138 +[<ffff0000080855dc>] ret_from_fork+0x10/0x18 + +If ata qc leaked too many, ata tag allocation will fail and io blocked +for ever. + +As suggested by Dan Williams, defer ata device commands to libata and +merge sas_eh_finish_cmd() with sas_eh_defer_cmd(). libata will handle +ata qcs correctly after this. + +Signed-off-by: Jason Yan <yanaijie@huawei.com> +CC: Xiaofei Tan <tanxiaofei@huawei.com> +CC: John Garry <john.garry@huawei.com> +CC: Dan Williams <dan.j.williams@intel.com> +Reviewed-by: Dan Williams <dan.j.williams@intel.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/libsas/sas_scsi_host.c | 33 +++++++++++++-------------------- + 1 file changed, 13 insertions(+), 20 deletions(-) + +diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c +index 626727207889..a372af68d9a9 100644 +--- a/drivers/scsi/libsas/sas_scsi_host.c ++++ b/drivers/scsi/libsas/sas_scsi_host.c +@@ -223,6 +223,7 @@ int sas_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) + static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) + { + struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(cmd->device->host); ++ struct domain_device *dev = cmd_to_domain_dev(cmd); + struct sas_task *task = TO_SAS_TASK(cmd); + + /* At this point, we only get called following an actual abort +@@ -231,6 +232,14 @@ static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) + */ + sas_end_task(cmd, task); + ++ if (dev_is_sata(dev)) { ++ /* defer commands to libata so that libata EH can ++ * handle ata qcs correctly ++ */ ++ list_move_tail(&cmd->eh_entry, &sas_ha->eh_ata_q); ++ return; ++ } ++ + /* now finish the command and move it on to the error + * handler done list, this also takes it off the + * error handler pending list. +@@ -238,22 +247,6 @@ static void sas_eh_finish_cmd(struct scsi_cmnd *cmd) + scsi_eh_finish_cmd(cmd, &sas_ha->eh_done_q); + } + +-static void sas_eh_defer_cmd(struct scsi_cmnd *cmd) +-{ +- struct domain_device *dev = cmd_to_domain_dev(cmd); +- struct sas_ha_struct *ha = dev->port->ha; +- struct sas_task *task = TO_SAS_TASK(cmd); +- +- if (!dev_is_sata(dev)) { +- sas_eh_finish_cmd(cmd); +- return; +- } +- +- /* report the timeout to libata */ +- sas_end_task(cmd, task); +- list_move_tail(&cmd->eh_entry, &ha->eh_ata_q); +-} +- + static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd *my_cmd) + { + struct scsi_cmnd *cmd, *n; +@@ -261,7 +254,7 @@ static void sas_scsi_clear_queue_lu(struct list_head *error_q, struct scsi_cmnd + list_for_each_entry_safe(cmd, n, error_q, eh_entry) { + if (cmd->device->sdev_target == my_cmd->device->sdev_target && + cmd->device->lun == my_cmd->device->lun) +- sas_eh_defer_cmd(cmd); ++ sas_eh_finish_cmd(cmd); + } + } + +@@ -618,12 +611,12 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head * + case TASK_IS_DONE: + SAS_DPRINTK("%s: task 0x%p is done\n", __func__, + task); +- sas_eh_defer_cmd(cmd); ++ sas_eh_finish_cmd(cmd); + continue; + case TASK_IS_ABORTED: + SAS_DPRINTK("%s: task 0x%p is aborted\n", + __func__, task); +- sas_eh_defer_cmd(cmd); ++ sas_eh_finish_cmd(cmd); + continue; + case TASK_IS_AT_LU: + SAS_DPRINTK("task 0x%p is at LU: lu recover\n", task); +@@ -634,7 +627,7 @@ static void sas_eh_handle_sas_errors(struct Scsi_Host *shost, struct list_head * + "recovered\n", + SAS_ADDR(task->dev), + cmd->device->lun); +- sas_eh_defer_cmd(cmd); ++ sas_eh_finish_cmd(cmd); + sas_scsi_clear_queue_lu(work_q, cmd); + goto Again; + } +-- +2.14.3 + diff --git a/0001-scsi-libsas-direct-call-probe-and-destruct.patch b/0001-scsi-libsas-direct-call-probe-and-destruct.patch index 20976a2c8..af4ecdb2c 100644 --- a/0001-scsi-libsas-direct-call-probe-and-destruct.patch +++ b/0001-scsi-libsas-direct-call-probe-and-destruct.patch @@ -1,4 +1,4 @@ -From 0558f33c06bb910e2879e355192227a8e8f0219d Mon Sep 17 00:00:00 2001 +From f66d69bd8357b59268f2adfd1c0c53b6d1dab453 Mon Sep 17 00:00:00 2001 From: Jason Yan <yanaijie@huawei.com> Date: Fri, 8 Dec 2017 17:42:09 +0800 Subject: [PATCH] scsi: libsas: direct call probe and destruct @@ -83,19 +83,19 @@ index 70be4425ae0b..2b3637b40dde 100644 @@ -730,7 +730,6 @@ int sas_discover_sata(struct domain_device *dev) if (res) return res; - + - sas_discover_event(dev->port, DISCE_PROBE); return 0; } - + diff --git a/drivers/scsi/libsas/sas_discover.c b/drivers/scsi/libsas/sas_discover.c -index 14f714d05767..e4fd078e4175 100644 +index 60de66252fa2..487d7345f515 100644 --- a/drivers/scsi/libsas/sas_discover.c +++ b/drivers/scsi/libsas/sas_discover.c @@ -212,13 +212,9 @@ void sas_notify_lldd_dev_gone(struct domain_device *dev) } } - + -static void sas_probe_devices(struct work_struct *work) +static void sas_probe_devices(struct asd_sas_port *port) { @@ -104,7 +104,7 @@ index 14f714d05767..e4fd078e4175 100644 - struct asd_sas_port *port = ev->port; - - clear_bit(DISCE_PROBE, &port->disc.pending); - + /* devices must be domain members before link recovery and probe */ list_for_each_entry(dev, &port->disco_list, disco_list_node) { @@ -294,7 +290,6 @@ int sas_discover_end_dev(struct domain_device *dev) @@ -112,13 +112,13 @@ index 14f714d05767..e4fd078e4175 100644 if (res) return res; - sas_discover_event(dev->port, DISCE_PROBE); - + return 0; } @@ -353,13 +348,9 @@ static void sas_unregister_common_dev(struct asd_sas_port *port, struct domain_d sas_put_device(dev); } - + -static void sas_destruct_devices(struct work_struct *work) +void sas_destruct_devices(struct asd_sas_port *port) { @@ -127,13 +127,13 @@ index 14f714d05767..e4fd078e4175 100644 - struct asd_sas_port *port = ev->port; - - clear_bit(DISCE_DESTRUCT, &port->disc.pending); - + list_for_each_entry_safe(dev, n, &port->destroy_list, disco_list_node) { list_del_init(&dev->disco_list_node); @@ -370,6 +361,16 @@ static void sas_destruct_devices(struct work_struct *work) } } - + +static void sas_destruct_ports(struct asd_sas_port *port) +{ + struct sas_port *sas_port, *p; @@ -154,11 +154,11 @@ index 14f714d05767..e4fd078e4175 100644 - sas_discover_event(dev->port, DISCE_DESTRUCT); } } - + @@ -490,6 +490,8 @@ static void sas_discover_domain(struct work_struct *work) port->port_dev = NULL; } - + + sas_probe_devices(port); + SAS_DPRINTK("DONE DISCOVERY on port %d, pid:%d, result:%d\n", port->id, @@ -173,7 +173,7 @@ index 14f714d05767..e4fd078e4175 100644 + sas_destruct_ports(port); + sas_probe_devices(port); } - + /* ---------- Events ---------- */ @@ -578,10 +584,8 @@ void sas_init_disc(struct sas_discovery *disc, struct asd_sas_port *port) static const work_func_t sas_event_fns[DISC_NUM_EVENTS] = { @@ -184,10 +184,10 @@ index 14f714d05767..e4fd078e4175 100644 [DISCE_RESUME] = sas_resume_devices, - [DISCE_DESTRUCT] = sas_destruct_devices, }; - + disc->pending = 0; diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c -index a8a57b0593e3..7444d40e261c 100644 +index 39e42744aa33..6a4f8198b78e 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -1916,7 +1916,8 @@ static void sas_unregister_devs_sas_addr(struct domain_device *parent, @@ -202,13 +202,13 @@ index a8a57b0593e3..7444d40e261c 100644 } @@ -2124,7 +2125,7 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev) struct domain_device *dev = NULL; - + res = sas_find_bcast_dev(port_dev, &dev); - while (res == 0 && dev) { + if (res == 0 && dev) { struct expander_device *ex = &dev->ex_dev; int i = 0, phy_id; - + @@ -2136,9 +2137,6 @@ int sas_ex_revalidate_domain(struct domain_device *port_dev) res = sas_rediscover(dev, phy_id); i = phy_id + 1; @@ -225,14 +225,14 @@ index d8826a747690..50e12d662ffe 100644 +++ b/drivers/scsi/libsas/sas_internal.h @@ -101,6 +101,7 @@ int sas_try_ata_reset(struct asd_sas_phy *phy); void sas_hae_reset(struct work_struct *work); - + void sas_free_device(struct kref *kref); +void sas_destruct_devices(struct asd_sas_port *port); - - #ifdef CONFIG_SCSI_SAS_HOST_SMP - extern void sas_smp_host_handler(struct bsg_job *job, struct Scsi_Host *shost); + + extern const work_func_t sas_phy_event_fns[PHY_NUM_EVENTS]; + extern const work_func_t sas_port_event_fns[PORT_NUM_EVENTS]; diff --git a/drivers/scsi/libsas/sas_port.c b/drivers/scsi/libsas/sas_port.c -index 64722f42b256..f07e55d3aa73 100644 +index 93266283f51f..170f5043e1df 100644 --- a/drivers/scsi/libsas/sas_port.c +++ b/drivers/scsi/libsas/sas_port.c @@ -66,6 +66,7 @@ static void sas_resume_port(struct asd_sas_phy *phy) @@ -242,16 +242,16 @@ index 64722f42b256..f07e55d3aa73 100644 + sas_destruct_devices(port); continue; } - -@@ -220,6 +221,7 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone) - + +@@ -219,6 +220,7 @@ void sas_deform_port(struct asd_sas_phy *phy, int gone) + if (port->num_phys == 1) { sas_unregister_domain_devices(port, gone); + sas_destruct_devices(port); sas_port_delete(port->port); port->port = NULL; } else { -@@ -317,6 +319,7 @@ static void sas_init_port(struct asd_sas_port *port, +@@ -313,6 +315,7 @@ static void sas_init_port(struct asd_sas_port *port, INIT_LIST_HEAD(&port->dev_list); INIT_LIST_HEAD(&port->disco_list); INIT_LIST_HEAD(&port->destroy_list); @@ -260,10 +260,10 @@ index 64722f42b256..f07e55d3aa73 100644 INIT_LIST_HEAD(&port->phy_list); port->ha = sas_ha; diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h -index 6255bb5ed1e4..1cab6f7af425 100644 +index 61c84d536a7e..38fa2f677cf2 100644 --- a/include/scsi/libsas.h +++ b/include/scsi/libsas.h -@@ -82,10 +82,8 @@ enum phy_event { +@@ -81,10 +81,8 @@ enum phy_event { enum discover_event { DISCE_DISCOVER_DOMAIN = 0U, DISCE_REVALIDATE_DOMAIN, @@ -273,26 +273,26 @@ index 6255bb5ed1e4..1cab6f7af425 100644 - DISCE_DESTRUCT, DISC_NUM_EVENTS, }; - -@@ -262,6 +260,7 @@ struct asd_sas_port { + +@@ -261,6 +259,7 @@ struct asd_sas_port { struct list_head dev_list; struct list_head disco_list; struct list_head destroy_list; + struct list_head sas_port_del_list; enum sas_linkrate linkrate; - + struct sas_work work; diff --git a/include/scsi/scsi_transport_sas.h b/include/scsi/scsi_transport_sas.h index 62895b405933..05ec927a3c72 100644 --- a/include/scsi/scsi_transport_sas.h +++ b/include/scsi/scsi_transport_sas.h @@ -156,6 +156,7 @@ struct sas_port { - + struct mutex phy_list_mutex; struct list_head phy_list; + struct list_head del_list; /* libsas only */ }; - + #define dev_to_sas_port(d) \ -- 2.14.3 diff --git a/0001-scsi-libsas-fix-memory-leak-in-sas_smp_get_phy_event.patch b/0001-scsi-libsas-fix-memory-leak-in-sas_smp_get_phy_event.patch deleted file mode 100644 index e78347c70..000000000 --- a/0001-scsi-libsas-fix-memory-leak-in-sas_smp_get_phy_event.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 4a491b1ab11ca0556d2fda1ff1301e862a2d44c4 Mon Sep 17 00:00:00 2001 -From: Jason Yan <yanaijie@huawei.com> -Date: Thu, 4 Jan 2018 21:04:31 +0800 -Subject: [PATCH] scsi: libsas: fix memory leak in sas_smp_get_phy_events() - -We've got a memory leak with the following producer: - -while true; -do cat /sys/class/sas_phy/phy-1:0:12/invalid_dword_count >/dev/null; -done - -The buffer req is allocated and not freed after we return. Fix it. - -Fixes: 2908d778ab3e ("[SCSI] aic94xx: new driver") -Signed-off-by: Jason Yan <yanaijie@huawei.com> -CC: John Garry <john.garry@huawei.com> -CC: chenqilin <chenqilin2@huawei.com> -CC: chenxiang <chenxiang66@hisilicon.com> -Reviewed-by: Christoph Hellwig <hch@lst.de> -Reviewed-by: Hannes Reinecke <hare@suse.com> -Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> ---- - drivers/scsi/libsas/sas_expander.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c -index ca1566237ae7..1de59c0fdbc0 100644 ---- a/drivers/scsi/libsas/sas_expander.c -+++ b/drivers/scsi/libsas/sas_expander.c -@@ -695,6 +695,7 @@ int sas_smp_get_phy_events(struct sas_phy *phy) - phy->phy_reset_problem_count = scsi_to_u32(&resp[24]); - - out: -+ kfree(req); - kfree(resp); - return res; - --- -2.14.3 - diff --git a/kernel.spec b/kernel.spec index 58eebbff6..b8c5fba96 100644 --- a/kernel.spec +++ b/kernel.spec @@ -672,9 +672,6 @@ Patch653: CVE-2018-1000026.patch # rhbz 1549316 Patch657: ipmi-fixes.patch -# CVE-2018-7757 rhbz 1553361 1553363 -Patch658: 0001-scsi-libsas-fix-memory-leak-in-sas_smp_get_phy_event.patch - # CVE-2018-8043 rhbz 1554199 1554200 Patch660: 0001-net-phy-mdio-bcm-unimac-fix-potential-NULL-dereferen.patch @@ -687,6 +684,9 @@ Patch664: drm-nouveau-bl-fix-backlight-regression.patch # rhbz 1558977 Patch665: sunrpc-remove-incorrect-HMAC-request-initialization.patch +# CVE-2018-10021 rhbz 1566407 1566409 +Patch666: 0001-scsi-libsas-defer-ata-device-eh-commands-to-libata.patch + # END OF PATCH DEFINITIONS %endif @@ -1968,6 +1968,12 @@ fi # # %changelog +* Thu Apr 12 2018 Laura Abbott <labbott@redhat.com> - 4.15.17-300 +- Linux v4.15.17 + +* Thu Apr 12 2018 Justin M. Forbes <jforbes@fedoraproject.org> +- Fix CVE-2018-10021 (rhbz 1566407 1566409) + * Mon Apr 09 2018 Laura Abbott <labbott@redhat.com> - 4.15.16-300 - Linux v4.15.16 |