forked from mirrors/linux
		
	Merge branch 'bpf-fs-mount-options-parsing-follow-ups'
Andrii Nakryiko says: ==================== BPF FS mount options parsing follow ups Original BPF token patch set ([0]) added delegate_xxx mount options which supported only special "any" value and hexadecimal bitmask. This patch set attempts to make specifying and inspecting these mount options more human-friendly by supporting string constants matching corresponding bpf_cmd, bpf_map_type, bpf_prog_type, and bpf_attach_type enumerators. This implementation relies on BTF information to find all supported symbolic names. If kernel wasn't built with BTF, BPF FS will still support "any" and hex-based mask. [0] https://patchwork.kernel.org/project/netdevbpf/list/?series=805707&state=* v1->v2: - strip BPF_, BPF_MAP_TYPE_, and BPF_PROG_TYPE_ prefixes, do case-insensitive comparison, normalize to lower case (Alexei). ==================== Link: https://lore.kernel.org/r/20231214225016.1209867-1-andrii@kernel.org Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
		
						commit
						0f5d5454c7
					
				
					 2 changed files with 240 additions and 55 deletions
				
			
		| 
						 | 
					@ -595,6 +595,136 @@ struct bpf_prog *bpf_prog_get_type_path(const char *name, enum bpf_prog_type typ
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(bpf_prog_get_type_path);
 | 
					EXPORT_SYMBOL(bpf_prog_get_type_path);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct bpffs_btf_enums {
 | 
				
			||||||
 | 
						const struct btf *btf;
 | 
				
			||||||
 | 
						const struct btf_type *cmd_t;
 | 
				
			||||||
 | 
						const struct btf_type *map_t;
 | 
				
			||||||
 | 
						const struct btf_type *prog_t;
 | 
				
			||||||
 | 
						const struct btf_type *attach_t;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int find_bpffs_btf_enums(struct bpffs_btf_enums *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct btf *btf;
 | 
				
			||||||
 | 
						const struct btf_type *t;
 | 
				
			||||||
 | 
						const char *name;
 | 
				
			||||||
 | 
						int i, n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						memset(info, 0, sizeof(*info));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						btf = bpf_get_btf_vmlinux();
 | 
				
			||||||
 | 
						if (IS_ERR(btf))
 | 
				
			||||||
 | 
							return PTR_ERR(btf);
 | 
				
			||||||
 | 
						if (!btf)
 | 
				
			||||||
 | 
							return -ENOENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						info->btf = btf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 1, n = btf_nr_types(btf); i < n; i++) {
 | 
				
			||||||
 | 
							t = btf_type_by_id(btf, i);
 | 
				
			||||||
 | 
							if (!btf_type_is_enum(t))
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							name = btf_name_by_offset(btf, t->name_off);
 | 
				
			||||||
 | 
							if (!name)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (strcmp(name, "bpf_cmd") == 0)
 | 
				
			||||||
 | 
								info->cmd_t = t;
 | 
				
			||||||
 | 
							else if (strcmp(name, "bpf_map_type") == 0)
 | 
				
			||||||
 | 
								info->map_t = t;
 | 
				
			||||||
 | 
							else if (strcmp(name, "bpf_prog_type") == 0)
 | 
				
			||||||
 | 
								info->prog_t = t;
 | 
				
			||||||
 | 
							else if (strcmp(name, "bpf_attach_type") == 0)
 | 
				
			||||||
 | 
								info->attach_t = t;
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (info->cmd_t && info->map_t && info->prog_t && info->attach_t)
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return -ESRCH;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static bool find_btf_enum_const(const struct btf *btf, const struct btf_type *enum_t,
 | 
				
			||||||
 | 
									const char *prefix, const char *str, int *value)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct btf_enum *e;
 | 
				
			||||||
 | 
						const char *name;
 | 
				
			||||||
 | 
						int i, n, pfx_len = strlen(prefix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						*value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!btf || !enum_t)
 | 
				
			||||||
 | 
							return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (i = 0, n = btf_vlen(enum_t); i < n; i++) {
 | 
				
			||||||
 | 
							e = &btf_enum(enum_t)[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							name = btf_name_by_offset(btf, e->name_off);
 | 
				
			||||||
 | 
							if (!name || strncasecmp(name, prefix, pfx_len) != 0)
 | 
				
			||||||
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* match symbolic name case insensitive and ignoring prefix */
 | 
				
			||||||
 | 
							if (strcasecmp(name + pfx_len, str) == 0) {
 | 
				
			||||||
 | 
								*value = e->val;
 | 
				
			||||||
 | 
								return true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void seq_print_delegate_opts(struct seq_file *m,
 | 
				
			||||||
 | 
									    const char *opt_name,
 | 
				
			||||||
 | 
									    const struct btf *btf,
 | 
				
			||||||
 | 
									    const struct btf_type *enum_t,
 | 
				
			||||||
 | 
									    const char *prefix,
 | 
				
			||||||
 | 
									    u64 delegate_msk, u64 any_msk)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						const struct btf_enum *e;
 | 
				
			||||||
 | 
						bool first = true;
 | 
				
			||||||
 | 
						const char *name;
 | 
				
			||||||
 | 
						u64 msk;
 | 
				
			||||||
 | 
						int i, n, pfx_len = strlen(prefix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						delegate_msk &= any_msk; /* clear unknown bits */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (delegate_msk == 0)
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						seq_printf(m, ",%s", opt_name);
 | 
				
			||||||
 | 
						if (delegate_msk == any_msk) {
 | 
				
			||||||
 | 
							seq_printf(m, "=any");
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (btf && enum_t) {
 | 
				
			||||||
 | 
							for (i = 0, n = btf_vlen(enum_t); i < n; i++) {
 | 
				
			||||||
 | 
								e = &btf_enum(enum_t)[i];
 | 
				
			||||||
 | 
								name = btf_name_by_offset(btf, e->name_off);
 | 
				
			||||||
 | 
								if (!name || strncasecmp(name, prefix, pfx_len) != 0)
 | 
				
			||||||
 | 
									continue;
 | 
				
			||||||
 | 
								msk = 1ULL << e->val;
 | 
				
			||||||
 | 
								if (delegate_msk & msk) {
 | 
				
			||||||
 | 
									/* emit lower-case name without prefix */
 | 
				
			||||||
 | 
									seq_printf(m, "%c", first ? '=' : ':');
 | 
				
			||||||
 | 
									name += pfx_len;
 | 
				
			||||||
 | 
									while (*name) {
 | 
				
			||||||
 | 
										seq_printf(m, "%c", tolower(*name));
 | 
				
			||||||
 | 
										name++;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
									delegate_msk &= ~msk;
 | 
				
			||||||
 | 
									first = false;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (delegate_msk)
 | 
				
			||||||
 | 
							seq_printf(m, "%c0x%llx", first ? '=' : ':', delegate_msk);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Display the mount options in /proc/mounts.
 | 
					 * Display the mount options in /proc/mounts.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
| 
						 | 
					@ -614,29 +744,34 @@ static int bpf_show_options(struct seq_file *m, struct dentry *root)
 | 
				
			||||||
	if (mode != S_IRWXUGO)
 | 
						if (mode != S_IRWXUGO)
 | 
				
			||||||
		seq_printf(m, ",mode=%o", mode);
 | 
							seq_printf(m, ",mode=%o", mode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mask = (1ULL << __MAX_BPF_CMD) - 1;
 | 
						if (opts->delegate_cmds || opts->delegate_maps ||
 | 
				
			||||||
	if ((opts->delegate_cmds & mask) == mask)
 | 
						    opts->delegate_progs || opts->delegate_attachs) {
 | 
				
			||||||
		seq_printf(m, ",delegate_cmds=any");
 | 
							struct bpffs_btf_enums info;
 | 
				
			||||||
	else if (opts->delegate_cmds)
 | 
					 | 
				
			||||||
		seq_printf(m, ",delegate_cmds=0x%llx", opts->delegate_cmds);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mask = (1ULL << __MAX_BPF_MAP_TYPE) - 1;
 | 
							/* ignore errors, fallback to hex */
 | 
				
			||||||
	if ((opts->delegate_maps & mask) == mask)
 | 
							(void)find_bpffs_btf_enums(&info);
 | 
				
			||||||
		seq_printf(m, ",delegate_maps=any");
 | 
					 | 
				
			||||||
	else if (opts->delegate_maps)
 | 
					 | 
				
			||||||
		seq_printf(m, ",delegate_maps=0x%llx", opts->delegate_maps);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mask = (1ULL << __MAX_BPF_PROG_TYPE) - 1;
 | 
							mask = (1ULL << __MAX_BPF_CMD) - 1;
 | 
				
			||||||
	if ((opts->delegate_progs & mask) == mask)
 | 
							seq_print_delegate_opts(m, "delegate_cmds",
 | 
				
			||||||
		seq_printf(m, ",delegate_progs=any");
 | 
										info.btf, info.cmd_t, "BPF_",
 | 
				
			||||||
	else if (opts->delegate_progs)
 | 
										opts->delegate_cmds, mask);
 | 
				
			||||||
		seq_printf(m, ",delegate_progs=0x%llx", opts->delegate_progs);
 | 
					
 | 
				
			||||||
 | 
							mask = (1ULL << __MAX_BPF_MAP_TYPE) - 1;
 | 
				
			||||||
 | 
							seq_print_delegate_opts(m, "delegate_maps",
 | 
				
			||||||
 | 
										info.btf, info.map_t, "BPF_MAP_TYPE_",
 | 
				
			||||||
 | 
										opts->delegate_maps, mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							mask = (1ULL << __MAX_BPF_PROG_TYPE) - 1;
 | 
				
			||||||
 | 
							seq_print_delegate_opts(m, "delegate_progs",
 | 
				
			||||||
 | 
										info.btf, info.prog_t, "BPF_PROG_TYPE_",
 | 
				
			||||||
 | 
										opts->delegate_progs, mask);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							mask = (1ULL << __MAX_BPF_ATTACH_TYPE) - 1;
 | 
				
			||||||
 | 
							seq_print_delegate_opts(m, "delegate_attachs",
 | 
				
			||||||
 | 
										info.btf, info.attach_t, "BPF_",
 | 
				
			||||||
 | 
										opts->delegate_attachs, mask);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mask = (1ULL << __MAX_BPF_ATTACH_TYPE) - 1;
 | 
					 | 
				
			||||||
	if ((opts->delegate_attachs & mask) == mask)
 | 
					 | 
				
			||||||
		seq_printf(m, ",delegate_attachs=any");
 | 
					 | 
				
			||||||
	else if (opts->delegate_attachs)
 | 
					 | 
				
			||||||
		seq_printf(m, ",delegate_attachs=0x%llx", opts->delegate_attachs);
 | 
					 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -686,7 +821,6 @@ static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
 | 
				
			||||||
	kuid_t uid;
 | 
						kuid_t uid;
 | 
				
			||||||
	kgid_t gid;
 | 
						kgid_t gid;
 | 
				
			||||||
	int opt, err;
 | 
						int opt, err;
 | 
				
			||||||
	u64 msk;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	opt = fs_parse(fc, bpf_fs_parameters, param, &result);
 | 
						opt = fs_parse(fc, bpf_fs_parameters, param, &result);
 | 
				
			||||||
	if (opt < 0) {
 | 
						if (opt < 0) {
 | 
				
			||||||
| 
						 | 
					@ -741,24 +875,63 @@ static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
 | 
				
			||||||
	case OPT_DELEGATE_CMDS:
 | 
						case OPT_DELEGATE_CMDS:
 | 
				
			||||||
	case OPT_DELEGATE_MAPS:
 | 
						case OPT_DELEGATE_MAPS:
 | 
				
			||||||
	case OPT_DELEGATE_PROGS:
 | 
						case OPT_DELEGATE_PROGS:
 | 
				
			||||||
	case OPT_DELEGATE_ATTACHS:
 | 
						case OPT_DELEGATE_ATTACHS: {
 | 
				
			||||||
		if (strcmp(param->string, "any") == 0) {
 | 
							struct bpffs_btf_enums info;
 | 
				
			||||||
			msk = ~0ULL;
 | 
							const struct btf_type *enum_t;
 | 
				
			||||||
		} else {
 | 
							const char *enum_pfx;
 | 
				
			||||||
			err = kstrtou64(param->string, 0, &msk);
 | 
							u64 *delegate_msk, msk = 0;
 | 
				
			||||||
			if (err)
 | 
							char *p;
 | 
				
			||||||
				return err;
 | 
							int val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* ignore errors, fallback to hex */
 | 
				
			||||||
 | 
							(void)find_bpffs_btf_enums(&info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							switch (opt) {
 | 
				
			||||||
 | 
							case OPT_DELEGATE_CMDS:
 | 
				
			||||||
 | 
								delegate_msk = &opts->delegate_cmds;
 | 
				
			||||||
 | 
								enum_t = info.cmd_t;
 | 
				
			||||||
 | 
								enum_pfx = "BPF_";
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case OPT_DELEGATE_MAPS:
 | 
				
			||||||
 | 
								delegate_msk = &opts->delegate_maps;
 | 
				
			||||||
 | 
								enum_t = info.map_t;
 | 
				
			||||||
 | 
								enum_pfx = "BPF_MAP_TYPE_";
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case OPT_DELEGATE_PROGS:
 | 
				
			||||||
 | 
								delegate_msk = &opts->delegate_progs;
 | 
				
			||||||
 | 
								enum_t = info.prog_t;
 | 
				
			||||||
 | 
								enum_pfx = "BPF_PROG_TYPE_";
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							case OPT_DELEGATE_ATTACHS:
 | 
				
			||||||
 | 
								delegate_msk = &opts->delegate_attachs;
 | 
				
			||||||
 | 
								enum_t = info.attach_t;
 | 
				
			||||||
 | 
								enum_pfx = "BPF_";
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							default:
 | 
				
			||||||
 | 
								return -EINVAL;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							while ((p = strsep(¶m->string, ":"))) {
 | 
				
			||||||
 | 
								if (strcmp(p, "any") == 0) {
 | 
				
			||||||
 | 
									msk |= ~0ULL;
 | 
				
			||||||
 | 
								} else if (find_btf_enum_const(info.btf, enum_t, enum_pfx, p, &val)) {
 | 
				
			||||||
 | 
									msk |= 1ULL << val;
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									err = kstrtou64(p, 0, &msk);
 | 
				
			||||||
 | 
									if (err)
 | 
				
			||||||
 | 
										return err;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Setting delegation mount options requires privileges */
 | 
							/* Setting delegation mount options requires privileges */
 | 
				
			||||||
		if (msk && !capable(CAP_SYS_ADMIN))
 | 
							if (msk && !capable(CAP_SYS_ADMIN))
 | 
				
			||||||
			return -EPERM;
 | 
								return -EPERM;
 | 
				
			||||||
		switch (opt) {
 | 
					
 | 
				
			||||||
		case OPT_DELEGATE_CMDS: opts->delegate_cmds |= msk; break;
 | 
							*delegate_msk |= msk;
 | 
				
			||||||
		case OPT_DELEGATE_MAPS: opts->delegate_maps |= msk; break;
 | 
							break;
 | 
				
			||||||
		case OPT_DELEGATE_PROGS: opts->delegate_progs |= msk; break;
 | 
						}
 | 
				
			||||||
		case OPT_DELEGATE_ATTACHS: opts->delegate_attachs |= msk; break;
 | 
						default:
 | 
				
			||||||
		default: return -EINVAL;
 | 
							/* ignore unknown mount options */
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,14 +66,22 @@ static int restore_priv_caps(__u64 old_caps)
 | 
				
			||||||
	return cap_enable_effective(old_caps, NULL);
 | 
						return cap_enable_effective(old_caps, NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int set_delegate_mask(int fs_fd, const char *key, __u64 mask)
 | 
					static int set_delegate_mask(int fs_fd, const char *key, __u64 mask, const char *mask_str)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char buf[32];
 | 
						char buf[32];
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	snprintf(buf, sizeof(buf), "0x%llx", (unsigned long long)mask);
 | 
						if (!mask_str) {
 | 
				
			||||||
 | 
							if (mask == ~0ULL) {
 | 
				
			||||||
 | 
								mask_str = "any";
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								snprintf(buf, sizeof(buf), "0x%llx", (unsigned long long)mask);
 | 
				
			||||||
 | 
								mask_str = buf;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err = sys_fsconfig(fs_fd, FSCONFIG_SET_STRING, key,
 | 
						err = sys_fsconfig(fs_fd, FSCONFIG_SET_STRING, key,
 | 
				
			||||||
			   mask == ~0ULL ? "any" : buf, 0);
 | 
								   mask_str, 0);
 | 
				
			||||||
	if (err < 0)
 | 
						if (err < 0)
 | 
				
			||||||
		err = -errno;
 | 
							err = -errno;
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
| 
						 | 
					@ -86,6 +94,10 @@ struct bpffs_opts {
 | 
				
			||||||
	__u64 maps;
 | 
						__u64 maps;
 | 
				
			||||||
	__u64 progs;
 | 
						__u64 progs;
 | 
				
			||||||
	__u64 attachs;
 | 
						__u64 attachs;
 | 
				
			||||||
 | 
						const char *cmds_str;
 | 
				
			||||||
 | 
						const char *maps_str;
 | 
				
			||||||
 | 
						const char *progs_str;
 | 
				
			||||||
 | 
						const char *attachs_str;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int create_bpffs_fd(void)
 | 
					static int create_bpffs_fd(void)
 | 
				
			||||||
| 
						 | 
					@ -104,16 +116,16 @@ static int materialize_bpffs_fd(int fs_fd, struct bpffs_opts *opts)
 | 
				
			||||||
	int mnt_fd, err;
 | 
						int mnt_fd, err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* set up token delegation mount options */
 | 
						/* set up token delegation mount options */
 | 
				
			||||||
	err = set_delegate_mask(fs_fd, "delegate_cmds", opts->cmds);
 | 
						err = set_delegate_mask(fs_fd, "delegate_cmds", opts->cmds, opts->cmds_str);
 | 
				
			||||||
	if (!ASSERT_OK(err, "fs_cfg_cmds"))
 | 
						if (!ASSERT_OK(err, "fs_cfg_cmds"))
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	err = set_delegate_mask(fs_fd, "delegate_maps", opts->maps);
 | 
						err = set_delegate_mask(fs_fd, "delegate_maps", opts->maps, opts->maps_str);
 | 
				
			||||||
	if (!ASSERT_OK(err, "fs_cfg_maps"))
 | 
						if (!ASSERT_OK(err, "fs_cfg_maps"))
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	err = set_delegate_mask(fs_fd, "delegate_progs", opts->progs);
 | 
						err = set_delegate_mask(fs_fd, "delegate_progs", opts->progs, opts->progs_str);
 | 
				
			||||||
	if (!ASSERT_OK(err, "fs_cfg_progs"))
 | 
						if (!ASSERT_OK(err, "fs_cfg_progs"))
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
	err = set_delegate_mask(fs_fd, "delegate_attachs", opts->attachs);
 | 
						err = set_delegate_mask(fs_fd, "delegate_attachs", opts->attachs, opts->attachs_str);
 | 
				
			||||||
	if (!ASSERT_OK(err, "fs_cfg_attachs"))
 | 
						if (!ASSERT_OK(err, "fs_cfg_attachs"))
 | 
				
			||||||
		return err;
 | 
							return err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -295,13 +307,13 @@ static void child(int sock_fd, struct bpffs_opts *opts, child_callback_fn callba
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* ensure unprivileged child cannot set delegation options */
 | 
						/* ensure unprivileged child cannot set delegation options */
 | 
				
			||||||
	err = set_delegate_mask(fs_fd, "delegate_cmds", 0x1);
 | 
						err = set_delegate_mask(fs_fd, "delegate_cmds", 0x1, NULL);
 | 
				
			||||||
	ASSERT_EQ(err, -EPERM, "delegate_cmd_eperm");
 | 
						ASSERT_EQ(err, -EPERM, "delegate_cmd_eperm");
 | 
				
			||||||
	err = set_delegate_mask(fs_fd, "delegate_maps", 0x1);
 | 
						err = set_delegate_mask(fs_fd, "delegate_maps", 0x1, NULL);
 | 
				
			||||||
	ASSERT_EQ(err, -EPERM, "delegate_maps_eperm");
 | 
						ASSERT_EQ(err, -EPERM, "delegate_maps_eperm");
 | 
				
			||||||
	err = set_delegate_mask(fs_fd, "delegate_progs", 0x1);
 | 
						err = set_delegate_mask(fs_fd, "delegate_progs", 0x1, NULL);
 | 
				
			||||||
	ASSERT_EQ(err, -EPERM, "delegate_progs_eperm");
 | 
						ASSERT_EQ(err, -EPERM, "delegate_progs_eperm");
 | 
				
			||||||
	err = set_delegate_mask(fs_fd, "delegate_attachs", 0x1);
 | 
						err = set_delegate_mask(fs_fd, "delegate_attachs", 0x1, NULL);
 | 
				
			||||||
	ASSERT_EQ(err, -EPERM, "delegate_attachs_eperm");
 | 
						ASSERT_EQ(err, -EPERM, "delegate_attachs_eperm");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* pass BPF FS context object to parent */
 | 
						/* pass BPF FS context object to parent */
 | 
				
			||||||
| 
						 | 
					@ -325,22 +337,22 @@ static void child(int sock_fd, struct bpffs_opts *opts, child_callback_fn callba
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* ensure unprivileged child cannot reconfigure to set delegation options */
 | 
						/* ensure unprivileged child cannot reconfigure to set delegation options */
 | 
				
			||||||
	err = set_delegate_mask(fs_fd, "delegate_cmds", ~0ULL);
 | 
						err = set_delegate_mask(fs_fd, "delegate_cmds", 0, "any");
 | 
				
			||||||
	if (!ASSERT_EQ(err, -EPERM, "delegate_cmd_eperm_reconfig")) {
 | 
						if (!ASSERT_EQ(err, -EPERM, "delegate_cmd_eperm_reconfig")) {
 | 
				
			||||||
		err = -EINVAL;
 | 
							err = -EINVAL;
 | 
				
			||||||
		goto cleanup;
 | 
							goto cleanup;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = set_delegate_mask(fs_fd, "delegate_maps", ~0ULL);
 | 
						err = set_delegate_mask(fs_fd, "delegate_maps", 0, "any");
 | 
				
			||||||
	if (!ASSERT_EQ(err, -EPERM, "delegate_maps_eperm_reconfig")) {
 | 
						if (!ASSERT_EQ(err, -EPERM, "delegate_maps_eperm_reconfig")) {
 | 
				
			||||||
		err = -EINVAL;
 | 
							err = -EINVAL;
 | 
				
			||||||
		goto cleanup;
 | 
							goto cleanup;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = set_delegate_mask(fs_fd, "delegate_progs", ~0ULL);
 | 
						err = set_delegate_mask(fs_fd, "delegate_progs", 0, "any");
 | 
				
			||||||
	if (!ASSERT_EQ(err, -EPERM, "delegate_progs_eperm_reconfig")) {
 | 
						if (!ASSERT_EQ(err, -EPERM, "delegate_progs_eperm_reconfig")) {
 | 
				
			||||||
		err = -EINVAL;
 | 
							err = -EINVAL;
 | 
				
			||||||
		goto cleanup;
 | 
							goto cleanup;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	err = set_delegate_mask(fs_fd, "delegate_attachs", ~0ULL);
 | 
						err = set_delegate_mask(fs_fd, "delegate_attachs", 0, "any");
 | 
				
			||||||
	if (!ASSERT_EQ(err, -EPERM, "delegate_attachs_eperm_reconfig")) {
 | 
						if (!ASSERT_EQ(err, -EPERM, "delegate_attachs_eperm_reconfig")) {
 | 
				
			||||||
		err = -EINVAL;
 | 
							err = -EINVAL;
 | 
				
			||||||
		goto cleanup;
 | 
							goto cleanup;
 | 
				
			||||||
| 
						 | 
					@ -933,8 +945,8 @@ void test_token(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (test__start_subtest("map_token")) {
 | 
						if (test__start_subtest("map_token")) {
 | 
				
			||||||
		struct bpffs_opts opts = {
 | 
							struct bpffs_opts opts = {
 | 
				
			||||||
			.cmds = 1ULL << BPF_MAP_CREATE,
 | 
								.cmds_str = "map_create",
 | 
				
			||||||
			.maps = 1ULL << BPF_MAP_TYPE_STACK,
 | 
								.maps_str = "stack",
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		subtest_userns(&opts, userns_map_create);
 | 
							subtest_userns(&opts, userns_map_create);
 | 
				
			||||||
| 
						 | 
					@ -948,9 +960,9 @@ void test_token(void)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (test__start_subtest("prog_token")) {
 | 
						if (test__start_subtest("prog_token")) {
 | 
				
			||||||
		struct bpffs_opts opts = {
 | 
							struct bpffs_opts opts = {
 | 
				
			||||||
			.cmds = 1ULL << BPF_PROG_LOAD,
 | 
								.cmds_str = "PROG_LOAD",
 | 
				
			||||||
			.progs = 1ULL << BPF_PROG_TYPE_XDP,
 | 
								.progs_str = "XDP",
 | 
				
			||||||
			.attachs = 1ULL << BPF_XDP,
 | 
								.attachs_str = "xdp",
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		subtest_userns(&opts, userns_prog_load);
 | 
							subtest_userns(&opts, userns_prog_load);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue