When doing matching based on dst_ip/src_ip make sure we are really looking

on an IPv4 packet as these variables are uninitialized if not.  This used to
allow arbitrary IPv6 packets depending on the value in the uninitialized
variables.

Some opcodes (most noteably O_REJECT) do not support IPv6 at all right now.

Reviewed by:	brooks, glebius
Security:	IPFW might pass IPv6 packets depending on stack contents.
Approved by:	re (blanket)
This commit is contained in:
Max Laier 2005-06-12 16:27:10 +00:00
parent 2ac7ea9add
commit cf21d53cbf
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=147319

View File

@ -2332,14 +2332,14 @@ do { \
break;
case O_IP_SRC:
match = (hlen > 0 &&
match = is_ipv4 && (hlen > 0 &&
((ipfw_insn_ip *)cmd)->addr.s_addr ==
src_ip.s_addr);
break;
case O_IP_SRC_LOOKUP:
case O_IP_DST_LOOKUP:
if (hlen > 0) {
if (hlen > 0 && is_ipv4) {
uint32_t a =
(cmd->opcode == O_IP_DST_LOOKUP) ?
dst_ip.s_addr : src_ip.s_addr;
@ -2356,7 +2356,7 @@ do { \
case O_IP_SRC_MASK:
case O_IP_DST_MASK:
if (hlen > 0) {
if (hlen > 0 && is_ipv4) {
uint32_t a =
(cmd->opcode == O_IP_DST_MASK) ?
dst_ip.s_addr : src_ip.s_addr;
@ -2369,7 +2369,7 @@ do { \
break;
case O_IP_SRC_ME:
if (hlen > 0) {
if (hlen > 0 && is_ipv4) {
struct ifnet *tif;
INADDR_TO_IFP(src_ip, tif);
@ -2379,7 +2379,7 @@ do { \
case O_IP_DST_SET:
case O_IP_SRC_SET:
if (hlen > 0) {
if (hlen > 0 && is_ipv4) {
u_int32_t *d = (u_int32_t *)(cmd+1);
u_int32_t addr =
cmd->opcode == O_IP_DST_SET ?
@ -2396,13 +2396,13 @@ do { \
break;
case O_IP_DST:
match = (hlen > 0 &&
match = is_ipv4 && (hlen > 0 &&
((ipfw_insn_ip *)cmd)->addr.s_addr ==
dst_ip.s_addr);
break;
case O_IP_DST_ME:
if (hlen > 0) {
if (hlen > 0 && is_ipv4) {
struct ifnet *tif;
INADDR_TO_IFP(dst_ip, tif);
@ -2605,14 +2605,16 @@ do { \
case O_VERSRCREACH:
/* Outgoing packets automatically pass/match */
/* XXX: IPv6 missing!?! */
match = (hlen > 0 && ((oif != NULL) ||
verify_path(src_ip, NULL)));
(is_ipv4 && verify_path(src_ip, NULL))));
break;
case O_ANTISPOOF:
/* Outgoing packets automatically pass/match */
/* XXX: IPv6 missing!?! */
if (oif == NULL && hlen > 0 &&
in_localaddr(src_ip))
(is_ipv4 && in_localaddr(src_ip)))
match = verify_path(src_ip,
m->m_pkthdr.rcvif);
else
@ -2834,7 +2836,8 @@ do { \
* if the packet is not ICMP (or is an ICMP
* query), and it is not multicast/broadcast.
*/
if (hlen > 0 &&
/* XXX: IPv6 missing!?! */
if (hlen > 0 && is_ipv4 &&
(proto != IPPROTO_ICMP ||
is_icmp_query(ICMP(ulp))) &&
!(m->m_flags & (M_BCAST|M_MCAST)) &&