The branch main has been updated by glebius:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=3358df2973251b4de690f197640eca5d794e0194

commit 3358df2973251b4de690f197640eca5d794e0194
Author:     Gleb Smirnoff <gleb...@freebsd.org>
AuthorDate: 2021-10-28 07:07:02 +0000
Commit:     Gleb Smirnoff <gleb...@freebsd.org>
CommitDate: 2021-11-03 17:39:34 +0000

    udp_input: remove a BSD stack relict
    
    I should had removed it 9 years ago in 8ad458a471ca.  That commit
    left save_ip as a write-only variable.
    
    With save_ip removed we got one case when IP header can be modified:
    the calculation of IP checksum with zeroed out header.  This place
    already has had a header saver char b[9].  However, the b[9] saver
    didn't cover the ip_sum field, which we explicitly overwrite aliased
    as (struct ipovly *)->ih_len.  This was fine in cb34210012d4e, since
    checksum doesn't need to be restored if packet is consumed.  Now we
    need to extend up to ip_sum field.
    
    In collaboration with:  ae
    Differential revision:  https://reviews.freebsd.org/D32719
---
 sys/netinet/udp_usrreq.c | 22 ++++++----------------
 1 file changed, 6 insertions(+), 16 deletions(-)

diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 46d687690713..7c5a642da040 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -398,7 +398,6 @@ udp_input(struct mbuf **mp, int *offp, int proto)
        struct inpcb *inp;
        uint16_t len, ip_len;
        struct inpcbinfo *pcbinfo;
-       struct ip save_ip;
        struct sockaddr_in udp_in[2];
        struct mbuf *m;
        struct m_tag *fwd_tag;
@@ -474,15 +473,6 @@ udp_input(struct mbuf **mp, int *offp, int proto)
                        m_adj(m, len - ip_len);
        }
 
-       /*
-        * Save a copy of the IP header in case we want restore it for
-        * sending an ICMP error message in response.
-        */
-       if (!V_udp_blackhole)
-               save_ip = *ip;
-       else
-               memset(&save_ip, 0, sizeof(save_ip));
-
        /*
         * Checksum extended UDP header and data.
         */
@@ -499,14 +489,15 @@ udp_input(struct mbuf **mp, int *offp, int proto)
                                    m->m_pkthdr.csum_data + proto));
                        uh_sum ^= 0xffff;
                } else {
-                       char b[9];
+                       char b[offsetof(struct ipovly, ih_src)];
+                       struct ipovly *ipov = (struct ipovly *)ip;
 
-                       bcopy(((struct ipovly *)ip)->ih_x1, b, 9);
-                       bzero(((struct ipovly *)ip)->ih_x1, 9);
-                       ((struct ipovly *)ip)->ih_len = (proto == IPPROTO_UDP) ?
+                       bcopy(ipov, b, sizeof(b));
+                       bzero(ipov, sizeof(ipov->ih_x1));
+                       ipov->ih_len = (proto == IPPROTO_UDP) ?
                            uh->uh_ulen : htons(ip_len);
                        uh_sum = in_cksum(m, len + sizeof (struct ip));
-                       bcopy(b, ((struct ipovly *)ip)->ih_x1, 9);
+                       bcopy(b, ipov, sizeof(b));
                }
                if (uh_sum) {
                        UDPSTAT_INC(udps_badsum);
@@ -714,7 +705,6 @@ udp_input(struct mbuf **mp, int *offp, int proto)
                        goto badunlocked;
                if (badport_bandlim(BANDLIM_ICMP_UNREACH) < 0)
                        goto badunlocked;
-               *ip = save_ip;
                icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);
                return (IPPROTO_DONE);
        }

Reply via email to