From patchwork Thu Nov 9 21:22:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Johannes Berg X-Patchwork-Id: 163611 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:b129:0:b0:403:3b70:6f57 with SMTP id q9csp722759vqs; Thu, 9 Nov 2023 13:40:46 -0800 (PST) X-Google-Smtp-Source: AGHT+IF8FX7FiCN7vgfNF3LYato+6teQEqPIDJ8uA9qLPj8qh2kQBbcPmXzZofLgGmN1KUhd4F2S X-Received: by 2002:a05:6a00:b46:b0:6be:2ace:deb8 with SMTP id p6-20020a056a000b4600b006be2acedeb8mr7487351pfo.20.1699566045818; Thu, 09 Nov 2023 13:40:45 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699566045; cv=none; d=google.com; s=arc-20160816; b=ZRJnmz7cnpjF6Wb15hWtlABs2d6NXTm7SQxkM2BIEHqcV5AZBsI8R4VWyx6sN5yAfq XU+Sati/VfF+RFWCrn1RfPBTeUbxZzmyMn0sGUQGkI04JfHA+N7lclYHryUVqwc4adoR NdFQIz4GLEV47OxKRdZAuqqZ4K4Z55DKfZ3VwypO9vVk5dMw4aR3A/jO1D85EBRiMiOs rjvH4HyJDYvGgr/zCqCdcNXuMVpqal2pQG835SqIYWfjpiWwBw0Qf1+bFm68aWqUWTkh AdU0KUDR0PnIVKzx64+FqjcTbRHJUiVQLQ9jrwnnMgefMGQ+O0HjhdCYU6dUu3/640/t aQCw== 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 :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=6ZT7FJvDZFk52iLWTs4ADJtCF3Ou7kQeTljiE1vVw8M=; fh=fr6hIKaSb7E+0K08IHhjy1pQvdN8X98xxmR7pnwhgag=; b=QjJ7KkfdJM+PvWZMOfIINnpRkDjT58qGNqN2QRZZj9G9f8K73hoB+rH4NUocYmeBit bFHFmr/57aPpHUuheNj2Pp7bkIGt50gdPsRlamBDHpqAD6VkZcsGMB+AMWjEwpgBNcw/ Rk3MmHawvP69w4HgtV3VmQ+dIg2ZyZSvvW/RBhV0HODDP1jQQKcvZ07kzRWJkl+MB48z hnSmhZN8C1rpLG3bQ2ljwdTxGcfISgWb3u70elWqpqRSEjnhdKwlishUt3k3dRkjY0op Zz/SbR8Xu3leq2bOCJccQ70pryic81dnTMoNdjmpAJJB+3amQo2wm2Ncb/++bu6sjeMF CTJg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=UAdlYhOA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from lipwig.vger.email (lipwig.vger.email. [23.128.96.33]) by mx.google.com with ESMTPS id ea27-20020a056a004c1b00b0068fcf6fe22esi17137532pfb.306.2023.11.09.13.40.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Nov 2023 13:40:45 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) client-ip=23.128.96.33; Authentication-Results: mx.google.com; dkim=pass header.i=@sipsolutions.net header.s=mail header.b=UAdlYhOA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=REJECT dis=NONE) header.from=sipsolutions.net Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id E76828060CA4; Thu, 9 Nov 2023 13:38:58 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345265AbjKIViY (ORCPT + 30 others); Thu, 9 Nov 2023 16:38:24 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42250 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345257AbjKIViW (ORCPT ); Thu, 9 Nov 2023 16:38:22 -0500 Received: from sipsolutions.net (s3.sipsolutions.net [IPv6:2a01:4f8:242:246e::2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7EBF43C39; Thu, 9 Nov 2023 13:38:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sipsolutions.net; s=mail; h=Content-Transfer-Encoding:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Content-Type:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From:Resent-To: Resent-Cc:Resent-Message-ID; bh=6ZT7FJvDZFk52iLWTs4ADJtCF3Ou7kQeTljiE1vVw8M=; t=1699565900; x=1700775500; b=UAdlYhOAvjrHYOPAbb2Mb8zNSg97SFKyj7Cpn+Y/RdoYZ1u +yHSpkU98GF4XU0nsiSTUsX/Hu186weqvkIKluzsGVehfN0TRaoeHwHohx0xtoFJoVpuKN3I1bYMU FsPxo/uwDa27c6G9HNR8LijMmQFG5PTf/o4FRLL6fpb2c94T4+MHvJsL4it87tZs4gmFXS2ytZ7S4 9z9IoMIgL4EtqMqirlgMgDUxxu8lsHsCgUTq+HAoolmn+CqRGxD0eDUXCvONr0GB/nxqdA/bAOwSt GDR2Iw81HONfl95SrVKojS6/cfvFUp+HSWhVMUVRn/nWFqfQsdWVFPJR3egkqstw==; Received: by sipsolutions.net with esmtpsa (TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256) (Exim 4.97) (envelope-from ) id 1r1CjB-00000001znF-1Xz5; Thu, 09 Nov 2023 22:38:17 +0100 From: Johannes Berg To: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, Greg Kroah-Hartman , "Rafael J. Wysocki" , Nicolai Stange , Ben Greear , Johannes Berg Subject: [RFC PATCH 1/6] debugfs: fix automount d_fsdata usage Date: Thu, 9 Nov 2023 22:22:53 +0100 Message-ID: <20231109222251.9e54cb55c700.I64fe5615568e87f9ae2d7fb2ac4e5fa96924cb50@changeid> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231109212251.213873-7-johannes@sipsolutions.net> References: <20231109212251.213873-7-johannes@sipsolutions.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (lipwig.vger.email [0.0.0.0]); Thu, 09 Nov 2023 13:38:59 -0800 (PST) X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782124166176939338 X-GMAIL-MSGID: 1782124166176939338 From: Johannes Berg debugfs_create_automount() stores a function pointer in d_fsdata, but since commit 7c8d469877b1 ("debugfs: add support for more elaborate ->d_fsdata") debugfs_release_dentry() will free it, now conditionally on DEBUGFS_FSDATA_IS_REAL_FOPS_BIT, but that's not set for the function pointer in automount. As a result, removing an automount dentry would attempt to free the function pointer. Luckily, the only user of this (tracing) never removes it. Nevertheless, it's safer if we just handle the fsdata in one way, namely either DEBUGFS_FSDATA_IS_REAL_FOPS_BIT or allocated. Thus, change the automount to allocate it, and use the real_fops in the data to indicate whether or not automount is filled, rather than adding a type tag. At least for now this isn't actually needed, but the next changes will require it. Also check in debugfs_file_get() that it gets only called on regular files, just to make things clearer. Signed-off-by: Johannes Berg --- fs/debugfs/file.c | 3 +++ fs/debugfs/inode.c | 25 ++++++++++++++++++------- fs/debugfs/internal.h | 10 ++++++++-- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 87b3753aa4b1..23bdfc126b5e 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -84,6 +84,9 @@ int debugfs_file_get(struct dentry *dentry) struct debugfs_fsdata *fsd; void *d_fsd; + if (WARN_ON(!d_is_reg(dentry))) + return -EINVAL; + d_fsd = READ_ONCE(dentry->d_fsdata); if (!((unsigned long)d_fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)) { fsd = d_fsd; diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index 83e57e9f9fa0..269bad87d552 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -236,17 +236,19 @@ static const struct super_operations debugfs_super_operations = { static void debugfs_release_dentry(struct dentry *dentry) { - void *fsd = dentry->d_fsdata; + struct debugfs_fsdata *fsd = dentry->d_fsdata; - if (!((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT)) - kfree(dentry->d_fsdata); + if ((unsigned long)fsd & DEBUGFS_FSDATA_IS_REAL_FOPS_BIT) + return; + + kfree(fsd); } static struct vfsmount *debugfs_automount(struct path *path) { - debugfs_automount_t f; - f = (debugfs_automount_t)path->dentry->d_fsdata; - return f(path->dentry, d_inode(path->dentry)->i_private); + struct debugfs_fsdata *fsd = path->dentry->d_fsdata; + + return fsd->automount(path->dentry, d_inode(path->dentry)->i_private); } static const struct dentry_operations debugfs_dops = { @@ -634,11 +636,20 @@ struct dentry *debugfs_create_automount(const char *name, void *data) { struct dentry *dentry = start_creating(name, parent); + struct debugfs_fsdata *fsd; struct inode *inode; if (IS_ERR(dentry)) return dentry; + fsd = kzalloc(sizeof(*fsd), GFP_KERNEL); + if (!fsd) { + failed_creating(dentry); + return ERR_PTR(-ENOMEM); + } + + fsd->automount = f; + if (!(debugfs_allow & DEBUGFS_ALLOW_API)) { failed_creating(dentry); return ERR_PTR(-EPERM); @@ -654,7 +665,7 @@ struct dentry *debugfs_create_automount(const char *name, make_empty_dir_inode(inode); inode->i_flags |= S_AUTOMOUNT; inode->i_private = data; - dentry->d_fsdata = (void *)f; + dentry->d_fsdata = fsd; /* directory inodes start off with i_nlink == 2 (for "." entry) */ inc_nlink(inode); d_instantiate(dentry, inode); diff --git a/fs/debugfs/internal.h b/fs/debugfs/internal.h index 92af8ae31313..f7c489b5a368 100644 --- a/fs/debugfs/internal.h +++ b/fs/debugfs/internal.h @@ -17,8 +17,14 @@ extern const struct file_operations debugfs_full_proxy_file_operations; struct debugfs_fsdata { const struct file_operations *real_fops; - refcount_t active_users; - struct completion active_users_drained; + union { + /* automount_fn is used when real_fops is NULL */ + debugfs_automount_t automount; + struct { + refcount_t active_users; + struct completion active_users_drained; + }; + }; }; /*