Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 12 May 2020 16:49:04 +0000 (UTC)
From:      Ed Maste <emaste@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r360971 - in stable: 11/sys/netinet/libalias 12/sys/netinet/libalias
Message-ID:  <202005121649.04CGn4OM057900@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: emaste
Date: Tue May 12 16:49:04 2020
New Revision: 360971
URL: https://svnweb.freebsd.org/changeset/base/360971

Log:
  MFC r360967: libalias: validate packet lengths before accessing headers
  
  admbugs:	956
  Submitted by:	ae
  Reported by:	Lucas Leong (@_wmliang_) of Trend Micro Zero Day Initiative
  Reported by:	Vishnu working with Trend Micro Zero Day Initiative
  Approved by:	so
  Security:	FreeBSD-SA-20:12.libalias
  Security:	CVE-2020-7454
  Security:	ZDI-CAN-10624, ZDI-CAN-10850

Modified:
  stable/12/sys/netinet/libalias/alias.c
Directory Properties:
  stable/12/   (props changed)

Changes in other areas also in this revision:
Modified:
  stable/11/sys/netinet/libalias/alias.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/12/sys/netinet/libalias/alias.c
==============================================================================
--- stable/12/sys/netinet/libalias/alias.c	Tue May 12 16:46:14 2020	(r360970)
+++ stable/12/sys/netinet/libalias/alias.c	Tue May 12 16:49:04 2020	(r360971)
@@ -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?202005121649.04CGn4OM057900>