Received: by 2002:ac0:a679:0:0:0:0:0 with SMTP id p54csp1685232imp; Fri, 22 Feb 2019 08:33:27 -0800 (PST) X-Google-Smtp-Source: AHgI3IYBCA3o5kXTm/MIq+iOGtar7Og+qVqWluZqbghHPfxzmvasixbTcy6eBtqSjquThfwtXI4z X-Received: by 2002:a63:1408:: with SMTP id u8mr4774048pgl.271.1550853207142; Fri, 22 Feb 2019 08:33:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550853207; cv=none; d=google.com; s=arc-20160816; b=KgJIRjr1a5WbOyjgShCrW6n/bMELHUKw3HtwrhullLxRLLgcQWB33dGonLsRovkOFQ lVIHW9jXeRhevqAwFUh2MFZcWVBl95yleHEhM+WVBb5UETeNg51Gya7zL3QkM2XItqct bg/Vy0+U97ZRxm/TAma9pOgMInx+phop9y/qRvjCsaCwHrB76ZbevU7uckJAUCpUXpnp PIsMVotCgN5Si28+HNSHXKpnIribDx0IMDoWL1WM7Bht3LK9W4OWH9Kp2BopPlTYYdRv Drh8zTVWCHv9eCdZDzAFaA34IZe28GiBTjHsMnLv/RhG6dk63ZycxTJilw+Hq0PTi2Rt +QAA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from; bh=mlK1G34lScJ4EIMVXw+NhGg7k0uSfORTk0Lq/TmF46s=; b=a+AU3XtWtHJTV2otODu8twfzuoKUGbpnnU2AU7jmx5oQ3vWNbkQ2bDtNBWYJhpXEQ6 6eFGJq2HxGoCZTtLsq/g6odHL3H0rwhqXKFwvc1WS8vEUxhQ2QvosQgh6uyH1siMpRjX UQgkNzRRb8h3Vu2MXYJw7oZQzXPO5vAQ2fJqq5T5PvvkVz5I7KIXB3H9z31zDTu63Txa BMod1hdqDYY57jKe08gRwUrZkJ0WrCb8Dvsg8HjUM+2pvLgN9cSI9UC6PHHq9YY796XB xwwcpYtf/OqxBkgH4Hs3FmbThWdNdd5g2M1JNzarF84OJPdkM2TbE3y7Jd/Zbg6sykZ2 7xGQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d19si1643800pgv.522.2019.02.22.08.33.11; Fri, 22 Feb 2019 08:33:27 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727217AbfBVQcc (ORCPT + 99 others); Fri, 22 Feb 2019 11:32:32 -0500 Received: from mx2.suse.de ([195.135.220.15]:39934 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726492AbfBVQcb (ORCPT ); Fri, 22 Feb 2019 11:32:31 -0500 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id A49BCAED7; Fri, 22 Feb 2019 16:32:30 +0000 (UTC) Received: by localhost (Postfix, from userid 1000) id 693261088E2; Fri, 22 Feb 2019 08:32:28 -0800 (PST) From: Lee Duncan To: linux-scsi@vger.kernel.org, linux-kernel@vger.kernel.org, cleech@redhat.com Cc: hare@suse.de, Lee Duncan Subject: [RESEND] [PATCH] Hold back_lock when calling iscsi_complete_task Date: Fri, 22 Feb 2019 08:29:47 -0800 Message-Id: <20190222162947.25178-1-leeman.duncan@gmail.com> X-Mailer: git-send-email 2.16.4 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Lee Duncan If there is an error queueing an iscsi command in iscsi_queuecommand(), for example if the transport fails to take the command in sessuin->tt->xmit_task(), then the error path can call iscsi_complete_task() without first aquiring the back_lock as required. This can lead to things like ITT pool can get corrupt, resulting in duplicate ITTs being sent out. The solution is to hold the back_lock around iscsi_complete_task() calls, and to add a little commenting to help others understand when back_lock must be held. --- drivers/scsi/libiscsi.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index b8d325ce8754..ef7871e8c6bd 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -838,7 +838,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu); * @datalen: len of buffer * * iscsi_cmd_rsp sets up the scsi_cmnd fields based on the PDU and - * then completes the command and task. + * then completes the command and task. called under back_lock **/ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, struct iscsi_task *task, char *data, @@ -941,6 +941,9 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, * @conn: iscsi connection * @hdr: iscsi pdu * @task: scsi command task + * + * iscsi_data_in_rsp sets up the scsi_cmnd fields based on the data received + * then completes the command and task. called under back_lock **/ static void iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, @@ -1025,6 +1028,16 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) return 0; } +/** + * iscsi_nop_out_rsp - SCSI NOP Response processing + * @task: scsi command task + * @nop: the nop structure + * @data: where to put the data + * @datalen: length of data + * + * iscsi_nop_out_rsp handles nop response from use or + * from user space. called under back_lock + **/ static int iscsi_nop_out_rsp(struct iscsi_task *task, struct iscsi_nopin *nop, char *data, int datalen) { @@ -1791,7 +1804,9 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) return 0; prepd_reject: + spin_lock_bh(&session->back_lock); iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ); + spin_unlock_bh(&session->back_lock); reject: spin_unlock_bh(&session->frwd_lock); ISCSI_DBG_SESSION(session, "cmd 0x%x rejected (%d)\n", @@ -1799,7 +1814,9 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc) return SCSI_MLQUEUE_TARGET_BUSY; prepd_fault: + spin_lock_bh(&session->back_lock); iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ); + spin_unlock_bh(&session->back_lock); fault: spin_unlock_bh(&session->frwd_lock); ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n", @@ -3121,8 +3138,9 @@ fail_mgmt_tasks(struct iscsi_session *session, struct iscsi_conn *conn) state = ISCSI_TASK_ABRT_SESS_RECOV; if (task->state == ISCSI_TASK_PENDING) state = ISCSI_TASK_COMPLETED; + spin_lock_bh(&session->back_lock); iscsi_complete_task(task, state); - + spin_unlock_bh(&session->back_lock); } } -- 2.16.4