diff options
author | Hannes Frederic Sowa <hannes@stressinduktion.org> | 2013-10-22 00:07:47 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-11-04 04:31:05 -0800 |
commit | b90cd7b9d0baab2e8176d9cca5f18a592ef16063 (patch) | |
tree | 236f88b6de20defeed6d7edc0bdda8528f50bd47 /net/ipv4 | |
parent | 872095cb74f0acd64d89e578a65df877870f198d (diff) | |
download | linux-3.10-b90cd7b9d0baab2e8176d9cca5f18a592ef16063.tar.gz linux-3.10-b90cd7b9d0baab2e8176d9cca5f18a592ef16063.tar.bz2 linux-3.10-b90cd7b9d0baab2e8176d9cca5f18a592ef16063.zip |
inet: fix possible memory corruption with UDP_CORK and UFO
[ This is a simplified -stable version of a set of upstream commits. ]
This is a replacement patch only for stable which does fix the problems
handled by the following two commits in -net:
"ip_output: do skb ufo init for peeked non ufo skb as well" (e93b7d748be887cd7639b113ba7d7ef792a7efb9)
"ip6_output: do skb ufo init for peeked non ufo skb as well" (c547dbf55d5f8cf615ccc0e7265e98db27d3fb8b)
Three frames are written on a corked udp socket for which the output
netdevice has UFO enabled. If the first and third frame are smaller than
the mtu and the second one is bigger, we enqueue the second frame with
skb_append_datato_frags without initializing the gso fields. This leads
to the third frame appended regulary and thus constructing an invalid skb.
This fixes the problem by always using skb_append_datato_frags as soon
as the first frag got enqueued to the skb without marking the packet
as SKB_GSO_UDP.
The problem with only two frames for ipv6 was fixed by "ipv6: udp
packets following an UFO enqueued packet need also be handled by UFO"
(2811ebac2521ceac84f2bdae402455baa6a7fb47).
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Cc: Jiri Pirko <jiri@resnulli.us>
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Cc: David Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/ip_output.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index ec2d430a6a5..6ca5873d617 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -844,7 +844,7 @@ static int __ip_append_data(struct sock *sk, csummode = CHECKSUM_PARTIAL; cork->length += length; - if (((length > mtu) || (skb && skb_is_gso(skb))) && + if (((length > mtu) || (skb && skb_has_frags(skb))) && (sk->sk_protocol == IPPROTO_UDP) && (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) { err = ip_ufo_append_data(sk, queue, getfrag, from, length, |