From 1266a13d1ce3d5d61706f7278a4361ba8a5914f6 Mon Sep 17 00:00:00 2001 From: ozaki-r Date: Tue, 6 Nov 2018 04:27:41 +0000 Subject: [PATCH] Restore the length check of a sockaddr passed from userland at udp6_output A sockaddr with invalid length could be passed to the network stack resulting in a kernel panic like this: panic: sockaddr_copy: source too long, 28 < 128 bytes fatal breakpoint trap in supervisor mode trap type 1 code 0 rip 0xffffffff80216c35 cs 0x8 rflags 0x246 cr2 0x7f7ff7ef3000 ilevel 0x4 rsp 0xffff80003308b690 curlwp 0xfffffe803e11ca40 pid 48.1 lowest kstack 0xffff8000330852c0 Stopped in pid 48.1 (a.out) at netbsd:breakpoint+0x5: leave db{1}> bt breakpoint() at netbsd:breakpoint+0x5 vpanic() at netbsd:vpanic+0x140 panic() at netbsd:panic+0x3c sockaddr_copy() at netbsd:sockaddr_copy+0x95 rtcache_setdst() at netbsd:rtcache_setdst+0x73 rtcache_lookup2() at netbsd:rtcache_lookup2+0x56 in6_selectroute() at netbsd:in6_selectroute+0x184 in6_selectsrc() at netbsd:in6_selectsrc+0x119 udp6_output() at netbsd:udp6_output+0x25e udp6_send_wrapper() at netbsd:udp6_send_wrapper+0x8a sosend() at netbsd:sosend+0x7bf do_sys_sendmsg_so() at netbsd:do_sys_sendmsg_so+0x28e do_sys_sendmsg() at netbsd:do_sys_sendmsg+0x89 sys_sendto() at netbsd:sys_sendto+0x5c syscall() at netbsd:syscall+0x1ed --- syscall (number 133) --- 7f7ff790173a: Reported by Paul Ripke --- sys/netinet6/udp6_usrreq.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 04caf8bbe6e6..a5a7aee14122 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -1,4 +1,4 @@ -/* $NetBSD: udp6_usrreq.c,v 1.142 2018/11/04 08:48:01 mlelstv Exp $ */ +/* $NetBSD: udp6_usrreq.c,v 1.143 2018/11/06 04:27:41 ozaki-r Exp $ */ /* $KAME: udp6_usrreq.c,v 1.86 2001/05/27 17:33:00 itojun Exp $ */ /* $KAME: udp6_output.c,v 1.43 2001/10/15 09:19:52 itojun Exp $ */ @@ -63,7 +63,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.142 2018/11/04 08:48:01 mlelstv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.143 2018/11/06 04:27:41 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -668,6 +668,10 @@ udp6_output(struct in6pcb * const in6p, struct mbuf *m, if (addr6) { sin6 = addr6; + if (sin6->sin6_len != sizeof(*sin6)) { + error = EINVAL; + goto release; + } if (sin6->sin6_family != AF_INET6) { error = EAFNOSUPPORT; goto release;