Paul Blakey <pa...@mellanox.com> wrote: > +/* Determine whether skb->_nfct is equal to the result of conntrack lookup. > */ > +static bool tcf_ct_skb_nfct_cached(struct net *net, struct sk_buff *skb, > + u16 zone_id, bool force) > +{ > + enum ip_conntrack_info ctinfo; > + struct nf_conn *ct; > + > + ct = nf_ct_get(skb, &ctinfo); > + if (!ct) > + return false; > + if (!net_eq(net, read_pnet(&ct->ct_net))) > + return false; > + if (nf_ct_zone(ct)->id != zone_id) > + return false; > + > + /* Force conntrack entry direction. */ > + if (force && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) { > + nf_conntrack_put(&ct->ct_general); > + nf_ct_set(skb, NULL, IP_CT_UNTRACKED); > + > + if (nf_ct_is_confirmed(ct)) > + nf_ct_kill(ct);
This looks like a possible UAF: nf_conntrack_put() may free the conntrack entry. It seems better to do do: if (nf_ct_is_confirmed(ct)) nf_ct_kill(ct); nf_conntrack_put(&ct->ct_general); nf_ct_set(skb, ...