aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_output.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2011-12-03 16:39:53 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-04 13:20:39 -0500
commit117632e64d2a5f464e491fe221d7169a3814a77b (patch)
tree88f3a036305da54a62835d900553dda9bc846a8f /net/ipv4/tcp_output.c
parentc2e4e25afcc8ae1835a6100089f1f9fd3a362430 (diff)
tcp: take care of misalignments
We discovered that TCP stack could retransmit misaligned skbs if a malicious peer acknowledged sub MSS frame. This currently can happen only if output interface is non SG enabled : If SG is enabled, tcp builds headless skbs (all payload is included in fragments), so the tcp trimming process only removes parts of skb fragments, header stay aligned. Some arches cant handle misalignments, so force a head reallocation and shrink headroom to MAX_TCP_HEADER. Dont care about misaligments on x86 and PPC (or other arches setting NET_IP_ALIGN to 0) This patch introduces __pskb_copy() which can specify the headroom of new head, and pskb_copy() becomes a wrapper on top of __pskb_copy() Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_output.c')
-rw-r--r--net/ipv4/tcp_output.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 58f69acd3d22..50788d67bdb7 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -2147,7 +2147,15 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
2147 */ 2147 */
2148 TCP_SKB_CB(skb)->when = tcp_time_stamp; 2148 TCP_SKB_CB(skb)->when = tcp_time_stamp;
2149 2149
2150 err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); 2150 /* make sure skb->data is aligned on arches that require it */
2151 if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) {
2152 struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,
2153 GFP_ATOMIC);
2154 err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
2155 -ENOBUFS;
2156 } else {
2157 err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
2158 }
2151 2159
2152 if (err == 0) { 2160 if (err == 0) {
2153 /* Update global TCP statistics. */ 2161 /* Update global TCP statistics. */