diff options
| author | 2011-07-08 22:11:17 +0000 | |
|---|---|---|
| committer | 2011-07-08 22:11:17 +0000 | |
| commit | e4fc4bddb9a469d90bd9ccb90462b69a0c0a650d (patch) | |
| tree | 4134e99c278708e8c8e03948be2b1e6dccb864be /sys/net/pf_table.c | |
| parent | First batch of converting SCSI HBAs from setting saa_targets and (diff) | |
| download | wireguard-openbsd-e4fc4bddb9a469d90bd9ccb90462b69a0c0a650d.tar.xz wireguard-openbsd-e4fc4bddb9a469d90bd9ccb90462b69a0c0a650d.zip | |
ensure that we won't enter an endless loop while iterating over
an address pool. problem found and solution tested by claudio.
ok claudio, henning, "reads fine" to zinke
Diffstat (limited to 'sys/net/pf_table.c')
| -rw-r--r-- | sys/net/pf_table.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/sys/net/pf_table.c b/sys/net/pf_table.c index c6f6f74ecc7..724ceb6e83d 100644 --- a/sys/net/pf_table.c +++ b/sys/net/pf_table.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_table.c,v 1.91 2011/07/03 23:37:55 zinke Exp $ */ +/* $OpenBSD: pf_table.c,v 1.92 2011/07/08 22:11:17 mikeb Exp $ */ /* * Copyright (c) 2002 Cedric Berger @@ -2148,7 +2148,7 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter, struct pfr_kentry *ke, *ke2; struct pf_addr *addr; union sockaddr_union mask; - int idx = -1, use_counter = 0; + int startidx, idx = -1, loop = 0, use_counter = 0; if (af == AF_INET) addr = (struct pf_addr *)&pfr_sin.sin_addr; @@ -2165,23 +2165,29 @@ pfr_pool_get(struct pfr_ktable *kt, int *pidx, struct pf_addr *counter, use_counter = 1; if (idx < 0) idx = 0; + startidx = idx; _next_block: + if (loop && startidx == idx) { + kt->pfrkt_nomatch++; + return (1); + } + ke = pfr_kentry_byidx(kt, idx, af); if (ke == NULL) { /* we don't have this idx, try looping */ - idx = 0; - ke = pfr_kentry_byidx(kt, idx, af); - if (ke == NULL) { + if (loop || (ke = pfr_kentry_byidx(kt, 0, af)) == NULL) { kt->pfrkt_nomatch++; return (1); } + idx = 0; + loop++; } pfr_prepare_network(&pfr_mask, af, ke->pfrke_net); *raddr = SUNION2PF(&ke->pfrke_sa, af); *rmask = SUNION2PF(&pfr_mask, af); - if (use_counter) { + if (use_counter && !PF_AZERO(counter, af)) { /* is supplied address within block? */ if (!PF_MATCHA(0, *raddr, *rmask, counter, af)) { /* no, go to next block in table */ |
