From patchwork Tue Apr 2 19:58:13 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bart Van Assche X-Patchwork-Id: 10882281 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 580F41390 for ; Tue, 2 Apr 2019 19:58:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3FB762875F for ; Tue, 2 Apr 2019 19:58:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 34037288D7; Tue, 2 Apr 2019 19:58:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B4D832875F for ; Tue, 2 Apr 2019 19:58:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726404AbfDBT6j (ORCPT ); Tue, 2 Apr 2019 15:58:39 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:46611 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726157AbfDBT6j (ORCPT ); Tue, 2 Apr 2019 15:58:39 -0400 Received: by mail-pg1-f194.google.com with SMTP id q1so7065791pgv.13 for ; Tue, 02 Apr 2019 12:58:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tCv0ipwA2XFoVNNQ1rbUjPSAYhv7VvseaH6qCNAJ8hQ=; b=TxPpkjs5Z0OSEkTSPdp+TC8YyqHrY0j0F1kDDepnt3kJ/42DKxan/dAfouJUDROJbX PdjPMtT+SUzgZDkadx0/Twiu0LZM05irSAof34I5QJi4Wvp1B63WBNH6bafxr1zt4R+2 4Q2sdz+EyhnyHFCWm83ML5gygXF75Ug4/5i1WVINFShB3is5xpYCYWAG1YTDlTW8+CWR R46ouFTY/eHWo6vQflc/TQE9xR7clHYkRQPBg3npGlNQ1kBcDFCLmBn8iqng2ZJJsGTK AHKPIe2E/NHhnMwfiygF4lIBNnWCTNmEmydXawhnkJ5/h7Tc0Lpvvh/r6VIJJaSg+usp KPng== X-Gm-Message-State: APjAAAV75HAZIAv/WANupSSNDDctZlT82dvWlh9/p8LYMbCdzspC9fW5 sRggBGuSafTqp1DGXLrrUIQ= X-Google-Smtp-Source: APXvYqzrVaPKsxMQw1zqRWrcbqwIq+Neumvbu4aUcoiwq6gJkPjhwirsx088EV+9j4Om58QHJlUGcg== X-Received: by 2002:a63:170d:: with SMTP id x13mr65435752pgl.169.1554235118415; Tue, 02 Apr 2019 12:58:38 -0700 (PDT) Received: from desktop-bart.svl.corp.google.com ([2620:15c:2cd:203:5cdc:422c:7b28:ebb5]) by smtp.gmail.com with ESMTPSA id o5sm49055490pfa.135.2019.04.02.12.58.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 02 Apr 2019 12:58:37 -0700 (PDT) From: Bart Van Assche To: "Martin K . Petersen" Cc: Mike Christie , Christoph Hellwig , target-devel@vger.kernel.org, Bart Van Assche , Mike Christie , Hannes Reinecke , Nicholas Bellinger Subject: [PATCH 09/11] target/iscsi: Handle too large immediate data buffers correctly Date: Tue, 2 Apr 2019 12:58:13 -0700 Message-Id: <20190402195815.254796-10-bvanassche@acm.org> X-Mailer: git-send-email 2.20.GIT In-Reply-To: <20190402195815.254796-1-bvanassche@acm.org> References: <20190402195815.254796-1-bvanassche@acm.org> MIME-Version: 1.0 Sender: target-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: target-devel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Since target_alloc_sgl() and iscsit_allocate_iovecs() allocate buffer space for se_cmd.data_length bytes and since that number can be smaller than the iSCSI Expected Data Transfer Length (EDTL), ensure that the iSCSI target driver does not attempt to receive more bytes than what fits in the receive buffer. Always receive the full immediate data buffer such that the iSCSI target driver does not attempt to parse immediate data as an iSCSI PDU. Note: the current code base only calls iscsit_get_dataout() if the size of the immediate data buffer does not exceed the buffer size derived from the SCSI CDB. See also target_cmd_size_check(). Cc: Mike Christie Cc: Christoph Hellwig Cc: Hannes Reinecke Cc: Nicholas Bellinger Signed-off-by: Bart Van Assche --- drivers/target/iscsi/iscsi_target.c | 27 +++++++++++++++++++++--- drivers/target/iscsi/iscsi_target_util.c | 1 + include/target/iscsi/iscsi_target_core.h | 1 + 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 828697015759..8cdea25f1377 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c @@ -1568,9 +1568,11 @@ iscsit_get_dataout(struct iscsi_conn *conn, struct iscsi_cmd *cmd, { struct kvec *iov; u32 checksum, iov_count = 0, padding = 0, rx_got = 0, rx_size = 0; - u32 payload_length = ntoh24(hdr->dlength); + u32 payload_length; int iov_ret, data_crc_failed = 0; + payload_length = min_t(u32, cmd->se_cmd.data_length, + ntoh24(hdr->dlength)); rx_size += payload_length; iov = &cmd->iov_data[0]; @@ -2575,14 +2577,33 @@ static int iscsit_handle_immediate_data( u32 checksum, iov_count = 0, padding = 0; struct iscsi_conn *conn = cmd->conn; struct kvec *iov; + void *overflow_buf = NULL; - iov_ret = iscsit_map_iovec(cmd, cmd->iov_data, cmd->write_data_done, length); + BUG_ON(cmd->write_data_done > cmd->se_cmd.data_length); + rx_size = min(cmd->se_cmd.data_length - cmd->write_data_done, length); + iov_ret = iscsit_map_iovec(cmd, cmd->iov_data, cmd->write_data_done, + rx_size); if (iov_ret < 0) return IMMEDIATE_DATA_CANNOT_RECOVER; - rx_size = length; iov_count = iov_ret; iov = &cmd->iov_data[0]; + if (rx_size < length) { + /* + * Special case: length of immediate data exceeds the data + * buffer size derived from the CDB. + */ + overflow_buf = kmalloc(length - rx_size, GFP_KERNEL); + if (!overflow_buf) { + iscsit_unmap_iovec(cmd); + return IMMEDIATE_DATA_CANNOT_RECOVER; + } + cmd->overflow_buf = overflow_buf; + iov[iov_count].iov_base = overflow_buf; + iov[iov_count].iov_len = length - rx_size; + iov_count++; + rx_size = length; + } padding = ((-length) & 3); if (padding != 0) { diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c index 5b26bc23016a..fae85bfd790e 100644 --- a/drivers/target/iscsi/iscsi_target_util.c +++ b/drivers/target/iscsi/iscsi_target_util.c @@ -737,6 +737,7 @@ void iscsit_release_cmd(struct iscsi_cmd *cmd) kfree(cmd->pdu_list); kfree(cmd->seq_list); kfree(cmd->tmr_req); + kfree(cmd->overflow_buf); kfree(cmd->iov_data); kfree(cmd->text_in_ptr); diff --git a/include/target/iscsi/iscsi_target_core.h b/include/target/iscsi/iscsi_target_core.h index 24c398f4a68f..a49d37140a64 100644 --- a/include/target/iscsi/iscsi_target_core.h +++ b/include/target/iscsi/iscsi_target_core.h @@ -473,6 +473,7 @@ struct iscsi_cmd { struct timer_list dataout_timer; /* Iovecs for SCSI data payload RX/TX w/ kernel level sockets */ struct kvec *iov_data; + void *overflow_buf; /* Iovecs for miscellaneous purposes */ #define ISCSI_MISC_IOVECS 5 struct kvec iov_misc[ISCSI_MISC_IOVECS];