Skip to contentSkip to conversation

tcp: Validate recv queue on repair and related stuff

PATCH Applied Pavel Emelyanov 3 participants 10 messages May 10, 2012 – May 11, 2012

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

cover tcp: Validate recv queue on repair and related stuff

As noted by Eric, no checks are performed when repairing data in tcp read queue. He also suggested that the tcp_try_rmem_schedule() gets out-lined for this.

This set does both of the above, more details are in patch comments.

Applies to net-next.

Thanks,
Pavel

#1 lore raw

PATCH 1/3 tcp: Move rcvq sending to tcp_input.c

It actually works on the input queue and will use its read mem routines, thus it's better to have in in the tcp_input.c file.

---
 include/net/tcp.h    |    3 +--
 net/ipv4/tcp.c       |   33 ---------------------------------
 net/ipv4/tcp_input.c |   35 ++++++++++++++++++++++++++++++++++-
 3 files changed, 35 insertions(+), 36 deletions(-)
include/net/tcp.h +1 -2
index 92faa6a..aaf5de9 100644
@@ -432,8 +432,7 @@ extern int tcp_disconnect(struct sock *sk, int flags);
 
 void tcp_connect_init(struct sock *sk);
 void tcp_finish_connect(struct sock *sk, struct sk_buff *skb);
-int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb,
-			       int hdrlen, bool *fragstolen);
+int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size);
 
 /* From syncookies.c */
 extern __u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS];
net/ipv4/tcp.c +0 -33
index 5654062..86e2cf2 100644
@@ -978,39 +978,6 @@ static inline int select_size(const struct sock *sk, bool sg)
 	return tmp;
 }
 
-static int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
-{
-	struct sk_buff *skb;
-	struct tcphdr *th;
-	bool fragstolen;
-
-	skb = alloc_skb(size + sizeof(*th), sk->sk_allocation);
-	if (!skb)
-		goto err;
-
-	th = (struct tcphdr *)skb_put(skb, sizeof(*th));
-	skb_reset_transport_header(skb);
-	memset(th, 0, sizeof(*th));
-
-	if (memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size))
-		goto err_free;
-
-	TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt;
-	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + size;
-	TCP_SKB_CB(skb)->ack_seq = tcp_sk(sk)->snd_una - 1;
-
-	if (tcp_queue_rcv(sk, skb, sizeof(*th), &fragstolen)) {
-		WARN_ON_ONCE(fragstolen); /* should not happen */
-		__kfree_skb(skb);
-	}
-	return size;
-
-err_free:
-	kfree_skb(skb);
-err:
-	return -ENOMEM;
-}
-
 int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 		size_t size)
 {
net/ipv4/tcp_input.c +34 -1
index eb58b94..7c6c99d 100644
@@ -4746,7 +4746,7 @@ end:
 		skb_set_owner_r(skb, sk);
 }
 
-int tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen,
+static int __must_check tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen,
 		  bool *fragstolen)
 {
 	int eaten;
@@ -4763,6 +4763,39 @@ int tcp_queue_rcv(struct sock *sk, struct sk_buff *skb, int hdrlen,
 	return eaten;
 }
 
+int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
+{
+	struct sk_buff *skb;
+	struct tcphdr *th;
+	bool fragstolen;
+
+	skb = alloc_skb(size + sizeof(*th), sk->sk_allocation);
+	if (!skb)
+		goto err;
+
+	th = (struct tcphdr *)skb_put(skb, sizeof(*th));
+	skb_reset_transport_header(skb);
+	memset(th, 0, sizeof(*th));
+
+	if (memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size))
+		goto err_free;
+
+	TCP_SKB_CB(skb)->seq = tcp_sk(sk)->rcv_nxt;
+	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + size;
+	TCP_SKB_CB(skb)->ack_seq = tcp_sk(sk)->snd_una - 1;
+
+	if (tcp_queue_rcv(sk, skb, sizeof(*th), &fragstolen)) {
+		WARN_ON_ONCE(fragstolen); /* should not happen */
+		__kfree_skb(skb);
+	}
+	return size;
+
+err_free:
+	kfree_skb(skb);
+err:
+	return -ENOMEM;
+}
+
 static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
 {
 	const struct tcphdr *th = tcp_hdr(skb);
Signature · 1 line
1.5.5.6
Acked-by on v1 1/3
#2 lore raw

Re: [PATCH 1/3] tcp: Move rcvq sending to tcp_input.c

Quoted 9 lines · Pavel Emelyanov

It actually works on the input queue and will use its read mem routines, thus it's better to have in in the tcp_input.c file.

---
 include/net/tcp.h    |    3 +--
 net/ipv4/tcp.c       |   33 ---------------------------------
 net/ipv4/tcp_input.c |   35 ++++++++++++++++++++++++++++++++++-
 3 files changed, 35 insertions(+), 36 deletions(-)
maintainer Applied
#3 lore raw

Re: [PATCH 1/3] tcp: Move rcvq sending to tcp_input.c

From: Eric Dumazet <[email protected]>
Date: Thu, 10 May 2012 14:00:14 +0200

Quoted 12 lines · Pavel Emelyanov
Quoted 9 lines

It actually works on the input queue and will use its read mem routines, thus it's better to have in in the tcp_input.c file.

---
 include/net/tcp.h    |    3 +--
 net/ipv4/tcp.c       |   33 ---------------------------------
 net/ipv4/tcp_input.c |   35 ++++++++++++++++++++++++++++++++++-
 3 files changed, 35 insertions(+), 36 deletions(-)

Applied.

#4 lore raw

PATCH 2/3 tcp: Schedule rmem for rcvq repair send

In reply to Pavel Emelyanov

As noted by Eric, no checks are performed on the data size we're putting in the read queue during repair. Thus, validate the given data size with the common rmem management routine.

---
 net/ipv4/tcp_input.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
net/ipv4/tcp_input.c +3 -0
index 7c6c99d..164659f 100644
@@ -4769,6 +4769,9 @@ int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size)
 	struct tcphdr *th;
 	bool fragstolen;
 
+	if (tcp_try_rmem_schedule(sk, size + sizeof(*th)))
+		goto err;
+
 	skb = alloc_skb(size + sizeof(*th), sk->sk_allocation);
 	if (!skb)
 		goto err;
Signature · 1 line
1.5.5.6
Acked-by on v1 2/3
#5 lore raw

Re: [PATCH 2/3] tcp: Schedule rmem for rcvq repair send

Quoted 8 lines · Pavel Emelyanov

As noted by Eric, no checks are performed on the data size we're putting in the read queue during repair. Thus, validate the given data size with the common rmem management routine.

---
 net/ipv4/tcp_input.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)
maintainer Applied
#6 lore raw

Re: [PATCH 2/3] tcp: Schedule rmem for rcvq repair send

From: Eric Dumazet <[email protected]>
Date: Thu, 10 May 2012 14:00:29 +0200

Quoted 11 lines · Pavel Emelyanov
Quoted 8 lines

As noted by Eric, no checks are performed on the data size we're putting in the read queue during repair. Thus, validate the given data size with the common rmem management routine.

---
 net/ipv4/tcp_input.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

Applied.

#7 lore raw

PATCH 3/3 tcp: Out-line tcp_try_rmem_schedule

In reply to Pavel Emelyanov

As proposed by Eric, make the tcp_input.o thinner.

add/remove: 1/1 grow/shrink: 1/4 up/down: 868/-1329 (-461)
function old new delta
tcp_try_rmem_schedule - 864 +864

tcp_ack                                     4811    4815      +4
tcp_validate_incoming                        817     815      -2
tcp_collapse                                 860     858      -2
tcp_send_rcvq                                555     353    -202
tcp_data_queue                              3435    3033    -402
tcp_prune_queue                              721       -    -721
---
 net/ipv4/tcp_input.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
net/ipv4/tcp_input.c +1 -1
index 164659f..b99ada2 100644
@@ -4511,7 +4511,7 @@ static void tcp_ofo_queue(struct sock *sk)
 static int tcp_prune_ofo_queue(struct sock *sk);
 static int tcp_prune_queue(struct sock *sk);
 
-static inline int tcp_try_rmem_schedule(struct sock *sk, unsigned int size)
+static int tcp_try_rmem_schedule(struct sock *sk, unsigned int size)
 {
 	if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
 	    !sk_rmem_schedule(sk, size)) {
Signature · 1 line
1.5.5.6
Acked-by on v1 3/3
#8 lore raw

Re: [PATCH 3/3] tcp: Out-line tcp_try_rmem_schedule

Quoted 12 lines · Pavel Emelyanov

As proposed by Eric, make the tcp_input.o thinner.

add/remove: 1/1 grow/shrink: 1/4 up/down: 868/-1329 (-461)
function old new delta
tcp_try_rmem_schedule - 864 +864

tcp_ack                                     4811    4815      +4
tcp_validate_incoming                        817     815      -2
tcp_collapse                                 860     858      -2
tcp_send_rcvq                                555     353    -202
tcp_data_queue                              3435    3033    -402
tcp_prune_queue                              721       -    -721
Quoted 4 lines
---
 net/ipv4/tcp_input.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

Thanks !

maintainer Applied
#9 lore raw

Re: [PATCH 3/3] tcp: Out-line tcp_try_rmem_schedule

From: Eric Dumazet <[email protected]>
Date: Thu, 10 May 2012 14:00:56 +0200

Quoted 13 lines · Pavel Emelyanov
Quoted 12 lines

As proposed by Eric, make the tcp_input.o thinner.

add/remove: 1/1 grow/shrink: 1/4 up/down: 868/-1329 (-461)
function old new delta
tcp_try_rmem_schedule - 864 +864

tcp_ack                                     4811    4815      +4
tcp_validate_incoming                        817     815      -2
tcp_collapse                                 860     858      -2
tcp_send_rcvq                                555     353    -202
tcp_data_queue                              3435    3033    -402
tcp_prune_queue                              721       -    -721
Quoted 6 lines
Quoted 4 lines
---
 net/ipv4/tcp_input.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

Applied.