From c30ec822b882e49d3380a269de33893ba06790b5 Mon Sep 17 00:00:00 2001 From: yasuoka Date: Wed, 3 Jun 2015 11:57:37 +0000 Subject: [PATCH] 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 --- sys/net/pf_lb.c | 22 +++++++++++++++++----- 1 file 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); -- 2.20.1