LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Kefeng Wang <wangkefeng.wang@huawei.com>
To: <linux-kernel@vger.kernel.org>, <netdev@vger.kernel.org>
Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	"David S . Miller" <davem@davemloft.net>,
	"Eric Dumazet" <edumazet@google.com>,
	Minmin chen <chenmingmin@huawei.com>,
	"Jakub Kicinski" <kuba@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Andrew Morton <akpm@linux-foundation.org>
Subject: Re: [PATCH] once: Fix panic when module unload
Date: Tue, 3 Aug 2021 10:11:18 +0800	[thread overview]
Message-ID: <6b4b7165-5438-df65-3a43-7dcb576dab93@huawei.com> (raw)
In-Reply-To: <20210622022138.23048-1-wangkefeng.wang@huawei.com>

Hi ALL, I don't know who maintain the lib/once.c, add Greg and Andrew too,

Hi David, I check the history, the lib/once.c is from net/core/utils.c 
since

commit 46234253b9363894a254844a6550b4cc5f3edfe8
Author: Hannes Frederic Sowa <hannes@stressinduktion.org>
Date:   Thu Oct 8 01:20:35 2015 +0200

     net: move net_get_random_once to lib

This bug is found in our product test, we want to make sure that whether 
this solution

is correct or not, so could David or any others help to review this patch.

Many thinks.

On 2021/6/22 10:21, Kefeng Wang wrote:
> DO_ONCE
> DEFINE_STATIC_KEY_TRUE(___once_key);
> __do_once_done
>    once_disable_jump(once_key);
>      INIT_WORK(&w->work, once_deferred);
>      struct once_work *w;
>      w->key = key;
>      schedule_work(&w->work);                     module unload
>                                                     //*the key is destroy*
> process_one_work
>    once_deferred
>      BUG_ON(!static_key_enabled(work->key));
>         static_key_count((struct static_key *)x)    //*access key, crash*
>
> When module uses DO_ONCE mechanism, it could crash due to the above
> concurrency problem, we could reproduce it with link[1].
>
> Fix it by add/put module refcount in the once work process.
>
> [1]
> https://lore.kernel.org/netdev/eaa6c371-465e-57eb-6be9-f4b16b9d7cbf@huawei.com/
>
> Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
> Cc: Daniel Borkmann <daniel@iogearbox.net>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: Eric Dumazet <edumazet@google.com>
> Reported-by: Minmin chen <chenmingmin@huawei.com>
> Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
> ---
>   lib/once.c | 17 +++++++++++++++++
>   1 file changed, 17 insertions(+)
>
> diff --git a/lib/once.c b/lib/once.c
> index 8b7d6235217e..959f8db41ccf 100644
> --- a/lib/once.c
> +++ b/lib/once.c
> @@ -3,10 +3,12 @@
>   #include <linux/spinlock.h>
>   #include <linux/once.h>
>   #include <linux/random.h>
> +#include <linux/module.h>
>   
>   struct once_work {
>   	struct work_struct work;
>   	struct static_key_true *key;
> +	struct module *module;
>   };
>   
>   static void once_deferred(struct work_struct *w)
> @@ -16,11 +18,24 @@ static void once_deferred(struct work_struct *w)
>   	work = container_of(w, struct once_work, work);
>   	BUG_ON(!static_key_enabled(work->key));
>   	static_branch_disable(work->key);
> +	module_put(work->module);
>   	kfree(work);
>   }
>   
> +static struct module *find_module_by_key(struct static_key_true *key)
> +{
> +	struct module *mod;
> +
> +	preempt_disable();
> +	mod = __module_address((unsigned long)key);
> +	preempt_enable();
> +
> +	return mod;
> +}
> +
>   static void once_disable_jump(struct static_key_true *key)
>   {
> +	struct module *mod = find_module_by_key(key);
>   	struct once_work *w;
>   
>   	w = kmalloc(sizeof(*w), GFP_ATOMIC);
> @@ -29,6 +44,8 @@ static void once_disable_jump(struct static_key_true *key)
>   
>   	INIT_WORK(&w->work, once_deferred);
>   	w->key = key;
> +	w->module = mod;
> +	__module_get(mod);
>   	schedule_work(&w->work);
>   }
>   

  parent reply	other threads:[~2021-08-03  2:11 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-22  2:21 Kefeng Wang
2021-07-16  5:03 ` Kefeng Wang
2021-08-03  2:11 ` Kefeng Wang [this message]
2021-08-03  9:59   ` Hannes Frederic Sowa
2021-08-04  1:49     ` Kefeng Wang

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=6b4b7165-5438-df65-3a43-7dcb576dab93@huawei.com \
    --to=wangkefeng.wang@huawei.com \
    --cc=akpm@linux-foundation.org \
    --cc=chenmingmin@huawei.com \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=hannes@stressinduktion.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --subject='Re: [PATCH] once: Fix panic when module unload' \
    /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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).