Skip to content

Commit 750e785

Browse files
Jie Jianganakryiko
authored andcommitted
bpf: Support uid and gid when mounting bpffs
Parse uid and gid in bpf_parse_param() so that they can be passed in as the `data` parameter when mount() bpffs. This will be useful when we want to control which user/group has the control to the mounted bpffs, otherwise a separate chown() call will be needed. Signed-off-by: Jie Jiang <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Acked-by: Mike Frysinger <[email protected]> Acked-by: Christian Brauner <[email protected]> Acked-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 62d9a96 commit 750e785

File tree

2 files changed

+51
-1
lines changed

2 files changed

+51
-1
lines changed

include/linux/bpf.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,6 +1595,8 @@ struct bpf_link_primer {
15951595
};
15961596

15971597
struct bpf_mount_opts {
1598+
kuid_t uid;
1599+
kgid_t gid;
15981600
umode_t mode;
15991601

16001602
/* BPF token-related delegation options */

kernel/bpf/inode.c

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,9 +601,16 @@ EXPORT_SYMBOL(bpf_prog_get_type_path);
601601
static int bpf_show_options(struct seq_file *m, struct dentry *root)
602602
{
603603
struct bpf_mount_opts *opts = root->d_sb->s_fs_info;
604-
umode_t mode = d_inode(root)->i_mode & S_IALLUGO & ~S_ISVTX;
604+
struct inode *inode = d_inode(root);
605+
umode_t mode = inode->i_mode & S_IALLUGO & ~S_ISVTX;
605606
u64 mask;
606607

608+
if (!uid_eq(inode->i_uid, GLOBAL_ROOT_UID))
609+
seq_printf(m, ",uid=%u",
610+
from_kuid_munged(&init_user_ns, inode->i_uid));
611+
if (!gid_eq(inode->i_gid, GLOBAL_ROOT_GID))
612+
seq_printf(m, ",gid=%u",
613+
from_kgid_munged(&init_user_ns, inode->i_gid));
607614
if (mode != S_IRWXUGO)
608615
seq_printf(m, ",mode=%o", mode);
609616

@@ -652,6 +659,8 @@ const struct super_operations bpf_super_ops = {
652659
};
653660

654661
enum {
662+
OPT_UID,
663+
OPT_GID,
655664
OPT_MODE,
656665
OPT_DELEGATE_CMDS,
657666
OPT_DELEGATE_MAPS,
@@ -660,6 +669,8 @@ enum {
660669
};
661670

662671
static const struct fs_parameter_spec bpf_fs_parameters[] = {
672+
fsparam_u32 ("uid", OPT_UID),
673+
fsparam_u32 ("gid", OPT_GID),
663674
fsparam_u32oct ("mode", OPT_MODE),
664675
fsparam_string ("delegate_cmds", OPT_DELEGATE_CMDS),
665676
fsparam_string ("delegate_maps", OPT_DELEGATE_MAPS),
@@ -672,6 +683,8 @@ static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
672683
{
673684
struct bpf_mount_opts *opts = fc->s_fs_info;
674685
struct fs_parse_result result;
686+
kuid_t uid;
687+
kgid_t gid;
675688
int opt, err;
676689
u64 msk;
677690

@@ -694,6 +707,34 @@ static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
694707
}
695708

696709
switch (opt) {
710+
case OPT_UID:
711+
uid = make_kuid(current_user_ns(), result.uint_32);
712+
if (!uid_valid(uid))
713+
goto bad_value;
714+
715+
/*
716+
* The requested uid must be representable in the
717+
* filesystem's idmapping.
718+
*/
719+
if (!kuid_has_mapping(fc->user_ns, uid))
720+
goto bad_value;
721+
722+
opts->uid = uid;
723+
break;
724+
case OPT_GID:
725+
gid = make_kgid(current_user_ns(), result.uint_32);
726+
if (!gid_valid(gid))
727+
goto bad_value;
728+
729+
/*
730+
* The requested gid must be representable in the
731+
* filesystem's idmapping.
732+
*/
733+
if (!kgid_has_mapping(fc->user_ns, gid))
734+
goto bad_value;
735+
736+
opts->gid = gid;
737+
break;
697738
case OPT_MODE:
698739
opts->mode = result.uint_32 & S_IALLUGO;
699740
break;
@@ -722,6 +763,9 @@ static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
722763
}
723764

724765
return 0;
766+
767+
bad_value:
768+
return invalfc(fc, "Bad value for '%s'", param->key);
725769
}
726770

727771
struct bpf_preload_ops *bpf_preload_ops;
@@ -808,6 +852,8 @@ static int bpf_fill_super(struct super_block *sb, struct fs_context *fc)
808852
sb->s_op = &bpf_super_ops;
809853

810854
inode = sb->s_root->d_inode;
855+
inode->i_uid = opts->uid;
856+
inode->i_gid = opts->gid;
811857
inode->i_op = &bpf_dir_iops;
812858
inode->i_mode &= ~S_IALLUGO;
813859
populate_bpffs(sb->s_root);
@@ -843,6 +889,8 @@ static int bpf_init_fs_context(struct fs_context *fc)
843889
return -ENOMEM;
844890

845891
opts->mode = S_IRWXUGO;
892+
opts->uid = current_fsuid();
893+
opts->gid = current_fsgid();
846894

847895
/* start out with no BPF token delegation enabled */
848896
opts->delegate_cmds = 0;

0 commit comments

Comments
 (0)