Skip to content

Commit 2aafd0d

Browse files
committed
Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git
2 parents 57d3744 + 5329aa5 commit 2aafd0d

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 |
@@ -72,6 +88,7 @@ static const struct super_operations efivarfs_ops = {
7288
.statfs = efivarfs_statfs,
7389
.drop_inode = generic_delete_inode,
7490
.evict_inode = efivarfs_evict_inode,
91+
.show_options = efivarfs_show_options,
7592
};
7693

7794
/*
@@ -233,6 +250,45 @@ static int efivarfs_destroy(struct efivar_entry *entry, void *data)
233250
return 0;
234251
}
235252

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

280336
static const struct fs_context_operations efivarfs_context_ops = {
281337
.get_tree = efivarfs_get_tree,
338+
.parse_param = efivarfs_parse_param,
282339
};
283340

284341
static int efivarfs_init_fs_context(struct fs_context *fc)
285342
{
343+
struct efivarfs_fs_info *sfi;
344+
345+
sfi = kzalloc(sizeof(*sfi), GFP_KERNEL);
346+
if (!sfi)
347+
return -ENOMEM;
348+
349+
sfi->mount_opts.uid = GLOBAL_ROOT_UID;
350+
sfi->mount_opts.gid = GLOBAL_ROOT_GID;
351+
352+
fc->s_fs_info = sfi;
286353
fc->ops = &efivarfs_context_ops;
287354
return 0;
288355
}
@@ -303,6 +370,7 @@ static struct file_system_type efivarfs_type = {
303370
.name = "efivarfs",
304371
.init_fs_context = efivarfs_init_fs_context,
305372
.kill_sb = efivarfs_kill_sb,
373+
.parameters = efivarfs_parameters,
306374
};
307375

308376
static __init int efivarfs_init(void)

0 commit comments

Comments
 (0)