summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordhartmei <dhartmei@FreeBSD.org>2004-12-19 19:43:04 +0000
committerdhartmei <dhartmei@FreeBSD.org>2004-12-19 19:43:04 +0000
commitb61c49cccce7d7a752e9f985c0dfc3b59655cbff (patch)
tree44066251e372ad74efc618bfe41d462b1c1ce39b /sys
parentae7f7772e559abc8a205346bbdb0fe8ad1ba1d2c (diff)
downloadFreeBSD-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.c8
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
OpenPOWER on IntegriCloud