--- cci/sys/netinet/ip_input.c 2019/07/28 12:24:19 1.1 +++ cci/sys/netinet/ip_input.c 2019/07/28 12:29:38 1.1.1.2 @@ -485,8 +485,11 @@ ip_dooptions(ip) break; if (opt == IPOPT_NOP) optlen = 1; - else + else { optlen = cp[1]; + if (optlen <= 0 || optlen > cnt) + goto bad; + } switch (opt) { default: @@ -601,6 +604,8 @@ ip_stripoptions(ip, mopt) int olen; olen = (ip->ip_hl<<2) - sizeof (struct ip); + if (olen < 0) + return(1); m = dtom(ip); ip++; if (mopt) { @@ -611,6 +616,7 @@ ip_stripoptions(ip, mopt) i = m->m_len - (sizeof (struct ip) + olen); bcopy((caddr_t)ip+olen, (caddr_t)ip, (unsigned)i); m->m_len -= olen; + return(0); } u_char inetctlerrmap[PRC_NCMDS] = { @@ -685,7 +691,16 @@ ip_forward(ip) */ mcopy = m_copy(dtom(ip), 0, imin(ip->ip_len, 64)); MBUFNULL(35, mcopy); /* for debugging */ - ip_stripoptions(ip, mopt); + if (ip_stripoptions(ip, mopt)) { + /* + * Bad options length, drop the packet. + */ + m_freem(dtom(ip)); + m_freem(mopt); + if (mcopy) + m_freem(mcopy); + return; + } error = ip_output(dtom(ip), mopt, (struct route *)0, IP_FORWARDING); if (error == 0) {