Thread (29 messages) 29 messages, 5 authors, 2023-10-12

Re: [PATCH v6 bpf-next 02/13] bpf: add BPF token delegation mount options to BPF FS

From: Andrii Nakryiko <hidden>
Date: 2023-10-12 00:30:33
Also in: bpf, linux-fsdevel, netdev

On Tue, Oct 10, 2023 at 12:09 AM Hou Tao [off-list ref] wrote:


On 9/28/2023 6:57 AM, Andrii Nakryiko wrote:
quoted
Add few new mount options to BPF FS that allow to specify that a given
BPF FS instance allows creation of BPF token (added in the next patch),
and what sort of operations are allowed under BPF token. As such, we get
4 new mount options, each is a bit mask
  - `delegate_cmds` allow to specify which bpf() syscall commands are
    allowed with BPF token derived from this BPF FS instance;
  - if BPF_MAP_CREATE command is allowed, `delegate_maps` specifies
    a set of allowable BPF map types that could be created with BPF token;
  - if BPF_PROG_LOAD command is allowed, `delegate_progs` specifies
    a set of allowable BPF program types that could be loaded with BPF token;
  - if BPF_PROG_LOAD command is allowed, `delegate_attachs` specifies
    a set of allowable BPF program attach types that could be loaded with
    BPF token; delegate_progs and delegate_attachs are meant to be used
    together, as full BPF program type is, in general, determined
    through both program type and program attach type.

Currently, these mount options accept the following forms of values:
  - a special value "any", that enables all possible values of a given
  bit set;
  - numeric value (decimal or hexadecimal, determined by kernel
  automatically) that specifies a bit mask value directly;
  - all the values for a given mount option are combined, if specified
  multiple times. E.g., `mount -t bpf nodev /path/to/mount -o
  delegate_maps=0x1 -o delegate_maps=0x2` will result in a combined 0x3
  mask.
SNIP
quoted
      return 0;
@@ -740,10 +786,14 @@ static int populate_bpffs(struct dentry *parent)
 static int bpf_fill_super(struct super_block *sb, struct fs_context *fc)
 {
      static const struct tree_descr bpf_rfiles[] = { { "" } };
-     struct bpf_mount_opts *opts = fc->fs_private;
+     struct bpf_mount_opts *opts = sb->s_fs_info;
      struct inode *inode;
      int ret;

+     /* Mounting an instance of BPF FS requires privileges */
+     if (fc->user_ns != &init_user_ns && !capable(CAP_SYS_ADMIN))
+             return -EPERM;
+
      ret = simple_fill_super(sb, BPF_FS_MAGIC, bpf_rfiles);
      if (ret)
              return ret;
@@ -765,7 +815,10 @@ static int bpf_get_tree(struct fs_context *fc)

 static void bpf_free_fc(struct fs_context *fc)
 {
-     kfree(fc->fs_private);
+     struct bpf_mount_opts *opts = fc->s_fs_info;
+
+     if (opts)
+             kfree(opts);
 }
The NULL check is not needed here, use kfree(fc->s_fs_info) will be enough.
yep, dropped the check

quoted
 static const struct fs_context_operations bpf_context_ops = {
@@ -787,17 +840,32 @@ static int bpf_init_fs_context(struct fs_context *fc)

      opts->mode = S_IRWXUGO;

-     fc->fs_private = opts;
+     /* start out with no BPF token delegation enabled */
+     opts->delegate_cmds = 0;
+     opts->delegate_maps = 0;
+     opts->delegate_progs = 0;
+     opts->delegate_attachs = 0;
+
+     fc->s_fs_info = opts;
      fc->ops = &bpf_context_ops;
      return 0;
 }

+static void bpf_kill_super(struct super_block *sb)
+{
+     struct bpf_mount_opts *opts = sb->s_fs_info;
+
+     kill_litter_super(sb);
+     kfree(opts);
+}
+
 static struct file_system_type bpf_fs_type = {
      .owner          = THIS_MODULE,
      .name           = "bpf",
      .init_fs_context = bpf_init_fs_context,
      .parameters     = bpf_fs_parameters,
-     .kill_sb        = kill_litter_super,
+     .kill_sb        = bpf_kill_super,
+     .fs_flags       = FS_USERNS_MOUNT,
 };

 static int __init bpf_init(void)
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help