lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1508860309-212397-9-git-send-email-john.garry@huawei.com>
Date:   Tue, 24 Oct 2017 23:51:38 +0800
From:   John Garry <john.garry@...wei.com>
To:     <jejb@...ux.vnet.ibm.com>, <martin.petersen@...cle.com>
CC:     <linuxarm@...wei.com>, <linux-scsi@...r.kernel.org>,
        <linux-kernel@...r.kernel.org>, <zhangfei.gao@...aro.org>,
        Xiaofei Tan <tanxiaofei@...wei.com>,
        John Garry <john.garry@...wei.com>
Subject: [PATCH 08/19] scsi: hisi_sas: fix the risk of freeing slot twice

From: Xiaofei Tan <tanxiaofei@...wei.com>

The function hisi_sas_slot_task_free() is used to free
the slot and do tidy-up of LLDD resources. The LLDD
generally should know the state of a slot and decide when
to free it, and it should only be done once.

For some scenarios, we really don't know the state, like
when TMF timeout. In this case, we check task->lldd_task
before calling hisi_sas_slot_task_free().

However, we may miss some scenarios when we should also
check task->lldd_task, and it is not SMP safe to check
task->lldd_task as we don't protect it within spin lock.

This patch is to fix this risk of freeing slot twice, as
follows:
1. Check task->lldd_task in the hisi_sas_slot_task_free(),
and give up freeing of this time if task->lldd_task is NULL.
2. Set slot->buf to NULL after it is freed.

Signed-off-by: Xiaofei Tan <tanxiaofei@...wei.com>
Signed-off-by: John Garry <john.garry@...wei.com>
---
 drivers/scsi/hisi_sas/hisi_sas_main.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c
index 2a209e1..6b4dabde 100644
--- a/drivers/scsi/hisi_sas/hisi_sas_main.c
+++ b/drivers/scsi/hisi_sas/hisi_sas_main.c
@@ -185,13 +185,16 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
 		struct domain_device *device = task->dev;
 		struct hisi_sas_device *sas_dev = device->lldd_dev;
 
+		if (!task->lldd_task)
+			return;
+
+		task->lldd_task = NULL;
+
 		if (!sas_protocol_ata(task->task_proto))
 			if (slot->n_elem)
 				dma_unmap_sg(dev, task->scatter, slot->n_elem,
 					     task->data_dir);
 
-		task->lldd_task = NULL;
-
 		if (sas_dev)
 			atomic64_dec(&sas_dev->running_req);
 	}
@@ -199,8 +202,8 @@ void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, struct sas_task *task,
 	if (slot->buf)
 		dma_pool_free(hisi_hba->buffer_pool, slot->buf, slot->buf_dma);
 
-
 	list_del_init(&slot->entry);
+	slot->buf = NULL;
 	slot->task = NULL;
 	slot->port = NULL;
 	hisi_sas_slot_index_free(hisi_hba, slot->idx);
-- 
1.9.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ