diff mbox

ipv6: Fix udp checksums with raw sockets

Message ID 1431650048-16189-1-git-send-email-vyasevic@redhat.com
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Vladislav Yasevich May 15, 2015, 12:34 a.m. UTC
It was reported that trancerout6 would cause
a kernel to crash when trying to compute checksums
on raw UDP packets.  The cause was the check in
__ip6_append_data that would attempt to use
partial checksums on the packet.  However,
raw sockets do not initialize partial checksum
fields so partial checksums can't be used.

Solve this the same way IPv4 does it.  raw sockets
pass transhdrlen value of 0 to ip_append_data which
causes the checksum to be computed in software.  Use
the same check in ip6_append_data (check transhdrlen).

Reported-by: Wolfgang Walter <linux@stwm.de>
CC: Wolfgang Walter <linux@stwm.de>
CC: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
---
 net/ipv6/ip6_output.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Comments

Eric Dumazet May 15, 2015, 1:24 a.m. UTC | #1
On Thu, 2015-05-14 at 20:34 -0400, Vladislav Yasevich wrote:
> It was reported that trancerout6 would cause
> a kernel to crash when trying to compute checksums
> on raw UDP packets.  The cause was the check in
> __ip6_append_data that would attempt to use
> partial checksums on the packet.  However,
> raw sockets do not initialize partial checksum
> fields so partial checksums can't be used.
> 
> Solve this the same way IPv4 does it.  raw sockets
> pass transhdrlen value of 0 to ip_append_data which
> causes the checksum to be computed in software.  Use
> the same check in ip6_append_data (check transhdrlen).
> 
> Reported-by: Wolfgang Walter <linux@stwm.de>
> CC: Wolfgang Walter <linux@stwm.de>
> CC: Eric Dumazet <eric.dumazet@gmail.com>
> Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
> ---

Acked-by: Eric Dumazet <edumazet@google.com>


--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
David Miller May 15, 2015, 2:27 a.m. UTC | #2
From: Vladislav Yasevich <vyasevich@gmail.com>
Date: Thu, 14 May 2015 20:34:08 -0400

> It was reported that trancerout6 would cause
> a kernel to crash when trying to compute checksums
> on raw UDP packets.  The cause was the check in
> __ip6_append_data that would attempt to use
> partial checksums on the packet.  However,
> raw sockets do not initialize partial checksum
> fields so partial checksums can't be used.
> 
> Solve this the same way IPv4 does it.  raw sockets
> pass transhdrlen value of 0 to ip_append_data which
> causes the checksum to be computed in software.  Use
> the same check in ip6_append_data (check transhdrlen).
> 
> Reported-by: Wolfgang Walter <linux@stwm.de>
> CC: Wolfgang Walter <linux@stwm.de>
> CC: Eric Dumazet <eric.dumazet@gmail.com>
> Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>

Applied.... This seems like -stable material?  If so, how far
back?

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Eric Dumazet May 15, 2015, 3:04 a.m. UTC | #3
On Thu, 2015-05-14 at 22:27 -0400, David Miller wrote:
> From: Vladislav Yasevich <vyasevich@gmail.com>
> Date: Thu, 14 May 2015 20:34:08 -0400
> 
> > It was reported that trancerout6 would cause
> > a kernel to crash when trying to compute checksums
> > on raw UDP packets.  The cause was the check in
> > __ip6_append_data that would attempt to use
> > partial checksums on the packet.  However,
> > raw sockets do not initialize partial checksum
> > fields so partial checksums can't be used.
> > 
> > Solve this the same way IPv4 does it.  raw sockets
> > pass transhdrlen value of 0 to ip_append_data which
> > causes the checksum to be computed in software.  Use
> > the same check in ip6_append_data (check transhdrlen).
> > 
> > Reported-by: Wolfgang Walter <linux@stwm.de>
> > CC: Wolfgang Walter <linux@stwm.de>
> > CC: Eric Dumazet <eric.dumazet@gmail.com>
> > Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
> 
> Applied.... This seems like -stable material?  If so, how far
> back?

Arg, the Fixes: tag is missing :(

Fixes: 32dce968dd98 ("ipv6: Allow for partial checksums on non-ufo packets")



--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Wolfgang Walter May 15, 2015, 9:37 a.m. UTC | #4
Am Donnerstag, 14. Mai 2015, 22:27:32 schrieben Sie:
> From: Vladislav Yasevich <vyasevich@gmail.com>
> Date: Thu, 14 May 2015 20:34:08 -0400
> 
> > It was reported that trancerout6 would cause
> > a kernel to crash when trying to compute checksums
> > on raw UDP packets.  The cause was the check in
> > __ip6_append_data that would attempt to use
> > partial checksums on the packet.  However,
> > raw sockets do not initialize partial checksum
> > fields so partial checksums can't be used.
> > 
> > Solve this the same way IPv4 does it.  raw sockets
> > pass transhdrlen value of 0 to ip_append_data which
> > causes the checksum to be computed in software.  Use
> > the same check in ip6_append_data (check transhdrlen).
> > 
> > Reported-by: Wolfgang Walter <linux@stwm.de>
> > CC: Wolfgang Walter <linux@stwm.de>
> > CC: Eric Dumazet <eric.dumazet@gmail.com>
> > Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
> 
> Applied.... This seems like -stable material?  If so, how far
> back?

starting with 4.0

Regards,
diff mbox

Patch

diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 7fde1f2..2a7c537 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1277,8 +1277,10 @@  emsgsize:
 
 	/* If this is the first and only packet and device
 	 * supports checksum offloading, let's use it.
+	 * Use transhdrlen, same as IPv4, because partial
+	 * sums only work when transhdrlen is set.
 	 */
-	if (!skb && sk->sk_protocol == IPPROTO_UDP &&
+	if (transhdrlen && sk->sk_protocol == IPPROTO_UDP &&
 	    length + fragheaderlen < mtu &&
 	    rt->dst.dev->features & NETIF_F_V6_CSUM &&
 	    !exthdrlen)