Source-Changes-HG archive

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

[src/netbsd-8]: src/sys Pull up following revision(s) (requested by ozaki-r i...



details:   https://anonhg.NetBSD.org/src/rev/d369cd69a443
branches:  netbsd-8
changeset: 850868:d369cd69a443
user:      snj <snj%NetBSD.org@localhost>
date:      Tue Jul 25 01:55:21 2017 +0000

description:
Pull up following revision(s) (requested by ozaki-r in ticket #140):
        sys/kern/uipc_domain.c: 1.97-1.99
        sys/net/rtsock.c: 1.225-1.227
        sys/sys/socket.h: 1.123
Restore the original length of a sockaddr for netmask
route(8) passes a sockaddr for netmask that is truncated with its
prefixlen. However the kernel basically doesn't expect such format
and may read beyond the data. So restore the original length of the
the data at the beginning of the kernel for the rest components.
Failures of ATF tests such as route_flags_blackhole6 should
be fixed.
--
Avoid DIAGNOSTIC warning with previous fix and simplify it (don't require
memory alloc/free).
--
put the code that returns the sizeof the socket by family in one place.
--
don't warn about AF_LINK sockets with sa_len less than the size of the sockaddr
--
don't print diagnostic for AF_LINK

diffstat:

 sys/kern/uipc_domain.c |  70 +++++++++++++++++++++++++------------------------
 sys/net/rtsock.c       |  24 +++++++++++++++-
 sys/sys/socket.h       |   5 ++-
 3 files changed, 61 insertions(+), 38 deletions(-)

diffs (181 lines):

diff -r a381d4aee005 -r d369cd69a443 sys/kern/uipc_domain.c
--- a/sys/kern/uipc_domain.c    Tue Jul 25 01:49:13 2017 +0000
+++ b/sys/kern/uipc_domain.c    Tue Jul 25 01:55:21 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uipc_domain.c,v 1.96 2014/12/02 19:45:58 christos Exp $        */
+/*     $NetBSD: uipc_domain.c,v 1.96.10.1 2017/07/25 01:55:21 snj Exp $        */
 
 /*
  * Copyright (c) 1982, 1986, 1993
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_domain.c,v 1.96 2014/12/02 19:45:58 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_domain.c,v 1.96.10.1 2017/07/25 01:55:21 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/socket.h>
@@ -228,7 +228,7 @@
 }
 
 const struct sockaddr *
-sockaddr_any_by_family(int family)
+sockaddr_any_by_family(sa_family_t family)
 {
        const struct domain *dom;
 
@@ -255,42 +255,44 @@
        return sockaddr_const_addr(any, slenp);
 }
 
+socklen_t
+sockaddr_getsize_by_family(sa_family_t af)
+{
+       switch (af) {
+       case AF_INET:
+               return sizeof(struct sockaddr_in);
+       case AF_INET6:
+               return sizeof(struct sockaddr_in6);
+       case AF_UNIX:
+               return sizeof(struct sockaddr_un);
+       case AF_LINK:
+               return sizeof(struct sockaddr_dl);
+       case AF_APPLETALK:
+               return sizeof(struct sockaddr_at);
+       default:
+#ifdef DIAGNOSTIC
+               printf("%s: Unhandled address family=%hhu\n", __func__, af);
+#endif
+               return 0;
+       }
+}
+
 #ifdef DIAGNOSTIC
 static void
 sockaddr_checklen(const struct sockaddr *sa)
 {
-       socklen_t len = 0;
-       switch (sa->sa_family) {
-       case AF_INET:
-               len = sizeof(struct sockaddr_in);
-               break;
-       case AF_INET6:
-               len = sizeof(struct sockaddr_in6);
-               break;
-       case AF_UNIX:
-               len = sizeof(struct sockaddr_un);
-               break;
-       case AF_LINK:
-               len = sizeof(struct sockaddr_dl);
-               // As long as it is not 0...
-               if (sa->sa_len != 0)
-                       return;
-               break;
-       case AF_APPLETALK:
-               len = sizeof(struct sockaddr_at);
-               break;
-       default:
-               printf("%s: Unhandled af=%hhu socklen=%hhu\n", __func__,
-                   sa->sa_family, sa->sa_len);
+       // Can't tell how much was allocated, if it was allocated.
+       if (sa->sa_family == AF_LINK)
                return;
-       }
-       if (len != sa->sa_len) {
-               char buf[512];
-               sockaddr_format(sa, buf, sizeof(buf));
-               printf("%s: %p bad len af=%hhu socklen=%hhu len=%u [%s]\n",
-                   __func__, sa, sa->sa_family, sa->sa_len,
-                   (unsigned)len, buf);
-       }
+
+       socklen_t len = sockaddr_getsize_by_family(sa->sa_family);
+       if (len == 0 || len == sa->sa_len)
+               return;
+
+       char buf[512];
+       sockaddr_format(sa, buf, sizeof(buf));
+       printf("%s: %p bad len af=%hhu socklen=%hhu len=%u [%s]\n",
+           __func__, sa, sa->sa_family, sa->sa_len, (unsigned)len, buf);
 }
 #else
 #define sockaddr_checklen(sa) ((void)0)
diff -r a381d4aee005 -r d369cd69a443 sys/net/rtsock.c
--- a/sys/net/rtsock.c  Tue Jul 25 01:49:13 2017 +0000
+++ b/sys/net/rtsock.c  Tue Jul 25 01:55:21 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: rtsock.c,v 1.213.2.1 2017/07/07 13:57:26 martin Exp $  */
+/*     $NetBSD: rtsock.c,v 1.213.2.2 2017/07/25 01:55:21 snj Exp $     */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.213.2.1 2017/07/07 13:57:26 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.213.2.2 2017/07/25 01:55:21 snj Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -736,6 +736,7 @@
        struct sockaddr_dl sdl;
        int bound = curlwp_bind();
        bool do_rt_free = false;
+       struct sockaddr_storage netmask;
 
 #define senderr(e) do { error = e; goto flush;} while (/*CONSTCOND*/ 0)
        if (m == NULL || ((m->m_len < sizeof(int32_t)) &&
@@ -793,6 +794,25 @@
            0, rtm, NULL, NULL) != 0)
                senderr(EACCES);
 
+       /*
+        * route(8) passes a sockaddr truncated with prefixlen.
+        * The kernel doesn't expect such sockaddr and need to 
+        * use a buffer that is big enough for the sockaddr expected
+        * (padded with 0's). We keep the original length of the sockaddr.
+        */
+       if (info.rti_info[RTAX_NETMASK]) {
+               socklen_t sa_len = sockaddr_getsize_by_family(
+                   info.rti_info[RTAX_NETMASK]->sa_family);
+               socklen_t masklen = sockaddr_getlen(
+                   info.rti_info[RTAX_NETMASK]);
+               if (sa_len != 0 && sa_len > masklen) {
+                       KASSERT(sa_len <= sizeof(netmask));
+                       memcpy(&netmask, info.rti_info[RTAX_NETMASK], masklen);
+                       memset((char *)&netmask + masklen, 0, sa_len - masklen);
+                       info.rti_info[RTAX_NETMASK] = sstocsa(&netmask);
+               }
+       }
+
        switch (rtm->rtm_type) {
 
        case RTM_ADD:
diff -r a381d4aee005 -r d369cd69a443 sys/sys/socket.h
--- a/sys/sys/socket.h  Tue Jul 25 01:49:13 2017 +0000
+++ b/sys/sys/socket.h  Tue Jul 25 01:55:21 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: socket.h,v 1.122 2017/05/27 21:02:56 bouyer Exp $      */
+/*     $NetBSD: socket.h,v 1.122.2.1 2017/07/25 01:55:21 snj Exp $     */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -625,6 +625,7 @@
 }
 
 __BEGIN_DECLS
+socklen_t sockaddr_getsize_by_family(sa_family_t);
 struct sockaddr *sockaddr_copy(struct sockaddr *, socklen_t,
     const struct sockaddr *);
 struct sockaddr *sockaddr_externalize(struct sockaddr *, socklen_t,
@@ -633,7 +634,7 @@
 const void *sockaddr_const_addr(const struct sockaddr *, socklen_t *);
 void *sockaddr_addr(struct sockaddr *, socklen_t *);
 const struct sockaddr *sockaddr_any(const struct sockaddr *);
-const struct sockaddr *sockaddr_any_by_family(int);
+const struct sockaddr *sockaddr_any_by_family(sa_family_t);
 const void *sockaddr_anyaddr(const struct sockaddr *, socklen_t *);
 int sockaddr_cmp(const struct sockaddr *, const struct sockaddr *);
 struct sockaddr *sockaddr_dup(const struct sockaddr *, int);



Home | Main Index | Thread Index | Old Index