Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <jiejiang@chromium.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Mike Frysinger <vapier@chromium.org>
Acked-by: Christian Brauner <brauner@kernel.org>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20231212093923.497838-1-jiejiang@chromium.org

authored by

Jie Jiang and committed by
Andrii Nakryiko
750e7857 62d9a969

+51 -1
+2
include/linux/bpf.h
··· 1595 1595 }; 1596 1596 1597 1597 struct bpf_mount_opts { 1598 + kuid_t uid; 1599 + kgid_t gid; 1598 1600 umode_t mode; 1599 1601 1600 1602 /* BPF token-related delegation options */
+49 -1
kernel/bpf/inode.c
··· 601 601 static int bpf_show_options(struct seq_file *m, struct dentry *root) 602 602 { 603 603 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; 605 606 u64 mask; 606 607 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)); 607 614 if (mode != S_IRWXUGO) 608 615 seq_printf(m, ",mode=%o", mode); 609 616 ··· 659 652 }; 660 653 661 654 enum { 655 + OPT_UID, 656 + OPT_GID, 662 657 OPT_MODE, 663 658 OPT_DELEGATE_CMDS, 664 659 OPT_DELEGATE_MAPS, ··· 669 660 }; 670 661 671 662 static const struct fs_parameter_spec bpf_fs_parameters[] = { 663 + fsparam_u32 ("uid", OPT_UID), 664 + fsparam_u32 ("gid", OPT_GID), 672 665 fsparam_u32oct ("mode", OPT_MODE), 673 666 fsparam_string ("delegate_cmds", OPT_DELEGATE_CMDS), 674 667 fsparam_string ("delegate_maps", OPT_DELEGATE_MAPS), ··· 683 672 { 684 673 struct bpf_mount_opts *opts = fc->s_fs_info; 685 674 struct fs_parse_result result; 675 + kuid_t uid; 676 + kgid_t gid; 686 677 int opt, err; 687 678 u64 msk; 688 679 ··· 707 694 } 708 695 709 696 switch (opt) { 697 + case OPT_UID: 698 + uid = make_kuid(current_user_ns(), result.uint_32); 699 + if (!uid_valid(uid)) 700 + goto bad_value; 701 + 702 + /* 703 + * The requested uid must be representable in the 704 + * filesystem's idmapping. 705 + */ 706 + if (!kuid_has_mapping(fc->user_ns, uid)) 707 + goto bad_value; 708 + 709 + opts->uid = uid; 710 + break; 711 + case OPT_GID: 712 + gid = make_kgid(current_user_ns(), result.uint_32); 713 + if (!gid_valid(gid)) 714 + goto bad_value; 715 + 716 + /* 717 + * The requested gid must be representable in the 718 + * filesystem's idmapping. 719 + */ 720 + if (!kgid_has_mapping(fc->user_ns, gid)) 721 + goto bad_value; 722 + 723 + opts->gid = gid; 724 + break; 710 725 case OPT_MODE: 711 726 opts->mode = result.uint_32 & S_IALLUGO; 712 727 break; ··· 763 722 } 764 723 765 724 return 0; 725 + 726 + bad_value: 727 + return invalfc(fc, "Bad value for '%s'", param->key); 766 728 } 767 729 768 730 struct bpf_preload_ops *bpf_preload_ops; ··· 852 808 sb->s_op = &bpf_super_ops; 853 809 854 810 inode = sb->s_root->d_inode; 811 + inode->i_uid = opts->uid; 812 + inode->i_gid = opts->gid; 855 813 inode->i_op = &bpf_dir_iops; 856 814 inode->i_mode &= ~S_IALLUGO; 857 815 populate_bpffs(sb->s_root); ··· 889 843 return -ENOMEM; 890 844 891 845 opts->mode = S_IRWXUGO; 846 + opts->uid = current_fsuid(); 847 + opts->gid = current_fsgid(); 892 848 893 849 /* start out with no BPF token delegation enabled */ 894 850 opts->delegate_cmds = 0;