Use cfg->nomatch_verdict as return value from NAT64LSN handler when

given mbuf is considered as not matched.

If mbuf was consumed or freed during handling, we must return
IP_FW_DENY, since ipfw's pfil handler ipfw_check_packet() expects
IP_FW_DENY when mbuf pointer is NULL. This fixes KASSERT panics
when NAT64 is used with INVARIANTS. Also remove unused nomatch_final
field from struct nat64lsn_cfg.

Reported by:	Justin Holcomb <justin at justinholcomb dot me>
Obtained from:	Yandex LLC
MFC after:	1 week
Sponsored by:	Yandex LLC
This commit is contained in:
Andrey V. Elsukov 2018-04-12 21:13:30 +00:00
parent c570565f12
commit eed302572a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=332457
3 changed files with 9 additions and 10 deletions

View File

@ -351,10 +351,11 @@ nat64lsn_translate4(struct nat64lsn_cfg *cfg, const struct ipfw_flow_id *f_id,
if (nat_proto == NAT_PROTO_ICMP) {
ret = inspect_icmp_mbuf(pm, &nat_proto, &addr, &port);
if (ret != 0) {
if (ret == ENOMEM)
if (ret == ENOMEM) {
NAT64STAT_INC(&cfg->stats, nomem);
else
NAT64STAT_INC(&cfg->stats, noproto);
return (IP_FW_DENY);
}
NAT64STAT_INC(&cfg->stats, noproto);
return (cfg->nomatch_verdict);
}
/* XXX: Check addr for validity */
@ -416,7 +417,7 @@ nat64lsn_translate4(struct nat64lsn_cfg *cfg, const struct ipfw_flow_id *f_id,
&cfg->stats, logdata);
if (ret == NAT64SKIP)
return (IP_FW_PASS);
return (cfg->nomatch_verdict);
if (ret == NAT64MFREE)
m_freem(*pm);
*pm = NULL;
@ -1362,7 +1363,7 @@ nat64lsn_request_host(struct nat64lsn_cfg *cfg,
NAT64STAT_INC(&cfg->stats, jhostsreq);
}
return (IP_FW_PASS);
return (IP_FW_DENY);
}
static NAT64NOINLINE int
@ -1391,7 +1392,7 @@ nat64lsn_request_portgroup(struct nat64lsn_cfg *cfg,
NAT64STAT_INC(&cfg->stats, jportreq);
}
return (IP_FW_PASS);
return (IP_FW_DENY);
}
static NAT64NOINLINE struct nat64lsn_state *
@ -1595,7 +1596,7 @@ nat64lsn_translate6(struct nat64lsn_cfg *cfg, struct ipfw_flow_id *f_id,
action = nat64_do_handle_ip6(*pm, aaddr, aport, &cfg->stats, logdata);
if (action == NAT64SKIP)
return (IP_FW_PASS);
return (cfg->nomatch_verdict);
if (action == NAT64MFREE)
m_freem(*pm);
*pm = NULL; /* mark mbuf as consumed */
@ -1631,7 +1632,7 @@ ipfw_nat64lsn(struct ip_fw_chain *ch, struct ip_fw_args *args,
ret = nat64lsn_translate6(cfg, &args->f_id, &args->m);
break;
default:
return (0);
return (cfg->nomatch_verdict);
}
return (ret);
}

View File

@ -199,7 +199,6 @@ struct nat64lsn_cfg {
uint8_t plen4;
uint8_t plen6;
uint8_t nomatch_verdict;/* What to return to ipfw on no-match */
uint8_t nomatch_final; /* Exit outer loop? */
struct in6_addr prefix6; /* IPv6 prefix to embed IPv4 hosts */
uint32_t ihcount; /* Number of items in host hash */

View File

@ -190,7 +190,6 @@ nat64lsn_create(struct ip_fw_chain *ch, ip_fw3_opheader *op3,
cfg->st_icmp_ttl = uc->st_icmp_ttl;
cfg->nomatch_verdict = IP_FW_DENY;
cfg->nomatch_final = 1; /* Exit outer loop by default */
IPFW_UH_WLOCK(ch);