Message ID | 20230717171428.1b229215@endymion.delvare |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:c923:0:b0:3e4:2afc:c1 with SMTP id j3csp1183559vqt; Mon, 17 Jul 2023 08:31:49 -0700 (PDT) X-Google-Smtp-Source: APBJJlHO4JaV3RWidVGT8dpGF/EQj8qFE8JubpDsyWvmuAkWJRXY8P35Rx7PXigDkGSi7G6B+cWk X-Received: by 2002:a17:906:3f13:b0:993:f276:9696 with SMTP id c19-20020a1709063f1300b00993f2769696mr10651810ejj.35.1689607909365; Mon, 17 Jul 2023 08:31:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1689607909; cv=none; d=google.com; s=arc-20160816; b=tyNznDYnZlxKTtG6aaecHKU3Jte1F4Nq3HAHFv0EUnOv+BoeE8HA5ET38f8gwJ/6dd djUKdGv1mvLo2Z0zaztJPJTOkVFLaeSKSReIaQ7DHcPmotqAHrwvLmzBCTuQ9catI41N SPh+GcWX9V2Z5oQDPcxxcW3pIinXVqhRkoqN4wiLOMlFlsKcD4KDUOMhsWB5WLYhR2a9 h/L2Ca0p+EGO6c8MM1/xCfmMF60CR91hqAzM2rf3ZCkkIF65wxKiEb3yEK0EB2FL0hR0 rWTsWbGFDGCwMjKUZ0/3amA2kkm14QC7UuFqAM4D+TxL8TQbrjTp8o33vZJEfhjGafQv +R6A== 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 :organization:message-id:subject:cc:to:from:date:dkim-signature :dkim-signature; bh=N6MW5aW5/tskhoIcmGl6SK2Dnqzk5QXBiM+B1KNWi+M=; fh=x0jJsNqvJf19Uw72Eg8AHWuP/frbjQiIaeZz53SZjSY=; b=BZK6981keEwB1tN3RSh+RumK2s38IsSzGWeiQ/mHtooPsceNmGzcG4CK+Ji8XXs/ni yiBurzkXKjtXu4Aiy1Glwv51cnC129zrOAbXiOZyTdPy673bHCV72TfPns4VM1be8aYG ukoRbh7BTsF4t55qCZuTHpkEL/FlCNi+y49iY7YMzgYOVt3c8UomjqizloDmSdzM5Ymm OL0NvBatazX6DQt0GNUokfe6MOr2cZZ0GkiHbs+oix+ZVAhBarGzVj0yZMKLMybwYHqz iQ+r8N/x1hNc47bs22QKMTzlyWQ8xYmgsSrepQBwn6D6fQMZw0tnXygGtJg/Ei5BSQJ9 JKDA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@suse.de header.s=susede2_rsa header.b="HFN/G3NO"; dkim=neutral (no key) header.i=@suse.de header.s=susede2_ed25519 header.b=6V3NV94K; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=suse.de Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id i2-20020a1709061e4200b00987e4102ebfsi5423009ejj.993.2023.07.17.08.31.25; Mon, 17 Jul 2023 08:31:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@suse.de header.s=susede2_rsa header.b="HFN/G3NO"; dkim=neutral (no key) header.i=@suse.de header.s=susede2_ed25519 header.b=6V3NV94K; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=suse.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231159AbjGQPOd (ORCPT <rfc822;hadasmailinglist@gmail.com> + 99 others); Mon, 17 Jul 2023 11:14:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230325AbjGQPOc (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Mon, 17 Jul 2023 11:14:32 -0400 Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 08E3BE6; Mon, 17 Jul 2023 08:14:31 -0700 (PDT) Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id BCA761FDB2; Mon, 17 Jul 2023 15:14:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_rsa; t=1689606869; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=N6MW5aW5/tskhoIcmGl6SK2Dnqzk5QXBiM+B1KNWi+M=; b=HFN/G3NO2gGRJM0V2tN23lvvf+p8tEX7BxDFYshfltWNgK5bh5HzXMRSmxFALcdh1Zi7sh J2Y/7w91NF7TztNC0eW2dn3TC+4QOyIrbM6IH9sf5ofCljPKSQ7fVaypeBB04kINyIkJpn o2mrAdIWASJ1s+aP+WH90g+UfPUgiHE= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.de; s=susede2_ed25519; t=1689606869; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=N6MW5aW5/tskhoIcmGl6SK2Dnqzk5QXBiM+B1KNWi+M=; b=6V3NV94KetzMZuh2uY0q2C5Z1CjV5Sz2KS4KKoAkMKKJY8AUWGArLTLVLlzQZugD4Gwu8X VmaXOHFG2cfcnYAQ== Received: from imap2.suse-dmz.suse.de (imap2.suse-dmz.suse.de [192.168.254.74]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap2.suse-dmz.suse.de (Postfix) with ESMTPS id 9453513276; Mon, 17 Jul 2023 15:14:29 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap2.suse-dmz.suse.de with ESMTPSA id NSioItVatWTACAAAMHmgww (envelope-from <jdelvare@suse.de>); Mon, 17 Jul 2023 15:14:29 +0000 Date: Mon, 17 Jul 2023 17:14:28 +0200 From: Jean Delvare <jdelvare@suse.de> To: Luis Chamberlain <mcgrof@kernel.org> Cc: Michal Hocko <mhocko@suse.com>, linux-modules@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v2] module: print module name on refcount error Message-ID: <20230717171428.1b229215@endymion.delvare> Organization: SUSE Linux X-Mailer: Claws Mail 4.0.0 (GTK+ 3.24.34; x86_64-suse-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1771682303030038910 X-GMAIL-MSGID: 1771682303030038910 |
Series |
[v2] module: print module name on refcount error
|
|
Commit Message
Jean Delvare
July 17, 2023, 3:14 p.m. UTC
If module_put() triggers a refcount error, and the module data is
still readable, include the culprit module name in the warning
message, to easy further investigation of the issue.
If the module name can't be read, this means the module has already
been removed while references to it still exist. This is a
user-after-free situation, so report it as such.
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Suggested-by: Michal Hocko <mhocko@suse.com>
Cc: Luis Chamberlain <mcgrof@kernel.org>
---
Hi Luis, this is a different approach to my initial proposal. We no
longer assume that struct module is still available and instead check
that the expected module name string is a valid string before printing
it.
This is safer, and lets us print a better diagnostics message: include
the module name if struct module is still there (the most likely case
IMHO, as rmmod is a relatively rare operation) else explicitly report a
use after free.
The downside is that this requires more code, but I think it's worth
it. What do you think?
kernel/module/main.c | 31 ++++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
Comments
On Mon 17-07-23 17:14:28, Jean Delvare wrote: > If module_put() triggers a refcount error, and the module data is > still readable, include the culprit module name in the warning > message, to easy further investigation of the issue. > > If the module name can't be read, this means the module has already > been removed while references to it still exist. This is a > user-after-free situation, so report it as such. > > Signed-off-by: Jean Delvare <jdelvare@suse.de> > Suggested-by: Michal Hocko <mhocko@suse.com> > Cc: Luis Chamberlain <mcgrof@kernel.org> > --- > Hi Luis, this is a different approach to my initial proposal. We no > longer assume that struct module is still available and instead check > that the expected module name string is a valid string before printing > it. > > This is safer, and lets us print a better diagnostics message: include > the module name if struct module is still there (the most likely case > IMHO, as rmmod is a relatively rare operation) else explicitly report a > use after free. > > The downside is that this requires more code, but I think it's worth > it. What do you think? Quite honestly, I do not think that extra ode is worth the risk. If the module could have been removed then we are in a bigger problem and trying to do some cosmetic checks doesn't help all that much IMHO. It is good idea to cap the name to MODULE_NAME_LEN to be bound on a garbage output. > > kernel/module/main.c | 31 ++++++++++++++++++++++++++++++- > 1 file changed, 30 insertions(+), 1 deletion(-) > > --- linux-6.3.orig/kernel/module/main.c > +++ linux-6.3/kernel/module/main.c > @@ -55,6 +55,7 @@ > #include <linux/dynamic_debug.h> > #include <linux/audit.h> > #include <linux/cfi.h> > +#include <linux/ctype.h> > #include <uapi/linux/module.h> > #include "internal.h" > > @@ -850,7 +851,35 @@ void module_put(struct module *module) > if (module) { > preempt_disable(); > ret = atomic_dec_if_positive(&module->refcnt); > - WARN_ON(ret < 0); /* Failed to put refcount */ > + if (ret < 0) { > + unsigned char modname_copy[MODULE_NAME_LEN]; > + unsigned char *p, *end; > + bool sane; > + > + /* > + * Report faulty module if name is still readable. > + * We must be careful here as the module may have > + * been already freed. > + */ > + memcpy(modname_copy, module->name, MODULE_NAME_LEN); > + end = memchr(modname_copy, '\0', MODULE_NAME_LEN); > + sane = end != NULL; > + if (sane) { > + for (p = modname_copy; p < end; p++) > + if (!isgraph(*p)) { > + sane = false; > + break; > + } > + } > + > + if (sane) > + WARN(1, > + KERN_WARNING "Failed to put refcount for module %s\n", > + modname_copy); > + else > + WARN(1, > + KERN_WARNING "Failed to put refcount, use-after-free detected\n"); > + } > trace_module_put(module, _RET_IP_); > preempt_enable(); > } > > > -- > Jean Delvare > SUSE L3 Support
--- linux-6.3.orig/kernel/module/main.c +++ linux-6.3/kernel/module/main.c @@ -55,6 +55,7 @@ #include <linux/dynamic_debug.h> #include <linux/audit.h> #include <linux/cfi.h> +#include <linux/ctype.h> #include <uapi/linux/module.h> #include "internal.h" @@ -850,7 +851,35 @@ void module_put(struct module *module) if (module) { preempt_disable(); ret = atomic_dec_if_positive(&module->refcnt); - WARN_ON(ret < 0); /* Failed to put refcount */ + if (ret < 0) { + unsigned char modname_copy[MODULE_NAME_LEN]; + unsigned char *p, *end; + bool sane; + + /* + * Report faulty module if name is still readable. + * We must be careful here as the module may have + * been already freed. + */ + memcpy(modname_copy, module->name, MODULE_NAME_LEN); + end = memchr(modname_copy, '\0', MODULE_NAME_LEN); + sane = end != NULL; + if (sane) { + for (p = modname_copy; p < end; p++) + if (!isgraph(*p)) { + sane = false; + break; + } + } + + if (sane) + WARN(1, + KERN_WARNING "Failed to put refcount for module %s\n", + modname_copy); + else + WARN(1, + KERN_WARNING "Failed to put refcount, use-after-free detected\n"); + } trace_module_put(module, _RET_IP_); preempt_enable(); }