Commit 8cf4f8c7 authored by David S. Miller's avatar David S. Miller
Browse files
David Howells says:

====================
rxrpc: Fix oops and missing config conditionals

The patches that were pulled into net-next previously[1] had some issues
that this patchset fixes:

 (1) Fix missing IPV6 config conditionals.

 (2) Fix an oops caused by calling udpv6_sendmsg() directly on an AF_INET
     socket.

 (3) Fix the validation of network addresses on entry to socket functions
     so that we don't allow an AF_INET6 address if we've selected an
     AF_INET transport socket.

Link: https://lore.kernel.org/r/166794587113.2389296.16484814996876530222.stgit@warthog.procyon.org.uk/

 [1]
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents fd896e38 66f6fd27
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -93,12 +93,11 @@ static int rxrpc_validate_address(struct rxrpc_sock *rx,
	    srx->transport_len > len)
		return -EINVAL;

	if (srx->transport.family != rx->family &&
	    srx->transport.family == AF_INET && rx->family != AF_INET6)
		return -EAFNOSUPPORT;

	switch (srx->transport.family) {
	case AF_INET:
		if (rx->family != AF_INET &&
		    rx->family != AF_INET6)
			return -EAFNOSUPPORT;
		if (srx->transport_len < sizeof(struct sockaddr_in))
			return -EINVAL;
		tail = offsetof(struct sockaddr_rxrpc, transport.sin.__pad);
@@ -106,6 +105,8 @@ static int rxrpc_validate_address(struct rxrpc_sock *rx,

#ifdef CONFIG_AF_RXRPC_IPV6
	case AF_INET6:
		if (rx->family != AF_INET6)
			return -EAFNOSUPPORT;
		if (srx->transport_len < sizeof(struct sockaddr_in6))
			return -EINVAL;
		tail = offsetof(struct sockaddr_rxrpc, transport) +
+2 −1
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ static void rxrpc_encap_err_rcv(struct sock *sk, struct sk_buff *skb, int err,
{
	if (ip_hdr(skb)->version == IPVERSION)
		return ip_icmp_error(sk, skb, err, port, info, payload);
	if (IS_ENABLED(CONFIG_AF_RXRPC_IPV6))
		return ipv6_icmp_error(sk, skb, err, port, info, payload);
}

+12 −6
Original line number Diff line number Diff line
@@ -18,15 +18,21 @@

extern int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len);

static ssize_t do_udp_sendmsg(struct socket *sk, struct msghdr *msg, size_t len)
static ssize_t do_udp_sendmsg(struct socket *socket, struct msghdr *msg, size_t len)
{
#if IS_ENABLED(CONFIG_AF_RXRPC_IPV6)
	struct sockaddr *sa = msg->msg_name;
	struct sock *sk = socket->sk;

	if (sa->sa_family == AF_INET6)
		return udpv6_sendmsg(sk->sk, msg, len);
#endif
	return udp_sendmsg(sk->sk, msg, len);
	if (IS_ENABLED(CONFIG_AF_RXRPC_IPV6)) {
		if (sa->sa_family == AF_INET6) {
			if (sk->sk_family != AF_INET6) {
				pr_warn("AF_INET6 address on AF_INET socket\n");
				return -ENOPROTOOPT;
			}
			return udpv6_sendmsg(sk, msg, len);
		}
	}
	return udp_sendmsg(sk, msg, len);
}

struct rxrpc_abort_buffer {