svn commit: r328264 - head/sys/net

Konstantin Belousov kib at FreeBSD.org
Mon Jan 22 20:49:19 UTC 2018


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 <yuripv at 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) {


More information about the svn-src-head mailing list