From: "Nicholas A. Bellinger" <nab@daterainc.com>
To: target-devel <target-devel@vger.kernel.org>
Cc: linux-kernel <linux-kernel@vger.kernel.org>,
Al Viro <viro@zeniv.linux.org.uk>,
"David S. Miller" <davem@davemloft.net>,
Nicholas Bellinger <nab@linux-iscsi.org>
Subject: [PATCH] iscsi-target: Fail connection on short writes/reads
Date: Tue, 16 Dec 2014 04:48:58 +0000 [thread overview]
Message-ID: <1418705338-23695-1-git-send-email-nab@daterainc.com> (raw)
From: Nicholas Bellinger <nab@linux-iscsi.org>
This patch changes iscsit_do_[tx,rx]_data() to fail on short
write/reads when kernel_[send,recv]msg() returns a value different
than the requested transfer length, returning -EPIPE and thus
causing a connection reset to occur.
This avoids a potential bug in the original code where a short
write/read would result in kernel_[send,recv]msg() being called
again with the original iovec base + length.
In practice this has not been an issue because iscsit_do_tx_data()
is only used for transferring 48 byte headers + 4 byte digests,
along with seldom used control payloads from NOPIN + TEXT_RSP +
REJECT with less than 32k of data. Nor has it been occuring with
iscsit_do_rx_data() because MSG_WAITALL won't return to caller
until the requested transfer length is reached, or an error has
occured.
So following Al's audit of iovec consumers, go ahead and fail
the connection on short writes/reads for now, and remove the
bogus logic.
Reported-by: Al Viro <viro@zeniv.linux.org.uk>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
---
drivers/target/iscsi/iscsi_target_util.c | 48 +++++++++++++-------------------
1 file changed, 20 insertions(+), 28 deletions(-)
diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
index ce87ce9..9aa24f1 100644
--- a/drivers/target/iscsi/iscsi_target_util.c
+++ b/drivers/target/iscsi/iscsi_target_util.c
@@ -1326,7 +1326,7 @@ static int iscsit_do_rx_data(
struct iscsi_conn *conn,
struct iscsi_data_count *count)
{
- int data = count->data_length, rx_loop = 0, total_rx = 0, iov_len;
+ int ret, iov_len;
struct kvec *iov_p;
struct msghdr msg;
@@ -1338,35 +1338,31 @@ static int iscsit_do_rx_data(
iov_p = count->iov;
iov_len = count->iov_count;
- while (total_rx < data) {
- rx_loop = kernel_recvmsg(conn->sock, &msg, iov_p, iov_len,
- (data - total_rx), MSG_WAITALL);
- if (rx_loop <= 0) {
- pr_debug("rx_loop: %d total_rx: %d\n",
- rx_loop, total_rx);
- return rx_loop;
- }
- total_rx += rx_loop;
- pr_debug("rx_loop: %d, total_rx: %d, data: %d\n",
- rx_loop, total_rx, data);
+ ret = kernel_recvmsg(conn->sock, &msg, iov_p, iov_len,
+ count->data_length, MSG_WAITALL);
+ if (ret != count->data_length) {
+ pr_err("Unexpected ret: %d recv data: %d\n",
+ ret, count->data_length);
+ return -EPIPE;
}
+ pr_debug("ret: %d, recv data: %d\n", ret, count->data_length);
- return total_rx;
+ return ret;
}
static int iscsit_do_tx_data(
struct iscsi_conn *conn,
struct iscsi_data_count *count)
{
- int data = count->data_length, total_tx = 0, tx_loop = 0, iov_len;
+ int ret, iov_len;
struct kvec *iov_p;
struct msghdr msg;
if (!conn || !conn->sock || !conn->conn_ops)
return -1;
- if (data <= 0) {
- pr_err("Data length is: %d\n", data);
+ if (count->data_length <= 0) {
+ pr_err("Data length is: %d\n", count->data_length);
return -1;
}
@@ -1375,20 +1371,16 @@ static int iscsit_do_tx_data(
iov_p = count->iov;
iov_len = count->iov_count;
- while (total_tx < data) {
- tx_loop = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len,
- (data - total_tx));
- if (tx_loop <= 0) {
- pr_debug("tx_loop: %d total_tx %d\n",
- tx_loop, total_tx);
- return tx_loop;
- }
- total_tx += tx_loop;
- pr_debug("tx_loop: %d, total_tx: %d, data: %d\n",
- tx_loop, total_tx, data);
+ ret = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len,
+ count->data_length);
+ if (ret != count->data_length) {
+ pr_err("Unexpected ret: %d send data %d\n",
+ ret, count->data_length);
+ return -EPIPE;
}
+ pr_debug("ret: %d, sent data: %d\n", ret, count->data_length);
- return total_tx;
+ return ret;
}
int rx_data(
--
1.9.1
next reply other threads:[~2014-12-16 5:20 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-12-16 4:48 Nicholas A. Bellinger [this message]
2014-12-16 6:04 ` Al Viro
2014-12-16 8:04 ` Nicholas A. Bellinger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1418705338-23695-1-git-send-email-nab@daterainc.com \
--to=nab@daterainc.com \
--cc=davem@davemloft.net \
--cc=linux-kernel@vger.kernel.org \
--cc=nab@linux-iscsi.org \
--cc=target-devel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®