On Mon, May 08, 2017 at 02:56:55PM +0200, Patrick Wildt wrote:
> @@ -2307,9 +2326,9 @@ pfr_pool_get(struct pf_pool *rpool, struct pf_addr 
> **raddr,
>                       rpool->curweight = kt->pfrkt_maxweight;
>       }
>  
> -     pfr_prepare_network(&pfr_mask, af, ke->pfrke_net);
> +     pfr_prepare_network(&mask, af, ke->pfrke_net);
>       *raddr = SUNION2PF(&ke->pfrke_sa, af);
> -     *rmask = SUNION2PF(&pfr_mask, af);
> +     *rmask = SUNION2PF(&mask, af);
>  
>       if (use_counter && !PF_AZERO(counter, af)) {
>               /* is supplied address within block? */

Before committing I realised that this actually returns the pointer
instead of the contents, which would mean that we would now return
a pointer to the callee's stack.

I think we should change pfr_pool_get() so that it's the caller's
responsibility to pass a structure where the rmask can fit into.  Then
we should always work with that structure and copy the elements instead
of changing rmask by setting it to a different pointer.

Maybe we should do the same for raddr.

Opinions?

diff --git a/sys/net/pf_lb.c b/sys/net/pf_lb.c
index 74acc538b8f..af57272c4dc 100644
--- a/sys/net/pf_lb.c
+++ b/sys/net/pf_lb.c
@@ -339,7 +339,7 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct 
pf_addr *saddr,
        unsigned char            hash[16];
        struct pf_addr           faddr;
        struct pf_addr          *raddr = &rpool->addr.v.a.addr;
-       struct pf_addr          *rmask = &rpool->addr.v.a.mask;
+       struct pf_addr           rmask = rpool->addr.v.a.mask;
        u_int64_t                states;
        u_int16_t                weight;
        u_int64_t                load;
@@ -361,7 +361,7 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct 
pf_addr *saddr,
                            !PF_POOL_DYNTYPE(rpool->opts))
                                return (1);
                        raddr = &rpool->addr.p.dyn->pfid_addr4;
-                       rmask = &rpool->addr.p.dyn->pfid_mask4;
+                       rmask = rpool->addr.p.dyn->pfid_mask4;
                        break;
 #ifdef INET6
                case AF_INET6:
@@ -369,7 +369,7 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct 
pf_addr *saddr,
                            !PF_POOL_DYNTYPE(rpool->opts))
                                return (1);
                        raddr = &rpool->addr.p.dyn->pfid_addr6;
-                       rmask = &rpool->addr.p.dyn->pfid_mask6;
+                       rmask = rpool->addr.p.dyn->pfid_mask6;
                        break;
 #endif /* INET6 */
                default:
@@ -380,7 +380,7 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct 
pf_addr *saddr,
                        return (1); /* unsupported */
        } else {
                raddr = &rpool->addr.v.a.addr;
-               rmask = &rpool->addr.v.a.mask;
+               rmask = rpool->addr.v.a.mask;
        }
 
        switch (rpool->opts & PF_POOL_TYPEMASK) {
@@ -388,7 +388,7 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct 
pf_addr *saddr,
                PF_ACPY(naddr, raddr, af);
                break;
        case PF_POOL_BITMASK:
-               PF_POOLMASK(naddr, raddr, rmask, saddr, af);
+               PF_POOLMASK(naddr, raddr, &rmask, saddr, af);
                break;
        case PF_POOL_RANDOM:
                if (rpool->addr.type == PF_ADDR_TABLE) {
@@ -418,31 +418,31 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct 
pf_addr *saddr,
                                break;
 #ifdef INET6
                        case AF_INET6:
-                               if (rmask->addr32[3] != 0xffffffff)
+                               if (rmask.addr32[3] != 0xffffffff)
                                        rpool->counter.addr32[3] = arc4random();
                                else
                                        break;
-                               if (rmask->addr32[2] != 0xffffffff)
+                               if (rmask.addr32[2] != 0xffffffff)
                                        rpool->counter.addr32[2] = arc4random();
                                else
                                        break;
-                               if (rmask->addr32[1] != 0xffffffff)
+                               if (rmask.addr32[1] != 0xffffffff)
                                        rpool->counter.addr32[1] = arc4random();
                                else
                                        break;
-                               if (rmask->addr32[0] != 0xffffffff)
+                               if (rmask.addr32[0] != 0xffffffff)
                                        rpool->counter.addr32[0] = arc4random();
                                break;
 #endif /* INET6 */
                        default:
                                unhandled_af(af);
                        }
-                       PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
+                       PF_POOLMASK(naddr, raddr, &rmask, &rpool->counter, af);
                        PF_ACPY(init_addr, naddr, af);
 
                } else {
                        PF_AINC(&rpool->counter, af);
-                       PF_POOLMASK(naddr, raddr, rmask, &rpool->counter, af);
+                       PF_POOLMASK(naddr, raddr, &rmask, &rpool->counter, af);
                }
                break;
        case PF_POOL_SRCHASH:
@@ -469,7 +469,7 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct 
pf_addr *saddr,
                                return (1);
                        PF_ACPY(naddr, &rpool->counter, af);
                } else {
-                       PF_POOLMASK(naddr, raddr, rmask,
+                       PF_POOLMASK(naddr, raddr, &rmask,
                            (struct pf_addr *)&hash, af);
                }
                break;
@@ -485,7 +485,7 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct 
pf_addr *saddr,
                                if (pfr_pool_get(rpool, &raddr, &rmask, af))
                                        return (1);
                        }
-               } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
+               } else if (pf_match_addr(0, raddr, &rmask, &rpool->counter, af))
                        return (1);
 
                /* iterate over table if it contains entries which are weighted 
*/
@@ -527,7 +527,7 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct 
pf_addr *saddr,
                                if (pfr_pool_get(rpool, &raddr, &rmask, af))
                                        return (1);
                        }
-               } else if (pf_match_addr(0, raddr, rmask, &rpool->counter, af))
+               } else if (pf_match_addr(0, raddr, &rmask, &rpool->counter, af))
                        return (1);
 
                states = rpool->states;
@@ -557,7 +557,7 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct 
pf_addr *saddr,
                            rpool->addr.type == PF_ADDR_DYNIFTL) {
                                if (pfr_pool_get(rpool, &raddr, &rmask, af))
                                        return (1);
-                       } else if (pf_match_addr(0, raddr, rmask,
+                       } else if (pf_match_addr(0, raddr, &rmask,
                            &rpool->counter, af))
                                return (1);
 
@@ -581,7 +581,7 @@ pf_map_addr(sa_family_t af, struct pf_rule *r, struct 
pf_addr *saddr,
                                    PF_AZERO(init_addr, af))
                                    PF_ACPY(init_addr, naddr, af);
                        }
-               } while (pf_match_addr(1, &faddr, rmask, &rpool->counter, af) &&
+               } while (pf_match_addr(1, &faddr, &rmask, &rpool->counter, af) 
&&
                    (states > 0));
 
                if (rpool->addr.type == PF_ADDR_TABLE) {
diff --git a/sys/net/pf_table.c b/sys/net/pf_table.c
index 7666ec7013c..f23739e8565 100644
--- a/sys/net/pf_table.c
+++ b/sys/net/pf_table.c
@@ -140,7 +140,6 @@ struct pfr_walktree {
 struct pool             pfr_ktable_pl;
 struct pool             pfr_kentry_pl[PFRKE_MAX];
 struct pool             pfr_kcounters_pl;
-union sockaddr_union    pfr_mask;
 struct pf_addr          pfr_ffaddr;
 
 int                     pfr_gcd(int, int);
@@ -2252,7 +2251,7 @@ pfr_islinklocal(sa_family_t af, struct pf_addr *addr)
 
 int
 pfr_pool_get(struct pf_pool *rpool, struct pf_addr **raddr,
-    struct pf_addr **rmask, sa_family_t af)
+    struct pf_addr *rmask, sa_family_t af)
 {
        struct pfr_ktable       *kt;
        struct pfr_kentry       *ke, *ke2;
@@ -2327,13 +2326,13 @@ pfr_pool_get(struct pf_pool *rpool, struct pf_addr 
**raddr,
                        rpool->curweight = kt->pfrkt_maxweight;
        }
 
-       pfr_prepare_network(&pfr_mask, af, ke->pfrke_net);
+       pfr_prepare_network(&mask, af, ke->pfrke_net);
        *raddr = SUNION2PF(&ke->pfrke_sa, af);
-       *rmask = SUNION2PF(&pfr_mask, af);
+       *rmask = *SUNION2PF(&mask, af);
 
        if (use_counter && !PF_AZERO(counter, af)) {
                /* is supplied address within block? */
-               if (!PF_MATCHA(0, *raddr, *rmask, counter, af)) {
+               if (!PF_MATCHA(0, *raddr, rmask, counter, af)) {
                        /* no, go to next block in table */
                        idx++;
                        use_counter = 0;
@@ -2417,7 +2416,7 @@ _next_entry:
                pfr_prepare_network(&mask, AF_INET, ke2->pfrke_net);
                PF_POOLMASK(addr, addr, SUNION2PF(&mask, af), &pfr_ffaddr, af);
                PF_AINC(addr, af);
-               if (!PF_MATCHA(0, *raddr, *rmask, addr, af)) {
+               if (!PF_MATCHA(0, *raddr, rmask, addr, af)) {
                        /* ok, we reached the end of our main block */
                        /* go to next block in table */
                        idx++;
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index 981d778e37a..982437b64ca 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1725,7 +1725,7 @@ int       pfr_match_addr(struct pfr_ktable *, struct 
pf_addr *, sa_family_t);
 void   pfr_update_stats(struct pfr_ktable *, struct pf_addr *,
            struct pf_pdesc *, int, int);
 int    pfr_pool_get(struct pf_pool *, struct pf_addr **,
-           struct pf_addr **, sa_family_t);
+           struct pf_addr *, sa_family_t);
 int    pfr_states_increase(struct pfr_ktable *, struct pf_addr *, int);
 int    pfr_states_decrease(struct pfr_ktable *, struct pf_addr *, int);
 struct pfr_kentry *

Reply via email to