diff --git a/sys/net/ipfw3_nat/ip_fw3_nat.c b/sys/net/ipfw3_nat/ip_fw3_nat.c --- a/sys/net/ipfw3_nat/ip_fw3_nat.c +++ b/sys/net/ipfw3_nat/ip_fw3_nat.c @@ -179,6 +179,7 @@ struct ip *ip = mtod(m, struct ip *); struct in_addr *old_addr = NULL, new_addr; uint16_t *old_port = NULL, new_port; + uint16_t in_port = 0; uint16_t *csum = NULL, dlen = 0; uint8_t udp = 0; boolean_t pseudo = FALSE, need_return_state = FALSE; @@ -201,18 +202,29 @@ switch (ip->ip_p) { case IPPROTO_TCP: old_port = &L3HDR(struct tcphdr, ip)->th_dport; - s2 = alias->tcp_in[*old_port - ALIAS_BEGIN]; + in_port = ntohs(*old_port); + if (in_port < ALIAS_BEGIN || + in_port >= ALIAS_BEGIN + ALIAS_RANGE) + goto oops; + s2 = alias->tcp_in[in_port - ALIAS_BEGIN]; csum = &L3HDR(struct tcphdr, ip)->th_sum; break; case IPPROTO_UDP: old_port = &L3HDR(struct udphdr, ip)->uh_dport; - s2 = alias->udp_in[*old_port - ALIAS_BEGIN]; + in_port = ntohs(*old_port); + if (in_port < ALIAS_BEGIN || + in_port >= ALIAS_BEGIN + ALIAS_RANGE) + goto oops; + s2 = alias->udp_in[in_port - ALIAS_BEGIN]; csum = &L3HDR(struct udphdr, ip)->uh_sum; udp = 1; break; case IPPROTO_ICMP: old_port = &L3HDR(struct icmp, ip)->icmp_id; - s2 = alias->icmp_in[*old_port]; + in_port = ntohs(*old_port); + if (in_port >= ALIAS_RANGE) + goto oops; + s2 = alias->icmp_in[in_port]; csum = &L3HDR(struct icmp, ip)->icmp_cksum; break; default: