git: 3358df297325 - main - udp_input: remove a BSD stack relict

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Wed, 03 Nov 2021 17:45:28 UTC
The branch main has been updated by glebius:

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

commit 3358df2973251b4de690f197640eca5d794e0194
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2021-10-28 07:07:02 +0000
Commit:     Gleb Smirnoff <glebius@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);
 	}