diff options
author | dhartmei <dhartmei@FreeBSD.org> | 2004-12-19 19:43:04 +0000 |
---|---|---|
committer | dhartmei <dhartmei@FreeBSD.org> | 2004-12-19 19:43:04 +0000 |
commit | b61c49cccce7d7a752e9f985c0dfc3b59655cbff (patch) | |
tree | 44066251e372ad74efc618bfe41d462b1c1ce39b /sys | |
parent | ae7f7772e559abc8a205346bbdb0fe8ad1ba1d2c (diff) | |
download | FreeBSD-src-b61c49cccce7d7a752e9f985c0dfc3b59655cbff.zip FreeBSD-src-b61c49cccce7d7a752e9f985c0dfc3b59655cbff.tar.gz |
Initialise init_addr in pf_map_addr() in the PF_POOL_ROUNDROBIN,
prevents a possible endless loop in pf_get_sport() with 'static-port'
ICMP state entries use the ICMP ID as port for the unique state key. When
checking for a usable key, construct the key in the same way. Otherwise,
a colliding key might be missed or a state insertion might be refused even
though it could be inserted. The second case triggers the endless loop,
possibly allowing a NATed LAN client to lock up the kernel.
PR: kern/74930
Reported and tested by: Hugo Silva, Srebrenko Sehic
MFC after: 3 days
Diffstat (limited to 'sys')
-rw-r--r-- | sys/contrib/pf/net/pf.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/sys/contrib/pf/net/pf.c b/sys/contrib/pf/net/pf.c index 99958c7..22ece97 100644 --- a/sys/contrib/pf/net/pf.c +++ b/sys/contrib/pf/net/pf.c @@ -2087,6 +2087,8 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr, get_addr: PF_ACPY(naddr, &rpool->counter, af); + if (init_addr != NULL && PF_AZERO(init_addr, af)) + PF_ACPY(init_addr, naddr, af); PF_AINC(&rpool->counter, af); break; } @@ -2129,7 +2131,7 @@ pf_get_sport(sa_family_t af, u_int8_t proto, struct pf_rule *r, * similar 2 portloop in in_pcbbind */ if (!(proto == IPPROTO_TCP || proto == IPPROTO_UDP)) { - key.gwy.port = 0; + key.gwy.port = dport; if (pf_find_state_all(&key, PF_EXT_GWY, NULL) == NULL) return (0); } else if (low == 0 && high == 0) { @@ -3405,7 +3407,7 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction, if (direction == PF_OUT) { /* check outgoing packet for BINAT/NAT */ if ((nr = pf_get_translation(pd, m, off, PF_OUT, kif, &nsn, - saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { + saddr, icmpid, daddr, icmpid, &pd->naddr, NULL)) != NULL) { PF_ACPY(&pd->baddr, saddr, af); switch (af) { #ifdef INET @@ -3429,7 +3431,7 @@ pf_test_icmp(struct pf_rule **rm, struct pf_state **sm, int direction, } else { /* check incoming packet for BINAT/RDR */ if ((nr = pf_get_translation(pd, m, off, PF_IN, kif, &nsn, - saddr, 0, daddr, 0, &pd->naddr, NULL)) != NULL) { + saddr, icmpid, daddr, icmpid, &pd->naddr, NULL)) != NULL) { PF_ACPY(&pd->baddr, daddr, af); switch (af) { #ifdef INET |