aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGordon Tetlow <gordon@FreeBSD.org>2020-05-12 16:51:11 +0000
committerGordon Tetlow <gordon@FreeBSD.org>2020-05-12 16:51:11 +0000
commit6c0cde56943c4da59933f6e15a22f94e0e8def09 (patch)
tree9d59d89d174347b288ee69ffc7d99bb66ae0b643
parenta320a4be4e2d8e79a6135bc49abd5221b85b50b8 (diff)
downloadsrc-6c0cde56943c4da59933f6e15a22f94e0e8def09.tar.gz
src-6c0cde56943c4da59933f6e15a22f94e0e8def09.zip
Fix insufficient packet length validation in libalias.
Approved by: so Approved by: re (implicit) Security: FreeBSD-SA-20:12.libalias Security: CVE-2020-7454
Notes
Notes: svn path=/releng/11.4/; revision=360972
-rw-r--r--sys/netinet/libalias/alias.c37
1 files changed, 34 insertions, 3 deletions
diff --git a/sys/netinet/libalias/alias.c b/sys/netinet/libalias/alias.c
index 6c9d7b44b749..ab06e1b62980 100644
--- a/sys/netinet/libalias/alias.c
+++ b/sys/netinet/libalias/alias.c
@@ -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 maxpacketsize, int create)
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 maxpacketsize, int create)
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)