summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThorsten Leemhuis <fedora@leemhuis.info>2018-04-19 09:11:11 +0200
committerThorsten Leemhuis <fedora@leemhuis.info>2018-04-19 09:11:11 +0200
commit941994c0dadd4c08c79a6bd79bade85298a18497 (patch)
tree83d5a87f4ab828379be00e4cef1ad601e677c3fe
parentbd8ce3d733265ef26fa9b3ba63100a60820b217c (diff)
parent2637ac8e11357063f4bf09c99b1d3ba8018a1ff3 (diff)
downloadkernel-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.patch130
-rw-r--r--0001-scsi-libsas-direct-call-probe-and-destruct.patch66
-rw-r--r--0001-scsi-libsas-fix-memory-leak-in-sas_smp_get_phy_event.patch40
-rw-r--r--kernel.spec12
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