lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <166858661773.2154965.17789493627949980987.stgit@warthog.procyon.org.uk>
Date:   Wed, 16 Nov 2022 08:16:57 +0000
From:   David Howells <dhowells@...hat.com>
To:     netdev@...r.kernel.org
Cc:     dhowells@...hat.com, linux-afs@...ts.infradead.org,
        linux-kernel@...r.kernel.org
Subject: [PATCH net-next 3/3] rxrpc: Fix network address validation

Fix network address validation on entry to uapi functions such as connect()
for AF_RXRPC.  The check for address compatibility with the transport
socket isn't correct and allows an AF_INET6 address to be given to an
AF_INET socket, resulting in an oops now that rxrpc is calling
udp_sendmsg() directly.

Sample program:

	#define _GNU_SOURCE
	#include <stdio.h>
	#include <stdlib.h>
	#include <sys/socket.h>
	#include <arpa/inet.h>
	#include <linux/rxrpc.h>
	static unsigned char ctrl[256] =
		"\x18\x00\x00\x00\x00\x00\x00\x00\x10\x01\x00\x00\x01";
	int main(void)
	{
		struct sockaddr_rxrpc srx = {
			.srx_family			= AF_RXRPC,
			.transport_type			= SOCK_DGRAM,
			.transport_len			= 28,
			.transport.sin6.sin6_family	= AF_INET6,
		};
		struct mmsghdr vec = {
			.msg_hdr.msg_control	= ctrl,
			.msg_hdr.msg_controllen	= 0x18,
		};
		int s;
		s = socket(AF_RXRPC, SOCK_DGRAM, AF_INET);
		if (s < 0) {
			perror("socket");
			exit(1);
		}
		if (connect(s, (struct sockaddr *)&srx, sizeof(srx)) < 0) {
			perror("connect");
			exit(1);
		}
		if (sendmmsg(s, &vec, 1, MSG_NOSIGNAL | MSG_MORE) < 0) {
			perror("sendmmsg");
			exit(1);
		}
		return 0;
	}

If working properly, connect() should fail with EAFNOSUPPORT.

Fixes: ed472b0c8783 ("rxrpc: Call udp_sendmsg() directly")
Reported-by: Eric Dumazet <edumazet@...gle.com>
Signed-off-by: David Howells <dhowells@...hat.com>
cc: Marc Dionne <marc.dionne@...istor.com>
cc: linux-afs@...ts.infradead.org
---

 net/rxrpc/af_rxrpc.c |    9 +++++----
 1 file changed, 5 insertions(+), 4 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) +


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ