Author: kib
Date: Mon Jan 22 20:49:17 2018
New Revision: 328264
URL: https://svnweb.freebsd.org/changeset/base/328264

Log:
  Fix compat32 for sysctl net.PF_ROUTE...NET_RT_IFLISTL.
  
  Route messages are aligned to the host long type alignment, which
  breaks 32bit.
  
  Reported and tested by:       lwhsu
  Diagnosed by: Yuri Pankov <yur...@icloud.com>
  Sponsored by: The FreeBSD Foundation
  MFC after:    1 week

Modified:
  head/sys/net/rtsock.c

Modified: head/sys/net/rtsock.c
==============================================================================
--- head/sys/net/rtsock.c       Mon Jan 22 18:40:19 2018        (r328263)
+++ head/sys/net/rtsock.c       Mon Jan 22 20:49:17 2018        (r328264)
@@ -112,6 +112,12 @@ struct ifa_msghdrl32 {
        int32_t ifam_metric;
        struct  if_data ifam_data;
 };
+
+#define SA_SIZE32(sa)                                          \
+    (  (((struct sockaddr *)(sa))->sa_len == 0) ?              \
+       sizeof(int)             :                               \
+       1 + ( (((struct sockaddr *)(sa))->sa_len - 1) | (sizeof(int) - 1) ) )
+
 #endif /* COMPAT_FREEBSD32 */
 
 MALLOC_DEFINE(M_RTABLE, "routetbl", "routing tables");
@@ -1116,6 +1122,9 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo
        struct sockaddr_storage ss;
        struct sockaddr_in6 *sin6;
 #endif
+#ifdef COMPAT_FREEBSD32
+       bool compat32 = false;
+#endif
 
        switch (type) {
 
@@ -1123,9 +1132,10 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo
        case RTM_NEWADDR:
                if (w != NULL && w->w_op == NET_RT_IFLISTL) {
 #ifdef COMPAT_FREEBSD32
-                       if (w->w_req->flags & SCTL_MASK32)
+                       if (w->w_req->flags & SCTL_MASK32) {
                                len = sizeof(struct ifa_msghdrl32);
-                       else
+                               compat32 = true;
+                       } else
 #endif
                                len = sizeof(struct ifa_msghdrl);
                } else
@@ -1139,6 +1149,7 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo
                                len = sizeof(struct if_msghdrl32);
                        else
                                len = sizeof(struct if_msghdr32);
+                       compat32 = true;
                        break;
                }
 #endif
@@ -1169,7 +1180,12 @@ rtsock_msg_buffer(int type, struct rt_addrinfo *rtinfo
                if ((sa = rtinfo->rti_info[i]) == NULL)
                        continue;
                rtinfo->rti_addrs |= (1 << i);
-               dlen = SA_SIZE(sa);
+#ifdef COMPAT_FREEBSD32
+               if (compat32)
+                       dlen = SA_SIZE32(sa);
+               else
+#endif
+                       dlen = SA_SIZE(sa);
                if (cp != NULL && buflen >= dlen) {
 #ifdef INET6
                        if (V_deembed_scopeid && sa->sa_family == AF_INET6) {
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to