git: 3358df297325 - main - udp_input: remove a BSD stack relict
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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);
}