From: Eric Dumazet <eric.dumazet@gmail.com>
To: David Miller <davem@davemloft.net>
Cc: subramanian.vijay@gmail.com, therbert@google.com, netdev@vger.kernel.org
Subject: [PATCH] tcp: take care of misalignments
Date: Sun, 04 Dec 2011 08:39:53 +0100 [thread overview]
Message-ID: <1322984393.2762.134.camel@edumazet-laptop> (raw)
In-Reply-To: <1322924992.2762.117.camel@edumazet-laptop>
Hi David
Here is the patch I tested this morning on my machine.
To simulate misalignement without a malicious peer, I did a quick hack
in tcp_ack() to ack N-1 bytes instead of N bytes every 10 acks.
Here is the patch suited for net tree.
Thanks
[PATCH] 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>
---
include/linux/skbuff.h | 11 +++++++++--
net/core/skbuff.c | 11 ++++++-----
net/ipv4/tcp_output.c | 10 +++++++++-
3 files changed, 24 insertions(+), 8 deletions(-)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index fe86488..dd9a0cd 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -561,8 +561,9 @@ extern struct sk_buff *skb_clone(struct sk_buff *skb,
gfp_t priority);
extern struct sk_buff *skb_copy(const struct sk_buff *skb,
gfp_t priority);
-extern struct sk_buff *pskb_copy(struct sk_buff *skb,
- gfp_t gfp_mask);
+extern struct sk_buff *__pskb_copy(struct sk_buff *skb,
+ int headroom, gfp_t gfp_mask);
+
extern int pskb_expand_head(struct sk_buff *skb,
int nhead, int ntail,
gfp_t gfp_mask);
@@ -1824,6 +1825,12 @@ static inline dma_addr_t skb_frag_dma_map(struct device *dev,
frag->page_offset + offset, size, dir);
}
+static inline struct sk_buff *pskb_copy(struct sk_buff *skb,
+ gfp_t gfp_mask)
+{
+ return __pskb_copy(skb, skb_headroom(skb), gfp_mask);
+}
+
/**
* skb_clone_writable - is the header of a clone writable
* @skb: buffer to check
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 3c30ee4..21c7361 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -791,8 +791,9 @@ struct sk_buff *skb_copy(const struct sk_buff *skb, gfp_t gfp_mask)
EXPORT_SYMBOL(skb_copy);
/**
- * pskb_copy - create copy of an sk_buff with private head.
+ * __pskb_copy - create copy of an sk_buff with private head.
* @skb: buffer to copy
+ * @headroom: headroom of new skb
* @gfp_mask: allocation priority
*
* Make a copy of both an &sk_buff and part of its data, located
@@ -803,16 +804,16 @@ EXPORT_SYMBOL(skb_copy);
* The returned buffer has a reference count of 1.
*/
-struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
+struct sk_buff *__pskb_copy(struct sk_buff *skb, int headroom, gfp_t gfp_mask)
{
- unsigned int size = skb_end_pointer(skb) - skb->head;
+ unsigned int size = skb_headlen(skb) + headroom;
struct sk_buff *n = alloc_skb(size, gfp_mask);
if (!n)
goto out;
/* Set the data pointer */
- skb_reserve(n, skb_headroom(skb));
+ skb_reserve(n, headroom);
/* Set the tail pointer and length */
skb_put(n, skb_headlen(skb));
/* Copy the bytes */
@@ -848,7 +849,7 @@ struct sk_buff *pskb_copy(struct sk_buff *skb, gfp_t gfp_mask)
out:
return n;
}
-EXPORT_SYMBOL(pskb_copy);
+EXPORT_SYMBOL(__pskb_copy);
/**
* pskb_expand_head - reallocate header of &sk_buff
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 63170e2..0973631 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)
*/
TCP_SKB_CB(skb)->when = tcp_time_stamp;
- err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
+ /* make sure skb->data is aligned on arches that require it */
+ if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) {
+ struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER,
+ GFP_ATOMIC);
+ err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) :
+ -ENOBUFS;
+ } else {
+ err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC);
+ }
if (err == 0) {
/* Update global TCP statistics. */
next prev parent reply other threads:[~2011-12-04 7:39 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-12-01 1:48 Bug in computing data_len in tcp_sendmsg? Tom Herbert
2011-12-01 3:42 ` Eric Dumazet
2011-12-01 4:06 ` Tom Herbert
2011-12-01 4:16 ` David Miller
2011-12-01 4:17 ` Eric Dumazet
2011-12-01 5:09 ` Tom Herbert
2011-12-01 9:15 ` Eric Dumazet
2011-12-01 17:29 ` Jesse Brandeburg
2011-12-01 18:04 ` David Miller
2011-12-01 20:37 ` Eric Dumazet
2011-12-01 22:18 ` Vijay Subramanian
2011-12-01 22:30 ` Eric Dumazet
2011-12-02 6:18 ` Vijay Subramanian
2011-12-02 11:59 ` Eric Dumazet
2011-12-02 15:44 ` Eric Dumazet
2011-12-02 16:05 ` Eric Dumazet
2011-12-02 18:13 ` David Miller
2011-12-02 18:36 ` Eric Dumazet
2011-12-02 18:40 ` David Miller
2011-12-02 20:22 ` Eric Dumazet
2011-12-02 20:24 ` David Miller
2011-12-02 20:45 ` Eric Dumazet
2011-12-02 20:48 ` Eric Dumazet
2011-12-02 21:30 ` David Miller
2011-12-03 15:09 ` Eric Dumazet
2011-12-04 7:39 ` Eric Dumazet [this message]
2011-12-04 18:21 ` [PATCH] tcp: take care of misalignments David Miller
2011-12-04 18:51 ` Eric Dumazet
2011-12-05 23:45 ` David Miller
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=1322984393.2762.134.camel@edumazet-laptop \
--to=eric.dumazet@gmail.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=subramanian.vijay@gmail.com \
--cc=therbert@google.com \
/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