Skip to content

Commit 4c975a4

Browse files
committed
Merge tag 'efi-next-for-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi
Pull EFI update from Ard Biesheuvel: "This is the only remaining EFI change, as everything else was taken via -tip this cycle: - implement uid/gid mount options for efivarfs" * tag 'efi-next-for-v6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi: efivarfs: Add uid/gid mount options
2 parents 0a23fb2 + 5329aa5 commit 4c975a4

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

fs/efivarfs/inode.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@ struct inode *efivarfs_get_inode(struct super_block *sb,
2121
dev_t dev, bool is_removable)
2222
{
2323
struct inode *inode = new_inode(sb);
24+
struct efivarfs_fs_info *fsi = sb->s_fs_info;
25+
struct efivarfs_mount_opts *opts = &fsi->mount_opts;
2426

2527
if (inode) {
28+
inode->i_uid = opts->uid;
29+
inode->i_gid = opts->gid;
2630
inode->i_ino = get_next_ino();
2731
inode->i_mode = mode;
2832
simple_inode_init_ts(inode);

fs/efivarfs/internal.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,15 @@
99
#include <linux/list.h>
1010
#include <linux/efi.h>
1111

12+
struct efivarfs_mount_opts {
13+
kuid_t uid;
14+
kgid_t gid;
15+
};
16+
17+
struct efivarfs_fs_info {
18+
struct efivarfs_mount_opts mount_opts;
19+
};
20+
1221
struct efi_variable {
1322
efi_char16_t VariableName[EFI_VAR_NAME_LEN/sizeof(efi_char16_t)];
1423
efi_guid_t VendorGuid;

fs/efivarfs/super.c

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <linux/efi.h>
99
#include <linux/fs.h>
1010
#include <linux/fs_context.h>
11+
#include <linux/fs_parser.h>
1112
#include <linux/module.h>
1213
#include <linux/pagemap.h>
1314
#include <linux/ucs2_string.h>
@@ -24,6 +25,21 @@ static void efivarfs_evict_inode(struct inode *inode)
2425
clear_inode(inode);
2526
}
2627

28+
static int efivarfs_show_options(struct seq_file *m, struct dentry *root)
29+
{
30+
struct super_block *sb = root->d_sb;
31+
struct efivarfs_fs_info *sbi = sb->s_fs_info;
32+
struct efivarfs_mount_opts *opts = &sbi->mount_opts;
33+
34+
if (!uid_eq(opts->uid, GLOBAL_ROOT_UID))
35+
seq_printf(m, ",uid=%u",
36+
from_kuid_munged(&init_user_ns, opts->uid));
37+
if (!gid_eq(opts->gid, GLOBAL_ROOT_GID))
38+
seq_printf(m, ",gid=%u",
39+
from_kgid_munged(&init_user_ns, opts->gid));
40+
return 0;
41+
}
42+
2743
static int efivarfs_statfs(struct dentry *dentry, struct kstatfs *buf)
2844
{
2945
const u32 attr = EFI_VARIABLE_NON_VOLATILE |
@@ -70,6 +86,7 @@ static const struct super_operations efivarfs_ops = {
7086
.statfs = efivarfs_statfs,
7187
.drop_inode = generic_delete_inode,
7288
.evict_inode = efivarfs_evict_inode,
89+
.show_options = efivarfs_show_options,
7390
};
7491

7592
/*
@@ -231,6 +248,45 @@ static int efivarfs_destroy(struct efivar_entry *entry, void *data)
231248
return 0;
232249
}
233250

251+
enum {
252+
Opt_uid, Opt_gid,
253+
};
254+
255+
static const struct fs_parameter_spec efivarfs_parameters[] = {
256+
fsparam_u32("uid", Opt_uid),
257+
fsparam_u32("gid", Opt_gid),
258+
{},
259+
};
260+
261+
static int efivarfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
262+
{
263+
struct efivarfs_fs_info *sbi = fc->s_fs_info;
264+
struct efivarfs_mount_opts *opts = &sbi->mount_opts;
265+
struct fs_parse_result result;
266+
int opt;
267+
268+
opt = fs_parse(fc, efivarfs_parameters, param, &result);
269+
if (opt < 0)
270+
return opt;
271+
272+
switch (opt) {
273+
case Opt_uid:
274+
opts->uid = make_kuid(current_user_ns(), result.uint_32);
275+
if (!uid_valid(opts->uid))
276+
return -EINVAL;
277+
break;
278+
case Opt_gid:
279+
opts->gid = make_kgid(current_user_ns(), result.uint_32);
280+
if (!gid_valid(opts->gid))
281+
return -EINVAL;
282+
break;
283+
default:
284+
return -EINVAL;
285+
}
286+
287+
return 0;
288+
}
289+
234290
static int efivarfs_fill_super(struct super_block *sb, struct fs_context *fc)
235291
{
236292
struct inode *inode = NULL;
@@ -277,10 +333,21 @@ static int efivarfs_get_tree(struct fs_context *fc)
277333

278334
static const struct fs_context_operations efivarfs_context_ops = {
279335
.get_tree = efivarfs_get_tree,
336+
.parse_param = efivarfs_parse_param,
280337
};
281338

282339
static int efivarfs_init_fs_context(struct fs_context *fc)
283340
{
341+
struct efivarfs_fs_info *sfi;
342+
343+
sfi = kzalloc(sizeof(*sfi), GFP_KERNEL);
344+
if (!sfi)
345+
return -ENOMEM;
346+
347+
sfi->mount_opts.uid = GLOBAL_ROOT_UID;
348+
sfi->mount_opts.gid = GLOBAL_ROOT_GID;
349+
350+
fc->s_fs_info = sfi;
284351
fc->ops = &efivarfs_context_ops;
285352
return 0;
286353
}
@@ -301,6 +368,7 @@ static struct file_system_type efivarfs_type = {
301368
.name = "efivarfs",
302369
.init_fs_context = efivarfs_init_fs_context,
303370
.kill_sb = efivarfs_kill_sb,
371+
.parameters = efivarfs_parameters,
304372
};
305373

306374
static __init int efivarfs_init(void)

0 commit comments

Comments
 (0)