summaryrefslogtreecommitdiff
path: root/net/rxrpc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2022-11-18 12:09:20 +0000
committerDavid S. Miller <davem@davemloft.net>2022-11-18 12:09:20 +0000
commit8cf4f8c7d99addb6c2c2273fac7c20ca7c50db45 (patch)
tree99dbd72ee730c75e9ebfba6ae5b61aaf8f233b63 /net/rxrpc
parentfd896e38e5df2c5b68c78eee2fc425c4dcd3b4dd (diff)
parent66f6fd278c6780ea8c8bb7dac839132d8e76dd53 (diff)
Merge tag 'rxrpc-next-20221116' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
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: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/rxrpc')
-rw-r--r--net/rxrpc/af_rxrpc.c9
-rw-r--r--net/rxrpc/local_object.c3
-rw-r--r--net/rxrpc/output.c18
3 files changed, 19 insertions, 11 deletions
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index 2f3991cf8715..aacdd96a9886 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -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) +
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index a178f71e5082..a943fdf91e24 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -33,7 +33,8 @@ 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);
- return ipv6_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);
}
/*
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c
index 04f945e042ab..c5eed0e83e47 100644
--- a/net/rxrpc/output.c
+++ b/net/rxrpc/output.c
@@ -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 {