On Thu, May 28, 2015 at 01:17 +0200, Alexandr Nedvedicky wrote: > Hello, > > > On Wed, May 27, 2015 at 07:44:15PM +0200, Mike Belopuhov wrote: > > On Wed, May 27, 2015 at 10:39 +0200, Alexandr Nedvedicky wrote: > > > Hello, > > > > > > > > - if (pf_state_insert(BOUND_IFACE(r, pd->kif), skw, sks, s)) { > > > > > - pf_state_key_detach(s, PF_SK_STACK); > > > > > - pf_state_key_detach(s, PF_SK_WIRE); > > > > > > > > This bug is not yours, but doing two pf_state_key_detach is wrong > > > > and results in all kinds of protection fault fireworks. The right > > > > thing is to do pf_detach_state that would handle the case where > > > > PF_SK_STACK == PF_SK_WIRE (i.e. we need only one invocation). > > > good catch. > > > > > > > > > > > In csfailed case we do pf_remove_src_node and then call > > > > pf_src_tree_remove_state. With your diff this means that > > > > pf_src_tree_remove_state will be dereferencing sni->sn that > > > > might be pool_put by the pf_remove_src_node. Therefore their > > > > order needs to be reversed. > > > > > > I see. Another option to fix it would be to do: > > > > > > sni->sn = sns[i]; > > > sns[i] = NULL; > > > > > > > I'm not sure I follow. Where do you want to do it? > > If it's when we pool_get sni's, then this would mean > > we won't run pf_remove_src_node and cleanup source > > nodes that might have been created. > > > > sorry I was too brief. The snippet below comes from > pf_create_state() with your patch applied: > > 3560 for (i = 0; i < PF_SN_MAX; i++) > 3561 if (sns[i] != NULL) { > 3562 struct pf_sn_item *sni; > 3563 > 3564 sni = pool_get(&pf_sn_item_pl, PR_NOWAIT); > 3565 if (sni == NULL) { > 3566 REASON_SET(&reason, PFRES_MEMORY); > 3567 goto csfailed; > 3568 } > 3569 sni->sn = sns[i]; > 3570 sns[i] = NULL; > 3571 SLIST_INSERT_HEAD(&s->src_nodes, sni, next); > 3572 sni->sn->states++; > 3573 } > 3574 > > the point of my suggestion is to transfer ownership of source node from > local variable sns[] to state. so the check performed later in csfailed > at line 3617, will find NULL pointer in sns[i] field and won't attempt > to call pf_remove_src_node(). > > 3610 csfailed: > 3611 if (s) { > 3612 pf_normalize_tcp_cleanup(s); /* safe even w/o init > */ > 3613 pf_src_tree_remove_state(s); > 3614 } > 3615 > 3616 for (i = 0; i < PF_SN_MAX; i++) > 3617 if (sns[i] != NULL) > 3618 pf_remove_src_node(sns[i]); > 3619 > > > your patch updated by my suggestion is further below. >
But that introduces a potential leak, as I said in my mail: we won't run pf_remove_src_node and cleanup source nodes that might have been created. sns[] is an array of pointers to independently tracked objects (inserted into the pf_src_tree).