Skip to content

Commit b08c8fc

Browse files
committed
bpf: Re-support uid and gid when mounting bpffs
For a clean, conflict-free revert of the token-related patches in commit d17aff8 ("Revert BPF token-related functionality"), the bpf fs commit 750e785 ("bpf: Support uid and gid when mounting bpffs") was undone temporarily as well. This patch manually re-adds the functionality from the original one back in 750e785, no other functional changes intended. Testing: # mount -t bpf -o uid=65534,gid=65534 bpffs ./foo # ls -la . | grep foo drwxrwxrwt 2 nobody nogroup 0 Dec 20 13:16 foo # mount -t bpf bpffs on /root/foo type bpf (rw,relatime,uid=65534,gid=65534) Also, passing invalid arguments for uid/gid are properly rejected as expected. Fixes: d17aff8 ("Revert BPF token-related functionality") Signed-off-by: Daniel Borkmann <[email protected]> Reviewed-by: Christian Brauner <[email protected]> Cc: Jie Jiang <[email protected]> Cc: Andrii Nakryiko <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/bpf/[email protected]
1 parent fc3a553 commit b08c8fc

File tree

1 file changed

+51
-2
lines changed

1 file changed

+51
-2
lines changed

kernel/bpf/inode.c

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,15 @@ EXPORT_SYMBOL(bpf_prog_get_type_path);
599599
*/
600600
static int bpf_show_options(struct seq_file *m, struct dentry *root)
601601
{
602-
umode_t mode = d_inode(root)->i_mode & S_IALLUGO & ~S_ISVTX;
603-
602+
struct inode *inode = d_inode(root);
603+
umode_t mode = inode->i_mode & S_IALLUGO & ~S_ISVTX;
604+
605+
if (!uid_eq(inode->i_uid, GLOBAL_ROOT_UID))
606+
seq_printf(m, ",uid=%u",
607+
from_kuid_munged(&init_user_ns, inode->i_uid));
608+
if (!gid_eq(inode->i_gid, GLOBAL_ROOT_GID))
609+
seq_printf(m, ",gid=%u",
610+
from_kgid_munged(&init_user_ns, inode->i_gid));
604611
if (mode != S_IRWXUGO)
605612
seq_printf(m, ",mode=%o", mode);
606613
return 0;
@@ -625,22 +632,30 @@ static const struct super_operations bpf_super_ops = {
625632
};
626633

627634
enum {
635+
OPT_UID,
636+
OPT_GID,
628637
OPT_MODE,
629638
};
630639

631640
static const struct fs_parameter_spec bpf_fs_parameters[] = {
641+
fsparam_u32 ("uid", OPT_UID),
642+
fsparam_u32 ("gid", OPT_GID),
632643
fsparam_u32oct ("mode", OPT_MODE),
633644
{}
634645
};
635646

636647
struct bpf_mount_opts {
648+
kuid_t uid;
649+
kgid_t gid;
637650
umode_t mode;
638651
};
639652

640653
static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
641654
{
642655
struct bpf_mount_opts *opts = fc->fs_private;
643656
struct fs_parse_result result;
657+
kuid_t uid;
658+
kgid_t gid;
644659
int opt;
645660

646661
opt = fs_parse(fc, bpf_fs_parameters, param, &result);
@@ -662,12 +677,42 @@ static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
662677
}
663678

664679
switch (opt) {
680+
case OPT_UID:
681+
uid = make_kuid(current_user_ns(), result.uint_32);
682+
if (!uid_valid(uid))
683+
goto bad_value;
684+
685+
/*
686+
* The requested uid must be representable in the
687+
* filesystem's idmapping.
688+
*/
689+
if (!kuid_has_mapping(fc->user_ns, uid))
690+
goto bad_value;
691+
692+
opts->uid = uid;
693+
break;
694+
case OPT_GID:
695+
gid = make_kgid(current_user_ns(), result.uint_32);
696+
if (!gid_valid(gid))
697+
goto bad_value;
698+
699+
/*
700+
* The requested gid must be representable in the
701+
* filesystem's idmapping.
702+
*/
703+
if (!kgid_has_mapping(fc->user_ns, gid))
704+
goto bad_value;
705+
706+
opts->gid = gid;
707+
break;
665708
case OPT_MODE:
666709
opts->mode = result.uint_32 & S_IALLUGO;
667710
break;
668711
}
669712

670713
return 0;
714+
bad_value:
715+
return invalfc(fc, "Bad value for '%s'", param->key);
671716
}
672717

673718
struct bpf_preload_ops *bpf_preload_ops;
@@ -750,6 +795,8 @@ static int bpf_fill_super(struct super_block *sb, struct fs_context *fc)
750795
sb->s_op = &bpf_super_ops;
751796

752797
inode = sb->s_root->d_inode;
798+
inode->i_uid = opts->uid;
799+
inode->i_gid = opts->gid;
753800
inode->i_op = &bpf_dir_iops;
754801
inode->i_mode &= ~S_IALLUGO;
755802
populate_bpffs(sb->s_root);
@@ -785,6 +832,8 @@ static int bpf_init_fs_context(struct fs_context *fc)
785832
return -ENOMEM;
786833

787834
opts->mode = S_IRWXUGO;
835+
opts->uid = current_fsuid();
836+
opts->gid = current_fsgid();
788837

789838
fc->fs_private = opts;
790839
fc->ops = &bpf_context_ops;

0 commit comments

Comments
 (0)