Skip to content

Commit 9302d7b

Browse files
jgunthorpedavem330
authored andcommitted
sctp: Fix mangled IPv4 addresses on a IPv6 listening socket
sctp_v4_map_v6 was subtly writing and reading from members of a union in a way the clobbered data it needed to read before it read it. Zeroing the v6 flowinfo overwrites the v4 sin_addr with 0, meaning that every place that calls sctp_v4_map_v6 gets ::ffff:0.0.0.0 as the result. Reorder things to guarantee correct behaviour no matter what the union layout is. This impacts user space clients that open an IPv6 SCTP socket and receive IPv4 connections. Prior to 299ee user space would see a sockaddr with AF_INET and a correct address, after 299ee the sockaddr is AF_INET6, but the address is wrong. Fixes: 299ee12 (sctp: Fixup v4mapped behaviour to comply with Sock API) Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Acked-by: Neil Horman <nhorman@tuxdriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 86e363d commit 9302d7b

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

include/net/sctp/sctp.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -574,11 +574,14 @@ static inline void sctp_v6_map_v4(union sctp_addr *addr)
574574
/* Map v4 address to v4-mapped v6 address */
575575
static inline void sctp_v4_map_v6(union sctp_addr *addr)
576576
{
577+
__be16 port;
578+
579+
port = addr->v4.sin_port;
580+
addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr;
581+
addr->v6.sin6_port = port;
577582
addr->v6.sin6_family = AF_INET6;
578583
addr->v6.sin6_flowinfo = 0;
579584
addr->v6.sin6_scope_id = 0;
580-
addr->v6.sin6_port = addr->v4.sin_port;
581-
addr->v6.sin6_addr.s6_addr32[3] = addr->v4.sin_addr.s_addr;
582585
addr->v6.sin6_addr.s6_addr32[0] = 0;
583586
addr->v6.sin6_addr.s6_addr32[1] = 0;
584587
addr->v6.sin6_addr.s6_addr32[2] = htonl(0x0000ffff);

0 commit comments

Comments
 (0)