diff mbox series

[net,v2] net: tls, correctly account for copied bytes with multiple sk_msgs

Message ID 156036023770.7273.14464005268434910852.stgit@ubuntu-kvm1
State Accepted
Delegated to: David Miller
Headers show
Series [net,v2] net: tls, correctly account for copied bytes with multiple sk_msgs | expand

Commit Message

John Fastabend June 12, 2019, 5:23 p.m. UTC
tls_sw_do_sendpage needs to return the total number of bytes sent
regardless of how many sk_msgs are allocated. Unfortunately, copied
(the value we return up the stack) is zero'd before each new sk_msg
is allocated so we only return the copied size of the last sk_msg used.

The caller (splice, etc.) of sendpage will then believe only part
of its data was sent and send the missing chunks again. However,
because the data actually was sent the receiver will get multiple
copies of the same data.

To reproduce this do multiple sendfile calls with a length close to
the max record size. This will in turn call splice/sendpage, sendpage
may use multiple sk_msg in this case and then returns the incorrect
number of bytes. This will cause splice to resend creating duplicate
data on the receiver. Andre created a C program that can easily
generate this case so we will push a similar selftest for this to
bpf-next shortly.

The fix is to _not_ zero the copied field so that the total sent
bytes is returned.

Reported-by: Steinar H. Gunderson <steinar+kernel@gunderson.no>
Reported-by: Andre Tomt <andre@tomt.net>
Tested-by: Andre Tomt <andre@tomt.net>
Fixes: d829e9c4112b ("tls: convert to generic sk_msg interface")
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
 net/tls/tls_sw.c |    1 -
 1 file changed, 1 deletion(-)

Comments

David Miller June 12, 2019, 6:05 p.m. UTC | #1
From: John Fastabend <john.fastabend@gmail.com>
Date: Wed, 12 Jun 2019 17:23:57 +0000

> tls_sw_do_sendpage needs to return the total number of bytes sent
> regardless of how many sk_msgs are allocated. Unfortunately, copied
> (the value we return up the stack) is zero'd before each new sk_msg
> is allocated so we only return the copied size of the last sk_msg used.
> 
> The caller (splice, etc.) of sendpage will then believe only part
> of its data was sent and send the missing chunks again. However,
> because the data actually was sent the receiver will get multiple
> copies of the same data.
> 
> To reproduce this do multiple sendfile calls with a length close to
> the max record size. This will in turn call splice/sendpage, sendpage
> may use multiple sk_msg in this case and then returns the incorrect
> number of bytes. This will cause splice to resend creating duplicate
> data on the receiver. Andre created a C program that can easily
> generate this case so we will push a similar selftest for this to
> bpf-next shortly.
> 
> The fix is to _not_ zero the copied field so that the total sent
> bytes is returned.
> 
> Reported-by: Steinar H. Gunderson <steinar+kernel@gunderson.no>
> Reported-by: Andre Tomt <andre@tomt.net>
> Tested-by: Andre Tomt <andre@tomt.net>
> Fixes: d829e9c4112b ("tls: convert to generic sk_msg interface")
> Signed-off-by: John Fastabend <john.fastabend@gmail.com>

Applied and queued up for -stable.
diff mbox series

Patch

diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c
index 960494f437ac..455a782c7658 100644
--- a/net/tls/tls_sw.c
+++ b/net/tls/tls_sw.c
@@ -1143,7 +1143,6 @@  static int tls_sw_do_sendpage(struct sock *sk, struct page *page,
 
 		full_record = false;
 		record_room = TLS_MAX_PAYLOAD_SIZE - msg_pl->sg.size;
-		copied = 0;
 		copy = size;
 		if (copy >= record_room) {
 			copy = record_room;