Module Name: src Committed By: riastradh Date: Tue Oct 8 02:28:43 UTC 2024
Modified Files: src/tests/net/if_wg: t_basic.sh Log Message: wg(4): Test truncated UDP input from the network. This triggers double-free in the IPv6 udp6_input path -- but, confusingly, not the IPv4 udp_input path, even though the overudp_cb interface ought to be the same: /* udp_input -- no further use of m if return is -1 */ if ((n = udp4_realinput(&src, &dst, &m, iphlen)) == -1) { UDP_STATINC(UDP_STAT_HDROPS); return; } /* udp6_input -- m_freem if return is not 0 */ if (udp6_realinput(AF_INET6, &src, &dst, &m, off) == 0) { ... } bad: m_freem(m); return IPPROTO_DONE; The subroutines udp4_realinput and udp6_realinput pass through the return value of overudp_cb in essentially the same way: /* udp4_realinput */ if (inp->inp_overudp_cb != NULL) { int ret; ret = inp->inp_overudp_cb(mp, off, inp->inp_socket, sintosa(src), inp->inp_overudp_arg); switch (ret) { case -1: /* Error, m was freed */ rcvcnt = -1; goto bad; ... bad: return rcvcnt; /* udp6_realinput */ if (inp->inp_overudp_cb != NULL) { int ret; ret = inp->inp_overudp_cb(mp, off, inp->inp_socket, sin6tosa(src), inp->inp_overudp_arg); switch (ret) { case -1: /* Error, m was freed */ rcvcnt = -1; goto bad; ... bad: return rcvcnt; PR kern/58688: userland panic of kernel via wg(4) To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/tests/net/if_wg/t_basic.sh Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/net/if_wg/t_basic.sh diff -u src/tests/net/if_wg/t_basic.sh:1.4 src/tests/net/if_wg/t_basic.sh:1.5 --- src/tests/net/if_wg/t_basic.sh:1.4 Tue Mar 2 07:16:24 2021 +++ src/tests/net/if_wg/t_basic.sh Tue Oct 8 02:28:43 2024 @@ -1,4 +1,4 @@ -# $NetBSD: t_basic.sh,v 1.4 2021/03/02 07:16:24 simonb Exp $ +# $NetBSD: t_basic.sh,v 1.5 2024/10/08 02:28:43 riastradh Exp $ # # Copyright (c) 2018 Ryota Ozaki <ozaki.ry...@gmail.com> # All rights reserved. @@ -48,6 +48,23 @@ check_ping_payload() done } +check_badudp() +{ + local proto=$1 + local ip=$2 + local port=51820 # XXX parametrize more clearly + + if [ $proto = inet ]; then + atf_check -o ignore -e ignore \ + $HIJACKING nc -4uv -w1 $ip $port </dev/null + else + atf_check -o ignore -e ignore \ + $HIJACKING nc -6uv -w1 $ip $port </dev/null + atf_expect_fail "PR kern/58688:" \ + " userland panic of kernel via wg(4)" + fi +} + test_common() { local type=$1 @@ -107,6 +124,9 @@ test_common() elif [ $type = payload ]; then export RUMP_SERVER=$SOCK_LOCAL check_ping_payload $inner_proto $ip_wg_peer + elif [ $type = badudp ]; then + export RUMP_SERVER=$SOCK_LOCAL + check_badudp $outer_proto $ip_peer fi destroy_wg_interfaces @@ -282,6 +302,36 @@ add_payload_sizes_test() atf_add_test_case ${name} } +add_badudp_test() +{ + local inner=$1 + local outer=$2 + local ipv4=inet + local ipv6=inet6 + + name="wg_badudp_${inner}_over_${outer}" + fulldesc="Test wg(4) with ${inner} over ${outer} with bad UDP packets" + + eval inner=\$$inner + eval outer=\$$outer + + atf_test_case ${name} cleanup + eval " + ${name}_head() { + atf_set descr \"${fulldesc}\" + atf_set require.progs rump_server wgconfig wg-keygen nc + } + ${name}_body() { + test_common badudp $outer $inner + rump_server_destroy_ifaces + } + ${name}_cleanup() { + \$DEBUG && dump + cleanup + }" + atf_add_test_case ${name} +} + atf_test_case wg_multiple_interfaces cleanup wg_multiple_interfaces_head() { @@ -459,6 +509,11 @@ wg_multiple_peers_cleanup() atf_init_test_cases() { + add_badudp_test ipv4 ipv4 + add_badudp_test ipv4 ipv6 + add_badudp_test ipv6 ipv4 + add_badudp_test ipv6 ipv6 + add_basic_test ipv4 ipv4 add_basic_test ipv4 ipv6 add_basic_test ipv6 ipv4