Date: Tue, 12 May 2020 16:51:11 +0000 (UTC) From: Gordon Tetlow <gordon@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org Subject: svn commit: r360972 - in releng: 11.3/sys/netinet/libalias 11.4/sys/netinet/libalias 12.1/sys/netinet/libalias Message-ID: <202005121651.04CGpBXT059015@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gordon Date: Tue May 12 16:51:11 2020 New Revision: 360972 URL: https://svnweb.freebsd.org/changeset/base/360972 Log: Fix insufficient packet length validation in libalias. Approved by: so Approved by: re (implicit) Security: FreeBSD-SA-20:12.libalias Security: CVE-2020-7454 Modified: releng/11.3/sys/netinet/libalias/alias.c releng/11.4/sys/netinet/libalias/alias.c releng/12.1/sys/netinet/libalias/alias.c Modified: releng/11.3/sys/netinet/libalias/alias.c ============================================================================== --- releng/11.3/sys/netinet/libalias/alias.c Tue May 12 16:49:04 2020 (r360971) +++ releng/11.3/sys/netinet/libalias/alias.c Tue May 12 16:51:11 2020 (r360972) @@ -439,10 +439,15 @@ fragment contained in ICMP data section */ static int IcmpAliasIn(struct libalias *la, struct ip *pip) { - int iresult; struct icmp *ic; + int dlen, iresult; LIBALIAS_LOCK_ASSERT(la); + + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < ICMP_MINLEN) + return (PKT_ALIAS_IGNORED); + /* Return if proxy-only mode is enabled */ if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) return (PKT_ALIAS_OK); @@ -461,6 +466,9 @@ IcmpAliasIn(struct libalias *la, struct ip *pip) case ICMP_SOURCEQUENCH: case ICMP_TIMXCEED: case ICMP_PARAMPROB: + if (dlen < ICMP_ADVLENMIN || + dlen < ICMP_ADVLEN(ic)) + return (PKT_ALIAS_IGNORED); iresult = IcmpAliasIn2(la, pip); break; case ICMP_ECHO: @@ -729,10 +737,17 @@ UdpAliasIn(struct libalias *la, struct ip *pip) { struct udphdr *ud; struct alias_link *lnk; + int dlen; LIBALIAS_LOCK_ASSERT(la); + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < sizeof(struct udphdr)) + return (PKT_ALIAS_IGNORED); + ud = (struct udphdr *)ip_next(pip); + if (dlen < ntohs(ud->uh_ulen)) + return (PKT_ALIAS_IGNORED); lnk = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst, ud->uh_sport, ud->uh_dport, @@ -821,12 +836,19 @@ UdpAliasOut(struct libalias *la, struct ip *pip, int m u_short dest_port; u_short proxy_server_port; int proxy_type; - int error; + int dlen, error; LIBALIAS_LOCK_ASSERT(la); /* Return if proxy-only mode is enabled and not proxyrule found.*/ + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < sizeof(struct udphdr)) + return (PKT_ALIAS_IGNORED); + ud = (struct udphdr *)ip_next(pip); + if (dlen < ntohs(ud->uh_ulen)) + return (PKT_ALIAS_IGNORED); + proxy_type = ProxyCheck(la, &proxy_server_address, &proxy_server_port, pip->ip_src, pip->ip_dst, ud->uh_dport, pip->ip_p); @@ -919,8 +941,13 @@ TcpAliasIn(struct libalias *la, struct ip *pip) { struct tcphdr *tc; struct alias_link *lnk; + int dlen; LIBALIAS_LOCK_ASSERT(la); + + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < sizeof(struct tcphdr)) + return (PKT_ALIAS_IGNORED); tc = (struct tcphdr *)ip_next(pip); lnk = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst, @@ -1039,7 +1066,7 @@ TcpAliasIn(struct libalias *la, struct ip *pip) static int TcpAliasOut(struct libalias *la, struct ip *pip, int maxpacketsize, int create) { - int proxy_type, error; + int dlen, proxy_type, error; u_short dest_port; u_short proxy_server_port; struct in_addr dest_address; @@ -1048,6 +1075,10 @@ TcpAliasOut(struct libalias *la, struct ip *pip, int m struct alias_link *lnk; LIBALIAS_LOCK_ASSERT(la); + + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < sizeof(struct tcphdr)) + return (PKT_ALIAS_IGNORED); tc = (struct tcphdr *)ip_next(pip); if (create) Modified: releng/11.4/sys/netinet/libalias/alias.c ============================================================================== --- releng/11.4/sys/netinet/libalias/alias.c Tue May 12 16:49:04 2020 (r360971) +++ releng/11.4/sys/netinet/libalias/alias.c Tue May 12 16:51:11 2020 (r360972) @@ -439,10 +439,15 @@ fragment contained in ICMP data section */ static int IcmpAliasIn(struct libalias *la, struct ip *pip) { - int iresult; struct icmp *ic; + int dlen, iresult; LIBALIAS_LOCK_ASSERT(la); + + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < ICMP_MINLEN) + return (PKT_ALIAS_IGNORED); + /* Return if proxy-only mode is enabled */ if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) return (PKT_ALIAS_OK); @@ -461,6 +466,9 @@ IcmpAliasIn(struct libalias *la, struct ip *pip) case ICMP_SOURCEQUENCH: case ICMP_TIMXCEED: case ICMP_PARAMPROB: + if (dlen < ICMP_ADVLENMIN || + dlen < ICMP_ADVLEN(ic)) + return (PKT_ALIAS_IGNORED); iresult = IcmpAliasIn2(la, pip); break; case ICMP_ECHO: @@ -729,10 +737,17 @@ UdpAliasIn(struct libalias *la, struct ip *pip) { struct udphdr *ud; struct alias_link *lnk; + int dlen; LIBALIAS_LOCK_ASSERT(la); + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < sizeof(struct udphdr)) + return (PKT_ALIAS_IGNORED); + ud = (struct udphdr *)ip_next(pip); + if (dlen < ntohs(ud->uh_ulen)) + return (PKT_ALIAS_IGNORED); lnk = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst, ud->uh_sport, ud->uh_dport, @@ -821,12 +836,19 @@ UdpAliasOut(struct libalias *la, struct ip *pip, int m u_short dest_port; u_short proxy_server_port; int proxy_type; - int error; + int dlen, error; LIBALIAS_LOCK_ASSERT(la); /* Return if proxy-only mode is enabled and not proxyrule found.*/ + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < sizeof(struct udphdr)) + return (PKT_ALIAS_IGNORED); + ud = (struct udphdr *)ip_next(pip); + if (dlen < ntohs(ud->uh_ulen)) + return (PKT_ALIAS_IGNORED); + proxy_type = ProxyCheck(la, &proxy_server_address, &proxy_server_port, pip->ip_src, pip->ip_dst, ud->uh_dport, pip->ip_p); @@ -919,8 +941,13 @@ TcpAliasIn(struct libalias *la, struct ip *pip) { struct tcphdr *tc; struct alias_link *lnk; + int dlen; LIBALIAS_LOCK_ASSERT(la); + + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < sizeof(struct tcphdr)) + return (PKT_ALIAS_IGNORED); tc = (struct tcphdr *)ip_next(pip); lnk = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst, @@ -1039,7 +1066,7 @@ TcpAliasIn(struct libalias *la, struct ip *pip) static int TcpAliasOut(struct libalias *la, struct ip *pip, int maxpacketsize, int create) { - int proxy_type, error; + int dlen, proxy_type, error; u_short dest_port; u_short proxy_server_port; struct in_addr dest_address; @@ -1048,6 +1075,10 @@ TcpAliasOut(struct libalias *la, struct ip *pip, int m struct alias_link *lnk; LIBALIAS_LOCK_ASSERT(la); + + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < sizeof(struct tcphdr)) + return (PKT_ALIAS_IGNORED); tc = (struct tcphdr *)ip_next(pip); if (create) Modified: releng/12.1/sys/netinet/libalias/alias.c ============================================================================== --- releng/12.1/sys/netinet/libalias/alias.c Tue May 12 16:49:04 2020 (r360971) +++ releng/12.1/sys/netinet/libalias/alias.c Tue May 12 16:51:11 2020 (r360972) @@ -441,10 +441,15 @@ fragment contained in ICMP data section */ static int IcmpAliasIn(struct libalias *la, struct ip *pip) { - int iresult; struct icmp *ic; + int dlen, iresult; LIBALIAS_LOCK_ASSERT(la); + + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < ICMP_MINLEN) + return (PKT_ALIAS_IGNORED); + /* Return if proxy-only mode is enabled */ if (la->packetAliasMode & PKT_ALIAS_PROXY_ONLY) return (PKT_ALIAS_OK); @@ -463,6 +468,9 @@ IcmpAliasIn(struct libalias *la, struct ip *pip) case ICMP_SOURCEQUENCH: case ICMP_TIMXCEED: case ICMP_PARAMPROB: + if (dlen < ICMP_ADVLENMIN || + dlen < ICMP_ADVLEN(ic)) + return (PKT_ALIAS_IGNORED); iresult = IcmpAliasIn2(la, pip); break; case ICMP_ECHO: @@ -731,10 +739,17 @@ UdpAliasIn(struct libalias *la, struct ip *pip) { struct udphdr *ud; struct alias_link *lnk; + int dlen; LIBALIAS_LOCK_ASSERT(la); + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < sizeof(struct udphdr)) + return (PKT_ALIAS_IGNORED); + ud = (struct udphdr *)ip_next(pip); + if (dlen < ntohs(ud->uh_ulen)) + return (PKT_ALIAS_IGNORED); lnk = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst, ud->uh_sport, ud->uh_dport, @@ -823,12 +838,19 @@ UdpAliasOut(struct libalias *la, struct ip *pip, int m u_short dest_port; u_short proxy_server_port; int proxy_type; - int error; + int dlen, error; LIBALIAS_LOCK_ASSERT(la); /* Return if proxy-only mode is enabled and not proxyrule found.*/ + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < sizeof(struct udphdr)) + return (PKT_ALIAS_IGNORED); + ud = (struct udphdr *)ip_next(pip); + if (dlen < ntohs(ud->uh_ulen)) + return (PKT_ALIAS_IGNORED); + proxy_type = ProxyCheck(la, &proxy_server_address, &proxy_server_port, pip->ip_src, pip->ip_dst, ud->uh_dport, pip->ip_p); @@ -921,8 +943,13 @@ TcpAliasIn(struct libalias *la, struct ip *pip) { struct tcphdr *tc; struct alias_link *lnk; + int dlen; LIBALIAS_LOCK_ASSERT(la); + + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < sizeof(struct tcphdr)) + return (PKT_ALIAS_IGNORED); tc = (struct tcphdr *)ip_next(pip); lnk = FindUdpTcpIn(la, pip->ip_src, pip->ip_dst, @@ -1041,7 +1068,7 @@ TcpAliasIn(struct libalias *la, struct ip *pip) static int TcpAliasOut(struct libalias *la, struct ip *pip, int maxpacketsize, int create) { - int proxy_type, error; + int dlen, proxy_type, error; u_short dest_port; u_short proxy_server_port; struct in_addr dest_address; @@ -1050,6 +1077,10 @@ TcpAliasOut(struct libalias *la, struct ip *pip, int m struct alias_link *lnk; LIBALIAS_LOCK_ASSERT(la); + + dlen = ntohs(pip->ip_len) - (pip->ip_hl << 2); + if (dlen < sizeof(struct tcphdr)) + return (PKT_ALIAS_IGNORED); tc = (struct tcphdr *)ip_next(pip); if (create)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202005121651.04CGpBXT059015>