Source-Changes-HG archive

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

[src/trunk]: src/sys/net Ensure sockaddrs have valid lengths for RO_MISSFILTER.



details:   https://anonhg.NetBSD.org/src/rev/d5e528b87c01
branches:  trunk
changeset: 935084:d5e528b87c01
user:      roy <roy%NetBSD.org@localhost>
date:      Wed Jun 24 12:27:51 2020 +0000

description:
Ensure sockaddrs have valid lengths for RO_MISSFILTER.

Thanks to maxv@ for spotting this.

diffstat:

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

diffs (55 lines):

diff -r 2904187c94fc -r d5e528b87c01 sys/net/rtsock_shared.c
--- a/sys/net/rtsock_shared.c   Wed Jun 24 10:30:43 2020 +0000
+++ b/sys/net/rtsock_shared.c   Wed Jun 24 12:27:51 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtsock_shared.c,v 1.17 2020/03/13 16:37:12 christos Exp $      */
+/*     $NetBSD: rtsock_shared.c,v 1.18 2020/06/24 12:27:51 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.17 2020/03/13 16:37:12 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtsock_shared.c,v 1.18 2020/06/24 12:27:51 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -96,6 +96,9 @@
 #include <compat/net/if.h>
 #include <compat/net/route.h>
 
+#define _SA_MINSIZE    (offsetof(struct sockaddr, sa_len) + \
+                        sizeof(((struct sockaddr *)0)->sa_len))
+
 #ifdef COMPAT_RTSOCK
 /*
  * These are used when #include-d from compat/common/rtsock_50.c
@@ -244,12 +247,13 @@
                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))
+               if (m->m_pkthdr.len < sizeof(*rtm) + _SA_MINSIZE)
                        return EINVAL;
                m_copydata(m, sizeof(*rtm) + offsetof(struct sockaddr, sa_len),
                    sizeof(ss.ss_len), &ss.ss_len);
-               if (m->m_pkthdr.len < sizeof(*rtm) + ss.ss_len)
+               if (ss.ss_len < _SA_MINSIZE ||
+                   ss.ss_len > sizeof(ss) ||
+                   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);
@@ -1059,6 +1063,9 @@
                                        break;
                                }
                                sa = (struct sockaddr *)cp;
+                               if (sa->sa_len < _SA_MINSIZE ||
+                                   sa->sa_len >sizeof(struct sockaddr_storage))
+                                       return EINVAL;
                                cp += RT_XROUNDUP(sa->sa_len);
                        }
                        if (cp != ep) {



Home | Main Index | Thread Index | Old Index