From: Greg Kroah-Hartman Date: Thu, 24 May 2018 07:37:06 +0000 (+0200) Subject: 3.18-stable patches X-Git-Tag: v3.18.110~15 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=58334b7920327accc653ea7db4045e9078562377;p=thirdparty%2Fkernel%2Fstable-queue.git 3.18-stable patches added patches: scsi-libsas-defer-ata-device-eh-commands-to-libata.patch scsi-sg-allocate-with-__gfp_zero-in-sg_build_indirect.patch --- diff --git a/queue-3.18/scsi-libsas-defer-ata-device-eh-commands-to-libata.patch b/queue-3.18/scsi-libsas-defer-ata-device-eh-commands-to-libata.patch new file mode 100644 index 00000000000..b083d5b87bb --- /dev/null +++ b/queue-3.18/scsi-libsas-defer-ata-device-eh-commands-to-libata.patch @@ -0,0 +1,132 @@ +From 318aaf34f1179b39fa9c30fa0f3288b645beee39 Mon Sep 17 00:00:00 2001 +From: Jason Yan +Date: Thu, 8 Mar 2018 10:34:53 +0800 +Subject: scsi: libsas: defer ata device eh commands to libata + +From: Jason Yan + +commit 318aaf34f1179b39fa9c30fa0f3288b645beee39 upstream. + +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: +[] ata_eh_finish+0xb4/0xcc +[] ata_do_eh+0xc4/0xd8 +[] ata_std_error_handler+0x44/0x8c +[] ata_scsi_port_error_handler+0x480/0x694 +[] async_sas_ata_eh+0x4c/0x80 +[] async_run_entry_fn+0x4c/0x170 +[] process_one_work+0x144/0x390 +[] worker_thread+0x144/0x418 +[] kthread+0x10c/0x138 +[] 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 +CC: Xiaofei Tan +CC: John Garry +CC: Dan Williams +Reviewed-by: Dan Williams +Signed-off-by: Martin K. Petersen +Cc: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/libsas/sas_scsi_host.c | 33 +++++++++++++-------------------- + 1 file changed, 13 insertions(+), 20 deletions(-) + +--- a/drivers/scsi/libsas/sas_scsi_host.c ++++ b/drivers/scsi/libsas/sas_scsi_host.c +@@ -250,6 +250,7 @@ out_done: + 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 +@@ -258,6 +259,14 @@ static void sas_eh_finish_cmd(struct scs + */ + 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. +@@ -265,22 +274,6 @@ static void sas_eh_finish_cmd(struct scs + 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; +@@ -288,7 +281,7 @@ static void sas_scsi_clear_queue_lu(stru + 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); + } + } + +@@ -678,12 +671,12 @@ static void sas_eh_handle_sas_errors(str + 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); +@@ -694,7 +687,7 @@ static void sas_eh_handle_sas_errors(str + "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; + } diff --git a/queue-3.18/scsi-sg-allocate-with-__gfp_zero-in-sg_build_indirect.patch b/queue-3.18/scsi-sg-allocate-with-__gfp_zero-in-sg_build_indirect.patch new file mode 100644 index 00000000000..2b1bb90ddaf --- /dev/null +++ b/queue-3.18/scsi-sg-allocate-with-__gfp_zero-in-sg_build_indirect.patch @@ -0,0 +1,35 @@ +From a45b599ad808c3c982fdcdc12b0b8611c2f92824 Mon Sep 17 00:00:00 2001 +From: Alexander Potapenko +Date: Fri, 18 May 2018 16:23:18 +0200 +Subject: scsi: sg: allocate with __GFP_ZERO in sg_build_indirect() + +From: Alexander Potapenko + +commit a45b599ad808c3c982fdcdc12b0b8611c2f92824 upstream. + +This shall help avoid copying uninitialized memory to the userspace when +calling ioctl(fd, SG_IO) with an empty command. + +Reported-by: syzbot+7d26fc1eea198488deab@syzkaller.appspotmail.com +Cc: stable@vger.kernel.org +Signed-off-by: Alexander Potapenko +Acked-by: Douglas Gilbert +Reviewed-by: Johannes Thumshirn +Signed-off-by: Martin K. Petersen +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/sg.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -1950,7 +1950,7 @@ retry: + num = (rem_sz > scatter_elem_sz_prev) ? + scatter_elem_sz_prev : rem_sz; + +- schp->pages[k] = alloc_pages(gfp_mask, order); ++ schp->pages[k] = alloc_pages(gfp_mask | __GFP_ZERO, order); + if (!schp->pages[k]) + goto out; + diff --git a/queue-3.18/series b/queue-3.18/series index 3a06bf7550d..5bc4f90c116 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -38,3 +38,5 @@ arm-8772-1-kprobes-prohibit-kprobes-on-get_user-functions.patch net-test-tailroom-before-appending-to-linear-skb.patch tcp-purge-write-queue-in-tcp_connect_init.patch ext2-fix-a-block-leak.patch +scsi-libsas-defer-ata-device-eh-commands-to-libata.patch +scsi-sg-allocate-with-__gfp_zero-in-sg_build_indirect.patch