Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp4300114pxj; Mon, 21 Jun 2021 19:14:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyR1HW80Ac6c60403pWMgJrbOoREbZMz0Y/Kjuw7JSX2vfCUNx0v/vx3zdN1F9AkdGCrIOy X-Received: by 2002:a5d:9059:: with SMTP id v25mr840057ioq.113.1624328062577; Mon, 21 Jun 2021 19:14:22 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1624328062; cv=none; d=google.com; s=arc-20160816; b=aQr4POFS+VIHpzCf7BKfQhSI3wR0fgXtwXAW87syPVAyJh/SgtNA9tUy8NXRC4Div0 NS8MIhd8uRqLItZOTLl4ocwaduRH484ntATkXNXUb7zgshvUAy0eRMvjrbOvG9zYFSCs CdgxFkagi3jrMBjDzm2yTkpP/uFODahTDNsZhDK/Ci7kLKC/ONxL/DZHMMy6QlvevRK7 hXAN0dg4pS2YQXVtPTDaAW7gtSbi97EqzjZ1EzCpnfnYsH4uNWu4I4cXeHNE/fMeUSNY newJJ1tl83BcZ1o8RH5T93bCJqzYf/ESUIjl3zbPyCrorcGbRJp/WKlrpK7FPQgWvI55 unjQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=gynt5VNJYDm6eA2lYDk40dX40zffx4EFXhedaxkImgA=; b=X9cyrkL+gXzMUfTi6xu0QHE3FAOZ3gYnzyhBNW2X9duMfb+zaygsGFFLx0ZtGjpN2Z fcd8pDsmBDnLjxleIha6Bqx8W+bAaxkHxRgEI609ayyJKbNE7lg6HdhnS7KSZvKuO1TI YKWGAj6V1wpznwT6pDjIdGT/wsKyfm2c0BJJ38v1de126UhGNKh49+UkWxHRbG9vrCax oHRTZZAbco5+YmtASN9FPJSIGgH/W0H+DCZ6wwZNPXKt0CZ86VGL4gdq2BzKKytleI75 DPvR9TR295cPh9auWy/0hp6GaYtbMzZXXTVivCndn6IUUsxEYQoCKwaKexHleaTmrvZd MRzQ== 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 b9si14618678ilq.92.2021.06.21.19.14.10; Mon, 21 Jun 2021 19:14:22 -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 S230390AbhFVCPu (ORCPT + 99 others); Mon, 21 Jun 2021 22:15:50 -0400 Received: from szxga01-in.huawei.com ([45.249.212.187]:5062 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229663AbhFVCPt (ORCPT ); Mon, 21 Jun 2021 22:15:49 -0400 Received: from dggemv703-chm.china.huawei.com (unknown [172.30.72.55]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4G88vC0r76zXfNK; Tue, 22 Jun 2021 10:08:23 +0800 (CST) Received: from dggpemm500001.china.huawei.com (7.185.36.107) by dggemv703-chm.china.huawei.com (10.3.19.46) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2176.2; Tue, 22 Jun 2021 10:13:31 +0800 Received: from localhost.localdomain.localdomain (10.175.113.25) 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, 22 Jun 2021 10:13:31 +0800 From: Kefeng Wang To: , CC: Kefeng Wang , Hannes Frederic Sowa , Daniel Borkmann , "David S . Miller" , Eric Dumazet , "Minmin chen" Subject: [PATCH] once: Fix panic when module unload Date: Tue, 22 Jun 2021 10:21:38 +0800 Message-ID: <20210622022138.23048-1-wangkefeng.wang@huawei.com> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Content-Transfer-Encoding: 7BIT Content-Type: text/plain; charset=US-ASCII X-Originating-IP: [10.175.113.25] X-ClientProxiedBy: dggems703-chm.china.huawei.com (10.3.19.180) 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 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); } -- 2.26.2