Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net route(4): dst addr could be in a different mbuf for ...



details:   https://anonhg.NetBSD.org/src/rev/751c32e3c8c8
branches:  trunk
changeset: 1007191:751c32e3c8c8
user:      roy <roy%NetBSD.org@localhost>
date:      Sun Feb 09 21:15:03 2020 +0000

description:
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.

diffstat:

 sys/net/rtsock_shared.c |  21 +++++++++++++++++----
 1 files changed, 17 insertions(+), 4 deletions(-)

diffs (45 lines):

diff -r 12ad9e5dfc82 -r 751c32e3c8c8 sys/net/rtsock_shared.c
--- a/sys/net/rtsock_shared.c   Sun Feb 09 16:06:17 2020 +0000
+++ b/sys/net/rtsock_shared.c   Sun Feb 09 21:15:03 2020 +0000
@@ -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 @@
                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 &&



Home | Main Index | Thread Index | Old Index