All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Abeni <pabeni@redhat.com>
To: Cong Wang <xiyou.wangcong@gmail.com>
Cc: Linux Kernel Network Developers <netdev@vger.kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	Jamal Hadi Salim <jhs@mojatatu.com>,
	Jiri Pirko <jiri@resnulli.us>, Li Shuang <shuali@redhat.com>,
	Ivan Vecera <ivecera@redhat.com>
Subject: Re: [PATCH net v2] cls_u32: fix use after free in u32_destroy_key()
Date: Sat, 03 Feb 2018 18:46:41 +0100	[thread overview]
Message-ID: <1517680001.2862.3.camel@redhat.com> (raw)
In-Reply-To: <CAM_iQpW80Mp63w6q9jWFaA7Nv_emRn2tx3ZjfS+ZoW7GbAQGZQ@mail.gmail.com>

Hi,
On Fri, 2018-02-02 at 13:52 -0800, Cong Wang wrote:
> On Fri, Feb 2, 2018 at 6:30 AM, Paolo Abeni <pabeni@redhat.com> wrote:
> > The problem is that the htnode is freed before the linked knodes and the
> > latter will try to access the first at u32_destroy_key() time.
> > This change addresses the issue using the htnode refcnt to guarantee
> > the correct free order. While at it also add a RCU annotation,
> > to keep sparse happy.
> > 
> > v1 -> v2: use rtnl_derefence() instead of RCU read locks
> > 
> > Reported-by: Li Shuang <shuali@redhat.com>
> > Fixes: c0d378ef1266 ("net_sched: use tcf_queue_work() in u32 filter")
> > Signed-off-by: Paolo Abeni <pabeni@redhat.com>
> > ---
> >  net/sched/cls_u32.c | 19 +++++++++++++++----
> >  1 file changed, 15 insertions(+), 4 deletions(-)
> > 
> > diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
> > index 60c892c36a60..10440fbf3c68 100644
> > --- a/net/sched/cls_u32.c
> > +++ b/net/sched/cls_u32.c
> > @@ -398,10 +398,12 @@ static int u32_init(struct tcf_proto *tp)
> >  static int u32_destroy_key(struct tcf_proto *tp, struct tc_u_knode *n,
> >                            bool free_pf)
> >  {
> > +       struct tc_u_hnode *ht = rtnl_dereference(n->ht_down);
> > +
> >         tcf_exts_destroy(&n->exts);
> >         tcf_exts_put_net(&n->exts);
> > -       if (n->ht_down)
> > -               n->ht_down->refcnt--;
> > +       if (ht && ht->refcnt-- == 0)
> > +               kfree(ht);
> >  #ifdef CONFIG_CLS_U32_PERF
> >         if (free_pf)
> >                 free_percpu(n->pf);
> > @@ -624,7 +626,12 @@ static int u32_destroy_hnode(struct tcf_proto *tp, struct tc_u_hnode *ht,
> >                         idr_destroy(&ht->handle_idr);
> >                         idr_remove_ext(&tp_c->handle_idr, ht->handle);
> >                         RCU_INIT_POINTER(*hn, ht->next);
> > -                       kfree_rcu(ht, rcu);
> > +
> > +                       /* u32_destroy_key() will will later free ht for us, if
> > +                        * it's still referenced by some knode
> > +                        */
> > +                       if (ht->refcnt == 0)
> > +                               kfree_rcu(ht, rcu);
> 
> 
> Isn't u32_destroy_hnode() always called with ht->refcnt==0 ?
> So no need this check at all?
> 
> 
> >                         return 0;
> >                 }
> >         }
> > @@ -667,7 +674,11 @@ static void u32_destroy(struct tcf_proto *tp, struct netlink_ext_ack *extack)
> > 
> >                 while ((ht = rtnl_dereference(tp_c->hlist)) != NULL) {
> >                         RCU_INIT_POINTER(tp_c->hlist, ht->next);
> > -                       kfree_rcu(ht, rcu);
> > +                       /* u32_destroy_key() will will later free ht for us, if
> 
> 
> Nit: double "will"
> 
> 
> > +                        * it's still referenced by some knode
> > +                        */
> > +                       if (ht->refcnt == 0)
> > +                               kfree_rcu(ht, rcu);
> 
> 
> This part looks fine.
> 
> Thanks!

Thank you for the feedback!

I will send a v3 soon, after some testing.

Cheers,

Paolo

  reply	other threads:[~2018-02-03 17:46 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-02 13:20 [PATCH net] cls_u32: fix use after free in u32_destroy_key() Paolo Abeni
2018-02-02 13:35 ` Paolo Abeni
2018-02-02 14:30 ` [PATCH net v2] " Paolo Abeni
2018-02-02 17:54   ` Ivan Vecera
2018-02-02 21:52   ` Cong Wang
2018-02-03 17:46     ` Paolo Abeni [this message]
2018-02-03 18:49   ` Paolo Abeni

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1517680001.2862.3.camel@redhat.com \
    --to=pabeni@redhat.com \
    --cc=davem@davemloft.net \
    --cc=ivecera@redhat.com \
    --cc=jhs@mojatatu.com \
    --cc=jiri@resnulli.us \
    --cc=netdev@vger.kernel.org \
    --cc=shuali@redhat.com \
    --cc=xiyou.wangcong@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.