Hello,

snippet below comes from pf_create_state():

   3559         if (pf_state_insert(BOUND_IFACE(r, pd->kif), skw, sks, s)) {
   3560                 pf_state_key_detach(s, PF_SK_STACK);
   3561                 pf_state_key_detach(s, PF_SK_WIRE);
   3562                 *sks = *skw = NULL;
   3563                 REASON_SET(&reason, PFRES_STATEINS);
   3564                 goto csfailed;
   3565         } else
   3566                 *sm = s;
   3567 
   3568         /* attach src nodes late, otherwise cleanup on error nontrivial 
*/
   3569         for (i = 0; i < PF_SN_MAX; i++)
   3570                 if (sns[i] != NULL) {
   3571                         struct pf_sn_item       *sni;
   3572 
   3573                         sni = pool_get(&pf_sn_item_pl, PR_NOWAIT);
   3574                         if (sni == NULL) {
   3575                                 REASON_SET(&reason, PFRES_MEMORY);
   3576                                 pf_src_tree_remove_state(s);
   3577                                 STATE_DEC_COUNTERS(s);
   3578                                 pool_put(&pf_state_pl, s);
   3579                                 return (PF_DROP);
   3580                         }
   3581                         sni->sn = sns[i];
   3582                         SLIST_INSERT_HEAD(&s->src_nodes, sni, next);
   3583                         sni->sn->states++;
   3584                 }

at line 3559 PF inserts state to table. If insert operation succeeds, then
state can no longer be killed using simple pool_put() as it currently
happens at line 3578. I think PF should go for pf_unlink_state() instead.

patch below should kill the bug.

also one more off-topic question:

        would you be interested in SMP patch for PF?
        it basically introduces fine locking and reference counting
        on PF data objects, so firewall can handle more packets at
        single instance of time.

regards
sasha

===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.913
diff -u -r1.913 pf.c
--- pf.c        11 May 2015 12:22:14 -0000      1.913
+++ pf.c        21 May 2015 15:20:01 -0000
@@ -3573,9 +3573,7 @@   
                        sni = pool_get(&pf_sn_item_pl, PR_NOWAIT);
                        if (sni == NULL) {
                                REASON_SET(&reason, PFRES_MEMORY);
-                               pf_src_tree_remove_state(s);
-                               STATE_DEC_COUNTERS(s);
-                               pool_put(&pf_state_pl, s);
+                               pf_unlink_state(s);
                                return (PF_DROP);
                        }
                        sni->sn = sns[i];

Reply via email to