Received: by 2002:a05:6358:d09b:b0:dc:cd0c:909e with SMTP id jc27csp7398240rwb; Tue, 15 Nov 2022 11:39:18 -0800 (PST) X-Google-Smtp-Source: AA0mqf6d5Ve8Q/RbjpnMC+EppXAubyTYP/jd0G4wId1u+TdczIHlqy8eC4ASKAYORIPI/sZcjxQw X-Received: by 2002:a17:907:76f1:b0:7ae:129b:2d3a with SMTP id kg17-20020a17090776f100b007ae129b2d3amr14872783ejc.552.1668541157879; Tue, 15 Nov 2022 11:39:17 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668541157; cv=none; d=google.com; s=arc-20160816; b=WWHqPQPKL66ppY8bQw+TLlhcXRfTHlzmPHUPVfA3z1NmJ4gEWHwh7gs89VQ3wAMssK FiDNQEtyl8W2IjPJ6sys3xrXWPsCFHP0otPcolcnuS7VpzkeotiWdekD06hvv0xKr9Mm YpdB5pPaX7yynYXsXLEOoXiDFLE8YM8QSD/KMZWMciKpWWk51SPi58vuRICwS1F5000y /wW7vAo/uymFQs4tS3IwMSmokglg1+XPf74VbfXXREpWN108L2iGUsP5R5HVxyq8QBjP dpS13GTMq4HXSQmqF670be3VEmLFjxOfcum96RBuk2MvTm4kXCfp2d9s9Ar0g+lc5j9A /2aQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date :dkim-signature; bh=mgO4rRXdMPTGi5Q4zNT8/529jd3tvagEvnNVftk04JQ=; b=YROXIds+hbJg2VCPGkoCXqQhY1TOxWn24oaNnywaUVhy0NreSh8/sDnlQiv46crMqw c3FRMnnRLi5CyIPdU0iwLXcdhKtytc1ncbOEhmwpYRjiKMm5VhZCEXAnJ+5lzYRAnbQO Z5arGwn9caKIlHOssg4ATXQwtKwnKJHb0YtcfhDovHYbTlRFh9BtqxIKUsBeGyX7BMGk aMe6IWCqWLBs2OBZXHMRBt9B+RrTffwztv+7EVML+iGECK6nvJyQxPHcSIQBY/QWBDKV KGLST32696dsFua1tI0fyIbMek6ChWxLgskChnkMth2C1cllPurevfJ04ehZabOBrMGj uSyg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@infradead.org header.s=bombadil.20210309 header.b=GfkGU3Ys; 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=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id he14-20020a1709073d8e00b007ad88f87ed6si13917171ejc.993.2022.11.15.11.38.53; Tue, 15 Nov 2022 11:39:17 -0800 (PST) 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=@infradead.org header.s=bombadil.20210309 header.b=GfkGU3Ys; 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=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231232AbiKOTfh (ORCPT + 91 others); Tue, 15 Nov 2022 14:35:37 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38456 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231175AbiKOTfZ (ORCPT ); Tue, 15 Nov 2022 14:35:25 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 58E23B7D7 for ; Tue, 15 Nov 2022 11:35:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Sender:In-Reply-To:Content-Type: MIME-Version:References:Message-ID:Subject:Cc:To:From:Date:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=mgO4rRXdMPTGi5Q4zNT8/529jd3tvagEvnNVftk04JQ=; b=GfkGU3YspjFGPAC0f9Ozgqdh1D aVpTM4IoJS3HLfE0vvX9qCO4Kg07XgVH3nAp3xcedmUW/H1Xou0hf5mUakK2uxou4E0KgRGNv+xr0 yLw0ArbpZp8YKkQXoWI2cxxeYY9l9dRqwMA1SRF7wFOJ689kviPqUGY0ia22CiW2jkJLfFMYzhUvv XbQgMGyzM7wnz1wLTQlrO7Xw//l/g7r8IR3QsGwrdv3H2QU/VDbggzngdCeok0DN4MfBdA0bgKJrq ujEO1QMWJfMaQePE9QFRsHdVjHQkDVEm15CLIdb5lT5dBI9S4KcHEG4IOrHUQx3ovqsY23Lpy1pZS Y1xID40g==; Received: from mcgrof by bombadil.infradead.org with local (Exim 4.94.2 #2 (Red Hat Linux)) id 1ov1iA-00EJQ3-Ve; Tue, 15 Nov 2022 19:35:10 +0000 Date: Tue, 15 Nov 2022 11:35:10 -0800 From: Luis Chamberlain To: Dmitry Torokhov Cc: Tejun Heo , Matthieu Castet , Stanislaw Gruszka , ming.lei@redhat.com, Hillf Danton , syzbot , linux-kernel@vger.kernel.org, syzkaller-bugs@googlegroups.com Subject: Re: [syzbot] KASAN: use-after-free Read in kernfs_next_descendant_post (2) Message-ID: References: <000000000000c183f505eb721745@google.com> <20221021225228.1750-1-hdanton@sina.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: Sender: Luis Chamberlain X-Spam-Status: No, score=-4.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_EF,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_NONE 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: X-Mailing-List: linux-kernel@vger.kernel.org On Mon, Nov 14, 2022 at 10:07:02AM -0800, Dmitry Torokhov wrote: > I do not see how moving the point where we acquire device refcount > around fixes anything. The patch I posted does two things, moving the point where we acquire device refcount was just one so it was not clear that what I really wanted to be enforce a check for first, and that is that the driver *did* do the correct thing. So while we can surely expect the driver to do proper device refcounting and waiting on device removal, buggy drivers do exist and we should strive to not allow UAF with them. So something like this: From 92c8f4465a205e744c70dcba320708f72900442e Mon Sep 17 00:00:00 2001 From: Luis Chamberlain Date: Tue, 15 Nov 2022 10:02:13 -0800 Subject: [PATCH] firmware_loader: avoid UAF on buggy request_firmware_nowait() users request_firmware_nowait() is documented as requiring the caller to ensure to maintain the the reference count of @device during the lifetime of the call to request_firmware_nowait() and the callback. It would seem drivers exist which don't follow these rules though, and things like syzbot can trigger UAF if the device gets nuked as request_firmware_nowait() is being called. Instead of enabling use UAF, defend against such improperly written drivers and complain about it. Make the documentaiton a bit clearer and give a hint as to how to easily accomplish device lifetime maintenance on the driver using a completion and a wait_for_completion(). Fixes: 0cfc1e1e7b534 ("firmware loader: fix device lifetime") Fixes: f8a4bd3456b98 ("firmware loader: embed device into firmware_priv structure") Cc: stable@vger.kernel.org # v2.6.36 Reported-by: syzbot+6bc35f3913193fe7f0d3@syzkaller.appspotmail.com Signed-off-by: Luis Chamberlain --- drivers/base/firmware_loader/main.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/base/firmware_loader/main.c b/drivers/base/firmware_loader/main.c index 7c3590fd97c2..6ac92dfdd85e 100644 --- a/drivers/base/firmware_loader/main.c +++ b/drivers/base/firmware_loader/main.c @@ -1118,15 +1118,16 @@ static void request_firmware_work_func(struct work_struct *work) * @uevent: sends uevent to copy the firmware image if this flag * is non-zero else the firmware copy must be done manually. * @name: name of firmware file - * @device: device for which firmware is being loaded + * @device: device for which firmware is being loaded. The caller must hold + * the reference count of @device during the lifetime of this routine + * and the @cont callback. This typically can be done with a completion + * and wait_for_completion prior to device teardown. * @gfp: allocation flags * @context: will be passed over to @cont, and * @fw may be %NULL if firmware request fails. * @cont: function will be called asynchronously when the firmware * request is over. * - * Caller must hold the reference count of @device. - * * Asynchronous variant of request_firmware() for user contexts: * - sleep for as small periods as possible since it may * increase kernel boot time of built-in device drivers @@ -1171,7 +1172,12 @@ request_firmware_nowait( return -EFAULT; } - get_device(fw_work->device); + if (WARN_ON(!get_device(fw_work->device))) { + module_put(module); + kfree_const(fw_work->name); + kfree(fw_work); + return -ENODEV; + } INIT_WORK(&fw_work->work, request_firmware_work_func); schedule_work(&fw_work->work); return 0; -- 2.35.1