summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormikeb <mikeb@openbsd.org>2011-07-08 22:11:17 +0000
committermikeb <mikeb@openbsd.org>2011-07-08 22:11:17 +0000
commite4fc4bddb9a469d90bd9ccb90462b69a0c0a650d (patch)
tree4134e99c278708e8c8e03948be2b1e6dccb864be
parentFirst batch of converting SCSI HBAs from setting saa_targets and (diff)
downloadwireguard-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
-rw-r--r--sys/net/pf_table.c18
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 */