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); }