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@icloud.com> Sponsored by: The FreeBSD Foundation MFC after: 1 week
This commit is contained in:
parent
66655bdfc8
commit
027c7f4d66
@ -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 walkarg *w, int *
|
||||
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, struct walkarg *w, int *
|
||||
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, struct walkarg *w, int *
|
||||
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, struct walkarg *w, int *
|
||||
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user