netinet: Disallow unspecified addresses in ICMP-embedded packets

Reported by:	glebius
Reported by:	syzbot+981c528ccb5c5534dffc@syzkaller.appspotmail.com
Reviewed by:	tuexen, glebius
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D38936
This commit is contained in:
Mark Johnston 2023-03-13 10:45:56 -04:00
parent 29c9b16733
commit aa71d6b4a2
2 changed files with 10 additions and 1 deletions

View File

@ -561,7 +561,8 @@ icmp_input(struct mbuf **mp, int *offp, int proto)
if (IN_MULTICAST(ntohl(icp->icmp_ip.ip_dst.s_addr))) if (IN_MULTICAST(ntohl(icp->icmp_ip.ip_dst.s_addr)))
goto badcode; goto badcode;
/* Filter out responses to INADDR_ANY, protocols ignore it. */ /* Filter out responses to INADDR_ANY, protocols ignore it. */
if (icp->icmp_ip.ip_dst.s_addr == INADDR_ANY) if (icp->icmp_ip.ip_dst.s_addr == INADDR_ANY ||
icp->icmp_ip.ip_src.s_addr == INADDR_ANY)
goto freeit; goto freeit;
#ifdef ICMPPRINTFS #ifdef ICMPPRINTFS
if (icmpprintfs) if (icmpprintfs)

View File

@ -1070,6 +1070,14 @@ icmp6_notify_error(struct mbuf **mp, int off, int icmp6len)
*/ */
eip6 = (struct ip6_hdr *)(icmp6 + 1); eip6 = (struct ip6_hdr *)(icmp6 + 1);
/*
* Protocol layers can't do anything useful with unspecified
* addresses.
*/
if (IN6_IS_ADDR_UNSPECIFIED(&eip6->ip6_src) ||
IN6_IS_ADDR_UNSPECIFIED(&eip6->ip6_dst))
goto freeit;
icmp6dst.sin6_len = sizeof(struct sockaddr_in6); icmp6dst.sin6_len = sizeof(struct sockaddr_in6);
icmp6dst.sin6_family = AF_INET6; icmp6dst.sin6_family = AF_INET6;
if (IN6_IS_ADDR_UNSPECIFIED(&icmp6dst.sin6_addr)) if (IN6_IS_ADDR_UNSPECIFIED(&icmp6dst.sin6_addr))