lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 10 Oct 2017 08:39:42 -0400
From:   Alexander Aring <aring@...atatu.com>
To:     Jamal Hadi Salim <jhs@...atatu.com>
Cc:     Cong Wang <xiyou.wangcong@...il.com>,
        Jiří Pírko <jiri@...nulli.us>,
        netdev@...r.kernel.org, Manish Kurup <kurup.manish@...il.com>,
        Brenda Butler <bjb@...atatu.com>,
        Alexander Aring <aring@...atatu.com>
Subject: Re: [RFC net 1/1] net: sched: act: fix rcu race in dump

Hi,

On Tue, Oct 10, 2017 at 8:32 AM, Alexander Aring <aring@...atatu.com> wrote:
> This patch fixes an issue with kfree_rcu which is not protected by RTNL
> lock. It could be that the current assigned rcu pointer will be freed by
> kfree_rcu while dump callback is running.
>
> To prevent this, we call rcu_synchronize at first. Then we are sure all
> latest rcu functions e.g. rcu_assign_pointer and kfree_rcu in init are
> done. After rcu_synchronize we dereference under RTNL lock which is also
> held in init function, which means no other rcu_assign_pointer or
> kfree_rcu will occur.
>
> To call rcu_synchronize will also prevent weird behaviours by doing over
> netlink:
>
>  - set params A
>  - set params B
>  - dump params
>   \--> will dump params A
>
> This could be a unlikely case that the last rcu_assign_pointer was not
> happened before dump callback.
>
> Signed-off-by: Alexander Aring <aring@...atatu.com>
> ---
>  net/sched/act_skbmod.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/net/sched/act_skbmod.c b/net/sched/act_skbmod.c
> index b642ad3d39dd..231e07bca384 100644
> --- a/net/sched/act_skbmod.c
> +++ b/net/sched/act_skbmod.c
> @@ -198,7 +198,7 @@ static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a,
>  {
>         struct tcf_skbmod *d = to_skbmod(a);
>         unsigned char *b = skb_tail_pointer(skb);
> -       struct tcf_skbmod_params  *p = rtnl_dereference(d->skbmod_p);
> +       struct tcf_skbmod_params  *p;
>         struct tc_skbmod opt = {
>                 .index   = d->tcf_index,
>                 .refcnt  = d->tcf_refcnt - ref,
> @@ -207,6 +207,11 @@ static int tcf_skbmod_dump(struct sk_buff *skb, struct tc_action *a,
>         };
>         struct tcf_t t;
>
> +       /* wait until last rcu_assign_pointer/kfree_rcu is done */
> +       rcu_synchronize();

... and next time I should use the right function:

s/rcu_synchronize/synchronize_rcu/

anyway there exists a reason why sent it as RFC. :-)

Thanks.

- Alex

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ