From patchwork Thu Nov 10 15:45:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Jason A. Donenfeld" X-Patchwork-Id: 18189 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:6687:0:0:0:0:0 with SMTP id l7csp221279wru; Thu, 10 Nov 2022 07:47:08 -0800 (PST) X-Google-Smtp-Source: AMsMyM7sK0Ro0YtRlRWuAFozzYNic8dfB6Ca/JH4kpodebrxCGpxnacKoezHnySfcqT+9BW6LX1B X-Received: by 2002:a05:6402:4504:b0:457:21ad:edea with SMTP id ez4-20020a056402450400b0045721adedeamr2546649edb.291.1668095228534; Thu, 10 Nov 2022 07:47:08 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1668095228; cv=none; d=google.com; s=arc-20160816; b=aP0B38ePRS5zrujPJse4zB2kFnapOgiMrUNM6qZp5GDNy65oOFW7PY2+nLeXtbklsj EjoRAxlvxQFpG3RYnNV8AwZBEGwHp4C9O1PDg5X28LPHvviLY9wGyEm6ij7Zu1ebZ+M2 seSirCjx08+6ESh+SgkcWBXD6focIFrRWmdo8IY7wuiTqLgtoCwn+2vWAB4HmWiOED3b d9nWP3XdjeIelfbniuWAhD7Q6qAj/62OZH7hs7o8+PTTopJi7hodsUOg4Y+tw7SCFvpJ eEqj09Hvr/yF9ZIeF7CnwrmTZKcoJmOxwECqXJ5rdheQu090Rz3JWjzKEzS/REoqy2QF VvIA== 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:dkim-signature; bh=Ps8DyLnWUFEOMzV5Hl0ko397uOHYl+uddPYlp1wLApA=; b=rgdmltAjnKbXU6KHyEFgLDFuD2g5cv+y302WdzdSVemwYitWo8nZdT5TJoXc0oLy7g 22g0hXSP4Lcl53HPDldBk/HJzCxPUwO1TIkptQ5eBX+OX9ADGCj3dmrtegaHar+qE0Y8 0eHLWWMypNDiaqS3DjT9g4iWuTaU5Ms/BXEZU66Fm3mNccPakgNr0s7wGehV3GCFEysu yge0w0QBg0HNFRifiNPLhcygB6mjMZOwlxQQCujVTnP1Z05pCuPfKWwXV5nwaULi50+f 5cDjo9z8iGxo/FOVdx14JYYAMxKwTjtj5emBw9jFFT+iY13gY0Y0waXJP8BA1Q7h84Pr gL8w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@zx2c4.com header.s=20210105 header.b=c5sSVGv6; 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=QUARANTINE sp=QUARANTINE dis=NONE) header.from=zx2c4.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id jz11-20020a170906bb0b00b00787aba35b7asi14909480ejb.102.2022.11.10.07.46.44; Thu, 10 Nov 2022 07:47:08 -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=@zx2c4.com header.s=20210105 header.b=c5sSVGv6; 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=QUARANTINE sp=QUARANTINE dis=NONE) header.from=zx2c4.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231511AbiKJPqZ (ORCPT + 99 others); Thu, 10 Nov 2022 10:46:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60396 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229703AbiKJPqY (ORCPT ); Thu, 10 Nov 2022 10:46:24 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ED4C022B14; Thu, 10 Nov 2022 07:46:22 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 7ABFCB82224; Thu, 10 Nov 2022 15:46:21 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6857AC433C1; Thu, 10 Nov 2022 15:46:19 +0000 (UTC) Authentication-Results: smtp.kernel.org; dkim=pass (1024-bit key) header.d=zx2c4.com header.i=@zx2c4.com header.b="c5sSVGv6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=zx2c4.com; s=20210105; t=1668095176; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding; bh=Ps8DyLnWUFEOMzV5Hl0ko397uOHYl+uddPYlp1wLApA=; b=c5sSVGv6D3cV3lHNPMTzl8p/lxxtl99+WBdwq8MiWaQvqdWmiWnsbgwBDBGUEM4HhVm0C2 GhC8wkz5IEFE0gm1h3tCP1+av16pMxsvH//4bYbufxRTzdJtM+bg65b1365iXrl19AZJoq ME2zkmPmdY0Zoxg5O0T4TcXBcNuhOGk= Received: by mail.zx2c4.com (ZX2C4 Mail Server) with ESMTPSA id fd02204a (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Thu, 10 Nov 2022 15:46:16 +0000 (UTC) From: "Jason A. Donenfeld" To: linux-efi@vger.kernel.org, linux-kernel@vger.kernel.org, ardb@kernel.org Cc: "Jason A. Donenfeld" , Jeremy Kerr , Matthew Garrett , Lennart Poettering Subject: [PATCH] efi: vars: allow passing fmode= and dmode= when mounting Date: Thu, 10 Nov 2022 16:45:47 +0100 Message-Id: <20221110154547.472519-1-Jason@zx2c4.com> MIME-Version: 1.0 X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_HI,SPF_HELO_NONE,SPF_PASS 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 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1749124622336152480?= X-GMAIL-MSGID: =?utf-8?q?1749124622336152480?= The default wide-open permissions of efivarfs make the prospect of storing secrets there a bit sketchy. Currently systemd does this, and then pid 1 takes care of chmodding particular nodes. But this is limited and error-prone. Rather, allow passing an explicit dmode for directories and fmode for files. Cc: Ard Biesheuvel Cc: Jeremy Kerr Cc: Matthew Garrett Suggested-by: Lennart Poettering Signed-off-by: Jason A. Donenfeld --- fs/efivarfs/internal.h | 5 ++++ fs/efivarfs/super.c | 60 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 60 insertions(+), 5 deletions(-) diff --git a/fs/efivarfs/internal.h b/fs/efivarfs/internal.h index 8ebf3a6a8aa2..ea1ca322d247 100644 --- a/fs/efivarfs/internal.h +++ b/fs/efivarfs/internal.h @@ -24,6 +24,11 @@ struct efivar_entry { struct kobject kobj; }; +struct efivarfs_sb_info { + umode_t dmode; + umode_t fmode; +}; + int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), void *data, bool duplicates, struct list_head *head); diff --git a/fs/efivarfs/super.c b/fs/efivarfs/super.c index 6780fc81cc11..45edbb1550e9 100644 --- a/fs/efivarfs/super.c +++ b/fs/efivarfs/super.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -107,6 +108,7 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor, unsigned long name_size, void *data) { struct super_block *sb = (struct super_block *)data; + struct efivarfs_sb_info *sbi = sb->s_fs_info; struct efivar_entry *entry; struct inode *inode = NULL; struct dentry *dentry, *root = sb->s_root; @@ -144,7 +146,7 @@ static int efivarfs_callback(efi_char16_t *name16, efi_guid_t vendor, /* replace invalid slashes like kobject_set_name_vargs does for /sys/firmware/efi/vars. */ strreplace(name, '/', '!'); - inode = efivarfs_get_inode(sb, d_inode(root), S_IFREG | 0644, 0, + inode = efivarfs_get_inode(sb, d_inode(root), S_IFREG | sbi->fmode, 0, is_removable); if (!inode) goto fail_name; @@ -187,6 +189,7 @@ static int efivarfs_destroy(struct efivar_entry *entry, void *data) static int efivarfs_fill_super(struct super_block *sb, struct fs_context *fc) { + struct efivarfs_sb_info *sbi = sb->s_fs_info; struct inode *inode = NULL; struct dentry *root; int err; @@ -202,7 +205,7 @@ static int efivarfs_fill_super(struct super_block *sb, struct fs_context *fc) if (!efivar_supports_writes()) sb->s_flags |= SB_RDONLY; - inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0, true); + inode = efivarfs_get_inode(sb, NULL, S_IFDIR | sbi->dmode, 0, true); if (!inode) return -ENOMEM; inode->i_op = &efivarfs_dir_inode_operations; @@ -226,12 +229,58 @@ static int efivarfs_get_tree(struct fs_context *fc) return get_tree_single(fc, efivarfs_fill_super); } +enum { + Opt_dmode, + Opt_fmode, +}; + +static const struct fs_parameter_spec efivarfs_parameters[] = { + fsparam_u32oct("dmode", Opt_dmode), + fsparam_u32oct("fmode", Opt_fmode), + {} +}; + +static int efivarfs_parse_param(struct fs_context *fc, + struct fs_parameter *param) +{ + struct efivarfs_sb_info *sbi = fc->s_fs_info; + struct fs_parse_result result; + int opt; + + opt = fs_parse(fc, efivarfs_parameters, param, &result); + if (opt < 0) + return opt; + + switch (opt) { + case Opt_dmode: + sbi->dmode = result.uint_32; + break; + case Opt_fmode: + sbi->fmode = result.uint_32; + break; + default: + return -EINVAL; + } + + return 0; +} + static const struct fs_context_operations efivarfs_context_ops = { .get_tree = efivarfs_get_tree, + .parse_param = efivarfs_parse_param, }; static int efivarfs_init_fs_context(struct fs_context *fc) { + struct efivarfs_sb_info *sbi; + + sbi = kzalloc(sizeof(*sbi), GFP_KERNEL); + if (!sbi) + return -ENOMEM; + sbi->dmode = 0755; + sbi->fmode = 0644; + fc->s_fs_info = sbi; + fc->ops = &efivarfs_context_ops; return 0; } @@ -245,10 +294,11 @@ static void efivarfs_kill_sb(struct super_block *sb) } static struct file_system_type efivarfs_type = { - .owner = THIS_MODULE, - .name = "efivarfs", + .owner = THIS_MODULE, + .name = "efivarfs", .init_fs_context = efivarfs_init_fs_context, - .kill_sb = efivarfs_kill_sb, + .parameters = efivarfs_parameters, + .kill_sb = efivarfs_kill_sb, }; static __init int efivarfs_init(void)