Commit 32f04f1f authored by Nicholas Bellinger's avatar Nicholas Bellinger Committed by Jiri Slaby

iscsi-target: Fail connection on short sendmsg writes

commit 6bf6ca75 upstream.

This patch changes iscsit_do_tx_data() to fail on short writes
when kernel_sendmsg() returns a value different than 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 would result in kernel_sendmsg() 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.

So following Al's audit of iovec consumers, go ahead and fail
the connection on short writes for now, and remove the bogus
logic ahead of his proper upstream fix.
Reported-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
parent b3bc17d5
...@@ -1355,15 +1355,15 @@ static int iscsit_do_tx_data( ...@@ -1355,15 +1355,15 @@ static int iscsit_do_tx_data(
struct iscsi_conn *conn, struct iscsi_conn *conn,
struct iscsi_data_count *count) 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 kvec *iov_p;
struct msghdr msg; struct msghdr msg;
if (!conn || !conn->sock || !conn->conn_ops) if (!conn || !conn->sock || !conn->conn_ops)
return -1; return -1;
if (data <= 0) { if (count->data_length <= 0) {
pr_err("Data length is: %d\n", data); pr_err("Data length is: %d\n", count->data_length);
return -1; return -1;
} }
...@@ -1372,20 +1372,16 @@ static int iscsit_do_tx_data( ...@@ -1372,20 +1372,16 @@ static int iscsit_do_tx_data(
iov_p = count->iov; iov_p = count->iov;
iov_len = count->iov_count; iov_len = count->iov_count;
while (total_tx < data) { ret = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len,
tx_loop = kernel_sendmsg(conn->sock, &msg, iov_p, iov_len, count->data_length);
(data - total_tx)); if (ret != count->data_length) {
if (tx_loop <= 0) { pr_err("Unexpected ret: %d send data %d\n",
pr_debug("tx_loop: %d total_tx %d\n", ret, count->data_length);
tx_loop, total_tx); return -EPIPE;
return tx_loop;
}
total_tx += tx_loop;
pr_debug("tx_loop: %d, total_tx: %d, data: %d\n",
tx_loop, total_tx, data);
} }
pr_debug("ret: %d, sent data: %d\n", ret, count->data_length);
return total_tx; return ret;
} }
int rx_data( int rx_data(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment