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
This commit is contained in:
parent
ae7f7772e5
commit
b61c49cccc
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user