summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2015-06-03 11:57:38 +0000
committerYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2015-06-03 11:57:38 +0000
commit35dffd8a159212ecbff3a22ae3674531374d9407 (patch)
treef7d4ec20c6f6482044dc7a22953ac11df591f9c6
parent33d756fa3399fb9c305e87e48230770e014f70ec (diff)
Fix pf_map_addr() not to cause dividing by 0. This fixes problem when
using table or dynamic interface addresses for source-hash. Also avoid calling arc4random_uniform() with upper_bound == 0. ok mikeb
-rw-r--r--sys/net/pf_lb.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/sys/net/pf_lb.c b/sys/net/pf_lb.c
index c8ae0432783..914ead8185f 100644
--- a/sys/net/pf_lb.c
+++ b/sys/net/pf_lb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_lb.c,v 1.42 2015/03/14 03:38:51 jsg Exp $ */
+/* $OpenBSD: pf_lb.c,v 1.43 2015/06/03 11:57:37 yasuoka Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -385,14 +385,20 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
case PF_POOL_RANDOM:
if (rpool->addr.type == PF_ADDR_TABLE) {
cnt = rpool->addr.p.tbl->pfrkt_cnt;
- rpool->tblidx = (int)arc4random_uniform(cnt);
+ if (cnt == 0)
+ rpool->tblidx = 0;
+ else
+ rpool->tblidx = (int)arc4random_uniform(cnt);
memset(&rpool->counter, 0, sizeof(rpool->counter));
if (pfr_pool_get(rpool, &raddr, &rmask, af))
return (1);
PF_ACPY(naddr, &rpool->counter, af);
} else if (rpool->addr.type == PF_ADDR_DYNIFTL) {
cnt = rpool->addr.p.dyn->pfid_kt->pfrkt_cnt;
- rpool->tblidx = (int)arc4random_uniform(cnt);
+ if (cnt == 0)
+ rpool->tblidx = 0;
+ else
+ rpool->tblidx = (int)arc4random_uniform(cnt);
memset(&rpool->counter, 0, sizeof(rpool->counter));
if (pfr_pool_get(rpool, &raddr, &rmask, af))
return (1);
@@ -438,14 +444,20 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct pf_addr *saddr,
pf_hash(saddr, (struct pf_addr *)&hash, &rpool->key, af);
if (rpool->addr.type == PF_ADDR_TABLE) {
cnt = rpool->addr.p.tbl->pfrkt_cnt;
- rpool->tblidx = (int)(hashidx % cnt);
+ if (cnt == 0)
+ rpool->tblidx = 0;
+ else
+ rpool->tblidx = (int)(hashidx % cnt);
memset(&rpool->counter, 0, sizeof(rpool->counter));
if (pfr_pool_get(rpool, &raddr, &rmask, af))
return (1);
PF_ACPY(naddr, &rpool->counter, af);
} else if (rpool->addr.type == PF_ADDR_DYNIFTL) {
cnt = rpool->addr.p.dyn->pfid_kt->pfrkt_cnt;
- rpool->tblidx = (int)(hashidx % cnt);
+ if (cnt == 0)
+ rpool->tblidx = 0;
+ else
+ rpool->tblidx = (int)(hashidx % cnt);
memset(&rpool->counter, 0, sizeof(rpool->counter));
if (pfr_pool_get(rpool, &raddr, &rmask, af))
return (1);