Don't copy more than sa_len from the sockaddr to the sysctl / rt msg buffer.
authorclaudio <claudio@openbsd.org>
Mon, 27 Jun 2022 08:15:38 +0000 (08:15 +0000)
committerclaudio <claudio@openbsd.org>
Mon, 27 Jun 2022 08:15:38 +0000 (08:15 +0000)
In the rt msg buffer the size of the full buffer is calculated first then
filled out after allocating the mbuf. In the sysctl code this is not needed
since the buffer is already provided.
OK mvs@

sys/net/rtsock.c

index cebddf4..67971dd 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: rtsock.c,v 1.330 2022/06/26 16:07:00 claudio Exp $    */
+/*     $OpenBSD: rtsock.c,v 1.331 2022/06/27 08:15:38 claudio Exp $    */
 /*     $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $  */
 
 /*
@@ -1565,26 +1565,32 @@ rtm_msg1(int type, struct rt_addrinfo *rtinfo)
        switch (type) {
        case RTM_DELADDR:
        case RTM_NEWADDR:
-               len = sizeof(struct ifa_msghdr);
+               hlen = sizeof(struct ifa_msghdr);
                break;
        case RTM_IFINFO:
-               len = sizeof(struct if_msghdr);
+               hlen = sizeof(struct if_msghdr);
                break;
        case RTM_IFANNOUNCE:
-               len = sizeof(struct if_announcemsghdr);
+               hlen = sizeof(struct if_announcemsghdr);
                break;
 #ifdef BFD
        case RTM_BFD:
-               len = sizeof(struct bfd_msghdr);
+               hlen = sizeof(struct bfd_msghdr);
                break;
 #endif
        case RTM_80211INFO:
-               len = sizeof(struct if_ieee80211_msghdr);
+               hlen = sizeof(struct if_ieee80211_msghdr);
                break;
        default:
-               len = sizeof(struct rt_msghdr);
+               hlen = sizeof(struct rt_msghdr);
                break;
        }
+       len = hlen;
+       for (i = 0; i < RTAX_MAX; i++) {
+               if (rtinfo == NULL || (sa = rtinfo->rti_info[i]) == NULL)
+                       continue;
+               len += ROUNDUP(sa->sa_len);
+       }
        if (len > MCLBYTES)
                panic("rtm_msg1");
        m = m_gethdr(M_DONTWAIT, MT_DATA);
@@ -1597,16 +1603,17 @@ rtm_msg1(int type, struct rt_addrinfo *rtinfo)
        }
        if (m == NULL)
                return (m);
-       m->m_pkthdr.len = m->m_len = hlen = len;
+       m->m_pkthdr.len = m->m_len = len;
        m->m_pkthdr.ph_ifidx = 0;
        rtm = mtod(m, struct rt_msghdr *);
        bzero(rtm, len);
+       len = hlen;
        for (i = 0; i < RTAX_MAX; i++) {
                if (rtinfo == NULL || (sa = rtinfo->rti_info[i]) == NULL)
                        continue;
                rtinfo->rti_addrs |= (1U << i);
                dlen = ROUNDUP(sa->sa_len);
-               if (m_copyback(m, len, dlen, sa, M_NOWAIT)) {
+               if (m_copyback(m, len, sa->sa_len, sa, M_NOWAIT)) {
                        m_freem(m);
                        return (NULL);
                }
@@ -1652,7 +1659,8 @@ again:
                rtinfo->rti_addrs |= (1U << i);
                dlen = ROUNDUP(sa->sa_len);
                if (cp) {
-                       bcopy(sa, cp, (size_t)dlen);
+                       bcopy(sa, cp, sa->sa_len);
+                       bzero(cp + sa->sa_len, dlen - sa->sa_len);
                        cp += dlen;
                }
                len += dlen;