Received: by 2002:a05:6a10:c7c6:0:0:0:0 with SMTP id h6csp2088905pxy; Mon, 2 Aug 2021 19:14:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxt0iBEenWNQq5/+ZRqGhFMqjHe0R0JDukHG2nyFbHhjjSe86VPsS3B7gFDMwz5s4ZUzW4a X-Received: by 2002:a05:6402:603:: with SMTP id n3mr21764125edv.61.1627956854229; Mon, 02 Aug 2021 19:14:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1627956854; cv=none; d=google.com; s=arc-20160816; b=BjzF8zl2t/abm6y/gibhjKLUHq02AFZg3KQP1tR8a3+Q5vHo+GdTsEGXfdK8fuY6UB 2v+gNdcePxKRPy5LykqaY6EQCpLfEsLVoA2tbJYuGAH1qsgosN/6ZO7DETSqev6bgftx 3XmoZ8ebkngA43UOgbDZfakOrVWzufJi/T2/+4HKRoPsAOUQuIGqaOUbau51YchNdPdS JTGqAiunS+PHI6aLhC5lpCMhuj/WbWloOYJLHXzMz4llFgEWvHTzjkigJuy6Bqvqo9G9 3CfFjc1QlasIyjqcXofXHO3yo9Y9Kl1F0EMWmUuB48abQAEOTXAEzkdeXWg586Z7dN8w 9bzQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-language:content-transfer-encoding :in-reply-to:mime-version:user-agent:date:message-id:from:references :cc:to:subject; bh=mlqyIDcnCurE1XqXfvqPCiJFUTOShbEhPkdWukibnJ8=; b=lEacaVFbcl0mE56tOF7QfbMZ8FKMO8jIH4ECu+KimYT9GwckjP/+RfwTVpj/fF0+jO btSPXAEY3CRbogns7eh7WyKuWeCTKPNy1fs4k+qUkjKRsMsXnoxba5+0N8T+uIEE5G5k GHX/dRGS3hyTzLBZ+mXyM2J10F9A/Q7sBtz3k6Fpd6gxQyQOOElZ5qLs745qO/H8Ut9M OS740EEZ+3XorKis+TWh5YtTIbbU3p8KFjeq3jnoTCHVKMh8HlyP4VEj3IvwjktRqoXv KqMU9+wCV0FHoga+8caXrIa6fV7vRkxRMXXEU+UtuAnRcU9GqXeNJ+RlsVETvrmBZiKY N2jg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=huawei.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id b6si12788608edu.126.2021.08.02.19.13.50; Mon, 02 Aug 2021 19:14:14 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=huawei.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233526AbhHCCLe (ORCPT + 99 others); Mon, 2 Aug 2021 22:11:34 -0400 Received: from szxga08-in.huawei.com ([45.249.212.255]:13225 "EHLO szxga08-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233270AbhHCCLc (ORCPT ); Mon, 2 Aug 2021 22:11:32 -0400 Received: from dggemv704-chm.china.huawei.com (unknown [172.30.72.57]) by szxga08-in.huawei.com (SkyGuard) with ESMTP id 4Gdyz80ClHz1CRMt; Tue, 3 Aug 2021 10:11:16 +0800 (CST) Received: from dggpemm500001.china.huawei.com (7.185.36.107) by dggemv704-chm.china.huawei.com (10.3.19.47) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2176.2; Tue, 3 Aug 2021 10:11:20 +0800 Received: from [10.174.177.243] (10.174.177.243) by dggpemm500001.china.huawei.com (7.185.36.107) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2176.2; Tue, 3 Aug 2021 10:11:18 +0800 Subject: Re: [PATCH] once: Fix panic when module unload To: , CC: Hannes Frederic Sowa , Daniel Borkmann , "David S . Miller" , "Eric Dumazet" , Minmin chen , "Jakub Kicinski" , Greg Kroah-Hartman , Andrew Morton References: <20210622022138.23048-1-wangkefeng.wang@huawei.com> From: Kefeng Wang Message-ID: <6b4b7165-5438-df65-3a43-7dcb576dab93@huawei.com> Date: Tue, 3 Aug 2021 10:11:18 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.7.0 MIME-Version: 1.0 In-Reply-To: <20210622022138.23048-1-wangkefeng.wang@huawei.com> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US X-Originating-IP: [10.174.177.243] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To dggpemm500001.china.huawei.com (7.185.36.107) X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 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 > Cc: Daniel Borkmann > Cc: David S. Miller > Cc: Eric Dumazet > Reported-by: Minmin chen > Signed-off-by: Kefeng Wang > --- > 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 > #include > #include > +#include > > 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); > } >