Commit d9be4f7a authored by Bill Sommerfeld's avatar Bill Sommerfeld Committed by David S. Miller

ipv4: Constrain UFO fragment sizes to multiples of 8 bytes

Because the ip fragment offset field counts 8-byte chunks, ip
fragments other than the last must contain a multiple of 8 bytes of
payload.  ip_ufo_append_data wasn't respecting this constraint and,
depending on the MTU and ip option sizes, could create malformed
non-final fragments.

Google-Bug-Id: 5009328
Signed-off-by: default avatarBill Sommerfeld <wsommerfeld@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2e66f55b
...@@ -734,7 +734,7 @@ static inline int ip_ufo_append_data(struct sock *sk, ...@@ -734,7 +734,7 @@ static inline int ip_ufo_append_data(struct sock *sk,
int getfrag(void *from, char *to, int offset, int len, int getfrag(void *from, char *to, int offset, int len,
int odd, struct sk_buff *skb), int odd, struct sk_buff *skb),
void *from, int length, int hh_len, int fragheaderlen, void *from, int length, int hh_len, int fragheaderlen,
int transhdrlen, int mtu, unsigned int flags) int transhdrlen, int maxfraglen, unsigned int flags)
{ {
struct sk_buff *skb; struct sk_buff *skb;
int err; int err;
...@@ -767,7 +767,7 @@ static inline int ip_ufo_append_data(struct sock *sk, ...@@ -767,7 +767,7 @@ static inline int ip_ufo_append_data(struct sock *sk,
skb->csum = 0; skb->csum = 0;
/* specify the length of each IP datagram fragment */ /* specify the length of each IP datagram fragment */
skb_shinfo(skb)->gso_size = mtu - fragheaderlen; skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen;
skb_shinfo(skb)->gso_type = SKB_GSO_UDP; skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
__skb_queue_tail(queue, skb); __skb_queue_tail(queue, skb);
} }
...@@ -831,7 +831,7 @@ static int __ip_append_data(struct sock *sk, ...@@ -831,7 +831,7 @@ static int __ip_append_data(struct sock *sk,
(rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) { (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) {
err = ip_ufo_append_data(sk, queue, getfrag, from, length, err = ip_ufo_append_data(sk, queue, getfrag, from, length,
hh_len, fragheaderlen, transhdrlen, hh_len, fragheaderlen, transhdrlen,
mtu, flags); maxfraglen, flags);
if (err) if (err)
goto error; goto error;
return 0; return 0;
......
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