Module Name:    src
Committed By:   riastradh
Date:           Thu Aug 27 02:52:34 UTC 2020

Modified Files:
        src/sys/net: if_wg.c
        src/tests/net/if_wg: t_misc.sh

Log Message:
wg: Check mbuf chain length before m_copydata.


To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sys/net/if_wg.c
cvs rdiff -u -r1.2 -r1.3 src/tests/net/if_wg/t_misc.sh

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/net/if_wg.c
diff -u src/sys/net/if_wg.c:1.24 src/sys/net/if_wg.c:1.25
--- src/sys/net/if_wg.c:1.24	Wed Aug 26 16:03:41 2020
+++ src/sys/net/if_wg.c	Thu Aug 27 02:52:33 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_wg.c,v 1.24 2020/08/26 16:03:41 riastradh Exp $	*/
+/*	$NetBSD: if_wg.c,v 1.25 2020/08/27 02:52:33 riastradh Exp $	*/
 
 /*
  * Copyright (C) Ryota Ozaki <ozaki.ry...@gmail.com>
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.24 2020/08/26 16:03:41 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_wg.c,v 1.25 2020/08/27 02:52:33 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -2915,9 +2915,25 @@ wg_overudp_cb(struct mbuf **mp, int offs
 
 	WG_TRACE("enter");
 
+	/* Verify the mbuf chain is long enough to have a wg msg header.  */
+	KASSERT(offset <= m_length(m));
+	if (__predict_false(m_length(m) - offset < sizeof(struct wg_msg))) {
+		m_freem(m);
+		return -1;
+	}
+
+	/*
+	 * Copy the message header (32-bit message type) out -- we'll
+	 * worry about contiguity and alignment later.
+	 */
 	m_copydata(m, offset, sizeof(struct wg_msg), &wgm);
 	WG_DLOG("type=%d\n", wgm.wgm_type);
 
+	/*
+	 * Handle DATA packets promptly as they arrive.  Other packets
+	 * may require expensive public-key crypto and are not as
+	 * sensitive to latency, so defer them to the worker thread.
+	 */
 	switch (wgm.wgm_type) {
 	case WG_MSG_TYPE_DATA:
 		m_adj(m, offset);

Index: src/tests/net/if_wg/t_misc.sh
diff -u src/tests/net/if_wg/t_misc.sh:1.2 src/tests/net/if_wg/t_misc.sh:1.3
--- src/tests/net/if_wg/t_misc.sh:1.2	Thu Aug 27 02:51:49 2020
+++ src/tests/net/if_wg/t_misc.sh	Thu Aug 27 02:52:33 2020
@@ -1,4 +1,4 @@
-#	$NetBSD: t_misc.sh,v 1.2 2020/08/27 02:51:49 riastradh Exp $
+#	$NetBSD: t_misc.sh,v 1.3 2020/08/27 02:52:33 riastradh Exp $
 #
 # Copyright (c) 2018 Ryota Ozaki <ozaki.ry...@gmail.com>
 # All rights reserved.
@@ -588,6 +588,78 @@ wg_psk_cleanup()
 	cleanup
 }
 
+atf_test_case wg_malformed cleanup
+wg_malformed_head()
+{
+
+	atf_set "descr" "tests malformed packet headers"
+	atf_set "require.progs" "nc" "rump_server" "wgconfig" "wg-keygen"
+	atf_set "timeout" "10"
+}
+
+wg_malformed_body()
+{
+	local ifconfig="atf_check -s exit:0 rump.ifconfig"
+	local ping="atf_check -s exit:0 -o ignore rump.ping -n -c 1 -w 1"
+	local ip_local=192.168.1.1
+	local ip_peer=192.168.1.2
+	local ip_wg_local=10.0.0.1
+	local ip_wg_peer=10.0.0.2
+	local port=51820
+	setup_servers
+
+	# It sets key_priv_local key_pub_local key_priv_peer key_pub_peer
+	generate_keys
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	setup_common shmif0 inet $ip_local 24
+	setup_wg_common wg0 inet $ip_wg_local 24 $port "$key_priv_local"
+
+	export RUMP_SERVER=$SOCK_PEER
+	setup_common shmif0 inet $ip_peer 24
+	setup_wg_common wg0 inet $ip_wg_peer 24 $port "$key_priv_peer"
+
+	export RUMP_SERVER=$SOCK_LOCAL
+	add_peer wg0 peer0 $key_pub_peer $ip_peer:$port $ip_wg_peer/32
+
+	export RUMP_SERVER=$SOCK_PEER
+	add_peer wg0 peer0 $key_pub_local $ip_local:$port $ip_wg_local/32
+
+	export RUMP_SERVER=$SOCK_LOCAL
+
+	$ping $ip_wg_peer
+
+	printf 'send malformed packets\n'
+
+	$HIJACKING ping -c 1 -n $ip_peer
+
+	printf 'x' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+	printf 'xy' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+	printf 'xyz' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+	printf 'xyzw' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+	printf '\x00\x00\x00\x00' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+	printf '\x00\x00\x00\x00z' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+	printf '\x01\x00\x00\x00' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+	printf '\x01\x00\x00\x00z' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+	printf '\x02\x00\x00\x00' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+	printf '\x02\x00\x00\x00z' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+	printf '\x03\x00\x00\x00' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+	printf '\x03\x00\x00\x00z' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+	printf '\x04\x00\x00\x00' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+	printf '\x04\x00\x00\x00z' | $HIJACKING nc -Nu -w 0 $ip_peer $port
+
+	printf 'done sending malformed packets\n'
+
+	$ping $ip_wg_peer
+}
+
+wg_malformed_cleanup()
+{
+
+	$DEBUG && dump
+	cleanup
+}
+
 atf_init_test_cases()
 {
 
@@ -597,4 +669,5 @@ atf_init_test_cases()
 	atf_add_test_case wg_mobility
 	atf_add_test_case wg_keepalive
 	atf_add_test_case wg_psk
+	atf_add_test_case wg_malformed
 }

Reply via email to