Module Name:    src
Committed By:   roy
Date:           Sun Feb  9 21:15:04 UTC 2020

Modified Files:
        src/sys/net: rtsock_shared.c

Log Message:
route(4): dst addr could be in a different mbuf for RO_MISSFILTER

While here, the correct assertation is RTAX_DST == 0.
RTA_DST is just a flag.


To generate a diff of this commit:
cvs rdiff -u -r1.13 -r1.14 src/sys/net/rtsock_shared.c

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/rtsock_shared.c
diff -u src/sys/net/rtsock_shared.c:1.13 src/sys/net/rtsock_shared.c:1.14
--- src/sys/net/rtsock_shared.c:1.13	Sat Feb  8 14:17:30 2020
+++ src/sys/net/rtsock_shared.c	Sun Feb  9 21:15:03 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtsock_shared.c,v 1.13 2020/02/08 14:17:30 roy Exp $	*/
+/*	$NetBSD: rtsock_shared.c,v 1.14 2020/02/09 21:15:03 roy Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtsock_shared.c,v 1.13 2020/02/08 14:17:30 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtsock_shared.c,v 1.14 2020/02/09 21:15:03 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -237,11 +237,24 @@ COMPATNAME(route_filter)(struct mbuf *m,
 		return EEXIST;
 
 	if (rop->rocb_missfilterlen != 0 && rtm->rtm_type == RTM_MISS) {
-		__CTASSERT(RTA_DST == 1);
-		struct sockaddr *sa, *dst = (struct sockaddr *)(rtm + 1);
+		__CTASSERT(RTAX_DST == 0);
+		struct sockaddr_storage ss;
+		struct sockaddr *dst = (struct sockaddr *)&ss, *sa;
 		char *cp = rop->rocb_missfilter;
 		char *ep = cp + rop->rocb_missfilterlen;
 
+		/* Ensure we can access sa_len */
+		if (m->m_pkthdr.len < sizeof(*rtm) +
+		    offsetof(struct sockaddr, sa_len) + sizeof(ss.ss_len))
+			return EINVAL;
+		m_copydata(m, sizeof(*rtm) + offsetof(struct sockaddr, sa_len),
+		    sizeof(ss.ss_len), &ss);
+		if (m->m_pkthdr.len < sizeof(*rtm) + ss.ss_len)
+			return EINVAL;
+		/* Copy out the destination sockaddr */
+		m_copydata(m, sizeof(*rtm), ss.ss_len, &ss);
+
+		/* Find a matching sockaddr in the filter */
 		while (cp < ep) {
 			sa = (struct sockaddr *)cp;
 			if (sa->sa_len == dst->sa_len &&

Reply via email to