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

Merge tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Daniel Borkmann says:

====================
pull-request: bpf-next 2023-12-19

Hi David, hi Jakub, hi Paolo, hi Eric,

The following pull-request contains BPF updates for your *net-next* tree.

We've added 2 non-merge commits during the last 1 day(s) which contain
a total of 40 files changed, 642 insertions(+), 2926 deletions(-).

The main changes are:

1) Revert all of BPF token-related patches for now as per list discussion [0],
from Andrii Nakryiko.

[0] https://lore.kernel.org/bpf/CAHk-=wg7JuFYwGy=GOMbRCtOL+jwSQsdUaBsRWkDVYbxipbM5A@mail.gmail.com

2) Fix a syzbot-reported use-after-free read in nla_find() triggered from
bpf_skb_get_nlattr_nest() helper, from Jakub Kicinski.

bpf-next-for-netdev

* tag 'for-netdev' of https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next:
Revert BPF token-related functionality
bpf: Use nla_ok() instead of checking nla_len directly
====================

Link: https://lore.kernel.org/r/20231219170359.11035-1-daniel@iogearbox.net
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+641 -2925
+1 -1
drivers/media/rc/bpf-lirc.c
··· 110 110 case BPF_FUNC_get_prandom_u32: 111 111 return &bpf_get_prandom_u32_proto; 112 112 case BPF_FUNC_trace_printk: 113 - if (bpf_token_capable(prog->aux->token, CAP_PERFMON)) 113 + if (perfmon_capable()) 114 114 return bpf_get_trace_printk_proto(); 115 115 fallthrough; 116 116 default:
+10 -75
include/linux/bpf.h
··· 52 52 struct bpf_func_state; 53 53 struct ftrace_ops; 54 54 struct cgroup; 55 - struct bpf_token; 56 - struct user_namespace; 57 - struct super_block; 58 - struct inode; 59 55 60 56 extern struct idr btf_idr; 61 57 extern spinlock_t btf_idr_lock; ··· 1484 1488 #ifdef CONFIG_SECURITY 1485 1489 void *security; 1486 1490 #endif 1487 - struct bpf_token *token; 1488 1491 struct bpf_prog_offload *offload; 1489 1492 struct btf *btf; 1490 1493 struct bpf_func_info *func_info; ··· 1606 1611 struct file *file; 1607 1612 int fd; 1608 1613 u32 id; 1609 - }; 1610 - 1611 - struct bpf_mount_opts { 1612 - kuid_t uid; 1613 - kgid_t gid; 1614 - umode_t mode; 1615 - 1616 - /* BPF token-related delegation options */ 1617 - u64 delegate_cmds; 1618 - u64 delegate_maps; 1619 - u64 delegate_progs; 1620 - u64 delegate_attachs; 1621 - }; 1622 - 1623 - struct bpf_token { 1624 - struct work_struct work; 1625 - atomic64_t refcnt; 1626 - struct user_namespace *userns; 1627 - u64 allowed_cmds; 1628 - u64 allowed_maps; 1629 - u64 allowed_progs; 1630 - u64 allowed_attachs; 1631 - #ifdef CONFIG_SECURITY 1632 - void *security; 1633 - #endif 1634 1614 }; 1635 1615 1636 1616 struct bpf_struct_ops_value; ··· 2067 2097 migrate_enable(); 2068 2098 } 2069 2099 2070 - extern const struct super_operations bpf_super_ops; 2071 2100 extern const struct file_operations bpf_map_fops; 2072 2101 extern const struct file_operations bpf_prog_fops; 2073 2102 extern const struct file_operations bpf_iter_fops; ··· 2201 2232 2202 2233 extern int sysctl_unprivileged_bpf_disabled; 2203 2234 2204 - bool bpf_token_capable(const struct bpf_token *token, int cap); 2205 - 2206 - static inline bool bpf_allow_ptr_leaks(const struct bpf_token *token) 2235 + static inline bool bpf_allow_ptr_leaks(void) 2207 2236 { 2208 - return bpf_token_capable(token, CAP_PERFMON); 2237 + return perfmon_capable(); 2209 2238 } 2210 2239 2211 - static inline bool bpf_allow_uninit_stack(const struct bpf_token *token) 2240 + static inline bool bpf_allow_uninit_stack(void) 2212 2241 { 2213 - return bpf_token_capable(token, CAP_PERFMON); 2242 + return perfmon_capable(); 2214 2243 } 2215 2244 2216 - static inline bool bpf_bypass_spec_v1(const struct bpf_token *token) 2245 + static inline bool bpf_bypass_spec_v1(void) 2217 2246 { 2218 - return cpu_mitigations_off() || bpf_token_capable(token, CAP_PERFMON); 2247 + return cpu_mitigations_off() || perfmon_capable(); 2219 2248 } 2220 2249 2221 - static inline bool bpf_bypass_spec_v4(const struct bpf_token *token) 2250 + static inline bool bpf_bypass_spec_v4(void) 2222 2251 { 2223 - return cpu_mitigations_off() || bpf_token_capable(token, CAP_PERFMON); 2252 + return cpu_mitigations_off() || perfmon_capable(); 2224 2253 } 2225 2254 2226 2255 int bpf_map_new_fd(struct bpf_map *map, int flags); ··· 2235 2268 struct bpf_link *bpf_link_get_from_fd(u32 ufd); 2236 2269 struct bpf_link *bpf_link_get_curr_or_next(u32 *id); 2237 2270 2238 - void bpf_token_inc(struct bpf_token *token); 2239 - void bpf_token_put(struct bpf_token *token); 2240 - int bpf_token_create(union bpf_attr *attr); 2241 - struct bpf_token *bpf_token_get_from_fd(u32 ufd); 2242 - 2243 - bool bpf_token_allow_cmd(const struct bpf_token *token, enum bpf_cmd cmd); 2244 - bool bpf_token_allow_map_type(const struct bpf_token *token, enum bpf_map_type type); 2245 - bool bpf_token_allow_prog_type(const struct bpf_token *token, 2246 - enum bpf_prog_type prog_type, 2247 - enum bpf_attach_type attach_type); 2248 - 2249 2271 int bpf_obj_pin_user(u32 ufd, int path_fd, const char __user *pathname); 2250 2272 int bpf_obj_get_user(int path_fd, const char __user *pathname, int flags); 2251 - struct inode *bpf_get_inode(struct super_block *sb, const struct inode *dir, 2252 - umode_t mode); 2253 2273 2254 2274 #define BPF_ITER_FUNC_PREFIX "bpf_iter_" 2255 2275 #define DEFINE_BPF_ITER_FUNC(target, args...) \ ··· 2480 2526 struct bpf_prog *bpf_prog_by_id(u32 id); 2481 2527 struct bpf_link *bpf_link_by_id(u32 id); 2482 2528 2483 - const struct bpf_func_proto *bpf_base_func_proto(enum bpf_func_id func_id, 2484 - const struct bpf_prog *prog); 2529 + const struct bpf_func_proto *bpf_base_func_proto(enum bpf_func_id func_id); 2485 2530 void bpf_task_storage_free(struct task_struct *task); 2486 2531 void bpf_cgrp_storage_free(struct cgroup *cgroup); 2487 2532 bool bpf_prog_has_kfunc_call(const struct bpf_prog *prog); ··· 2597 2644 static inline int bpf_obj_get_user(const char __user *pathname, int flags) 2598 2645 { 2599 2646 return -EOPNOTSUPP; 2600 - } 2601 - 2602 - static inline bool bpf_token_capable(const struct bpf_token *token, int cap) 2603 - { 2604 - return capable(cap) || (cap != CAP_SYS_ADMIN && capable(CAP_SYS_ADMIN)); 2605 - } 2606 - 2607 - static inline void bpf_token_inc(struct bpf_token *token) 2608 - { 2609 - } 2610 - 2611 - static inline void bpf_token_put(struct bpf_token *token) 2612 - { 2613 - } 2614 - 2615 - static inline struct bpf_token *bpf_token_get_from_fd(u32 ufd) 2616 - { 2617 - return ERR_PTR(-EOPNOTSUPP); 2618 2647 } 2619 2648 2620 2649 static inline void __dev_flush(void) ··· 2722 2787 } 2723 2788 2724 2789 static inline const struct bpf_func_proto * 2725 - bpf_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 2790 + bpf_base_func_proto(enum bpf_func_id func_id) 2726 2791 { 2727 2792 return NULL; 2728 2793 }
+1 -1
include/linux/filter.h
··· 1139 1139 return false; 1140 1140 if (!bpf_jit_harden) 1141 1141 return false; 1142 - if (bpf_jit_harden == 1 && bpf_token_capable(prog->aux->token, CAP_BPF)) 1142 + if (bpf_jit_harden == 1 && bpf_capable()) 1143 1143 return false; 1144 1144 1145 1145 return true;
+4 -11
include/linux/lsm_hook_defs.h
··· 398 398 LSM_HOOK(int, 0, bpf, int cmd, union bpf_attr *attr, unsigned int size) 399 399 LSM_HOOK(int, 0, bpf_map, struct bpf_map *map, fmode_t fmode) 400 400 LSM_HOOK(int, 0, bpf_prog, struct bpf_prog *prog) 401 - LSM_HOOK(int, 0, bpf_map_create, struct bpf_map *map, union bpf_attr *attr, 402 - struct bpf_token *token) 403 - LSM_HOOK(void, LSM_RET_VOID, bpf_map_free, struct bpf_map *map) 404 - LSM_HOOK(int, 0, bpf_prog_load, struct bpf_prog *prog, union bpf_attr *attr, 405 - struct bpf_token *token) 406 - LSM_HOOK(void, LSM_RET_VOID, bpf_prog_free, struct bpf_prog *prog) 407 - LSM_HOOK(int, 0, bpf_token_create, struct bpf_token *token, union bpf_attr *attr, 408 - struct path *path) 409 - LSM_HOOK(void, LSM_RET_VOID, bpf_token_free, struct bpf_token *token) 410 - LSM_HOOK(int, 0, bpf_token_cmd, const struct bpf_token *token, enum bpf_cmd cmd) 411 - LSM_HOOK(int, 0, bpf_token_capable, const struct bpf_token *token, int cap) 401 + LSM_HOOK(int, 0, bpf_map_alloc_security, struct bpf_map *map) 402 + LSM_HOOK(void, LSM_RET_VOID, bpf_map_free_security, struct bpf_map *map) 403 + LSM_HOOK(int, 0, bpf_prog_alloc_security, struct bpf_prog_aux *aux) 404 + LSM_HOOK(void, LSM_RET_VOID, bpf_prog_free_security, struct bpf_prog_aux *aux) 412 405 #endif /* CONFIG_BPF_SYSCALL */ 413 406 414 407 LSM_HOOK(int, 0, locked_down, enum lockdown_reason what)
+7 -36
include/linux/security.h
··· 32 32 #include <linux/string.h> 33 33 #include <linux/mm.h> 34 34 #include <linux/sockptr.h> 35 - #include <linux/bpf.h> 36 35 37 36 struct linux_binprm; 38 37 struct cred; ··· 2020 2021 union bpf_attr; 2021 2022 struct bpf_map; 2022 2023 struct bpf_prog; 2023 - struct bpf_token; 2024 + struct bpf_prog_aux; 2024 2025 #ifdef CONFIG_SECURITY 2025 2026 extern int security_bpf(int cmd, union bpf_attr *attr, unsigned int size); 2026 2027 extern int security_bpf_map(struct bpf_map *map, fmode_t fmode); 2027 2028 extern int security_bpf_prog(struct bpf_prog *prog); 2028 - extern int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr, 2029 - struct bpf_token *token); 2029 + extern int security_bpf_map_alloc(struct bpf_map *map); 2030 2030 extern void security_bpf_map_free(struct bpf_map *map); 2031 - extern int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr, 2032 - struct bpf_token *token); 2033 - extern void security_bpf_prog_free(struct bpf_prog *prog); 2034 - extern int security_bpf_token_create(struct bpf_token *token, union bpf_attr *attr, 2035 - struct path *path); 2036 - extern void security_bpf_token_free(struct bpf_token *token); 2037 - extern int security_bpf_token_cmd(const struct bpf_token *token, enum bpf_cmd cmd); 2038 - extern int security_bpf_token_capable(const struct bpf_token *token, int cap); 2031 + extern int security_bpf_prog_alloc(struct bpf_prog_aux *aux); 2032 + extern void security_bpf_prog_free(struct bpf_prog_aux *aux); 2039 2033 #else 2040 2034 static inline int security_bpf(int cmd, union bpf_attr *attr, 2041 2035 unsigned int size) ··· 2046 2054 return 0; 2047 2055 } 2048 2056 2049 - static inline int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr, 2050 - struct bpf_token *token) 2057 + static inline int security_bpf_map_alloc(struct bpf_map *map) 2051 2058 { 2052 2059 return 0; 2053 2060 } ··· 2054 2063 static inline void security_bpf_map_free(struct bpf_map *map) 2055 2064 { } 2056 2065 2057 - static inline int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr, 2058 - struct bpf_token *token) 2066 + static inline int security_bpf_prog_alloc(struct bpf_prog_aux *aux) 2059 2067 { 2060 2068 return 0; 2061 2069 } 2062 2070 2063 - static inline void security_bpf_prog_free(struct bpf_prog *prog) 2071 + static inline void security_bpf_prog_free(struct bpf_prog_aux *aux) 2064 2072 { } 2065 - 2066 - static inline int security_bpf_token_create(struct bpf_token *token, union bpf_attr *attr, 2067 - struct path *path) 2068 - { 2069 - return 0; 2070 - } 2071 - 2072 - static inline void security_bpf_token_free(struct bpf_token *token) 2073 - { } 2074 - 2075 - static inline int security_bpf_token_cmd(const struct bpf_token *token, enum bpf_cmd cmd) 2076 - { 2077 - return 0; 2078 - } 2079 - 2080 - static inline int security_bpf_token_capable(const struct bpf_token *token, int cap) 2081 - { 2082 - return 0; 2083 - } 2084 2073 #endif /* CONFIG_SECURITY */ 2085 2074 #endif /* CONFIG_BPF_SYSCALL */ 2086 2075
-42
include/uapi/linux/bpf.h
··· 847 847 * Returns zero on success. On error, -1 is returned and *errno* 848 848 * is set appropriately. 849 849 * 850 - * BPF_TOKEN_CREATE 851 - * Description 852 - * Create BPF token with embedded information about what 853 - * BPF-related functionality it allows: 854 - * - a set of allowed bpf() syscall commands; 855 - * - a set of allowed BPF map types to be created with 856 - * BPF_MAP_CREATE command, if BPF_MAP_CREATE itself is allowed; 857 - * - a set of allowed BPF program types and BPF program attach 858 - * types to be loaded with BPF_PROG_LOAD command, if 859 - * BPF_PROG_LOAD itself is allowed. 860 - * 861 - * BPF token is created (derived) from an instance of BPF FS, 862 - * assuming it has necessary delegation mount options specified. 863 - * This BPF token can be passed as an extra parameter to various 864 - * bpf() syscall commands to grant BPF subsystem functionality to 865 - * unprivileged processes. 866 - * 867 - * When created, BPF token is "associated" with the owning 868 - * user namespace of BPF FS instance (super block) that it was 869 - * derived from, and subsequent BPF operations performed with 870 - * BPF token would be performing capabilities checks (i.e., 871 - * CAP_BPF, CAP_PERFMON, CAP_NET_ADMIN, CAP_SYS_ADMIN) within 872 - * that user namespace. Without BPF token, such capabilities 873 - * have to be granted in init user namespace, making bpf() 874 - * syscall incompatible with user namespace, for the most part. 875 - * 876 - * Return 877 - * A new file descriptor (a nonnegative integer), or -1 if an 878 - * error occurred (in which case, *errno* is set appropriately). 879 - * 880 850 * NOTES 881 851 * eBPF objects (maps and programs) can be shared between processes. 882 852 * ··· 901 931 BPF_ITER_CREATE, 902 932 BPF_LINK_DETACH, 903 933 BPF_PROG_BIND_MAP, 904 - BPF_TOKEN_CREATE, 905 - __MAX_BPF_CMD, 906 934 }; 907 935 908 936 enum bpf_map_type { ··· 951 983 BPF_MAP_TYPE_BLOOM_FILTER, 952 984 BPF_MAP_TYPE_USER_RINGBUF, 953 985 BPF_MAP_TYPE_CGRP_STORAGE, 954 - __MAX_BPF_MAP_TYPE 955 986 }; 956 987 957 988 /* Note that tracing related programs such as ··· 995 1028 BPF_PROG_TYPE_SK_LOOKUP, 996 1029 BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ 997 1030 BPF_PROG_TYPE_NETFILTER, 998 - __MAX_BPF_PROG_TYPE 999 1031 }; 1000 1032 1001 1033 enum bpf_attach_type { ··· 1403 1437 * to using 5 hash functions). 1404 1438 */ 1405 1439 __u64 map_extra; 1406 - __u32 map_token_fd; 1407 1440 }; 1408 1441 1409 1442 struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */ ··· 1472 1507 * truncated), or smaller (if log buffer wasn't filled completely). 1473 1508 */ 1474 1509 __u32 log_true_size; 1475 - __u32 prog_token_fd; 1476 1510 }; 1477 1511 1478 1512 struct { /* anonymous struct used by BPF_OBJ_* commands */ ··· 1584 1620 * truncated), or smaller (if log buffer wasn't filled completely). 1585 1621 */ 1586 1622 __u32 btf_log_true_size; 1587 - __u32 btf_token_fd; 1588 1623 }; 1589 1624 1590 1625 struct { ··· 1713 1750 __u32 map_fd; 1714 1751 __u32 flags; /* extra flags */ 1715 1752 } prog_bind_map; 1716 - 1717 - struct { /* struct used by BPF_TOKEN_CREATE command */ 1718 - __u32 flags; 1719 - __u32 bpffs_fd; 1720 - } token_create; 1721 1753 1722 1754 } __attribute__((aligned(8))); 1723 1755
+1 -1
kernel/bpf/Makefile
··· 6 6 endif 7 7 CFLAGS_core.o += $(call cc-disable-warning, override-init) $(cflags-nogcse-yy) 8 8 9 - obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o log.o token.o 9 + obj-$(CONFIG_BPF_SYSCALL) += syscall.o verifier.o inode.o helpers.o tnum.o log.o 10 10 obj-$(CONFIG_BPF_SYSCALL) += bpf_iter.o map_iter.o task_iter.o prog_iter.o link_iter.o 11 11 obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list.o lpm_trie.o map_in_map.o bloom_filter.o 12 12 obj-$(CONFIG_BPF_SYSCALL) += local_storage.o queue_stack_maps.o ringbuf.o
+1 -1
kernel/bpf/arraymap.c
··· 82 82 bool percpu = attr->map_type == BPF_MAP_TYPE_PERCPU_ARRAY; 83 83 int numa_node = bpf_map_attr_numa_node(attr); 84 84 u32 elem_size, index_mask, max_entries; 85 - bool bypass_spec_v1 = bpf_bypass_spec_v1(NULL); 85 + bool bypass_spec_v1 = bpf_bypass_spec_v1(); 86 86 u64 array_size, mask64; 87 87 struct bpf_array *array; 88 88
+5 -10
kernel/bpf/bpf_lsm.c
··· 260 260 BTF_SET_START(sleepable_lsm_hooks) 261 261 BTF_ID(func, bpf_lsm_bpf) 262 262 BTF_ID(func, bpf_lsm_bpf_map) 263 - BTF_ID(func, bpf_lsm_bpf_map_create) 264 - BTF_ID(func, bpf_lsm_bpf_map_free) 263 + BTF_ID(func, bpf_lsm_bpf_map_alloc_security) 264 + BTF_ID(func, bpf_lsm_bpf_map_free_security) 265 265 BTF_ID(func, bpf_lsm_bpf_prog) 266 - BTF_ID(func, bpf_lsm_bpf_prog_load) 267 - BTF_ID(func, bpf_lsm_bpf_prog_free) 268 - BTF_ID(func, bpf_lsm_bpf_token_create) 269 - BTF_ID(func, bpf_lsm_bpf_token_free) 270 - BTF_ID(func, bpf_lsm_bpf_token_cmd) 271 - BTF_ID(func, bpf_lsm_bpf_token_capable) 272 266 BTF_ID(func, bpf_lsm_bprm_check_security) 273 267 BTF_ID(func, bpf_lsm_bprm_committed_creds) 274 268 BTF_ID(func, bpf_lsm_bprm_committing_creds) ··· 357 363 BTF_SET_END(sleepable_lsm_hooks) 358 364 359 365 BTF_SET_START(untrusted_lsm_hooks) 360 - BTF_ID(func, bpf_lsm_bpf_map_free) 361 - BTF_ID(func, bpf_lsm_bpf_prog_free) 366 + BTF_ID(func, bpf_lsm_bpf_map_free_security) 367 + BTF_ID(func, bpf_lsm_bpf_prog_alloc_security) 368 + BTF_ID(func, bpf_lsm_bpf_prog_free_security) 362 369 BTF_ID(func, bpf_lsm_file_alloc_security) 363 370 BTF_ID(func, bpf_lsm_file_free_security) 364 371 #ifdef CONFIG_SECURITY_NETWORK
+3 -3
kernel/bpf/cgroup.c
··· 1630 1630 case BPF_FUNC_perf_event_output: 1631 1631 return &bpf_event_output_data_proto; 1632 1632 default: 1633 - return bpf_base_func_proto(func_id, prog); 1633 + return bpf_base_func_proto(func_id); 1634 1634 } 1635 1635 } 1636 1636 ··· 2191 2191 case BPF_FUNC_perf_event_output: 2192 2192 return &bpf_event_output_data_proto; 2193 2193 default: 2194 - return bpf_base_func_proto(func_id, prog); 2194 + return bpf_base_func_proto(func_id); 2195 2195 } 2196 2196 } 2197 2197 ··· 2348 2348 case BPF_FUNC_perf_event_output: 2349 2349 return &bpf_event_output_data_proto; 2350 2350 default: 2351 - return bpf_base_func_proto(func_id, prog); 2351 + return bpf_base_func_proto(func_id); 2352 2352 } 2353 2353 } 2354 2354
+1 -2
kernel/bpf/core.c
··· 682 682 void bpf_prog_kallsyms_add(struct bpf_prog *fp) 683 683 { 684 684 if (!bpf_prog_kallsyms_candidate(fp) || 685 - !bpf_token_capable(fp->aux->token, CAP_BPF)) 685 + !bpf_capable()) 686 686 return; 687 687 688 688 bpf_prog_ksym_set_addr(fp); ··· 2779 2779 2780 2780 if (aux->dst_prog) 2781 2781 bpf_prog_put(aux->dst_prog); 2782 - bpf_token_put(aux->token); 2783 2782 INIT_WORK(&aux->work, bpf_prog_free_deferred); 2784 2783 schedule_work(&aux->work); 2785 2784 }
+3 -3
kernel/bpf/helpers.c
··· 1679 1679 const struct bpf_func_proto bpf_task_pt_regs_proto __weak; 1680 1680 1681 1681 const struct bpf_func_proto * 1682 - bpf_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 1682 + bpf_base_func_proto(enum bpf_func_id func_id) 1683 1683 { 1684 1684 switch (func_id) { 1685 1685 case BPF_FUNC_map_lookup_elem: ··· 1730 1730 break; 1731 1731 } 1732 1732 1733 - if (!bpf_token_capable(prog->aux->token, CAP_BPF)) 1733 + if (!bpf_capable()) 1734 1734 return NULL; 1735 1735 1736 1736 switch (func_id) { ··· 1788 1788 break; 1789 1789 } 1790 1790 1791 - if (!bpf_token_capable(prog->aux->token, CAP_PERFMON)) 1791 + if (!perfmon_capable()) 1792 1792 return NULL; 1793 1793 1794 1794 switch (func_id) {
+15 -309
kernel/bpf/inode.c
··· 20 20 #include <linux/filter.h> 21 21 #include <linux/bpf.h> 22 22 #include <linux/bpf_trace.h> 23 - #include <linux/kstrtox.h> 24 23 #include "preload/bpf_preload.h" 25 24 26 25 enum bpf_type { ··· 98 99 static const struct inode_operations bpf_map_iops = { }; 99 100 static const struct inode_operations bpf_link_iops = { }; 100 101 101 - struct inode *bpf_get_inode(struct super_block *sb, 102 - const struct inode *dir, 103 - umode_t mode) 102 + static struct inode *bpf_get_inode(struct super_block *sb, 103 + const struct inode *dir, 104 + umode_t mode) 104 105 { 105 106 struct inode *inode; 106 107 ··· 594 595 } 595 596 EXPORT_SYMBOL(bpf_prog_get_type_path); 596 597 597 - struct bpffs_btf_enums { 598 - const struct btf *btf; 599 - const struct btf_type *cmd_t; 600 - const struct btf_type *map_t; 601 - const struct btf_type *prog_t; 602 - const struct btf_type *attach_t; 603 - }; 604 - 605 - static int find_bpffs_btf_enums(struct bpffs_btf_enums *info) 606 - { 607 - const struct btf *btf; 608 - const struct btf_type *t; 609 - const char *name; 610 - int i, n; 611 - 612 - memset(info, 0, sizeof(*info)); 613 - 614 - btf = bpf_get_btf_vmlinux(); 615 - if (IS_ERR(btf)) 616 - return PTR_ERR(btf); 617 - if (!btf) 618 - return -ENOENT; 619 - 620 - info->btf = btf; 621 - 622 - for (i = 1, n = btf_nr_types(btf); i < n; i++) { 623 - t = btf_type_by_id(btf, i); 624 - if (!btf_type_is_enum(t)) 625 - continue; 626 - 627 - name = btf_name_by_offset(btf, t->name_off); 628 - if (!name) 629 - continue; 630 - 631 - if (strcmp(name, "bpf_cmd") == 0) 632 - info->cmd_t = t; 633 - else if (strcmp(name, "bpf_map_type") == 0) 634 - info->map_t = t; 635 - else if (strcmp(name, "bpf_prog_type") == 0) 636 - info->prog_t = t; 637 - else if (strcmp(name, "bpf_attach_type") == 0) 638 - info->attach_t = t; 639 - else 640 - continue; 641 - 642 - if (info->cmd_t && info->map_t && info->prog_t && info->attach_t) 643 - return 0; 644 - } 645 - 646 - return -ESRCH; 647 - } 648 - 649 - static bool find_btf_enum_const(const struct btf *btf, const struct btf_type *enum_t, 650 - const char *prefix, const char *str, int *value) 651 - { 652 - const struct btf_enum *e; 653 - const char *name; 654 - int i, n, pfx_len = strlen(prefix); 655 - 656 - *value = 0; 657 - 658 - if (!btf || !enum_t) 659 - return false; 660 - 661 - for (i = 0, n = btf_vlen(enum_t); i < n; i++) { 662 - e = &btf_enum(enum_t)[i]; 663 - 664 - name = btf_name_by_offset(btf, e->name_off); 665 - if (!name || strncasecmp(name, prefix, pfx_len) != 0) 666 - continue; 667 - 668 - /* match symbolic name case insensitive and ignoring prefix */ 669 - if (strcasecmp(name + pfx_len, str) == 0) { 670 - *value = e->val; 671 - return true; 672 - } 673 - } 674 - 675 - return false; 676 - } 677 - 678 - static void seq_print_delegate_opts(struct seq_file *m, 679 - const char *opt_name, 680 - const struct btf *btf, 681 - const struct btf_type *enum_t, 682 - const char *prefix, 683 - u64 delegate_msk, u64 any_msk) 684 - { 685 - const struct btf_enum *e; 686 - bool first = true; 687 - const char *name; 688 - u64 msk; 689 - int i, n, pfx_len = strlen(prefix); 690 - 691 - delegate_msk &= any_msk; /* clear unknown bits */ 692 - 693 - if (delegate_msk == 0) 694 - return; 695 - 696 - seq_printf(m, ",%s", opt_name); 697 - if (delegate_msk == any_msk) { 698 - seq_printf(m, "=any"); 699 - return; 700 - } 701 - 702 - if (btf && enum_t) { 703 - for (i = 0, n = btf_vlen(enum_t); i < n; i++) { 704 - e = &btf_enum(enum_t)[i]; 705 - name = btf_name_by_offset(btf, e->name_off); 706 - if (!name || strncasecmp(name, prefix, pfx_len) != 0) 707 - continue; 708 - msk = 1ULL << e->val; 709 - if (delegate_msk & msk) { 710 - /* emit lower-case name without prefix */ 711 - seq_printf(m, "%c", first ? '=' : ':'); 712 - name += pfx_len; 713 - while (*name) { 714 - seq_printf(m, "%c", tolower(*name)); 715 - name++; 716 - } 717 - 718 - delegate_msk &= ~msk; 719 - first = false; 720 - } 721 - } 722 - } 723 - if (delegate_msk) 724 - seq_printf(m, "%c0x%llx", first ? '=' : ':', delegate_msk); 725 - } 726 - 727 598 /* 728 599 * Display the mount options in /proc/mounts. 729 600 */ 730 601 static int bpf_show_options(struct seq_file *m, struct dentry *root) 731 602 { 732 - struct bpf_mount_opts *opts = root->d_sb->s_fs_info; 733 - struct inode *inode = d_inode(root); 734 - umode_t mode = inode->i_mode & S_IALLUGO & ~S_ISVTX; 735 - u64 mask; 603 + umode_t mode = d_inode(root)->i_mode & S_IALLUGO & ~S_ISVTX; 736 604 737 - if (!uid_eq(inode->i_uid, GLOBAL_ROOT_UID)) 738 - seq_printf(m, ",uid=%u", 739 - from_kuid_munged(&init_user_ns, inode->i_uid)); 740 - if (!gid_eq(inode->i_gid, GLOBAL_ROOT_GID)) 741 - seq_printf(m, ",gid=%u", 742 - from_kgid_munged(&init_user_ns, inode->i_gid)); 743 605 if (mode != S_IRWXUGO) 744 606 seq_printf(m, ",mode=%o", mode); 745 - 746 - if (opts->delegate_cmds || opts->delegate_maps || 747 - opts->delegate_progs || opts->delegate_attachs) { 748 - struct bpffs_btf_enums info; 749 - 750 - /* ignore errors, fallback to hex */ 751 - (void)find_bpffs_btf_enums(&info); 752 - 753 - mask = (1ULL << __MAX_BPF_CMD) - 1; 754 - seq_print_delegate_opts(m, "delegate_cmds", 755 - info.btf, info.cmd_t, "BPF_", 756 - opts->delegate_cmds, mask); 757 - 758 - mask = (1ULL << __MAX_BPF_MAP_TYPE) - 1; 759 - seq_print_delegate_opts(m, "delegate_maps", 760 - info.btf, info.map_t, "BPF_MAP_TYPE_", 761 - opts->delegate_maps, mask); 762 - 763 - mask = (1ULL << __MAX_BPF_PROG_TYPE) - 1; 764 - seq_print_delegate_opts(m, "delegate_progs", 765 - info.btf, info.prog_t, "BPF_PROG_TYPE_", 766 - opts->delegate_progs, mask); 767 - 768 - mask = (1ULL << __MAX_BPF_ATTACH_TYPE) - 1; 769 - seq_print_delegate_opts(m, "delegate_attachs", 770 - info.btf, info.attach_t, "BPF_", 771 - opts->delegate_attachs, mask); 772 - } 773 - 774 607 return 0; 775 608 } 776 609 ··· 617 786 free_inode_nonrcu(inode); 618 787 } 619 788 620 - const struct super_operations bpf_super_ops = { 789 + static const struct super_operations bpf_super_ops = { 621 790 .statfs = simple_statfs, 622 791 .drop_inode = generic_delete_inode, 623 792 .show_options = bpf_show_options, ··· 625 794 }; 626 795 627 796 enum { 628 - OPT_UID, 629 - OPT_GID, 630 797 OPT_MODE, 631 - OPT_DELEGATE_CMDS, 632 - OPT_DELEGATE_MAPS, 633 - OPT_DELEGATE_PROGS, 634 - OPT_DELEGATE_ATTACHS, 635 798 }; 636 799 637 800 static const struct fs_parameter_spec bpf_fs_parameters[] = { 638 - fsparam_u32 ("uid", OPT_UID), 639 - fsparam_u32 ("gid", OPT_GID), 640 801 fsparam_u32oct ("mode", OPT_MODE), 641 - fsparam_string ("delegate_cmds", OPT_DELEGATE_CMDS), 642 - fsparam_string ("delegate_maps", OPT_DELEGATE_MAPS), 643 - fsparam_string ("delegate_progs", OPT_DELEGATE_PROGS), 644 - fsparam_string ("delegate_attachs", OPT_DELEGATE_ATTACHS), 645 802 {} 803 + }; 804 + 805 + struct bpf_mount_opts { 806 + umode_t mode; 646 807 }; 647 808 648 809 static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param) 649 810 { 650 - struct bpf_mount_opts *opts = fc->s_fs_info; 811 + struct bpf_mount_opts *opts = fc->fs_private; 651 812 struct fs_parse_result result; 652 - kuid_t uid; 653 - kgid_t gid; 654 - int opt, err; 813 + int opt; 655 814 656 815 opt = fs_parse(fc, bpf_fs_parameters, param, &result); 657 816 if (opt < 0) { ··· 662 841 } 663 842 664 843 switch (opt) { 665 - case OPT_UID: 666 - uid = make_kuid(current_user_ns(), result.uint_32); 667 - if (!uid_valid(uid)) 668 - goto bad_value; 669 - 670 - /* 671 - * The requested uid must be representable in the 672 - * filesystem's idmapping. 673 - */ 674 - if (!kuid_has_mapping(fc->user_ns, uid)) 675 - goto bad_value; 676 - 677 - opts->uid = uid; 678 - break; 679 - case OPT_GID: 680 - gid = make_kgid(current_user_ns(), result.uint_32); 681 - if (!gid_valid(gid)) 682 - goto bad_value; 683 - 684 - /* 685 - * The requested gid must be representable in the 686 - * filesystem's idmapping. 687 - */ 688 - if (!kgid_has_mapping(fc->user_ns, gid)) 689 - goto bad_value; 690 - 691 - opts->gid = gid; 692 - break; 693 844 case OPT_MODE: 694 845 opts->mode = result.uint_32 & S_IALLUGO; 695 - break; 696 - case OPT_DELEGATE_CMDS: 697 - case OPT_DELEGATE_MAPS: 698 - case OPT_DELEGATE_PROGS: 699 - case OPT_DELEGATE_ATTACHS: { 700 - struct bpffs_btf_enums info; 701 - const struct btf_type *enum_t; 702 - const char *enum_pfx; 703 - u64 *delegate_msk, msk = 0; 704 - char *p; 705 - int val; 706 - 707 - /* ignore errors, fallback to hex */ 708 - (void)find_bpffs_btf_enums(&info); 709 - 710 - switch (opt) { 711 - case OPT_DELEGATE_CMDS: 712 - delegate_msk = &opts->delegate_cmds; 713 - enum_t = info.cmd_t; 714 - enum_pfx = "BPF_"; 715 - break; 716 - case OPT_DELEGATE_MAPS: 717 - delegate_msk = &opts->delegate_maps; 718 - enum_t = info.map_t; 719 - enum_pfx = "BPF_MAP_TYPE_"; 720 - break; 721 - case OPT_DELEGATE_PROGS: 722 - delegate_msk = &opts->delegate_progs; 723 - enum_t = info.prog_t; 724 - enum_pfx = "BPF_PROG_TYPE_"; 725 - break; 726 - case OPT_DELEGATE_ATTACHS: 727 - delegate_msk = &opts->delegate_attachs; 728 - enum_t = info.attach_t; 729 - enum_pfx = "BPF_"; 730 - break; 731 - default: 732 - return -EINVAL; 733 - } 734 - 735 - while ((p = strsep(&param->string, ":"))) { 736 - if (strcmp(p, "any") == 0) { 737 - msk |= ~0ULL; 738 - } else if (find_btf_enum_const(info.btf, enum_t, enum_pfx, p, &val)) { 739 - msk |= 1ULL << val; 740 - } else { 741 - err = kstrtou64(p, 0, &msk); 742 - if (err) 743 - return err; 744 - } 745 - } 746 - 747 - /* Setting delegation mount options requires privileges */ 748 - if (msk && !capable(CAP_SYS_ADMIN)) 749 - return -EPERM; 750 - 751 - *delegate_msk |= msk; 752 - break; 753 - } 754 - default: 755 - /* ignore unknown mount options */ 756 846 break; 757 847 } 758 848 759 849 return 0; 760 - 761 - bad_value: 762 - return invalfc(fc, "Bad value for '%s'", param->key); 763 850 } 764 851 765 852 struct bpf_preload_ops *bpf_preload_ops; ··· 739 1010 static int bpf_fill_super(struct super_block *sb, struct fs_context *fc) 740 1011 { 741 1012 static const struct tree_descr bpf_rfiles[] = { { "" } }; 742 - struct bpf_mount_opts *opts = sb->s_fs_info; 1013 + struct bpf_mount_opts *opts = fc->fs_private; 743 1014 struct inode *inode; 744 1015 int ret; 745 - 746 - /* Mounting an instance of BPF FS requires privileges */ 747 - if (fc->user_ns != &init_user_ns && !capable(CAP_SYS_ADMIN)) 748 - return -EPERM; 749 1016 750 1017 ret = simple_fill_super(sb, BPF_FS_MAGIC, bpf_rfiles); 751 1018 if (ret) ··· 750 1025 sb->s_op = &bpf_super_ops; 751 1026 752 1027 inode = sb->s_root->d_inode; 753 - inode->i_uid = opts->uid; 754 - inode->i_gid = opts->gid; 755 1028 inode->i_op = &bpf_dir_iops; 756 1029 inode->i_mode &= ~S_IALLUGO; 757 1030 populate_bpffs(sb->s_root); ··· 764 1041 765 1042 static void bpf_free_fc(struct fs_context *fc) 766 1043 { 767 - kfree(fc->s_fs_info); 1044 + kfree(fc->fs_private); 768 1045 } 769 1046 770 1047 static const struct fs_context_operations bpf_context_ops = { ··· 785 1062 return -ENOMEM; 786 1063 787 1064 opts->mode = S_IRWXUGO; 788 - opts->uid = current_fsuid(); 789 - opts->gid = current_fsgid(); 790 1065 791 - /* start out with no BPF token delegation enabled */ 792 - opts->delegate_cmds = 0; 793 - opts->delegate_maps = 0; 794 - opts->delegate_progs = 0; 795 - opts->delegate_attachs = 0; 796 - 797 - fc->s_fs_info = opts; 1066 + fc->fs_private = opts; 798 1067 fc->ops = &bpf_context_ops; 799 1068 return 0; 800 - } 801 - 802 - static void bpf_kill_super(struct super_block *sb) 803 - { 804 - struct bpf_mount_opts *opts = sb->s_fs_info; 805 - 806 - kill_litter_super(sb); 807 - kfree(opts); 808 1069 } 809 1070 810 1071 static struct file_system_type bpf_fs_type = { ··· 796 1089 .name = "bpf", 797 1090 .init_fs_context = bpf_init_fs_context, 798 1091 .parameters = bpf_fs_parameters, 799 - .kill_sb = bpf_kill_super, 800 - .fs_flags = FS_USERNS_MOUNT, 1092 + .kill_sb = kill_litter_super, 801 1093 }; 802 1094 803 1095 static int __init bpf_init(void)
+56 -159
kernel/bpf/syscall.c
··· 1011 1011 return -ENOTSUPP; 1012 1012 } 1013 1013 1014 - static int map_check_btf(struct bpf_map *map, struct bpf_token *token, 1015 - const struct btf *btf, u32 btf_key_id, u32 btf_value_id) 1014 + static int map_check_btf(struct bpf_map *map, const struct btf *btf, 1015 + u32 btf_key_id, u32 btf_value_id) 1016 1016 { 1017 1017 const struct btf_type *key_type, *value_type; 1018 1018 u32 key_size, value_size; ··· 1040 1040 if (!IS_ERR_OR_NULL(map->record)) { 1041 1041 int i; 1042 1042 1043 - if (!bpf_token_capable(token, CAP_BPF)) { 1043 + if (!bpf_capable()) { 1044 1044 ret = -EPERM; 1045 1045 goto free_map_tab; 1046 1046 } ··· 1123 1123 return ret; 1124 1124 } 1125 1125 1126 - static bool bpf_net_capable(void) 1127 - { 1128 - return capable(CAP_NET_ADMIN) || capable(CAP_SYS_ADMIN); 1129 - } 1130 - 1131 - #define BPF_MAP_CREATE_LAST_FIELD map_token_fd 1126 + #define BPF_MAP_CREATE_LAST_FIELD map_extra 1132 1127 /* called via syscall */ 1133 1128 static int map_create(union bpf_attr *attr) 1134 1129 { 1135 1130 const struct bpf_map_ops *ops; 1136 - struct bpf_token *token = NULL; 1137 1131 int numa_node = bpf_map_attr_numa_node(attr); 1138 1132 u32 map_type = attr->map_type; 1139 1133 struct bpf_map *map; ··· 1178 1184 if (!ops->map_mem_usage) 1179 1185 return -EINVAL; 1180 1186 1181 - if (attr->map_token_fd) { 1182 - token = bpf_token_get_from_fd(attr->map_token_fd); 1183 - if (IS_ERR(token)) 1184 - return PTR_ERR(token); 1185 - 1186 - /* if current token doesn't grant map creation permissions, 1187 - * then we can't use this token, so ignore it and rely on 1188 - * system-wide capabilities checks 1189 - */ 1190 - if (!bpf_token_allow_cmd(token, BPF_MAP_CREATE) || 1191 - !bpf_token_allow_map_type(token, attr->map_type)) { 1192 - bpf_token_put(token); 1193 - token = NULL; 1194 - } 1195 - } 1196 - 1197 - err = -EPERM; 1198 - 1199 1187 /* Intent here is for unprivileged_bpf_disabled to block BPF map 1200 1188 * creation for unprivileged users; other actions depend 1201 1189 * on fd availability and access to bpffs, so are dependent on 1202 1190 * object creation success. Even with unprivileged BPF disabled, 1203 1191 * capability checks are still carried out. 1204 1192 */ 1205 - if (sysctl_unprivileged_bpf_disabled && !bpf_token_capable(token, CAP_BPF)) 1206 - goto put_token; 1193 + if (sysctl_unprivileged_bpf_disabled && !bpf_capable()) 1194 + return -EPERM; 1207 1195 1208 1196 /* check privileged map type permissions */ 1209 1197 switch (map_type) { ··· 1218 1242 case BPF_MAP_TYPE_LRU_PERCPU_HASH: 1219 1243 case BPF_MAP_TYPE_STRUCT_OPS: 1220 1244 case BPF_MAP_TYPE_CPUMAP: 1221 - if (!bpf_token_capable(token, CAP_BPF)) 1222 - goto put_token; 1245 + if (!bpf_capable()) 1246 + return -EPERM; 1223 1247 break; 1224 1248 case BPF_MAP_TYPE_SOCKMAP: 1225 1249 case BPF_MAP_TYPE_SOCKHASH: 1226 1250 case BPF_MAP_TYPE_DEVMAP: 1227 1251 case BPF_MAP_TYPE_DEVMAP_HASH: 1228 1252 case BPF_MAP_TYPE_XSKMAP: 1229 - if (!bpf_token_capable(token, CAP_NET_ADMIN)) 1230 - goto put_token; 1253 + if (!capable(CAP_NET_ADMIN)) 1254 + return -EPERM; 1231 1255 break; 1232 1256 default: 1233 1257 WARN(1, "unsupported map type %d", map_type); 1234 - goto put_token; 1258 + return -EPERM; 1235 1259 } 1236 1260 1237 1261 map = ops->map_alloc(attr); 1238 - if (IS_ERR(map)) { 1239 - err = PTR_ERR(map); 1240 - goto put_token; 1241 - } 1262 + if (IS_ERR(map)) 1263 + return PTR_ERR(map); 1242 1264 map->ops = ops; 1243 1265 map->map_type = map_type; 1244 1266 ··· 1273 1299 map->btf = btf; 1274 1300 1275 1301 if (attr->btf_value_type_id) { 1276 - err = map_check_btf(map, token, btf, attr->btf_key_type_id, 1302 + err = map_check_btf(map, btf, attr->btf_key_type_id, 1277 1303 attr->btf_value_type_id); 1278 1304 if (err) 1279 1305 goto free_map; ··· 1285 1311 attr->btf_vmlinux_value_type_id; 1286 1312 } 1287 1313 1288 - err = security_bpf_map_create(map, attr, token); 1314 + err = security_bpf_map_alloc(map); 1289 1315 if (err) 1290 - goto free_map_sec; 1316 + goto free_map; 1291 1317 1292 1318 err = bpf_map_alloc_id(map); 1293 1319 if (err) 1294 1320 goto free_map_sec; 1295 1321 1296 1322 bpf_map_save_memcg(map); 1297 - bpf_token_put(token); 1298 1323 1299 1324 err = bpf_map_new_fd(map, f_flags); 1300 1325 if (err < 0) { ··· 1314 1341 free_map: 1315 1342 btf_put(map->btf); 1316 1343 map->ops->map_free(map); 1317 - put_token: 1318 - bpf_token_put(token); 1319 1344 return err; 1320 1345 } 1321 1346 ··· 2144 2173 kvfree(aux->func_info); 2145 2174 kfree(aux->func_info_aux); 2146 2175 free_uid(aux->user); 2147 - security_bpf_prog_free(aux->prog); 2176 + security_bpf_prog_free(aux); 2148 2177 bpf_prog_free(aux->prog); 2149 2178 } 2150 2179 ··· 2590 2619 } 2591 2620 2592 2621 /* last field in 'union bpf_attr' used by this command */ 2593 - #define BPF_PROG_LOAD_LAST_FIELD prog_token_fd 2622 + #define BPF_PROG_LOAD_LAST_FIELD log_true_size 2594 2623 2595 2624 static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, u32 uattr_size) 2596 2625 { 2597 2626 enum bpf_prog_type type = attr->prog_type; 2598 2627 struct bpf_prog *prog, *dst_prog = NULL; 2599 2628 struct btf *attach_btf = NULL; 2600 - struct bpf_token *token = NULL; 2601 - bool bpf_cap; 2602 2629 int err; 2603 2630 char license[128]; 2604 2631 ··· 2613 2644 BPF_F_TEST_REG_INVARIANTS)) 2614 2645 return -EINVAL; 2615 2646 2616 - bpf_prog_load_fixup_attach_type(attr); 2617 - 2618 - if (attr->prog_token_fd) { 2619 - token = bpf_token_get_from_fd(attr->prog_token_fd); 2620 - if (IS_ERR(token)) 2621 - return PTR_ERR(token); 2622 - /* if current token doesn't grant prog loading permissions, 2623 - * then we can't use this token, so ignore it and rely on 2624 - * system-wide capabilities checks 2625 - */ 2626 - if (!bpf_token_allow_cmd(token, BPF_PROG_LOAD) || 2627 - !bpf_token_allow_prog_type(token, attr->prog_type, 2628 - attr->expected_attach_type)) { 2629 - bpf_token_put(token); 2630 - token = NULL; 2631 - } 2632 - } 2633 - 2634 - bpf_cap = bpf_token_capable(token, CAP_BPF); 2635 - err = -EPERM; 2636 - 2637 2647 if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && 2638 2648 (attr->prog_flags & BPF_F_ANY_ALIGNMENT) && 2639 - !bpf_cap) 2640 - goto put_token; 2649 + !bpf_capable()) 2650 + return -EPERM; 2641 2651 2642 2652 /* Intent here is for unprivileged_bpf_disabled to block BPF program 2643 2653 * creation for unprivileged users; other actions depend ··· 2625 2677 * capability checks are still carried out for these 2626 2678 * and other operations. 2627 2679 */ 2628 - if (sysctl_unprivileged_bpf_disabled && !bpf_cap) 2629 - goto put_token; 2680 + if (sysctl_unprivileged_bpf_disabled && !bpf_capable()) 2681 + return -EPERM; 2630 2682 2631 2683 if (attr->insn_cnt == 0 || 2632 - attr->insn_cnt > (bpf_cap ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS)) { 2633 - err = -E2BIG; 2634 - goto put_token; 2635 - } 2684 + attr->insn_cnt > (bpf_capable() ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS)) 2685 + return -E2BIG; 2636 2686 if (type != BPF_PROG_TYPE_SOCKET_FILTER && 2637 2687 type != BPF_PROG_TYPE_CGROUP_SKB && 2638 - !bpf_cap) 2639 - goto put_token; 2688 + !bpf_capable()) 2689 + return -EPERM; 2640 2690 2641 - if (is_net_admin_prog_type(type) && !bpf_token_capable(token, CAP_NET_ADMIN)) 2642 - goto put_token; 2643 - if (is_perfmon_prog_type(type) && !bpf_token_capable(token, CAP_PERFMON)) 2644 - goto put_token; 2691 + if (is_net_admin_prog_type(type) && !capable(CAP_NET_ADMIN) && !capable(CAP_SYS_ADMIN)) 2692 + return -EPERM; 2693 + if (is_perfmon_prog_type(type) && !perfmon_capable()) 2694 + return -EPERM; 2645 2695 2646 2696 /* attach_prog_fd/attach_btf_obj_fd can specify fd of either bpf_prog 2647 2697 * or btf, we need to check which one it is ··· 2649 2703 if (IS_ERR(dst_prog)) { 2650 2704 dst_prog = NULL; 2651 2705 attach_btf = btf_get_by_fd(attr->attach_btf_obj_fd); 2652 - if (IS_ERR(attach_btf)) { 2653 - err = -EINVAL; 2654 - goto put_token; 2655 - } 2706 + if (IS_ERR(attach_btf)) 2707 + return -EINVAL; 2656 2708 if (!btf_is_kernel(attach_btf)) { 2657 2709 /* attaching through specifying bpf_prog's BTF 2658 2710 * objects directly might be supported eventually 2659 2711 */ 2660 2712 btf_put(attach_btf); 2661 - err = -ENOTSUPP; 2662 - goto put_token; 2713 + return -ENOTSUPP; 2663 2714 } 2664 2715 } 2665 2716 } else if (attr->attach_btf_id) { 2666 2717 /* fall back to vmlinux BTF, if BTF type ID is specified */ 2667 2718 attach_btf = bpf_get_btf_vmlinux(); 2668 - if (IS_ERR(attach_btf)) { 2669 - err = PTR_ERR(attach_btf); 2670 - goto put_token; 2671 - } 2672 - if (!attach_btf) { 2673 - err = -EINVAL; 2674 - goto put_token; 2675 - } 2719 + if (IS_ERR(attach_btf)) 2720 + return PTR_ERR(attach_btf); 2721 + if (!attach_btf) 2722 + return -EINVAL; 2676 2723 btf_get(attach_btf); 2677 2724 } 2678 2725 2726 + bpf_prog_load_fixup_attach_type(attr); 2679 2727 if (bpf_prog_load_check_attach(type, attr->expected_attach_type, 2680 2728 attach_btf, attr->attach_btf_id, 2681 2729 dst_prog)) { ··· 2677 2737 bpf_prog_put(dst_prog); 2678 2738 if (attach_btf) 2679 2739 btf_put(attach_btf); 2680 - err = -EINVAL; 2681 - goto put_token; 2740 + return -EINVAL; 2682 2741 } 2683 2742 2684 2743 /* plain bpf_prog allocation */ ··· 2687 2748 bpf_prog_put(dst_prog); 2688 2749 if (attach_btf) 2689 2750 btf_put(attach_btf); 2690 - err = -EINVAL; 2691 - goto put_token; 2751 + return -ENOMEM; 2692 2752 } 2693 2753 2694 2754 prog->expected_attach_type = attr->expected_attach_type; ··· 2698 2760 prog->aux->sleepable = attr->prog_flags & BPF_F_SLEEPABLE; 2699 2761 prog->aux->xdp_has_frags = attr->prog_flags & BPF_F_XDP_HAS_FRAGS; 2700 2762 2701 - /* move token into prog->aux, reuse taken refcnt */ 2702 - prog->aux->token = token; 2703 - token = NULL; 2763 + err = security_bpf_prog_alloc(prog->aux); 2764 + if (err) 2765 + goto free_prog; 2704 2766 2705 2767 prog->aux->user = get_current_user(); 2706 2768 prog->len = attr->insn_cnt; ··· 2709 2771 if (copy_from_bpfptr(prog->insns, 2710 2772 make_bpfptr(attr->insns, uattr.is_kernel), 2711 2773 bpf_prog_insn_size(prog)) != 0) 2712 - goto free_prog; 2774 + goto free_prog_sec; 2713 2775 /* copy eBPF program license from user space */ 2714 2776 if (strncpy_from_bpfptr(license, 2715 2777 make_bpfptr(attr->license, uattr.is_kernel), 2716 2778 sizeof(license) - 1) < 0) 2717 - goto free_prog; 2779 + goto free_prog_sec; 2718 2780 license[sizeof(license) - 1] = 0; 2719 2781 2720 2782 /* eBPF programs must be GPL compatible to use GPL-ed functions */ ··· 2728 2790 if (bpf_prog_is_dev_bound(prog->aux)) { 2729 2791 err = bpf_prog_dev_bound_init(prog, attr); 2730 2792 if (err) 2731 - goto free_prog; 2793 + goto free_prog_sec; 2732 2794 } 2733 2795 2734 2796 if (type == BPF_PROG_TYPE_EXT && dst_prog && 2735 2797 bpf_prog_is_dev_bound(dst_prog->aux)) { 2736 2798 err = bpf_prog_dev_bound_inherit(prog, dst_prog); 2737 2799 if (err) 2738 - goto free_prog; 2800 + goto free_prog_sec; 2739 2801 } 2740 2802 2741 2803 /* find program type: socket_filter vs tracing_filter */ 2742 2804 err = find_prog_type(type, prog); 2743 2805 if (err < 0) 2744 - goto free_prog; 2806 + goto free_prog_sec; 2745 2807 2746 2808 prog->aux->load_time = ktime_get_boottime_ns(); 2747 2809 err = bpf_obj_name_cpy(prog->aux->name, attr->prog_name, 2748 2810 sizeof(attr->prog_name)); 2749 2811 if (err < 0) 2750 - goto free_prog; 2751 - 2752 - err = security_bpf_prog_load(prog, attr, token); 2753 - if (err) 2754 2812 goto free_prog_sec; 2755 2813 2756 2814 /* run eBPF verifier */ ··· 2792 2858 */ 2793 2859 __bpf_prog_put_noref(prog, prog->aux->real_func_cnt); 2794 2860 return err; 2795 - 2796 2861 free_prog_sec: 2797 - security_bpf_prog_free(prog); 2798 - free_prog: 2799 2862 free_uid(prog->aux->user); 2863 + security_bpf_prog_free(prog->aux); 2864 + free_prog: 2800 2865 if (prog->aux->attach_btf) 2801 2866 btf_put(prog->aux->attach_btf); 2802 2867 bpf_prog_free(prog); 2803 - put_token: 2804 - bpf_token_put(token); 2805 2868 return err; 2806 2869 } 2807 2870 ··· 3788 3857 case BPF_PROG_TYPE_SK_LOOKUP: 3789 3858 return attach_type == prog->expected_attach_type ? 0 : -EINVAL; 3790 3859 case BPF_PROG_TYPE_CGROUP_SKB: 3791 - if (!bpf_token_capable(prog->aux->token, CAP_NET_ADMIN)) 3860 + if (!capable(CAP_NET_ADMIN)) 3792 3861 /* cg-skb progs can be loaded by unpriv user. 3793 3862 * check permissions at attach time. 3794 3863 */ ··· 3991 4060 static int bpf_prog_query(const union bpf_attr *attr, 3992 4061 union bpf_attr __user *uattr) 3993 4062 { 3994 - if (!bpf_net_capable()) 4063 + if (!capable(CAP_NET_ADMIN)) 3995 4064 return -EPERM; 3996 4065 if (CHECK_ATTR(BPF_PROG_QUERY)) 3997 4066 return -EINVAL; ··· 4759 4828 return err; 4760 4829 } 4761 4830 4762 - #define BPF_BTF_LOAD_LAST_FIELD btf_token_fd 4831 + #define BPF_BTF_LOAD_LAST_FIELD btf_log_true_size 4763 4832 4764 4833 static int bpf_btf_load(const union bpf_attr *attr, bpfptr_t uattr, __u32 uattr_size) 4765 4834 { 4766 - struct bpf_token *token = NULL; 4767 - 4768 4835 if (CHECK_ATTR(BPF_BTF_LOAD)) 4769 4836 return -EINVAL; 4770 4837 4771 - if (attr->btf_token_fd) { 4772 - token = bpf_token_get_from_fd(attr->btf_token_fd); 4773 - if (IS_ERR(token)) 4774 - return PTR_ERR(token); 4775 - if (!bpf_token_allow_cmd(token, BPF_BTF_LOAD)) { 4776 - bpf_token_put(token); 4777 - token = NULL; 4778 - } 4779 - } 4780 - 4781 - if (!bpf_token_capable(token, CAP_BPF)) { 4782 - bpf_token_put(token); 4838 + if (!bpf_capable()) 4783 4839 return -EPERM; 4784 - } 4785 - 4786 - bpf_token_put(token); 4787 4840 4788 4841 return btf_new_fd(attr, uattr, uattr_size); 4789 4842 } ··· 5385 5470 return ret; 5386 5471 } 5387 5472 5388 - #define BPF_TOKEN_CREATE_LAST_FIELD token_create.bpffs_fd 5389 - 5390 - static int token_create(union bpf_attr *attr) 5391 - { 5392 - if (CHECK_ATTR(BPF_TOKEN_CREATE)) 5393 - return -EINVAL; 5394 - 5395 - /* no flags are supported yet */ 5396 - if (attr->token_create.flags) 5397 - return -EINVAL; 5398 - 5399 - return bpf_token_create(attr); 5400 - } 5401 - 5402 5473 static int __sys_bpf(int cmd, bpfptr_t uattr, unsigned int size) 5403 5474 { 5404 5475 union bpf_attr attr; ··· 5518 5617 case BPF_PROG_BIND_MAP: 5519 5618 err = bpf_prog_bind_map(&attr); 5520 5619 break; 5521 - case BPF_TOKEN_CREATE: 5522 - err = token_create(&attr); 5523 - break; 5524 5620 default: 5525 5621 err = -EINVAL; 5526 5622 break; ··· 5624 5726 const struct bpf_func_proto * __weak 5625 5727 tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 5626 5728 { 5627 - return bpf_base_func_proto(func_id, prog); 5729 + return bpf_base_func_proto(func_id); 5628 5730 } 5629 5731 5630 5732 BPF_CALL_1(bpf_sys_close, u32, fd) ··· 5674 5776 { 5675 5777 switch (func_id) { 5676 5778 case BPF_FUNC_sys_bpf: 5677 - return !bpf_token_capable(prog->aux->token, CAP_PERFMON) 5678 - ? NULL : &bpf_sys_bpf_proto; 5779 + return !perfmon_capable() ? NULL : &bpf_sys_bpf_proto; 5679 5780 case BPF_FUNC_btf_find_by_name_kind: 5680 5781 return &bpf_btf_find_by_name_kind_proto; 5681 5782 case BPF_FUNC_sys_close:
-271
kernel/bpf/token.c
··· 1 - #include <linux/bpf.h> 2 - #include <linux/vmalloc.h> 3 - #include <linux/fdtable.h> 4 - #include <linux/file.h> 5 - #include <linux/fs.h> 6 - #include <linux/kernel.h> 7 - #include <linux/idr.h> 8 - #include <linux/namei.h> 9 - #include <linux/user_namespace.h> 10 - #include <linux/security.h> 11 - 12 - bool bpf_token_capable(const struct bpf_token *token, int cap) 13 - { 14 - /* BPF token allows ns_capable() level of capabilities, but only if 15 - * token's userns is *exactly* the same as current user's userns 16 - */ 17 - if (token && current_user_ns() == token->userns) { 18 - if (ns_capable(token->userns, cap) || 19 - (cap != CAP_SYS_ADMIN && ns_capable(token->userns, CAP_SYS_ADMIN))) 20 - return security_bpf_token_capable(token, cap) == 0; 21 - } 22 - /* otherwise fallback to capable() checks */ 23 - return capable(cap) || (cap != CAP_SYS_ADMIN && capable(CAP_SYS_ADMIN)); 24 - } 25 - 26 - void bpf_token_inc(struct bpf_token *token) 27 - { 28 - atomic64_inc(&token->refcnt); 29 - } 30 - 31 - static void bpf_token_free(struct bpf_token *token) 32 - { 33 - security_bpf_token_free(token); 34 - put_user_ns(token->userns); 35 - kvfree(token); 36 - } 37 - 38 - static void bpf_token_put_deferred(struct work_struct *work) 39 - { 40 - struct bpf_token *token = container_of(work, struct bpf_token, work); 41 - 42 - bpf_token_free(token); 43 - } 44 - 45 - void bpf_token_put(struct bpf_token *token) 46 - { 47 - if (!token) 48 - return; 49 - 50 - if (!atomic64_dec_and_test(&token->refcnt)) 51 - return; 52 - 53 - INIT_WORK(&token->work, bpf_token_put_deferred); 54 - schedule_work(&token->work); 55 - } 56 - 57 - static int bpf_token_release(struct inode *inode, struct file *filp) 58 - { 59 - struct bpf_token *token = filp->private_data; 60 - 61 - bpf_token_put(token); 62 - return 0; 63 - } 64 - 65 - static void bpf_token_show_fdinfo(struct seq_file *m, struct file *filp) 66 - { 67 - struct bpf_token *token = filp->private_data; 68 - u64 mask; 69 - 70 - BUILD_BUG_ON(__MAX_BPF_CMD >= 64); 71 - mask = (1ULL << __MAX_BPF_CMD) - 1; 72 - if ((token->allowed_cmds & mask) == mask) 73 - seq_printf(m, "allowed_cmds:\tany\n"); 74 - else 75 - seq_printf(m, "allowed_cmds:\t0x%llx\n", token->allowed_cmds); 76 - 77 - BUILD_BUG_ON(__MAX_BPF_MAP_TYPE >= 64); 78 - mask = (1ULL << __MAX_BPF_MAP_TYPE) - 1; 79 - if ((token->allowed_maps & mask) == mask) 80 - seq_printf(m, "allowed_maps:\tany\n"); 81 - else 82 - seq_printf(m, "allowed_maps:\t0x%llx\n", token->allowed_maps); 83 - 84 - BUILD_BUG_ON(__MAX_BPF_PROG_TYPE >= 64); 85 - mask = (1ULL << __MAX_BPF_PROG_TYPE) - 1; 86 - if ((token->allowed_progs & mask) == mask) 87 - seq_printf(m, "allowed_progs:\tany\n"); 88 - else 89 - seq_printf(m, "allowed_progs:\t0x%llx\n", token->allowed_progs); 90 - 91 - BUILD_BUG_ON(__MAX_BPF_ATTACH_TYPE >= 64); 92 - mask = (1ULL << __MAX_BPF_ATTACH_TYPE) - 1; 93 - if ((token->allowed_attachs & mask) == mask) 94 - seq_printf(m, "allowed_attachs:\tany\n"); 95 - else 96 - seq_printf(m, "allowed_attachs:\t0x%llx\n", token->allowed_attachs); 97 - } 98 - 99 - #define BPF_TOKEN_INODE_NAME "bpf-token" 100 - 101 - static const struct inode_operations bpf_token_iops = { }; 102 - 103 - static const struct file_operations bpf_token_fops = { 104 - .release = bpf_token_release, 105 - .show_fdinfo = bpf_token_show_fdinfo, 106 - }; 107 - 108 - int bpf_token_create(union bpf_attr *attr) 109 - { 110 - struct bpf_mount_opts *mnt_opts; 111 - struct bpf_token *token = NULL; 112 - struct user_namespace *userns; 113 - struct inode *inode; 114 - struct file *file; 115 - struct path path; 116 - struct fd f; 117 - umode_t mode; 118 - int err, fd; 119 - 120 - f = fdget(attr->token_create.bpffs_fd); 121 - if (!f.file) 122 - return -EBADF; 123 - 124 - path = f.file->f_path; 125 - path_get(&path); 126 - fdput(f); 127 - 128 - if (path.dentry != path.mnt->mnt_sb->s_root) { 129 - err = -EINVAL; 130 - goto out_path; 131 - } 132 - if (path.mnt->mnt_sb->s_op != &bpf_super_ops) { 133 - err = -EINVAL; 134 - goto out_path; 135 - } 136 - err = path_permission(&path, MAY_ACCESS); 137 - if (err) 138 - goto out_path; 139 - 140 - userns = path.dentry->d_sb->s_user_ns; 141 - /* 142 - * Enforce that creators of BPF tokens are in the same user 143 - * namespace as the BPF FS instance. This makes reasoning about 144 - * permissions a lot easier and we can always relax this later. 145 - */ 146 - if (current_user_ns() != userns) { 147 - err = -EPERM; 148 - goto out_path; 149 - } 150 - if (!ns_capable(userns, CAP_BPF)) { 151 - err = -EPERM; 152 - goto out_path; 153 - } 154 - 155 - mnt_opts = path.dentry->d_sb->s_fs_info; 156 - if (mnt_opts->delegate_cmds == 0 && 157 - mnt_opts->delegate_maps == 0 && 158 - mnt_opts->delegate_progs == 0 && 159 - mnt_opts->delegate_attachs == 0) { 160 - err = -ENOENT; /* no BPF token delegation is set up */ 161 - goto out_path; 162 - } 163 - 164 - mode = S_IFREG | ((S_IRUSR | S_IWUSR) & ~current_umask()); 165 - inode = bpf_get_inode(path.mnt->mnt_sb, NULL, mode); 166 - if (IS_ERR(inode)) { 167 - err = PTR_ERR(inode); 168 - goto out_path; 169 - } 170 - 171 - inode->i_op = &bpf_token_iops; 172 - inode->i_fop = &bpf_token_fops; 173 - clear_nlink(inode); /* make sure it is unlinked */ 174 - 175 - file = alloc_file_pseudo(inode, path.mnt, BPF_TOKEN_INODE_NAME, O_RDWR, &bpf_token_fops); 176 - if (IS_ERR(file)) { 177 - iput(inode); 178 - err = PTR_ERR(file); 179 - goto out_path; 180 - } 181 - 182 - token = kvzalloc(sizeof(*token), GFP_USER); 183 - if (!token) { 184 - err = -ENOMEM; 185 - goto out_file; 186 - } 187 - 188 - atomic64_set(&token->refcnt, 1); 189 - 190 - /* remember bpffs owning userns for future ns_capable() checks */ 191 - token->userns = get_user_ns(userns); 192 - 193 - token->allowed_cmds = mnt_opts->delegate_cmds; 194 - token->allowed_maps = mnt_opts->delegate_maps; 195 - token->allowed_progs = mnt_opts->delegate_progs; 196 - token->allowed_attachs = mnt_opts->delegate_attachs; 197 - 198 - err = security_bpf_token_create(token, attr, &path); 199 - if (err) 200 - goto out_token; 201 - 202 - fd = get_unused_fd_flags(O_CLOEXEC); 203 - if (fd < 0) { 204 - err = fd; 205 - goto out_token; 206 - } 207 - 208 - file->private_data = token; 209 - fd_install(fd, file); 210 - 211 - path_put(&path); 212 - return fd; 213 - 214 - out_token: 215 - bpf_token_free(token); 216 - out_file: 217 - fput(file); 218 - out_path: 219 - path_put(&path); 220 - return err; 221 - } 222 - 223 - struct bpf_token *bpf_token_get_from_fd(u32 ufd) 224 - { 225 - struct fd f = fdget(ufd); 226 - struct bpf_token *token; 227 - 228 - if (!f.file) 229 - return ERR_PTR(-EBADF); 230 - if (f.file->f_op != &bpf_token_fops) { 231 - fdput(f); 232 - return ERR_PTR(-EINVAL); 233 - } 234 - 235 - token = f.file->private_data; 236 - bpf_token_inc(token); 237 - fdput(f); 238 - 239 - return token; 240 - } 241 - 242 - bool bpf_token_allow_cmd(const struct bpf_token *token, enum bpf_cmd cmd) 243 - { 244 - /* BPF token can be used only within exactly the same userns in which 245 - * it was created 246 - */ 247 - if (!token || current_user_ns() != token->userns) 248 - return false; 249 - if (!(token->allowed_cmds & (1ULL << cmd))) 250 - return false; 251 - return security_bpf_token_cmd(token, cmd) == 0; 252 - } 253 - 254 - bool bpf_token_allow_map_type(const struct bpf_token *token, enum bpf_map_type type) 255 - { 256 - if (!token || type >= __MAX_BPF_MAP_TYPE) 257 - return false; 258 - 259 - return token->allowed_maps & (1ULL << type); 260 - } 261 - 262 - bool bpf_token_allow_prog_type(const struct bpf_token *token, 263 - enum bpf_prog_type prog_type, 264 - enum bpf_attach_type attach_type) 265 - { 266 - if (!token || prog_type >= __MAX_BPF_PROG_TYPE || attach_type >= __MAX_BPF_ATTACH_TYPE) 267 - return false; 268 - 269 - return (token->allowed_progs & (1ULL << prog_type)) && 270 - (token->allowed_attachs & (1ULL << attach_type)); 271 - }
+7 -6
kernel/bpf/verifier.c
··· 20594 20594 env->prog = *prog; 20595 20595 env->ops = bpf_verifier_ops[env->prog->type]; 20596 20596 env->fd_array = make_bpfptr(attr->fd_array, uattr.is_kernel); 20597 - 20598 - env->allow_ptr_leaks = bpf_allow_ptr_leaks(env->prog->aux->token); 20599 - env->allow_uninit_stack = bpf_allow_uninit_stack(env->prog->aux->token); 20600 - env->bypass_spec_v1 = bpf_bypass_spec_v1(env->prog->aux->token); 20601 - env->bypass_spec_v4 = bpf_bypass_spec_v4(env->prog->aux->token); 20602 - env->bpf_capable = is_priv = bpf_token_capable(env->prog->aux->token, CAP_BPF); 20597 + is_priv = bpf_capable(); 20603 20598 20604 20599 bpf_get_btf_vmlinux(); 20605 20600 ··· 20625 20630 env->strict_alignment = true; 20626 20631 if (attr->prog_flags & BPF_F_ANY_ALIGNMENT) 20627 20632 env->strict_alignment = false; 20633 + 20634 + env->allow_ptr_leaks = bpf_allow_ptr_leaks(); 20635 + env->allow_uninit_stack = bpf_allow_uninit_stack(); 20636 + env->bypass_spec_v1 = bpf_bypass_spec_v1(); 20637 + env->bypass_spec_v4 = bpf_bypass_spec_v4(); 20638 + env->bpf_capable = bpf_capable(); 20628 20639 20629 20640 if (is_priv) 20630 20641 env->test_state_freq = attr->prog_flags & BPF_F_TEST_STATE_FREQ;
+1 -1
kernel/trace/bpf_trace.c
··· 1629 1629 case BPF_FUNC_trace_vprintk: 1630 1630 return bpf_get_trace_vprintk_proto(); 1631 1631 default: 1632 - return bpf_base_func_proto(func_id, prog); 1632 + return bpf_base_func_proto(func_id); 1633 1633 } 1634 1634 } 1635 1635
+19 -19
net/core/filter.c
··· 87 87 #include "dev.h" 88 88 89 89 static const struct bpf_func_proto * 90 - bpf_sk_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog); 90 + bpf_sk_base_func_proto(enum bpf_func_id func_id); 91 91 92 92 int copy_bpf_fprog_from_user(struct sock_fprog *dst, sockptr_t src, int len) 93 93 { ··· 203 203 return 0; 204 204 205 205 nla = (struct nlattr *) &skb->data[a]; 206 - if (nla->nla_len > skb->len - a) 206 + if (!nla_ok(nla, skb->len - a)) 207 207 return 0; 208 208 209 209 nla = nla_find_nested(nla, x); ··· 7862 7862 case BPF_FUNC_ktime_get_coarse_ns: 7863 7863 return &bpf_ktime_get_coarse_ns_proto; 7864 7864 default: 7865 - return bpf_base_func_proto(func_id, prog); 7865 + return bpf_base_func_proto(func_id); 7866 7866 } 7867 7867 } 7868 7868 ··· 7955 7955 return NULL; 7956 7956 } 7957 7957 default: 7958 - return bpf_sk_base_func_proto(func_id, prog); 7958 + return bpf_sk_base_func_proto(func_id); 7959 7959 } 7960 7960 } 7961 7961 ··· 7974 7974 case BPF_FUNC_perf_event_output: 7975 7975 return &bpf_skb_event_output_proto; 7976 7976 default: 7977 - return bpf_sk_base_func_proto(func_id, prog); 7977 + return bpf_sk_base_func_proto(func_id); 7978 7978 } 7979 7979 } 7980 7980 ··· 8161 8161 #endif 8162 8162 #endif 8163 8163 default: 8164 - return bpf_sk_base_func_proto(func_id, prog); 8164 + return bpf_sk_base_func_proto(func_id); 8165 8165 } 8166 8166 } 8167 8167 ··· 8220 8220 #endif 8221 8221 #endif 8222 8222 default: 8223 - return bpf_sk_base_func_proto(func_id, prog); 8223 + return bpf_sk_base_func_proto(func_id); 8224 8224 } 8225 8225 8226 8226 #if IS_MODULE(CONFIG_NF_CONNTRACK) && IS_ENABLED(CONFIG_DEBUG_INFO_BTF_MODULES) ··· 8281 8281 return &bpf_tcp_sock_proto; 8282 8282 #endif /* CONFIG_INET */ 8283 8283 default: 8284 - return bpf_sk_base_func_proto(func_id, prog); 8284 + return bpf_sk_base_func_proto(func_id); 8285 8285 } 8286 8286 } 8287 8287 ··· 8323 8323 return &bpf_get_cgroup_classid_curr_proto; 8324 8324 #endif 8325 8325 default: 8326 - return bpf_sk_base_func_proto(func_id, prog); 8326 + return bpf_sk_base_func_proto(func_id); 8327 8327 } 8328 8328 } 8329 8329 ··· 8367 8367 return &bpf_skc_lookup_tcp_proto; 8368 8368 #endif 8369 8369 default: 8370 - return bpf_sk_base_func_proto(func_id, prog); 8370 + return bpf_sk_base_func_proto(func_id); 8371 8371 } 8372 8372 } 8373 8373 ··· 8378 8378 case BPF_FUNC_skb_load_bytes: 8379 8379 return &bpf_flow_dissector_load_bytes_proto; 8380 8380 default: 8381 - return bpf_sk_base_func_proto(func_id, prog); 8381 + return bpf_sk_base_func_proto(func_id); 8382 8382 } 8383 8383 } 8384 8384 ··· 8405 8405 case BPF_FUNC_skb_under_cgroup: 8406 8406 return &bpf_skb_under_cgroup_proto; 8407 8407 default: 8408 - return bpf_sk_base_func_proto(func_id, prog); 8408 + return bpf_sk_base_func_proto(func_id); 8409 8409 } 8410 8410 } 8411 8411 ··· 8580 8580 return false; 8581 8581 case bpf_ctx_range(struct __sk_buff, data): 8582 8582 case bpf_ctx_range(struct __sk_buff, data_end): 8583 - if (!bpf_token_capable(prog->aux->token, CAP_BPF)) 8583 + if (!bpf_capable()) 8584 8584 return false; 8585 8585 break; 8586 8586 } ··· 8592 8592 case bpf_ctx_range_till(struct __sk_buff, cb[0], cb[4]): 8593 8593 break; 8594 8594 case bpf_ctx_range(struct __sk_buff, tstamp): 8595 - if (!bpf_token_capable(prog->aux->token, CAP_BPF)) 8595 + if (!bpf_capable()) 8596 8596 return false; 8597 8597 break; 8598 8598 default: ··· 11236 11236 case BPF_FUNC_ktime_get_coarse_ns: 11237 11237 return &bpf_ktime_get_coarse_ns_proto; 11238 11238 default: 11239 - return bpf_base_func_proto(func_id, prog); 11239 + return bpf_base_func_proto(func_id); 11240 11240 } 11241 11241 } 11242 11242 ··· 11418 11418 case BPF_FUNC_sk_release: 11419 11419 return &bpf_sk_release_proto; 11420 11420 default: 11421 - return bpf_sk_base_func_proto(func_id, prog); 11421 + return bpf_sk_base_func_proto(func_id); 11422 11422 } 11423 11423 } 11424 11424 ··· 11752 11752 }; 11753 11753 11754 11754 static const struct bpf_func_proto * 11755 - bpf_sk_base_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 11755 + bpf_sk_base_func_proto(enum bpf_func_id func_id) 11756 11756 { 11757 11757 const struct bpf_func_proto *func; 11758 11758 ··· 11781 11781 case BPF_FUNC_ktime_get_coarse_ns: 11782 11782 return &bpf_ktime_get_coarse_ns_proto; 11783 11783 default: 11784 - return bpf_base_func_proto(func_id, prog); 11784 + return bpf_base_func_proto(func_id); 11785 11785 } 11786 11786 11787 - if (!bpf_token_capable(prog->aux->token, CAP_PERFMON)) 11787 + if (!perfmon_capable()) 11788 11788 return NULL; 11789 11789 11790 11790 return func;
+1 -1
net/ipv4/bpf_tcp_ca.c
··· 191 191 case BPF_FUNC_ktime_get_coarse_ns: 192 192 return &bpf_ktime_get_coarse_ns_proto; 193 193 default: 194 - return bpf_base_func_proto(func_id, prog); 194 + return bpf_base_func_proto(func_id); 195 195 } 196 196 } 197 197
+1 -1
net/netfilter/nf_bpf_link.c
··· 314 314 static const struct bpf_func_proto * 315 315 bpf_nf_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) 316 316 { 317 - return bpf_base_func_proto(func_id, prog); 317 + return bpf_base_func_proto(func_id); 318 318 } 319 319 320 320 const struct bpf_verifier_ops netfilter_verifier_ops = {
+16 -85
security/security.c
··· 5167 5167 } 5168 5168 5169 5169 /** 5170 - * security_bpf_map_create() - Check if BPF map creation is allowed 5171 - * @map: BPF map object 5172 - * @attr: BPF syscall attributes used to create BPF map 5173 - * @token: BPF token used to grant user access 5170 + * security_bpf_map_alloc() - Allocate a bpf map LSM blob 5171 + * @map: bpf map 5174 5172 * 5175 - * Do a check when the kernel creates a new BPF map. This is also the 5176 - * point where LSM blob is allocated for LSMs that need them. 5173 + * Initialize the security field inside bpf map. 5177 5174 * 5178 5175 * Return: Returns 0 on success, error on failure. 5179 5176 */ 5180 - int security_bpf_map_create(struct bpf_map *map, union bpf_attr *attr, 5181 - struct bpf_token *token) 5177 + int security_bpf_map_alloc(struct bpf_map *map) 5182 5178 { 5183 - return call_int_hook(bpf_map_create, 0, map, attr, token); 5179 + return call_int_hook(bpf_map_alloc_security, 0, map); 5184 5180 } 5185 5181 5186 5182 /** 5187 - * security_bpf_prog_load() - Check if loading of BPF program is allowed 5188 - * @prog: BPF program object 5189 - * @attr: BPF syscall attributes used to create BPF program 5190 - * @token: BPF token used to grant user access to BPF subsystem 5183 + * security_bpf_prog_alloc() - Allocate a bpf program LSM blob 5184 + * @aux: bpf program aux info struct 5191 5185 * 5192 - * Perform an access control check when the kernel loads a BPF program and 5193 - * allocates associated BPF program object. This hook is also responsible for 5194 - * allocating any required LSM state for the BPF program. 5186 + * Initialize the security field inside bpf program. 5195 5187 * 5196 5188 * Return: Returns 0 on success, error on failure. 5197 5189 */ 5198 - int security_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr, 5199 - struct bpf_token *token) 5190 + int security_bpf_prog_alloc(struct bpf_prog_aux *aux) 5200 5191 { 5201 - return call_int_hook(bpf_prog_load, 0, prog, attr, token); 5202 - } 5203 - 5204 - /** 5205 - * security_bpf_token_create() - Check if creating of BPF token is allowed 5206 - * @token: BPF token object 5207 - * @attr: BPF syscall attributes used to create BPF token 5208 - * @path: path pointing to BPF FS mount point from which BPF token is created 5209 - * 5210 - * Do a check when the kernel instantiates a new BPF token object from BPF FS 5211 - * instance. This is also the point where LSM blob can be allocated for LSMs. 5212 - * 5213 - * Return: Returns 0 on success, error on failure. 5214 - */ 5215 - int security_bpf_token_create(struct bpf_token *token, union bpf_attr *attr, 5216 - struct path *path) 5217 - { 5218 - return call_int_hook(bpf_token_create, 0, token, attr, path); 5219 - } 5220 - 5221 - /** 5222 - * security_bpf_token_cmd() - Check if BPF token is allowed to delegate 5223 - * requested BPF syscall command 5224 - * @token: BPF token object 5225 - * @cmd: BPF syscall command requested to be delegated by BPF token 5226 - * 5227 - * Do a check when the kernel decides whether provided BPF token should allow 5228 - * delegation of requested BPF syscall command. 5229 - * 5230 - * Return: Returns 0 on success, error on failure. 5231 - */ 5232 - int security_bpf_token_cmd(const struct bpf_token *token, enum bpf_cmd cmd) 5233 - { 5234 - return call_int_hook(bpf_token_cmd, 0, token, cmd); 5235 - } 5236 - 5237 - /** 5238 - * security_bpf_token_capable() - Check if BPF token is allowed to delegate 5239 - * requested BPF-related capability 5240 - * @token: BPF token object 5241 - * @cap: capabilities requested to be delegated by BPF token 5242 - * 5243 - * Do a check when the kernel decides whether provided BPF token should allow 5244 - * delegation of requested BPF-related capabilities. 5245 - * 5246 - * Return: Returns 0 on success, error on failure. 5247 - */ 5248 - int security_bpf_token_capable(const struct bpf_token *token, int cap) 5249 - { 5250 - return call_int_hook(bpf_token_capable, 0, token, cap); 5192 + return call_int_hook(bpf_prog_alloc_security, 0, aux); 5251 5193 } 5252 5194 5253 5195 /** ··· 5200 5258 */ 5201 5259 void security_bpf_map_free(struct bpf_map *map) 5202 5260 { 5203 - call_void_hook(bpf_map_free, map); 5261 + call_void_hook(bpf_map_free_security, map); 5204 5262 } 5205 5263 5206 5264 /** 5207 - * security_bpf_prog_free() - Free a BPF program's LSM blob 5208 - * @prog: BPF program struct 5265 + * security_bpf_prog_free() - Free a bpf program's LSM blob 5266 + * @aux: bpf program aux info struct 5209 5267 * 5210 - * Clean up the security information stored inside BPF program. 5268 + * Clean up the security information stored inside bpf prog. 5211 5269 */ 5212 - void security_bpf_prog_free(struct bpf_prog *prog) 5270 + void security_bpf_prog_free(struct bpf_prog_aux *aux) 5213 5271 { 5214 - call_void_hook(bpf_prog_free, prog); 5215 - } 5216 - 5217 - /** 5218 - * security_bpf_token_free() - Free a BPF token's LSM blob 5219 - * @token: BPF token struct 5220 - * 5221 - * Clean up the security information stored inside BPF token. 5222 - */ 5223 - void security_bpf_token_free(struct bpf_token *token) 5224 - { 5225 - call_void_hook(bpf_token_free, token); 5272 + call_void_hook(bpf_prog_free_security, aux); 5226 5273 } 5227 5274 #endif /* CONFIG_BPF_SYSCALL */ 5228 5275
+10 -37
security/selinux/hooks.c
··· 6783 6783 BPF__PROG_RUN, NULL); 6784 6784 } 6785 6785 6786 - static int selinux_bpf_map_create(struct bpf_map *map, union bpf_attr *attr, 6787 - struct bpf_token *token) 6786 + static int selinux_bpf_map_alloc(struct bpf_map *map) 6788 6787 { 6789 6788 struct bpf_security_struct *bpfsec; 6790 6789 ··· 6805 6806 kfree(bpfsec); 6806 6807 } 6807 6808 6808 - static int selinux_bpf_prog_load(struct bpf_prog *prog, union bpf_attr *attr, 6809 - struct bpf_token *token) 6809 + static int selinux_bpf_prog_alloc(struct bpf_prog_aux *aux) 6810 6810 { 6811 6811 struct bpf_security_struct *bpfsec; 6812 6812 ··· 6814 6816 return -ENOMEM; 6815 6817 6816 6818 bpfsec->sid = current_sid(); 6817 - prog->aux->security = bpfsec; 6819 + aux->security = bpfsec; 6818 6820 6819 6821 return 0; 6820 6822 } 6821 6823 6822 - static void selinux_bpf_prog_free(struct bpf_prog *prog) 6824 + static void selinux_bpf_prog_free(struct bpf_prog_aux *aux) 6823 6825 { 6824 - struct bpf_security_struct *bpfsec = prog->aux->security; 6826 + struct bpf_security_struct *bpfsec = aux->security; 6825 6827 6826 - prog->aux->security = NULL; 6827 - kfree(bpfsec); 6828 - } 6829 - 6830 - static int selinux_bpf_token_create(struct bpf_token *token, union bpf_attr *attr, 6831 - struct path *path) 6832 - { 6833 - struct bpf_security_struct *bpfsec; 6834 - 6835 - bpfsec = kzalloc(sizeof(*bpfsec), GFP_KERNEL); 6836 - if (!bpfsec) 6837 - return -ENOMEM; 6838 - 6839 - bpfsec->sid = current_sid(); 6840 - token->security = bpfsec; 6841 - 6842 - return 0; 6843 - } 6844 - 6845 - static void selinux_bpf_token_free(struct bpf_token *token) 6846 - { 6847 - struct bpf_security_struct *bpfsec = token->security; 6848 - 6849 - token->security = NULL; 6828 + aux->security = NULL; 6850 6829 kfree(bpfsec); 6851 6830 } 6852 6831 #endif ··· 7179 7204 LSM_HOOK_INIT(bpf, selinux_bpf), 7180 7205 LSM_HOOK_INIT(bpf_map, selinux_bpf_map), 7181 7206 LSM_HOOK_INIT(bpf_prog, selinux_bpf_prog), 7182 - LSM_HOOK_INIT(bpf_map_free, selinux_bpf_map_free), 7183 - LSM_HOOK_INIT(bpf_prog_free, selinux_bpf_prog_free), 7184 - LSM_HOOK_INIT(bpf_token_free, selinux_bpf_token_free), 7207 + LSM_HOOK_INIT(bpf_map_free_security, selinux_bpf_map_free), 7208 + LSM_HOOK_INIT(bpf_prog_free_security, selinux_bpf_prog_free), 7185 7209 #endif 7186 7210 7187 7211 #ifdef CONFIG_PERF_EVENTS ··· 7237 7263 LSM_HOOK_INIT(audit_rule_init, selinux_audit_rule_init), 7238 7264 #endif 7239 7265 #ifdef CONFIG_BPF_SYSCALL 7240 - LSM_HOOK_INIT(bpf_map_create, selinux_bpf_map_create), 7241 - LSM_HOOK_INIT(bpf_prog_load, selinux_bpf_prog_load), 7242 - LSM_HOOK_INIT(bpf_token_create, selinux_bpf_token_create), 7266 + LSM_HOOK_INIT(bpf_map_alloc_security, selinux_bpf_map_alloc), 7267 + LSM_HOOK_INIT(bpf_prog_alloc_security, selinux_bpf_prog_alloc), 7243 7268 #endif 7244 7269 #ifdef CONFIG_PERF_EVENTS 7245 7270 LSM_HOOK_INIT(perf_event_alloc, selinux_perf_event_alloc),
-42
tools/include/uapi/linux/bpf.h
··· 847 847 * Returns zero on success. On error, -1 is returned and *errno* 848 848 * is set appropriately. 849 849 * 850 - * BPF_TOKEN_CREATE 851 - * Description 852 - * Create BPF token with embedded information about what 853 - * BPF-related functionality it allows: 854 - * - a set of allowed bpf() syscall commands; 855 - * - a set of allowed BPF map types to be created with 856 - * BPF_MAP_CREATE command, if BPF_MAP_CREATE itself is allowed; 857 - * - a set of allowed BPF program types and BPF program attach 858 - * types to be loaded with BPF_PROG_LOAD command, if 859 - * BPF_PROG_LOAD itself is allowed. 860 - * 861 - * BPF token is created (derived) from an instance of BPF FS, 862 - * assuming it has necessary delegation mount options specified. 863 - * This BPF token can be passed as an extra parameter to various 864 - * bpf() syscall commands to grant BPF subsystem functionality to 865 - * unprivileged processes. 866 - * 867 - * When created, BPF token is "associated" with the owning 868 - * user namespace of BPF FS instance (super block) that it was 869 - * derived from, and subsequent BPF operations performed with 870 - * BPF token would be performing capabilities checks (i.e., 871 - * CAP_BPF, CAP_PERFMON, CAP_NET_ADMIN, CAP_SYS_ADMIN) within 872 - * that user namespace. Without BPF token, such capabilities 873 - * have to be granted in init user namespace, making bpf() 874 - * syscall incompatible with user namespace, for the most part. 875 - * 876 - * Return 877 - * A new file descriptor (a nonnegative integer), or -1 if an 878 - * error occurred (in which case, *errno* is set appropriately). 879 - * 880 850 * NOTES 881 851 * eBPF objects (maps and programs) can be shared between processes. 882 852 * ··· 901 931 BPF_ITER_CREATE, 902 932 BPF_LINK_DETACH, 903 933 BPF_PROG_BIND_MAP, 904 - BPF_TOKEN_CREATE, 905 - __MAX_BPF_CMD, 906 934 }; 907 935 908 936 enum bpf_map_type { ··· 951 983 BPF_MAP_TYPE_BLOOM_FILTER, 952 984 BPF_MAP_TYPE_USER_RINGBUF, 953 985 BPF_MAP_TYPE_CGRP_STORAGE, 954 - __MAX_BPF_MAP_TYPE 955 986 }; 956 987 957 988 /* Note that tracing related programs such as ··· 995 1028 BPF_PROG_TYPE_SK_LOOKUP, 996 1029 BPF_PROG_TYPE_SYSCALL, /* a program that can execute syscalls */ 997 1030 BPF_PROG_TYPE_NETFILTER, 998 - __MAX_BPF_PROG_TYPE 999 1031 }; 1000 1032 1001 1033 enum bpf_attach_type { ··· 1403 1437 * to using 5 hash functions). 1404 1438 */ 1405 1439 __u64 map_extra; 1406 - __u32 map_token_fd; 1407 1440 }; 1408 1441 1409 1442 struct { /* anonymous struct used by BPF_MAP_*_ELEM commands */ ··· 1472 1507 * truncated), or smaller (if log buffer wasn't filled completely). 1473 1508 */ 1474 1509 __u32 log_true_size; 1475 - __u32 prog_token_fd; 1476 1510 }; 1477 1511 1478 1512 struct { /* anonymous struct used by BPF_OBJ_* commands */ ··· 1584 1620 * truncated), or smaller (if log buffer wasn't filled completely). 1585 1621 */ 1586 1622 __u32 btf_log_true_size; 1587 - __u32 btf_token_fd; 1588 1623 }; 1589 1624 1590 1625 struct { ··· 1713 1750 __u32 map_fd; 1714 1751 __u32 flags; /* extra flags */ 1715 1752 } prog_bind_map; 1716 - 1717 - struct { /* struct used by BPF_TOKEN_CREATE command */ 1718 - __u32 flags; 1719 - __u32 bpffs_fd; 1720 - } token_create; 1721 1753 1722 1754 } __attribute__((aligned(8))); 1723 1755
+1 -1
tools/lib/bpf/Build
··· 1 1 libbpf-y := libbpf.o bpf.o nlattr.o btf.o libbpf_errno.o str_error.o \ 2 2 netlink.o bpf_prog_linfo.o libbpf_probes.o hashmap.o \ 3 3 btf_dump.o ringbuf.o strset.o linker.o gen_loader.o relo_core.o \ 4 - usdt.o zip.o elf.o features.o 4 + usdt.o zip.o elf.o
+7 -30
tools/lib/bpf/bpf.c
··· 103 103 * [0] https://lore.kernel.org/bpf/20201201215900.3569844-1-guro@fb.com/ 104 104 * [1] d05512618056 ("bpf: Add bpf_ktime_get_coarse_ns helper") 105 105 */ 106 - int probe_memcg_account(int token_fd) 106 + int probe_memcg_account(void) 107 107 { 108 108 const size_t attr_sz = offsetofend(union bpf_attr, attach_btf_obj_fd); 109 109 struct bpf_insn insns[] = { ··· 120 120 attr.insns = ptr_to_u64(insns); 121 121 attr.insn_cnt = insn_cnt; 122 122 attr.license = ptr_to_u64("GPL"); 123 - attr.prog_token_fd = token_fd; 124 123 125 124 prog_fd = sys_bpf_fd(BPF_PROG_LOAD, &attr, attr_sz); 126 125 if (prog_fd >= 0) { ··· 146 147 struct rlimit rlim; 147 148 148 149 /* if kernel supports memcg-based accounting, skip bumping RLIMIT_MEMLOCK */ 149 - if (memlock_bumped || feat_supported(NULL, FEAT_MEMCG_ACCOUNT)) 150 + if (memlock_bumped || kernel_supports(NULL, FEAT_MEMCG_ACCOUNT)) 150 151 return 0; 151 152 152 153 memlock_bumped = true; ··· 169 170 __u32 max_entries, 170 171 const struct bpf_map_create_opts *opts) 171 172 { 172 - const size_t attr_sz = offsetofend(union bpf_attr, map_token_fd); 173 + const size_t attr_sz = offsetofend(union bpf_attr, map_extra); 173 174 union bpf_attr attr; 174 175 int fd; 175 176 ··· 181 182 return libbpf_err(-EINVAL); 182 183 183 184 attr.map_type = map_type; 184 - if (map_name && feat_supported(NULL, FEAT_PROG_NAME)) 185 + if (map_name && kernel_supports(NULL, FEAT_PROG_NAME)) 185 186 libbpf_strlcpy(attr.map_name, map_name, sizeof(attr.map_name)); 186 187 attr.key_size = key_size; 187 188 attr.value_size = value_size; ··· 197 198 attr.map_extra = OPTS_GET(opts, map_extra, 0); 198 199 attr.numa_node = OPTS_GET(opts, numa_node, 0); 199 200 attr.map_ifindex = OPTS_GET(opts, map_ifindex, 0); 200 - 201 - attr.map_token_fd = OPTS_GET(opts, token_fd, 0); 202 201 203 202 fd = sys_bpf_fd(BPF_MAP_CREATE, &attr, attr_sz); 204 203 return libbpf_err_errno(fd); ··· 232 235 const struct bpf_insn *insns, size_t insn_cnt, 233 236 struct bpf_prog_load_opts *opts) 234 237 { 235 - const size_t attr_sz = offsetofend(union bpf_attr, prog_token_fd); 238 + const size_t attr_sz = offsetofend(union bpf_attr, log_true_size); 236 239 void *finfo = NULL, *linfo = NULL; 237 240 const char *func_info, *line_info; 238 241 __u32 log_size, log_level, attach_prog_fd, attach_btf_obj_fd; ··· 261 264 attr.prog_flags = OPTS_GET(opts, prog_flags, 0); 262 265 attr.prog_ifindex = OPTS_GET(opts, prog_ifindex, 0); 263 266 attr.kern_version = OPTS_GET(opts, kern_version, 0); 264 - attr.prog_token_fd = OPTS_GET(opts, token_fd, 0); 265 267 266 - if (prog_name && feat_supported(NULL, FEAT_PROG_NAME)) 268 + if (prog_name && kernel_supports(NULL, FEAT_PROG_NAME)) 267 269 libbpf_strlcpy(attr.prog_name, prog_name, sizeof(attr.prog_name)); 268 270 attr.license = ptr_to_u64(license); 269 271 ··· 1182 1186 1183 1187 int bpf_btf_load(const void *btf_data, size_t btf_size, struct bpf_btf_load_opts *opts) 1184 1188 { 1185 - const size_t attr_sz = offsetofend(union bpf_attr, btf_token_fd); 1189 + const size_t attr_sz = offsetofend(union bpf_attr, btf_log_true_size); 1186 1190 union bpf_attr attr; 1187 1191 char *log_buf; 1188 1192 size_t log_size; ··· 1207 1211 1208 1212 attr.btf = ptr_to_u64(btf_data); 1209 1213 attr.btf_size = btf_size; 1210 - attr.btf_token_fd = OPTS_GET(opts, token_fd, 0); 1211 - 1212 1214 /* log_level == 0 and log_buf != NULL means "try loading without 1213 1215 * log_buf, but retry with log_buf and log_level=1 on error", which is 1214 1216 * consistent across low-level and high-level BTF and program loading ··· 1286 1292 1287 1293 ret = sys_bpf(BPF_PROG_BIND_MAP, &attr, attr_sz); 1288 1294 return libbpf_err_errno(ret); 1289 - } 1290 - 1291 - int bpf_token_create(int bpffs_fd, struct bpf_token_create_opts *opts) 1292 - { 1293 - const size_t attr_sz = offsetofend(union bpf_attr, token_create); 1294 - union bpf_attr attr; 1295 - int fd; 1296 - 1297 - if (!OPTS_VALID(opts, bpf_token_create_opts)) 1298 - return libbpf_err(-EINVAL); 1299 - 1300 - memset(&attr, 0, attr_sz); 1301 - attr.token_create.bpffs_fd = bpffs_fd; 1302 - attr.token_create.flags = OPTS_GET(opts, flags, 0); 1303 - 1304 - fd = sys_bpf_fd(BPF_TOKEN_CREATE, &attr, attr_sz); 1305 - return libbpf_err_errno(fd); 1306 1295 }
+3 -32
tools/lib/bpf/bpf.h
··· 51 51 52 52 __u32 numa_node; 53 53 __u32 map_ifindex; 54 - 55 - __u32 token_fd; 56 - size_t :0; 57 54 }; 58 - #define bpf_map_create_opts__last_field token_fd 55 + #define bpf_map_create_opts__last_field map_ifindex 59 56 60 57 LIBBPF_API int bpf_map_create(enum bpf_map_type map_type, 61 58 const char *map_name, ··· 102 105 * If kernel doesn't support this feature, log_size is left unchanged. 103 106 */ 104 107 __u32 log_true_size; 105 - __u32 token_fd; 106 108 size_t :0; 107 109 }; 108 - #define bpf_prog_load_opts__last_field token_fd 110 + #define bpf_prog_load_opts__last_field log_true_size 109 111 110 112 LIBBPF_API int bpf_prog_load(enum bpf_prog_type prog_type, 111 113 const char *prog_name, const char *license, ··· 130 134 * If kernel doesn't support this feature, log_size is left unchanged. 131 135 */ 132 136 __u32 log_true_size; 133 - __u32 token_fd; 134 137 size_t :0; 135 138 }; 136 - #define bpf_btf_load_opts__last_field token_fd 139 + #define bpf_btf_load_opts__last_field log_true_size 137 140 138 141 LIBBPF_API int bpf_btf_load(const void *btf_data, size_t btf_size, 139 142 struct bpf_btf_load_opts *opts); ··· 639 644 640 645 LIBBPF_API int bpf_prog_test_run_opts(int prog_fd, 641 646 struct bpf_test_run_opts *opts); 642 - 643 - struct bpf_token_create_opts { 644 - size_t sz; /* size of this struct for forward/backward compatibility */ 645 - __u32 flags; 646 - size_t :0; 647 - }; 648 - #define bpf_token_create_opts__last_field flags 649 - 650 - /** 651 - * @brief **bpf_token_create()** creates a new instance of BPF token derived 652 - * from specified BPF FS mount point. 653 - * 654 - * BPF token created with this API can be passed to bpf() syscall for 655 - * commands like BPF_PROG_LOAD, BPF_MAP_CREATE, etc. 656 - * 657 - * @param bpffs_fd FD for BPF FS instance from which to derive a BPF token 658 - * instance. 659 - * @param opts optional BPF token creation options, can be NULL 660 - * 661 - * @return BPF token FD > 0, on success; negative error code, otherwise (errno 662 - * is also set to the error code) 663 - */ 664 - LIBBPF_API int bpf_token_create(int bpffs_fd, 665 - struct bpf_token_create_opts *opts); 666 647 667 648 #ifdef __cplusplus 668 649 } /* extern "C" */
+2 -5
tools/lib/bpf/btf.c
··· 1317 1317 1318 1318 static void *btf_get_raw_data(const struct btf *btf, __u32 *size, bool swap_endian); 1319 1319 1320 - int btf_load_into_kernel(struct btf *btf, 1321 - char *log_buf, size_t log_sz, __u32 log_level, 1322 - int token_fd) 1320 + int btf_load_into_kernel(struct btf *btf, char *log_buf, size_t log_sz, __u32 log_level) 1323 1321 { 1324 1322 LIBBPF_OPTS(bpf_btf_load_opts, opts); 1325 1323 __u32 buf_sz = 0, raw_size; ··· 1367 1369 opts.log_level = log_level; 1368 1370 } 1369 1371 1370 - opts.token_fd = token_fd; 1371 1372 btf->fd = bpf_btf_load(raw_data, raw_size, &opts); 1372 1373 if (btf->fd < 0) { 1373 1374 /* time to turn on verbose mode and try again */ ··· 1394 1397 1395 1398 int btf__load_into_kernel(struct btf *btf) 1396 1399 { 1397 - return btf_load_into_kernel(btf, NULL, 0, 0, 0); 1400 + return btf_load_into_kernel(btf, NULL, 0, 0); 1398 1401 } 1399 1402 1400 1403 int btf__fd(const struct btf *btf)
+2
tools/lib/bpf/elf.c
··· 11 11 #include "libbpf_internal.h" 12 12 #include "str_error.h" 13 13 14 + #define STRERR_BUFSIZE 128 15 + 14 16 /* A SHT_GNU_versym section holds 16-bit words. This bit is set if 15 17 * the symbol is hidden and can only be seen when referenced using an 16 18 * explicit version number. This is a GNU extension.
-478
tools/lib/bpf/features.c
··· 1 - // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) 2 - /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */ 3 - #include <linux/kernel.h> 4 - #include <linux/filter.h> 5 - #include "bpf.h" 6 - #include "libbpf.h" 7 - #include "libbpf_common.h" 8 - #include "libbpf_internal.h" 9 - #include "str_error.h" 10 - 11 - static inline __u64 ptr_to_u64(const void *ptr) 12 - { 13 - return (__u64)(unsigned long)ptr; 14 - } 15 - 16 - static int probe_fd(int fd) 17 - { 18 - if (fd >= 0) 19 - close(fd); 20 - return fd >= 0; 21 - } 22 - 23 - static int probe_kern_prog_name(int token_fd) 24 - { 25 - const size_t attr_sz = offsetofend(union bpf_attr, prog_name); 26 - struct bpf_insn insns[] = { 27 - BPF_MOV64_IMM(BPF_REG_0, 0), 28 - BPF_EXIT_INSN(), 29 - }; 30 - union bpf_attr attr; 31 - int ret; 32 - 33 - memset(&attr, 0, attr_sz); 34 - attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER; 35 - attr.license = ptr_to_u64("GPL"); 36 - attr.insns = ptr_to_u64(insns); 37 - attr.insn_cnt = (__u32)ARRAY_SIZE(insns); 38 - attr.prog_token_fd = token_fd; 39 - libbpf_strlcpy(attr.prog_name, "libbpf_nametest", sizeof(attr.prog_name)); 40 - 41 - /* make sure loading with name works */ 42 - ret = sys_bpf_prog_load(&attr, attr_sz, PROG_LOAD_ATTEMPTS); 43 - return probe_fd(ret); 44 - } 45 - 46 - static int probe_kern_global_data(int token_fd) 47 - { 48 - char *cp, errmsg[STRERR_BUFSIZE]; 49 - struct bpf_insn insns[] = { 50 - BPF_LD_MAP_VALUE(BPF_REG_1, 0, 16), 51 - BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42), 52 - BPF_MOV64_IMM(BPF_REG_0, 0), 53 - BPF_EXIT_INSN(), 54 - }; 55 - LIBBPF_OPTS(bpf_map_create_opts, map_opts, .token_fd = token_fd); 56 - LIBBPF_OPTS(bpf_prog_load_opts, prog_opts, .token_fd = token_fd); 57 - int ret, map, insn_cnt = ARRAY_SIZE(insns); 58 - 59 - map = bpf_map_create(BPF_MAP_TYPE_ARRAY, "libbpf_global", sizeof(int), 32, 1, &map_opts); 60 - if (map < 0) { 61 - ret = -errno; 62 - cp = libbpf_strerror_r(ret, errmsg, sizeof(errmsg)); 63 - pr_warn("Error in %s():%s(%d). Couldn't create simple array map.\n", 64 - __func__, cp, -ret); 65 - return ret; 66 - } 67 - 68 - insns[0].imm = map; 69 - 70 - ret = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", insns, insn_cnt, &prog_opts); 71 - close(map); 72 - return probe_fd(ret); 73 - } 74 - 75 - static int probe_kern_btf(int token_fd) 76 - { 77 - static const char strs[] = "\0int"; 78 - __u32 types[] = { 79 - /* int */ 80 - BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), 81 - }; 82 - 83 - return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 84 - strs, sizeof(strs), token_fd)); 85 - } 86 - 87 - static int probe_kern_btf_func(int token_fd) 88 - { 89 - static const char strs[] = "\0int\0x\0a"; 90 - /* void x(int a) {} */ 91 - __u32 types[] = { 92 - /* int */ 93 - BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 94 - /* FUNC_PROTO */ /* [2] */ 95 - BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 0), 96 - BTF_PARAM_ENC(7, 1), 97 - /* FUNC x */ /* [3] */ 98 - BTF_TYPE_ENC(5, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0), 2), 99 - }; 100 - 101 - return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 102 - strs, sizeof(strs), token_fd)); 103 - } 104 - 105 - static int probe_kern_btf_func_global(int token_fd) 106 - { 107 - static const char strs[] = "\0int\0x\0a"; 108 - /* static void x(int a) {} */ 109 - __u32 types[] = { 110 - /* int */ 111 - BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 112 - /* FUNC_PROTO */ /* [2] */ 113 - BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 0), 114 - BTF_PARAM_ENC(7, 1), 115 - /* FUNC x BTF_FUNC_GLOBAL */ /* [3] */ 116 - BTF_TYPE_ENC(5, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 2), 117 - }; 118 - 119 - return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 120 - strs, sizeof(strs), token_fd)); 121 - } 122 - 123 - static int probe_kern_btf_datasec(int token_fd) 124 - { 125 - static const char strs[] = "\0x\0.data"; 126 - /* static int a; */ 127 - __u32 types[] = { 128 - /* int */ 129 - BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 130 - /* VAR x */ /* [2] */ 131 - BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_VAR, 0, 0), 1), 132 - BTF_VAR_STATIC, 133 - /* DATASEC val */ /* [3] */ 134 - BTF_TYPE_ENC(3, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 135 - BTF_VAR_SECINFO_ENC(2, 0, 4), 136 - }; 137 - 138 - return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 139 - strs, sizeof(strs), token_fd)); 140 - } 141 - 142 - static int probe_kern_btf_float(int token_fd) 143 - { 144 - static const char strs[] = "\0float"; 145 - __u32 types[] = { 146 - /* float */ 147 - BTF_TYPE_FLOAT_ENC(1, 4), 148 - }; 149 - 150 - return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 151 - strs, sizeof(strs), token_fd)); 152 - } 153 - 154 - static int probe_kern_btf_decl_tag(int token_fd) 155 - { 156 - static const char strs[] = "\0tag"; 157 - __u32 types[] = { 158 - /* int */ 159 - BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 160 - /* VAR x */ /* [2] */ 161 - BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_VAR, 0, 0), 1), 162 - BTF_VAR_STATIC, 163 - /* attr */ 164 - BTF_TYPE_DECL_TAG_ENC(1, 2, -1), 165 - }; 166 - 167 - return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 168 - strs, sizeof(strs), token_fd)); 169 - } 170 - 171 - static int probe_kern_btf_type_tag(int token_fd) 172 - { 173 - static const char strs[] = "\0tag"; 174 - __u32 types[] = { 175 - /* int */ 176 - BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 177 - /* attr */ 178 - BTF_TYPE_TYPE_TAG_ENC(1, 1), /* [2] */ 179 - /* ptr */ 180 - BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2), /* [3] */ 181 - }; 182 - 183 - return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 184 - strs, sizeof(strs), token_fd)); 185 - } 186 - 187 - static int probe_kern_array_mmap(int token_fd) 188 - { 189 - LIBBPF_OPTS(bpf_map_create_opts, opts, 190 - .map_flags = BPF_F_MMAPABLE, 191 - .token_fd = token_fd, 192 - ); 193 - int fd; 194 - 195 - fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "libbpf_mmap", sizeof(int), sizeof(int), 1, &opts); 196 - return probe_fd(fd); 197 - } 198 - 199 - static int probe_kern_exp_attach_type(int token_fd) 200 - { 201 - LIBBPF_OPTS(bpf_prog_load_opts, opts, 202 - .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE, 203 - .token_fd = token_fd, 204 - ); 205 - struct bpf_insn insns[] = { 206 - BPF_MOV64_IMM(BPF_REG_0, 0), 207 - BPF_EXIT_INSN(), 208 - }; 209 - int fd, insn_cnt = ARRAY_SIZE(insns); 210 - 211 - /* use any valid combination of program type and (optional) 212 - * non-zero expected attach type (i.e., not a BPF_CGROUP_INET_INGRESS) 213 - * to see if kernel supports expected_attach_type field for 214 - * BPF_PROG_LOAD command 215 - */ 216 - fd = bpf_prog_load(BPF_PROG_TYPE_CGROUP_SOCK, NULL, "GPL", insns, insn_cnt, &opts); 217 - return probe_fd(fd); 218 - } 219 - 220 - static int probe_kern_probe_read_kernel(int token_fd) 221 - { 222 - LIBBPF_OPTS(bpf_prog_load_opts, opts, .token_fd = token_fd); 223 - struct bpf_insn insns[] = { 224 - BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), /* r1 = r10 (fp) */ 225 - BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), /* r1 += -8 */ 226 - BPF_MOV64_IMM(BPF_REG_2, 8), /* r2 = 8 */ 227 - BPF_MOV64_IMM(BPF_REG_3, 0), /* r3 = 0 */ 228 - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_probe_read_kernel), 229 - BPF_EXIT_INSN(), 230 - }; 231 - int fd, insn_cnt = ARRAY_SIZE(insns); 232 - 233 - fd = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, NULL, "GPL", insns, insn_cnt, &opts); 234 - return probe_fd(fd); 235 - } 236 - 237 - static int probe_prog_bind_map(int token_fd) 238 - { 239 - char *cp, errmsg[STRERR_BUFSIZE]; 240 - struct bpf_insn insns[] = { 241 - BPF_MOV64_IMM(BPF_REG_0, 0), 242 - BPF_EXIT_INSN(), 243 - }; 244 - LIBBPF_OPTS(bpf_map_create_opts, map_opts, .token_fd = token_fd); 245 - LIBBPF_OPTS(bpf_prog_load_opts, prog_opts, .token_fd = token_fd); 246 - int ret, map, prog, insn_cnt = ARRAY_SIZE(insns); 247 - 248 - map = bpf_map_create(BPF_MAP_TYPE_ARRAY, "libbpf_det_bind", sizeof(int), 32, 1, &map_opts); 249 - if (map < 0) { 250 - ret = -errno; 251 - cp = libbpf_strerror_r(ret, errmsg, sizeof(errmsg)); 252 - pr_warn("Error in %s():%s(%d). Couldn't create simple array map.\n", 253 - __func__, cp, -ret); 254 - return ret; 255 - } 256 - 257 - prog = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", insns, insn_cnt, &prog_opts); 258 - if (prog < 0) { 259 - close(map); 260 - return 0; 261 - } 262 - 263 - ret = bpf_prog_bind_map(prog, map, NULL); 264 - 265 - close(map); 266 - close(prog); 267 - 268 - return ret >= 0; 269 - } 270 - 271 - static int probe_module_btf(int token_fd) 272 - { 273 - static const char strs[] = "\0int"; 274 - __u32 types[] = { 275 - /* int */ 276 - BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), 277 - }; 278 - struct bpf_btf_info info; 279 - __u32 len = sizeof(info); 280 - char name[16]; 281 - int fd, err; 282 - 283 - fd = libbpf__load_raw_btf((char *)types, sizeof(types), strs, sizeof(strs), token_fd); 284 - if (fd < 0) 285 - return 0; /* BTF not supported at all */ 286 - 287 - memset(&info, 0, sizeof(info)); 288 - info.name = ptr_to_u64(name); 289 - info.name_len = sizeof(name); 290 - 291 - /* check that BPF_OBJ_GET_INFO_BY_FD supports specifying name pointer; 292 - * kernel's module BTF support coincides with support for 293 - * name/name_len fields in struct bpf_btf_info. 294 - */ 295 - err = bpf_btf_get_info_by_fd(fd, &info, &len); 296 - close(fd); 297 - return !err; 298 - } 299 - 300 - static int probe_perf_link(int token_fd) 301 - { 302 - struct bpf_insn insns[] = { 303 - BPF_MOV64_IMM(BPF_REG_0, 0), 304 - BPF_EXIT_INSN(), 305 - }; 306 - LIBBPF_OPTS(bpf_prog_load_opts, opts, .token_fd = token_fd); 307 - int prog_fd, link_fd, err; 308 - 309 - prog_fd = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, NULL, "GPL", 310 - insns, ARRAY_SIZE(insns), &opts); 311 - if (prog_fd < 0) 312 - return -errno; 313 - 314 - /* use invalid perf_event FD to get EBADF, if link is supported; 315 - * otherwise EINVAL should be returned 316 - */ 317 - link_fd = bpf_link_create(prog_fd, -1, BPF_PERF_EVENT, NULL); 318 - err = -errno; /* close() can clobber errno */ 319 - 320 - if (link_fd >= 0) 321 - close(link_fd); 322 - close(prog_fd); 323 - 324 - return link_fd < 0 && err == -EBADF; 325 - } 326 - 327 - static int probe_uprobe_multi_link(int token_fd) 328 - { 329 - LIBBPF_OPTS(bpf_prog_load_opts, load_opts, 330 - .expected_attach_type = BPF_TRACE_UPROBE_MULTI, 331 - .token_fd = token_fd, 332 - ); 333 - LIBBPF_OPTS(bpf_link_create_opts, link_opts); 334 - struct bpf_insn insns[] = { 335 - BPF_MOV64_IMM(BPF_REG_0, 0), 336 - BPF_EXIT_INSN(), 337 - }; 338 - int prog_fd, link_fd, err; 339 - unsigned long offset = 0; 340 - 341 - prog_fd = bpf_prog_load(BPF_PROG_TYPE_KPROBE, NULL, "GPL", 342 - insns, ARRAY_SIZE(insns), &load_opts); 343 - if (prog_fd < 0) 344 - return -errno; 345 - 346 - /* Creating uprobe in '/' binary should fail with -EBADF. */ 347 - link_opts.uprobe_multi.path = "/"; 348 - link_opts.uprobe_multi.offsets = &offset; 349 - link_opts.uprobe_multi.cnt = 1; 350 - 351 - link_fd = bpf_link_create(prog_fd, -1, BPF_TRACE_UPROBE_MULTI, &link_opts); 352 - err = -errno; /* close() can clobber errno */ 353 - 354 - if (link_fd >= 0) 355 - close(link_fd); 356 - close(prog_fd); 357 - 358 - return link_fd < 0 && err == -EBADF; 359 - } 360 - 361 - static int probe_kern_bpf_cookie(int token_fd) 362 - { 363 - struct bpf_insn insns[] = { 364 - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_attach_cookie), 365 - BPF_EXIT_INSN(), 366 - }; 367 - LIBBPF_OPTS(bpf_prog_load_opts, opts, .token_fd = token_fd); 368 - int ret, insn_cnt = ARRAY_SIZE(insns); 369 - 370 - ret = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, NULL, "GPL", insns, insn_cnt, &opts); 371 - return probe_fd(ret); 372 - } 373 - 374 - static int probe_kern_btf_enum64(int token_fd) 375 - { 376 - static const char strs[] = "\0enum64"; 377 - __u32 types[] = { 378 - BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 0), 8), 379 - }; 380 - 381 - return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 382 - strs, sizeof(strs), token_fd)); 383 - } 384 - 385 - typedef int (*feature_probe_fn)(int /* token_fd */); 386 - 387 - static struct kern_feature_cache feature_cache; 388 - 389 - static struct kern_feature_desc { 390 - const char *desc; 391 - feature_probe_fn probe; 392 - } feature_probes[__FEAT_CNT] = { 393 - [FEAT_PROG_NAME] = { 394 - "BPF program name", probe_kern_prog_name, 395 - }, 396 - [FEAT_GLOBAL_DATA] = { 397 - "global variables", probe_kern_global_data, 398 - }, 399 - [FEAT_BTF] = { 400 - "minimal BTF", probe_kern_btf, 401 - }, 402 - [FEAT_BTF_FUNC] = { 403 - "BTF functions", probe_kern_btf_func, 404 - }, 405 - [FEAT_BTF_GLOBAL_FUNC] = { 406 - "BTF global function", probe_kern_btf_func_global, 407 - }, 408 - [FEAT_BTF_DATASEC] = { 409 - "BTF data section and variable", probe_kern_btf_datasec, 410 - }, 411 - [FEAT_ARRAY_MMAP] = { 412 - "ARRAY map mmap()", probe_kern_array_mmap, 413 - }, 414 - [FEAT_EXP_ATTACH_TYPE] = { 415 - "BPF_PROG_LOAD expected_attach_type attribute", 416 - probe_kern_exp_attach_type, 417 - }, 418 - [FEAT_PROBE_READ_KERN] = { 419 - "bpf_probe_read_kernel() helper", probe_kern_probe_read_kernel, 420 - }, 421 - [FEAT_PROG_BIND_MAP] = { 422 - "BPF_PROG_BIND_MAP support", probe_prog_bind_map, 423 - }, 424 - [FEAT_MODULE_BTF] = { 425 - "module BTF support", probe_module_btf, 426 - }, 427 - [FEAT_BTF_FLOAT] = { 428 - "BTF_KIND_FLOAT support", probe_kern_btf_float, 429 - }, 430 - [FEAT_PERF_LINK] = { 431 - "BPF perf link support", probe_perf_link, 432 - }, 433 - [FEAT_BTF_DECL_TAG] = { 434 - "BTF_KIND_DECL_TAG support", probe_kern_btf_decl_tag, 435 - }, 436 - [FEAT_BTF_TYPE_TAG] = { 437 - "BTF_KIND_TYPE_TAG support", probe_kern_btf_type_tag, 438 - }, 439 - [FEAT_MEMCG_ACCOUNT] = { 440 - "memcg-based memory accounting", probe_memcg_account, 441 - }, 442 - [FEAT_BPF_COOKIE] = { 443 - "BPF cookie support", probe_kern_bpf_cookie, 444 - }, 445 - [FEAT_BTF_ENUM64] = { 446 - "BTF_KIND_ENUM64 support", probe_kern_btf_enum64, 447 - }, 448 - [FEAT_SYSCALL_WRAPPER] = { 449 - "Kernel using syscall wrapper", probe_kern_syscall_wrapper, 450 - }, 451 - [FEAT_UPROBE_MULTI_LINK] = { 452 - "BPF multi-uprobe link support", probe_uprobe_multi_link, 453 - }, 454 - }; 455 - 456 - bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id) 457 - { 458 - struct kern_feature_desc *feat = &feature_probes[feat_id]; 459 - int ret; 460 - 461 - /* assume global feature cache, unless custom one is provided */ 462 - if (!cache) 463 - cache = &feature_cache; 464 - 465 - if (READ_ONCE(cache->res[feat_id]) == FEAT_UNKNOWN) { 466 - ret = feat->probe(cache->token_fd); 467 - if (ret > 0) { 468 - WRITE_ONCE(cache->res[feat_id], FEAT_SUPPORTED); 469 - } else if (ret == 0) { 470 - WRITE_ONCE(cache->res[feat_id], FEAT_MISSING); 471 - } else { 472 - pr_warn("Detection of kernel %s support failed: %d\n", feat->desc, ret); 473 - WRITE_ONCE(cache->res[feat_id], FEAT_MISSING); 474 - } 475 - } 476 - 477 - return READ_ONCE(cache->res[feat_id]) == FEAT_SUPPORTED; 478 - }
+455 -118
tools/lib/bpf/libbpf.c
··· 59 59 #define BPF_FS_MAGIC 0xcafe4a11 60 60 #endif 61 61 62 - #define BPF_FS_DEFAULT_PATH "/sys/fs/bpf" 63 - 64 62 #define BPF_INSN_SZ (sizeof(struct bpf_insn)) 65 63 66 64 /* vsprintf() in __base_pr() uses nonliteral format string. It may break ··· 692 694 size_t fd_array_cnt; 693 695 694 696 struct usdt_manager *usdt_man; 695 - 696 - struct kern_feature_cache *feat_cache; 697 - char *token_path; 698 - int token_fd; 699 697 700 698 char path[]; 701 699 }; ··· 2192 2198 int err; 2193 2199 2194 2200 if (!path) 2195 - path = BPF_FS_DEFAULT_PATH; 2201 + path = "/sys/fs/bpf"; 2196 2202 2197 2203 err = pathname_concat(buf, sizeof(buf), path, bpf_map__name(map)); 2198 2204 if (err) ··· 3279 3285 } else { 3280 3286 /* currently BPF_BTF_LOAD only supports log_level 1 */ 3281 3287 err = btf_load_into_kernel(kern_btf, obj->log_buf, obj->log_size, 3282 - obj->log_level ? 1 : 0, obj->token_fd); 3288 + obj->log_level ? 1 : 0); 3283 3289 } 3284 3290 if (sanitize) { 3285 3291 if (!err) { ··· 4602 4608 return 0; 4603 4609 } 4604 4610 4605 - static int bpf_object_prepare_token(struct bpf_object *obj) 4606 - { 4607 - const char *bpffs_path; 4608 - int bpffs_fd = -1, token_fd, err; 4609 - bool mandatory; 4610 - enum libbpf_print_level level; 4611 - 4612 - /* token is already set up */ 4613 - if (obj->token_fd > 0) 4614 - return 0; 4615 - /* token is explicitly prevented */ 4616 - if (obj->token_fd < 0) { 4617 - pr_debug("object '%s': token is prevented, skipping...\n", obj->name); 4618 - /* reset to zero to avoid extra checks during map_create and prog_load steps */ 4619 - obj->token_fd = 0; 4620 - return 0; 4621 - } 4622 - 4623 - mandatory = obj->token_path != NULL; 4624 - level = mandatory ? LIBBPF_WARN : LIBBPF_DEBUG; 4625 - 4626 - bpffs_path = obj->token_path ?: BPF_FS_DEFAULT_PATH; 4627 - bpffs_fd = open(bpffs_path, O_DIRECTORY, O_RDWR); 4628 - if (bpffs_fd < 0) { 4629 - err = -errno; 4630 - __pr(level, "object '%s': failed (%d) to open BPF FS mount at '%s'%s\n", 4631 - obj->name, err, bpffs_path, 4632 - mandatory ? "" : ", skipping optional step..."); 4633 - return mandatory ? err : 0; 4634 - } 4635 - 4636 - token_fd = bpf_token_create(bpffs_fd, 0); 4637 - close(bpffs_fd); 4638 - if (token_fd < 0) { 4639 - if (!mandatory && token_fd == -ENOENT) { 4640 - pr_debug("object '%s': BPF FS at '%s' doesn't have BPF token delegation set up, skipping...\n", 4641 - obj->name, bpffs_path); 4642 - return 0; 4643 - } 4644 - __pr(level, "object '%s': failed (%d) to create BPF token from '%s'%s\n", 4645 - obj->name, token_fd, bpffs_path, 4646 - mandatory ? "" : ", skipping optional step..."); 4647 - return mandatory ? token_fd : 0; 4648 - } 4649 - 4650 - obj->feat_cache = calloc(1, sizeof(*obj->feat_cache)); 4651 - if (!obj->feat_cache) { 4652 - close(token_fd); 4653 - return -ENOMEM; 4654 - } 4655 - 4656 - obj->token_fd = token_fd; 4657 - obj->feat_cache->token_fd = token_fd; 4658 - 4659 - return 0; 4660 - } 4661 - 4662 4611 static int 4663 4612 bpf_object__probe_loading(struct bpf_object *obj) 4664 4613 { ··· 4611 4674 BPF_EXIT_INSN(), 4612 4675 }; 4613 4676 int ret, insn_cnt = ARRAY_SIZE(insns); 4614 - LIBBPF_OPTS(bpf_prog_load_opts, opts, .token_fd = obj->token_fd); 4615 4677 4616 4678 if (obj->gen_loader) 4617 4679 return 0; ··· 4620 4684 pr_warn("Failed to bump RLIMIT_MEMLOCK (err = %d), you might need to do it explicitly!\n", ret); 4621 4685 4622 4686 /* make sure basic loading works */ 4623 - ret = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", insns, insn_cnt, &opts); 4687 + ret = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", insns, insn_cnt, NULL); 4624 4688 if (ret < 0) 4625 - ret = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, NULL, "GPL", insns, insn_cnt, &opts); 4689 + ret = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, NULL, "GPL", insns, insn_cnt, NULL); 4626 4690 if (ret < 0) { 4627 4691 ret = errno; 4628 4692 cp = libbpf_strerror_r(ret, errmsg, sizeof(errmsg)); ··· 4637 4701 return 0; 4638 4702 } 4639 4703 4704 + static int probe_fd(int fd) 4705 + { 4706 + if (fd >= 0) 4707 + close(fd); 4708 + return fd >= 0; 4709 + } 4710 + 4711 + static int probe_kern_prog_name(void) 4712 + { 4713 + const size_t attr_sz = offsetofend(union bpf_attr, prog_name); 4714 + struct bpf_insn insns[] = { 4715 + BPF_MOV64_IMM(BPF_REG_0, 0), 4716 + BPF_EXIT_INSN(), 4717 + }; 4718 + union bpf_attr attr; 4719 + int ret; 4720 + 4721 + memset(&attr, 0, attr_sz); 4722 + attr.prog_type = BPF_PROG_TYPE_SOCKET_FILTER; 4723 + attr.license = ptr_to_u64("GPL"); 4724 + attr.insns = ptr_to_u64(insns); 4725 + attr.insn_cnt = (__u32)ARRAY_SIZE(insns); 4726 + libbpf_strlcpy(attr.prog_name, "libbpf_nametest", sizeof(attr.prog_name)); 4727 + 4728 + /* make sure loading with name works */ 4729 + ret = sys_bpf_prog_load(&attr, attr_sz, PROG_LOAD_ATTEMPTS); 4730 + return probe_fd(ret); 4731 + } 4732 + 4733 + static int probe_kern_global_data(void) 4734 + { 4735 + char *cp, errmsg[STRERR_BUFSIZE]; 4736 + struct bpf_insn insns[] = { 4737 + BPF_LD_MAP_VALUE(BPF_REG_1, 0, 16), 4738 + BPF_ST_MEM(BPF_DW, BPF_REG_1, 0, 42), 4739 + BPF_MOV64_IMM(BPF_REG_0, 0), 4740 + BPF_EXIT_INSN(), 4741 + }; 4742 + int ret, map, insn_cnt = ARRAY_SIZE(insns); 4743 + 4744 + map = bpf_map_create(BPF_MAP_TYPE_ARRAY, "libbpf_global", sizeof(int), 32, 1, NULL); 4745 + if (map < 0) { 4746 + ret = -errno; 4747 + cp = libbpf_strerror_r(ret, errmsg, sizeof(errmsg)); 4748 + pr_warn("Error in %s():%s(%d). Couldn't create simple array map.\n", 4749 + __func__, cp, -ret); 4750 + return ret; 4751 + } 4752 + 4753 + insns[0].imm = map; 4754 + 4755 + ret = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", insns, insn_cnt, NULL); 4756 + close(map); 4757 + return probe_fd(ret); 4758 + } 4759 + 4760 + static int probe_kern_btf(void) 4761 + { 4762 + static const char strs[] = "\0int"; 4763 + __u32 types[] = { 4764 + /* int */ 4765 + BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), 4766 + }; 4767 + 4768 + return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 4769 + strs, sizeof(strs))); 4770 + } 4771 + 4772 + static int probe_kern_btf_func(void) 4773 + { 4774 + static const char strs[] = "\0int\0x\0a"; 4775 + /* void x(int a) {} */ 4776 + __u32 types[] = { 4777 + /* int */ 4778 + BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 4779 + /* FUNC_PROTO */ /* [2] */ 4780 + BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 0), 4781 + BTF_PARAM_ENC(7, 1), 4782 + /* FUNC x */ /* [3] */ 4783 + BTF_TYPE_ENC(5, BTF_INFO_ENC(BTF_KIND_FUNC, 0, 0), 2), 4784 + }; 4785 + 4786 + return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 4787 + strs, sizeof(strs))); 4788 + } 4789 + 4790 + static int probe_kern_btf_func_global(void) 4791 + { 4792 + static const char strs[] = "\0int\0x\0a"; 4793 + /* static void x(int a) {} */ 4794 + __u32 types[] = { 4795 + /* int */ 4796 + BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 4797 + /* FUNC_PROTO */ /* [2] */ 4798 + BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_FUNC_PROTO, 0, 1), 0), 4799 + BTF_PARAM_ENC(7, 1), 4800 + /* FUNC x BTF_FUNC_GLOBAL */ /* [3] */ 4801 + BTF_TYPE_ENC(5, BTF_INFO_ENC(BTF_KIND_FUNC, 0, BTF_FUNC_GLOBAL), 2), 4802 + }; 4803 + 4804 + return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 4805 + strs, sizeof(strs))); 4806 + } 4807 + 4808 + static int probe_kern_btf_datasec(void) 4809 + { 4810 + static const char strs[] = "\0x\0.data"; 4811 + /* static int a; */ 4812 + __u32 types[] = { 4813 + /* int */ 4814 + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 4815 + /* VAR x */ /* [2] */ 4816 + BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_VAR, 0, 0), 1), 4817 + BTF_VAR_STATIC, 4818 + /* DATASEC val */ /* [3] */ 4819 + BTF_TYPE_ENC(3, BTF_INFO_ENC(BTF_KIND_DATASEC, 0, 1), 4), 4820 + BTF_VAR_SECINFO_ENC(2, 0, 4), 4821 + }; 4822 + 4823 + return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 4824 + strs, sizeof(strs))); 4825 + } 4826 + 4827 + static int probe_kern_btf_float(void) 4828 + { 4829 + static const char strs[] = "\0float"; 4830 + __u32 types[] = { 4831 + /* float */ 4832 + BTF_TYPE_FLOAT_ENC(1, 4), 4833 + }; 4834 + 4835 + return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 4836 + strs, sizeof(strs))); 4837 + } 4838 + 4839 + static int probe_kern_btf_decl_tag(void) 4840 + { 4841 + static const char strs[] = "\0tag"; 4842 + __u32 types[] = { 4843 + /* int */ 4844 + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 4845 + /* VAR x */ /* [2] */ 4846 + BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_VAR, 0, 0), 1), 4847 + BTF_VAR_STATIC, 4848 + /* attr */ 4849 + BTF_TYPE_DECL_TAG_ENC(1, 2, -1), 4850 + }; 4851 + 4852 + return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 4853 + strs, sizeof(strs))); 4854 + } 4855 + 4856 + static int probe_kern_btf_type_tag(void) 4857 + { 4858 + static const char strs[] = "\0tag"; 4859 + __u32 types[] = { 4860 + /* int */ 4861 + BTF_TYPE_INT_ENC(0, BTF_INT_SIGNED, 0, 32, 4), /* [1] */ 4862 + /* attr */ 4863 + BTF_TYPE_TYPE_TAG_ENC(1, 1), /* [2] */ 4864 + /* ptr */ 4865 + BTF_TYPE_ENC(0, BTF_INFO_ENC(BTF_KIND_PTR, 0, 0), 2), /* [3] */ 4866 + }; 4867 + 4868 + return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 4869 + strs, sizeof(strs))); 4870 + } 4871 + 4872 + static int probe_kern_array_mmap(void) 4873 + { 4874 + LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_MMAPABLE); 4875 + int fd; 4876 + 4877 + fd = bpf_map_create(BPF_MAP_TYPE_ARRAY, "libbpf_mmap", sizeof(int), sizeof(int), 1, &opts); 4878 + return probe_fd(fd); 4879 + } 4880 + 4881 + static int probe_kern_exp_attach_type(void) 4882 + { 4883 + LIBBPF_OPTS(bpf_prog_load_opts, opts, .expected_attach_type = BPF_CGROUP_INET_SOCK_CREATE); 4884 + struct bpf_insn insns[] = { 4885 + BPF_MOV64_IMM(BPF_REG_0, 0), 4886 + BPF_EXIT_INSN(), 4887 + }; 4888 + int fd, insn_cnt = ARRAY_SIZE(insns); 4889 + 4890 + /* use any valid combination of program type and (optional) 4891 + * non-zero expected attach type (i.e., not a BPF_CGROUP_INET_INGRESS) 4892 + * to see if kernel supports expected_attach_type field for 4893 + * BPF_PROG_LOAD command 4894 + */ 4895 + fd = bpf_prog_load(BPF_PROG_TYPE_CGROUP_SOCK, NULL, "GPL", insns, insn_cnt, &opts); 4896 + return probe_fd(fd); 4897 + } 4898 + 4899 + static int probe_kern_probe_read_kernel(void) 4900 + { 4901 + struct bpf_insn insns[] = { 4902 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_10), /* r1 = r10 (fp) */ 4903 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -8), /* r1 += -8 */ 4904 + BPF_MOV64_IMM(BPF_REG_2, 8), /* r2 = 8 */ 4905 + BPF_MOV64_IMM(BPF_REG_3, 0), /* r3 = 0 */ 4906 + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_probe_read_kernel), 4907 + BPF_EXIT_INSN(), 4908 + }; 4909 + int fd, insn_cnt = ARRAY_SIZE(insns); 4910 + 4911 + fd = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, NULL, "GPL", insns, insn_cnt, NULL); 4912 + return probe_fd(fd); 4913 + } 4914 + 4915 + static int probe_prog_bind_map(void) 4916 + { 4917 + char *cp, errmsg[STRERR_BUFSIZE]; 4918 + struct bpf_insn insns[] = { 4919 + BPF_MOV64_IMM(BPF_REG_0, 0), 4920 + BPF_EXIT_INSN(), 4921 + }; 4922 + int ret, map, prog, insn_cnt = ARRAY_SIZE(insns); 4923 + 4924 + map = bpf_map_create(BPF_MAP_TYPE_ARRAY, "libbpf_det_bind", sizeof(int), 32, 1, NULL); 4925 + if (map < 0) { 4926 + ret = -errno; 4927 + cp = libbpf_strerror_r(ret, errmsg, sizeof(errmsg)); 4928 + pr_warn("Error in %s():%s(%d). Couldn't create simple array map.\n", 4929 + __func__, cp, -ret); 4930 + return ret; 4931 + } 4932 + 4933 + prog = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", insns, insn_cnt, NULL); 4934 + if (prog < 0) { 4935 + close(map); 4936 + return 0; 4937 + } 4938 + 4939 + ret = bpf_prog_bind_map(prog, map, NULL); 4940 + 4941 + close(map); 4942 + close(prog); 4943 + 4944 + return ret >= 0; 4945 + } 4946 + 4947 + static int probe_module_btf(void) 4948 + { 4949 + static const char strs[] = "\0int"; 4950 + __u32 types[] = { 4951 + /* int */ 4952 + BTF_TYPE_INT_ENC(1, BTF_INT_SIGNED, 0, 32, 4), 4953 + }; 4954 + struct bpf_btf_info info; 4955 + __u32 len = sizeof(info); 4956 + char name[16]; 4957 + int fd, err; 4958 + 4959 + fd = libbpf__load_raw_btf((char *)types, sizeof(types), strs, sizeof(strs)); 4960 + if (fd < 0) 4961 + return 0; /* BTF not supported at all */ 4962 + 4963 + memset(&info, 0, sizeof(info)); 4964 + info.name = ptr_to_u64(name); 4965 + info.name_len = sizeof(name); 4966 + 4967 + /* check that BPF_OBJ_GET_INFO_BY_FD supports specifying name pointer; 4968 + * kernel's module BTF support coincides with support for 4969 + * name/name_len fields in struct bpf_btf_info. 4970 + */ 4971 + err = bpf_btf_get_info_by_fd(fd, &info, &len); 4972 + close(fd); 4973 + return !err; 4974 + } 4975 + 4976 + static int probe_perf_link(void) 4977 + { 4978 + struct bpf_insn insns[] = { 4979 + BPF_MOV64_IMM(BPF_REG_0, 0), 4980 + BPF_EXIT_INSN(), 4981 + }; 4982 + int prog_fd, link_fd, err; 4983 + 4984 + prog_fd = bpf_prog_load(BPF_PROG_TYPE_TRACEPOINT, NULL, "GPL", 4985 + insns, ARRAY_SIZE(insns), NULL); 4986 + if (prog_fd < 0) 4987 + return -errno; 4988 + 4989 + /* use invalid perf_event FD to get EBADF, if link is supported; 4990 + * otherwise EINVAL should be returned 4991 + */ 4992 + link_fd = bpf_link_create(prog_fd, -1, BPF_PERF_EVENT, NULL); 4993 + err = -errno; /* close() can clobber errno */ 4994 + 4995 + if (link_fd >= 0) 4996 + close(link_fd); 4997 + close(prog_fd); 4998 + 4999 + return link_fd < 0 && err == -EBADF; 5000 + } 5001 + 5002 + static int probe_uprobe_multi_link(void) 5003 + { 5004 + LIBBPF_OPTS(bpf_prog_load_opts, load_opts, 5005 + .expected_attach_type = BPF_TRACE_UPROBE_MULTI, 5006 + ); 5007 + LIBBPF_OPTS(bpf_link_create_opts, link_opts); 5008 + struct bpf_insn insns[] = { 5009 + BPF_MOV64_IMM(BPF_REG_0, 0), 5010 + BPF_EXIT_INSN(), 5011 + }; 5012 + int prog_fd, link_fd, err; 5013 + unsigned long offset = 0; 5014 + 5015 + prog_fd = bpf_prog_load(BPF_PROG_TYPE_KPROBE, NULL, "GPL", 5016 + insns, ARRAY_SIZE(insns), &load_opts); 5017 + if (prog_fd < 0) 5018 + return -errno; 5019 + 5020 + /* Creating uprobe in '/' binary should fail with -EBADF. */ 5021 + link_opts.uprobe_multi.path = "/"; 5022 + link_opts.uprobe_multi.offsets = &offset; 5023 + link_opts.uprobe_multi.cnt = 1; 5024 + 5025 + link_fd = bpf_link_create(prog_fd, -1, BPF_TRACE_UPROBE_MULTI, &link_opts); 5026 + err = -errno; /* close() can clobber errno */ 5027 + 5028 + if (link_fd >= 0) 5029 + close(link_fd); 5030 + close(prog_fd); 5031 + 5032 + return link_fd < 0 && err == -EBADF; 5033 + } 5034 + 5035 + static int probe_kern_bpf_cookie(void) 5036 + { 5037 + struct bpf_insn insns[] = { 5038 + BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_attach_cookie), 5039 + BPF_EXIT_INSN(), 5040 + }; 5041 + int ret, insn_cnt = ARRAY_SIZE(insns); 5042 + 5043 + ret = bpf_prog_load(BPF_PROG_TYPE_KPROBE, NULL, "GPL", insns, insn_cnt, NULL); 5044 + return probe_fd(ret); 5045 + } 5046 + 5047 + static int probe_kern_btf_enum64(void) 5048 + { 5049 + static const char strs[] = "\0enum64"; 5050 + __u32 types[] = { 5051 + BTF_TYPE_ENC(1, BTF_INFO_ENC(BTF_KIND_ENUM64, 0, 0), 8), 5052 + }; 5053 + 5054 + return probe_fd(libbpf__load_raw_btf((char *)types, sizeof(types), 5055 + strs, sizeof(strs))); 5056 + } 5057 + 5058 + static int probe_kern_syscall_wrapper(void); 5059 + 5060 + enum kern_feature_result { 5061 + FEAT_UNKNOWN = 0, 5062 + FEAT_SUPPORTED = 1, 5063 + FEAT_MISSING = 2, 5064 + }; 5065 + 5066 + typedef int (*feature_probe_fn)(void); 5067 + 5068 + static struct kern_feature_desc { 5069 + const char *desc; 5070 + feature_probe_fn probe; 5071 + enum kern_feature_result res; 5072 + } feature_probes[__FEAT_CNT] = { 5073 + [FEAT_PROG_NAME] = { 5074 + "BPF program name", probe_kern_prog_name, 5075 + }, 5076 + [FEAT_GLOBAL_DATA] = { 5077 + "global variables", probe_kern_global_data, 5078 + }, 5079 + [FEAT_BTF] = { 5080 + "minimal BTF", probe_kern_btf, 5081 + }, 5082 + [FEAT_BTF_FUNC] = { 5083 + "BTF functions", probe_kern_btf_func, 5084 + }, 5085 + [FEAT_BTF_GLOBAL_FUNC] = { 5086 + "BTF global function", probe_kern_btf_func_global, 5087 + }, 5088 + [FEAT_BTF_DATASEC] = { 5089 + "BTF data section and variable", probe_kern_btf_datasec, 5090 + }, 5091 + [FEAT_ARRAY_MMAP] = { 5092 + "ARRAY map mmap()", probe_kern_array_mmap, 5093 + }, 5094 + [FEAT_EXP_ATTACH_TYPE] = { 5095 + "BPF_PROG_LOAD expected_attach_type attribute", 5096 + probe_kern_exp_attach_type, 5097 + }, 5098 + [FEAT_PROBE_READ_KERN] = { 5099 + "bpf_probe_read_kernel() helper", probe_kern_probe_read_kernel, 5100 + }, 5101 + [FEAT_PROG_BIND_MAP] = { 5102 + "BPF_PROG_BIND_MAP support", probe_prog_bind_map, 5103 + }, 5104 + [FEAT_MODULE_BTF] = { 5105 + "module BTF support", probe_module_btf, 5106 + }, 5107 + [FEAT_BTF_FLOAT] = { 5108 + "BTF_KIND_FLOAT support", probe_kern_btf_float, 5109 + }, 5110 + [FEAT_PERF_LINK] = { 5111 + "BPF perf link support", probe_perf_link, 5112 + }, 5113 + [FEAT_BTF_DECL_TAG] = { 5114 + "BTF_KIND_DECL_TAG support", probe_kern_btf_decl_tag, 5115 + }, 5116 + [FEAT_BTF_TYPE_TAG] = { 5117 + "BTF_KIND_TYPE_TAG support", probe_kern_btf_type_tag, 5118 + }, 5119 + [FEAT_MEMCG_ACCOUNT] = { 5120 + "memcg-based memory accounting", probe_memcg_account, 5121 + }, 5122 + [FEAT_BPF_COOKIE] = { 5123 + "BPF cookie support", probe_kern_bpf_cookie, 5124 + }, 5125 + [FEAT_BTF_ENUM64] = { 5126 + "BTF_KIND_ENUM64 support", probe_kern_btf_enum64, 5127 + }, 5128 + [FEAT_SYSCALL_WRAPPER] = { 5129 + "Kernel using syscall wrapper", probe_kern_syscall_wrapper, 5130 + }, 5131 + [FEAT_UPROBE_MULTI_LINK] = { 5132 + "BPF multi-uprobe link support", probe_uprobe_multi_link, 5133 + }, 5134 + }; 5135 + 4640 5136 bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id) 4641 5137 { 5138 + struct kern_feature_desc *feat = &feature_probes[feat_id]; 5139 + int ret; 5140 + 4642 5141 if (obj && obj->gen_loader) 4643 5142 /* To generate loader program assume the latest kernel 4644 5143 * to avoid doing extra prog_load, map_create syscalls. 4645 5144 */ 4646 5145 return true; 4647 5146 4648 - if (obj->token_fd) 4649 - return feat_supported(obj->feat_cache, feat_id); 5147 + if (READ_ONCE(feat->res) == FEAT_UNKNOWN) { 5148 + ret = feat->probe(); 5149 + if (ret > 0) { 5150 + WRITE_ONCE(feat->res, FEAT_SUPPORTED); 5151 + } else if (ret == 0) { 5152 + WRITE_ONCE(feat->res, FEAT_MISSING); 5153 + } else { 5154 + pr_warn("Detection of kernel %s support failed: %d\n", feat->desc, ret); 5155 + WRITE_ONCE(feat->res, FEAT_MISSING); 5156 + } 5157 + } 4650 5158 4651 - return feat_supported(NULL, feat_id); 5159 + return READ_ONCE(feat->res) == FEAT_SUPPORTED; 4652 5160 } 4653 5161 4654 5162 static bool map_is_reuse_compat(const struct bpf_map *map, int map_fd) ··· 5211 4831 create_attr.map_flags = def->map_flags; 5212 4832 create_attr.numa_node = map->numa_node; 5213 4833 create_attr.map_extra = map->map_extra; 5214 - create_attr.token_fd = obj->token_fd; 5215 4834 5216 4835 if (bpf_map__is_struct_ops(map)) 5217 4836 create_attr.btf_vmlinux_value_type_id = map->btf_vmlinux_value_type_id; ··· 7046 6667 load_attr.attach_btf_id = prog->attach_btf_id; 7047 6668 load_attr.kern_version = kern_version; 7048 6669 load_attr.prog_ifindex = prog->prog_ifindex; 7049 - load_attr.token_fd = obj->token_fd; 7050 6670 7051 6671 /* specify func_info/line_info only if kernel supports them */ 7052 6672 btf_fd = bpf_object__btf_fd(obj); ··· 7507 7129 static struct bpf_object *bpf_object_open(const char *path, const void *obj_buf, size_t obj_buf_sz, 7508 7130 const struct bpf_object_open_opts *opts) 7509 7131 { 7510 - const char *obj_name, *kconfig, *btf_tmp_path, *token_path; 7132 + const char *obj_name, *kconfig, *btf_tmp_path; 7511 7133 struct bpf_object *obj; 7512 7134 char tmp_name[64]; 7513 - int err, token_fd; 7135 + int err; 7514 7136 char *log_buf; 7515 7137 size_t log_size; 7516 7138 __u32 log_level; ··· 7544 7166 if (log_size && !log_buf) 7545 7167 return ERR_PTR(-EINVAL); 7546 7168 7547 - token_path = OPTS_GET(opts, bpf_token_path, NULL); 7548 - token_fd = OPTS_GET(opts, bpf_token_fd, -1); 7549 - /* non-empty token path can't be combined with invalid token FD */ 7550 - if (token_path && token_path[0] != '\0' && token_fd < 0) 7551 - return ERR_PTR(-EINVAL); 7552 - /* empty token path can't be combined with valid token FD */ 7553 - if (token_path && token_path[0] == '\0' && token_fd > 0) 7554 - return ERR_PTR(-EINVAL); 7555 - /* if user didn't specify bpf_token_path/bpf_token_fd explicitly, 7556 - * check if LIBBPF_BPF_TOKEN_PATH envvar was set and treat it as 7557 - * bpf_token_path option 7558 - */ 7559 - if (token_fd == 0 && !token_path) 7560 - token_path = getenv("LIBBPF_BPF_TOKEN_PATH"); 7561 - /* empty token_path is equivalent to invalid token_fd */ 7562 - if (token_path && token_path[0] == '\0') { 7563 - token_path = NULL; 7564 - token_fd = -1; 7565 - } 7566 - if (token_path && strlen(token_path) >= PATH_MAX) 7567 - return ERR_PTR(-ENAMETOOLONG); 7568 - 7569 7169 obj = bpf_object__new(path, obj_buf, obj_buf_sz, obj_name); 7570 7170 if (IS_ERR(obj)) 7571 7171 return obj; ··· 7551 7195 obj->log_buf = log_buf; 7552 7196 obj->log_size = log_size; 7553 7197 obj->log_level = log_level; 7554 - 7555 - obj->token_fd = token_fd <= 0 ? token_fd : dup_good_fd(token_fd); 7556 - if (token_fd > 0 && obj->token_fd < 0) { 7557 - err = -errno; 7558 - goto out; 7559 - } 7560 - if (token_path) { 7561 - obj->token_path = strdup(token_path); 7562 - if (!obj->token_path) { 7563 - err = -ENOMEM; 7564 - goto out; 7565 - } 7566 - } 7567 7198 7568 7199 btf_tmp_path = OPTS_GET(opts, btf_custom_path, NULL); 7569 7200 if (btf_tmp_path) { ··· 8062 7719 if (obj->gen_loader) 8063 7720 bpf_gen__init(obj->gen_loader, extra_log_level, obj->nr_programs, obj->nr_maps); 8064 7721 8065 - err = bpf_object_prepare_token(obj); 8066 - err = err ? : bpf_object__probe_loading(obj); 7722 + err = bpf_object__probe_loading(obj); 8067 7723 err = err ? : bpf_object__load_vmlinux_btf(obj, false); 8068 7724 err = err ? : bpf_object__resolve_externs(obj, obj->kconfig); 8069 7725 err = err ? : bpf_object__sanitize_and_load_btf(obj); ··· 8598 8256 bpf_program__exit(&obj->programs[i]); 8599 8257 } 8600 8258 zfree(&obj->programs); 8601 - 8602 - zfree(&obj->feat_cache); 8603 - zfree(&obj->token_path); 8604 - if (obj->token_fd > 0) 8605 - close(obj->token_fd); 8606 8259 8607 8260 free(obj); 8608 8261 } ··· 10612 10275 #endif 10613 10276 } 10614 10277 10615 - int probe_kern_syscall_wrapper(int token_fd) 10278 + static int probe_kern_syscall_wrapper(void) 10616 10279 { 10617 10280 char syscall_name[64]; 10618 10281 const char *ksys_pfx;
+1 -36
tools/lib/bpf/libbpf.h
··· 177 177 * logs through its print callback. 178 178 */ 179 179 __u32 kernel_log_level; 180 - /* FD of a BPF token instantiated by user through bpf_token_create() 181 - * API. BPF object will keep dup()'ed FD internally, so passed token 182 - * FD can be closed after BPF object/skeleton open step. 183 - * 184 - * Setting bpf_token_fd to negative value disables libbpf's automatic 185 - * attempt to create BPF token from default BPF FS mount point 186 - * (/sys/fs/bpf), in case this default behavior is undesirable. 187 - * 188 - * If bpf_token_path and bpf_token_fd are not specified, libbpf will 189 - * consult LIBBPF_BPF_TOKEN_PATH environment variable. If set, it will 190 - * be taken as a value of bpf_token_path option and will force libbpf 191 - * to either create BPF token from provided custom BPF FS path, or 192 - * will disable implicit BPF token creation, if envvar value is an 193 - * empty string. 194 - * 195 - * bpf_token_path and bpf_token_fd are mutually exclusive and only one 196 - * of those options should be set. Either of them overrides 197 - * LIBBPF_BPF_TOKEN_PATH envvar. 198 - */ 199 - int bpf_token_fd; 200 - /* Path to BPF FS mount point to derive BPF token from. 201 - * 202 - * Created BPF token will be used for all bpf() syscall operations 203 - * that accept BPF token (e.g., map creation, BTF and program loads, 204 - * etc) automatically within instantiated BPF object. 205 - * 206 - * Setting bpf_token_path option to empty string disables libbpf's 207 - * automatic attempt to create BPF token from default BPF FS mount 208 - * point (/sys/fs/bpf), in case this default behavior is undesirable. 209 - * 210 - * bpf_token_path and bpf_token_fd are mutually exclusive and only one 211 - * of those options should be set. Either of them overrides 212 - * LIBBPF_BPF_TOKEN_PATH envvar. 213 - */ 214 - const char *bpf_token_path; 215 180 216 181 size_t :0; 217 182 }; 218 - #define bpf_object_open_opts__last_field bpf_token_path 183 + #define bpf_object_open_opts__last_field kernel_log_level 219 184 220 185 /** 221 186 * @brief **bpf_object__open()** creates a bpf_object by opening
-1
tools/lib/bpf/libbpf.map
··· 401 401 bpf_program__attach_netkit; 402 402 bpf_program__attach_tcx; 403 403 bpf_program__attach_uprobe_multi; 404 - bpf_token_create; 405 404 ring__avail_data_size; 406 405 ring__consume; 407 406 ring__consumer_pos;
+4 -32
tools/lib/bpf/libbpf_internal.h
··· 360 360 __FEAT_CNT, 361 361 }; 362 362 363 - enum kern_feature_result { 364 - FEAT_UNKNOWN = 0, 365 - FEAT_SUPPORTED = 1, 366 - FEAT_MISSING = 2, 367 - }; 368 - 369 - struct kern_feature_cache { 370 - enum kern_feature_result res[__FEAT_CNT]; 371 - int token_fd; 372 - }; 373 - 374 - bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id); 363 + int probe_memcg_account(void); 375 364 bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id); 376 - 377 - int probe_kern_syscall_wrapper(int token_fd); 378 - int probe_memcg_account(int token_fd); 379 365 int bump_rlimit_memlock(void); 380 366 381 367 int parse_cpu_mask_str(const char *s, bool **mask, int *mask_sz); 382 368 int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz); 383 369 int libbpf__load_raw_btf(const char *raw_types, size_t types_len, 384 - const char *str_sec, size_t str_len, 385 - int token_fd); 386 - int btf_load_into_kernel(struct btf *btf, 387 - char *log_buf, size_t log_sz, __u32 log_level, 388 - int token_fd); 370 + const char *str_sec, size_t str_len); 371 + int btf_load_into_kernel(struct btf *btf, char *log_buf, size_t log_sz, __u32 log_level); 389 372 390 373 struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf); 391 374 void btf_get_kernel_prefix_kind(enum bpf_attach_type attach_type, ··· 532 549 return insn->code == (BPF_LD | BPF_IMM | BPF_DW); 533 550 } 534 551 535 - /* Unconditionally dup FD, ensuring it doesn't use [0, 2] range. 536 - * Original FD is not closed or altered in any other way. 537 - * Preserves original FD value, if it's invalid (negative). 538 - */ 539 - static inline int dup_good_fd(int fd) 540 - { 541 - if (fd < 0) 542 - return fd; 543 - return fcntl(fd, F_DUPFD_CLOEXEC, 3); 544 - } 545 - 546 552 /* if fd is stdin, stdout, or stderr, dup to a fd greater than 2 547 553 * Takes ownership of the fd passed in, and closes it if calling 548 554 * fcntl(fd, F_DUPFD_CLOEXEC, 3). ··· 543 571 if (fd < 0) 544 572 return fd; 545 573 if (fd < 3) { 546 - fd = dup_good_fd(fd); 574 + fd = fcntl(fd, F_DUPFD_CLOEXEC, 3); 547 575 saved_errno = errno; 548 576 close(old_fd); 549 577 errno = saved_errno;
+3 -5
tools/lib/bpf/libbpf_probes.c
··· 219 219 } 220 220 221 221 int libbpf__load_raw_btf(const char *raw_types, size_t types_len, 222 - const char *str_sec, size_t str_len, 223 - int token_fd) 222 + const char *str_sec, size_t str_len) 224 223 { 225 224 struct btf_header hdr = { 226 225 .magic = BTF_MAGIC, ··· 229 230 .str_off = types_len, 230 231 .str_len = str_len, 231 232 }; 232 - LIBBPF_OPTS(bpf_btf_load_opts, opts, .token_fd = token_fd); 233 233 int btf_fd, btf_len; 234 234 __u8 *raw_btf; 235 235 ··· 241 243 memcpy(raw_btf + hdr.hdr_len, raw_types, hdr.type_len); 242 244 memcpy(raw_btf + hdr.hdr_len + hdr.type_len, str_sec, hdr.str_len); 243 245 244 - btf_fd = bpf_btf_load(raw_btf, btf_len, &opts); 246 + btf_fd = bpf_btf_load(raw_btf, btf_len, NULL); 245 247 246 248 free(raw_btf); 247 249 return btf_fd; ··· 271 273 }; 272 274 273 275 return libbpf__load_raw_btf((char *)types, sizeof(types), 274 - strs, sizeof(strs), 0); 276 + strs, sizeof(strs)); 275 277 } 276 278 277 279 static int probe_map_create(enum bpf_map_type map_type)
-3
tools/lib/bpf/str_error.h
··· 2 2 #ifndef __LIBBPF_STR_ERROR_H 3 3 #define __LIBBPF_STR_ERROR_H 4 4 5 - #define STRERR_BUFSIZE 128 6 - 7 5 char *libbpf_strerror_r(int err, char *dst, int len); 8 - 9 6 #endif /* __LIBBPF_STR_ERROR_H */
-4
tools/testing/selftests/bpf/prog_tests/libbpf_probes.c
··· 30 30 31 31 if (prog_type == BPF_PROG_TYPE_UNSPEC) 32 32 continue; 33 - if (strcmp(prog_type_name, "__MAX_BPF_PROG_TYPE") == 0) 34 - continue; 35 33 36 34 if (!test__start_subtest(prog_type_name)) 37 35 continue; ··· 67 69 int res; 68 70 69 71 if (map_type == BPF_MAP_TYPE_UNSPEC) 70 - continue; 71 - if (strcmp(map_type_name, "__MAX_BPF_MAP_TYPE") == 0) 72 72 continue; 73 73 74 74 if (!test__start_subtest(map_type_name))
-6
tools/testing/selftests/bpf/prog_tests/libbpf_str.c
··· 132 132 const char *map_type_str; 133 133 char buf[256]; 134 134 135 - if (map_type == __MAX_BPF_MAP_TYPE) 136 - continue; 137 - 138 135 map_type_name = btf__str_by_offset(btf, e->name_off); 139 136 map_type_str = libbpf_bpf_map_type_str(map_type); 140 137 ASSERT_OK_PTR(map_type_str, map_type_name); ··· 185 188 const char *prog_type_name; 186 189 const char *prog_type_str; 187 190 char buf[256]; 188 - 189 - if (prog_type == __MAX_BPF_PROG_TYPE) 190 - continue; 191 191 192 192 prog_type_name = btf__str_by_offset(btf, e->name_off); 193 193 prog_type_str = libbpf_bpf_prog_type_str(prog_type);
-1031
tools/testing/selftests/bpf/prog_tests/token.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */ 3 - #define _GNU_SOURCE 4 - #include <test_progs.h> 5 - #include <bpf/btf.h> 6 - #include "cap_helpers.h" 7 - #include <fcntl.h> 8 - #include <sched.h> 9 - #include <signal.h> 10 - #include <unistd.h> 11 - #include <linux/filter.h> 12 - #include <linux/unistd.h> 13 - #include <linux/mount.h> 14 - #include <sys/socket.h> 15 - #include <sys/stat.h> 16 - #include <sys/syscall.h> 17 - #include <sys/un.h> 18 - #include "priv_map.skel.h" 19 - #include "priv_prog.skel.h" 20 - #include "dummy_st_ops_success.skel.h" 21 - 22 - static inline int sys_mount(const char *dev_name, const char *dir_name, 23 - const char *type, unsigned long flags, 24 - const void *data) 25 - { 26 - return syscall(__NR_mount, dev_name, dir_name, type, flags, data); 27 - } 28 - 29 - static inline int sys_fsopen(const char *fsname, unsigned flags) 30 - { 31 - return syscall(__NR_fsopen, fsname, flags); 32 - } 33 - 34 - static inline int sys_fspick(int dfd, const char *path, unsigned flags) 35 - { 36 - return syscall(__NR_fspick, dfd, path, flags); 37 - } 38 - 39 - static inline int sys_fsconfig(int fs_fd, unsigned cmd, const char *key, const void *val, int aux) 40 - { 41 - return syscall(__NR_fsconfig, fs_fd, cmd, key, val, aux); 42 - } 43 - 44 - static inline int sys_fsmount(int fs_fd, unsigned flags, unsigned ms_flags) 45 - { 46 - return syscall(__NR_fsmount, fs_fd, flags, ms_flags); 47 - } 48 - 49 - static inline int sys_move_mount(int from_dfd, const char *from_path, 50 - int to_dfd, const char *to_path, 51 - unsigned flags) 52 - { 53 - return syscall(__NR_move_mount, from_dfd, from_path, to_dfd, to_path, flags); 54 - } 55 - 56 - static int drop_priv_caps(__u64 *old_caps) 57 - { 58 - return cap_disable_effective((1ULL << CAP_BPF) | 59 - (1ULL << CAP_PERFMON) | 60 - (1ULL << CAP_NET_ADMIN) | 61 - (1ULL << CAP_SYS_ADMIN), old_caps); 62 - } 63 - 64 - static int restore_priv_caps(__u64 old_caps) 65 - { 66 - return cap_enable_effective(old_caps, NULL); 67 - } 68 - 69 - static int set_delegate_mask(int fs_fd, const char *key, __u64 mask, const char *mask_str) 70 - { 71 - char buf[32]; 72 - int err; 73 - 74 - if (!mask_str) { 75 - if (mask == ~0ULL) { 76 - mask_str = "any"; 77 - } else { 78 - snprintf(buf, sizeof(buf), "0x%llx", (unsigned long long)mask); 79 - mask_str = buf; 80 - } 81 - } 82 - 83 - err = sys_fsconfig(fs_fd, FSCONFIG_SET_STRING, key, 84 - mask_str, 0); 85 - if (err < 0) 86 - err = -errno; 87 - return err; 88 - } 89 - 90 - #define zclose(fd) do { if (fd >= 0) close(fd); fd = -1; } while (0) 91 - 92 - struct bpffs_opts { 93 - __u64 cmds; 94 - __u64 maps; 95 - __u64 progs; 96 - __u64 attachs; 97 - const char *cmds_str; 98 - const char *maps_str; 99 - const char *progs_str; 100 - const char *attachs_str; 101 - }; 102 - 103 - static int create_bpffs_fd(void) 104 - { 105 - int fs_fd; 106 - 107 - /* create VFS context */ 108 - fs_fd = sys_fsopen("bpf", 0); 109 - ASSERT_GE(fs_fd, 0, "fs_fd"); 110 - 111 - return fs_fd; 112 - } 113 - 114 - static int materialize_bpffs_fd(int fs_fd, struct bpffs_opts *opts) 115 - { 116 - int mnt_fd, err; 117 - 118 - /* set up token delegation mount options */ 119 - err = set_delegate_mask(fs_fd, "delegate_cmds", opts->cmds, opts->cmds_str); 120 - if (!ASSERT_OK(err, "fs_cfg_cmds")) 121 - return err; 122 - err = set_delegate_mask(fs_fd, "delegate_maps", opts->maps, opts->maps_str); 123 - if (!ASSERT_OK(err, "fs_cfg_maps")) 124 - return err; 125 - err = set_delegate_mask(fs_fd, "delegate_progs", opts->progs, opts->progs_str); 126 - if (!ASSERT_OK(err, "fs_cfg_progs")) 127 - return err; 128 - err = set_delegate_mask(fs_fd, "delegate_attachs", opts->attachs, opts->attachs_str); 129 - if (!ASSERT_OK(err, "fs_cfg_attachs")) 130 - return err; 131 - 132 - /* instantiate FS object */ 133 - err = sys_fsconfig(fs_fd, FSCONFIG_CMD_CREATE, NULL, NULL, 0); 134 - if (err < 0) 135 - return -errno; 136 - 137 - /* create O_PATH fd for detached mount */ 138 - mnt_fd = sys_fsmount(fs_fd, 0, 0); 139 - if (err < 0) 140 - return -errno; 141 - 142 - return mnt_fd; 143 - } 144 - 145 - /* send FD over Unix domain (AF_UNIX) socket */ 146 - static int sendfd(int sockfd, int fd) 147 - { 148 - struct msghdr msg = {}; 149 - struct cmsghdr *cmsg; 150 - int fds[1] = { fd }, err; 151 - char iobuf[1]; 152 - struct iovec io = { 153 - .iov_base = iobuf, 154 - .iov_len = sizeof(iobuf), 155 - }; 156 - union { 157 - char buf[CMSG_SPACE(sizeof(fds))]; 158 - struct cmsghdr align; 159 - } u; 160 - 161 - msg.msg_iov = &io; 162 - msg.msg_iovlen = 1; 163 - msg.msg_control = u.buf; 164 - msg.msg_controllen = sizeof(u.buf); 165 - cmsg = CMSG_FIRSTHDR(&msg); 166 - cmsg->cmsg_level = SOL_SOCKET; 167 - cmsg->cmsg_type = SCM_RIGHTS; 168 - cmsg->cmsg_len = CMSG_LEN(sizeof(fds)); 169 - memcpy(CMSG_DATA(cmsg), fds, sizeof(fds)); 170 - 171 - err = sendmsg(sockfd, &msg, 0); 172 - if (err < 0) 173 - err = -errno; 174 - if (!ASSERT_EQ(err, 1, "sendmsg")) 175 - return -EINVAL; 176 - 177 - return 0; 178 - } 179 - 180 - /* receive FD over Unix domain (AF_UNIX) socket */ 181 - static int recvfd(int sockfd, int *fd) 182 - { 183 - struct msghdr msg = {}; 184 - struct cmsghdr *cmsg; 185 - int fds[1], err; 186 - char iobuf[1]; 187 - struct iovec io = { 188 - .iov_base = iobuf, 189 - .iov_len = sizeof(iobuf), 190 - }; 191 - union { 192 - char buf[CMSG_SPACE(sizeof(fds))]; 193 - struct cmsghdr align; 194 - } u; 195 - 196 - msg.msg_iov = &io; 197 - msg.msg_iovlen = 1; 198 - msg.msg_control = u.buf; 199 - msg.msg_controllen = sizeof(u.buf); 200 - 201 - err = recvmsg(sockfd, &msg, 0); 202 - if (err < 0) 203 - err = -errno; 204 - if (!ASSERT_EQ(err, 1, "recvmsg")) 205 - return -EINVAL; 206 - 207 - cmsg = CMSG_FIRSTHDR(&msg); 208 - if (!ASSERT_OK_PTR(cmsg, "cmsg_null") || 209 - !ASSERT_EQ(cmsg->cmsg_len, CMSG_LEN(sizeof(fds)), "cmsg_len") || 210 - !ASSERT_EQ(cmsg->cmsg_level, SOL_SOCKET, "cmsg_level") || 211 - !ASSERT_EQ(cmsg->cmsg_type, SCM_RIGHTS, "cmsg_type")) 212 - return -EINVAL; 213 - 214 - memcpy(fds, CMSG_DATA(cmsg), sizeof(fds)); 215 - *fd = fds[0]; 216 - 217 - return 0; 218 - } 219 - 220 - static ssize_t write_nointr(int fd, const void *buf, size_t count) 221 - { 222 - ssize_t ret; 223 - 224 - do { 225 - ret = write(fd, buf, count); 226 - } while (ret < 0 && errno == EINTR); 227 - 228 - return ret; 229 - } 230 - 231 - static int write_file(const char *path, const void *buf, size_t count) 232 - { 233 - int fd; 234 - ssize_t ret; 235 - 236 - fd = open(path, O_WRONLY | O_CLOEXEC | O_NOCTTY | O_NOFOLLOW); 237 - if (fd < 0) 238 - return -1; 239 - 240 - ret = write_nointr(fd, buf, count); 241 - close(fd); 242 - if (ret < 0 || (size_t)ret != count) 243 - return -1; 244 - 245 - return 0; 246 - } 247 - 248 - static int create_and_enter_userns(void) 249 - { 250 - uid_t uid; 251 - gid_t gid; 252 - char map[100]; 253 - 254 - uid = getuid(); 255 - gid = getgid(); 256 - 257 - if (unshare(CLONE_NEWUSER)) 258 - return -1; 259 - 260 - if (write_file("/proc/self/setgroups", "deny", sizeof("deny") - 1) && 261 - errno != ENOENT) 262 - return -1; 263 - 264 - snprintf(map, sizeof(map), "0 %d 1", uid); 265 - if (write_file("/proc/self/uid_map", map, strlen(map))) 266 - return -1; 267 - 268 - 269 - snprintf(map, sizeof(map), "0 %d 1", gid); 270 - if (write_file("/proc/self/gid_map", map, strlen(map))) 271 - return -1; 272 - 273 - if (setgid(0)) 274 - return -1; 275 - 276 - if (setuid(0)) 277 - return -1; 278 - 279 - return 0; 280 - } 281 - 282 - typedef int (*child_callback_fn)(int); 283 - 284 - static void child(int sock_fd, struct bpffs_opts *opts, child_callback_fn callback) 285 - { 286 - LIBBPF_OPTS(bpf_map_create_opts, map_opts); 287 - int mnt_fd = -1, fs_fd = -1, err = 0, bpffs_fd = -1; 288 - 289 - /* setup userns with root mappings */ 290 - err = create_and_enter_userns(); 291 - if (!ASSERT_OK(err, "create_and_enter_userns")) 292 - goto cleanup; 293 - 294 - /* setup mountns to allow creating BPF FS (fsopen("bpf")) from unpriv process */ 295 - err = unshare(CLONE_NEWNS); 296 - if (!ASSERT_OK(err, "create_mountns")) 297 - goto cleanup; 298 - 299 - err = sys_mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, 0); 300 - if (!ASSERT_OK(err, "remount_root")) 301 - goto cleanup; 302 - 303 - fs_fd = create_bpffs_fd(); 304 - if (!ASSERT_GE(fs_fd, 0, "create_bpffs_fd")) { 305 - err = -EINVAL; 306 - goto cleanup; 307 - } 308 - 309 - /* ensure unprivileged child cannot set delegation options */ 310 - err = set_delegate_mask(fs_fd, "delegate_cmds", 0x1, NULL); 311 - ASSERT_EQ(err, -EPERM, "delegate_cmd_eperm"); 312 - err = set_delegate_mask(fs_fd, "delegate_maps", 0x1, NULL); 313 - ASSERT_EQ(err, -EPERM, "delegate_maps_eperm"); 314 - err = set_delegate_mask(fs_fd, "delegate_progs", 0x1, NULL); 315 - ASSERT_EQ(err, -EPERM, "delegate_progs_eperm"); 316 - err = set_delegate_mask(fs_fd, "delegate_attachs", 0x1, NULL); 317 - ASSERT_EQ(err, -EPERM, "delegate_attachs_eperm"); 318 - 319 - /* pass BPF FS context object to parent */ 320 - err = sendfd(sock_fd, fs_fd); 321 - if (!ASSERT_OK(err, "send_fs_fd")) 322 - goto cleanup; 323 - zclose(fs_fd); 324 - 325 - /* avoid mucking around with mount namespaces and mounting at 326 - * well-known path, just get detach-mounted BPF FS fd back from parent 327 - */ 328 - err = recvfd(sock_fd, &mnt_fd); 329 - if (!ASSERT_OK(err, "recv_mnt_fd")) 330 - goto cleanup; 331 - 332 - /* try to fspick() BPF FS and try to add some delegation options */ 333 - fs_fd = sys_fspick(mnt_fd, "", FSPICK_EMPTY_PATH); 334 - if (!ASSERT_GE(fs_fd, 0, "bpffs_fspick")) { 335 - err = -EINVAL; 336 - goto cleanup; 337 - } 338 - 339 - /* ensure unprivileged child cannot reconfigure to set delegation options */ 340 - err = set_delegate_mask(fs_fd, "delegate_cmds", 0, "any"); 341 - if (!ASSERT_EQ(err, -EPERM, "delegate_cmd_eperm_reconfig")) { 342 - err = -EINVAL; 343 - goto cleanup; 344 - } 345 - err = set_delegate_mask(fs_fd, "delegate_maps", 0, "any"); 346 - if (!ASSERT_EQ(err, -EPERM, "delegate_maps_eperm_reconfig")) { 347 - err = -EINVAL; 348 - goto cleanup; 349 - } 350 - err = set_delegate_mask(fs_fd, "delegate_progs", 0, "any"); 351 - if (!ASSERT_EQ(err, -EPERM, "delegate_progs_eperm_reconfig")) { 352 - err = -EINVAL; 353 - goto cleanup; 354 - } 355 - err = set_delegate_mask(fs_fd, "delegate_attachs", 0, "any"); 356 - if (!ASSERT_EQ(err, -EPERM, "delegate_attachs_eperm_reconfig")) { 357 - err = -EINVAL; 358 - goto cleanup; 359 - } 360 - zclose(fs_fd); 361 - 362 - bpffs_fd = openat(mnt_fd, ".", 0, O_RDWR); 363 - if (!ASSERT_GE(bpffs_fd, 0, "bpffs_open")) { 364 - err = -EINVAL; 365 - goto cleanup; 366 - } 367 - 368 - /* do custom test logic with customly set up BPF FS instance */ 369 - err = callback(bpffs_fd); 370 - if (!ASSERT_OK(err, "test_callback")) 371 - goto cleanup; 372 - 373 - err = 0; 374 - cleanup: 375 - zclose(sock_fd); 376 - zclose(mnt_fd); 377 - zclose(fs_fd); 378 - zclose(bpffs_fd); 379 - 380 - exit(-err); 381 - } 382 - 383 - static int wait_for_pid(pid_t pid) 384 - { 385 - int status, ret; 386 - 387 - again: 388 - ret = waitpid(pid, &status, 0); 389 - if (ret == -1) { 390 - if (errno == EINTR) 391 - goto again; 392 - 393 - return -1; 394 - } 395 - 396 - if (!WIFEXITED(status)) 397 - return -1; 398 - 399 - return WEXITSTATUS(status); 400 - } 401 - 402 - static void parent(int child_pid, struct bpffs_opts *bpffs_opts, int sock_fd) 403 - { 404 - int fs_fd = -1, mnt_fd = -1, err; 405 - 406 - err = recvfd(sock_fd, &fs_fd); 407 - if (!ASSERT_OK(err, "recv_bpffs_fd")) 408 - goto cleanup; 409 - 410 - mnt_fd = materialize_bpffs_fd(fs_fd, bpffs_opts); 411 - if (!ASSERT_GE(mnt_fd, 0, "materialize_bpffs_fd")) { 412 - err = -EINVAL; 413 - goto cleanup; 414 - } 415 - zclose(fs_fd); 416 - 417 - /* pass BPF FS context object to parent */ 418 - err = sendfd(sock_fd, mnt_fd); 419 - if (!ASSERT_OK(err, "send_mnt_fd")) 420 - goto cleanup; 421 - zclose(mnt_fd); 422 - 423 - err = wait_for_pid(child_pid); 424 - ASSERT_OK(err, "waitpid_child"); 425 - 426 - cleanup: 427 - zclose(sock_fd); 428 - zclose(fs_fd); 429 - zclose(mnt_fd); 430 - 431 - if (child_pid > 0) 432 - (void)kill(child_pid, SIGKILL); 433 - } 434 - 435 - static void subtest_userns(struct bpffs_opts *bpffs_opts, child_callback_fn cb) 436 - { 437 - int sock_fds[2] = { -1, -1 }; 438 - int child_pid = 0, err; 439 - 440 - err = socketpair(AF_UNIX, SOCK_STREAM, 0, sock_fds); 441 - if (!ASSERT_OK(err, "socketpair")) 442 - goto cleanup; 443 - 444 - child_pid = fork(); 445 - if (!ASSERT_GE(child_pid, 0, "fork")) 446 - goto cleanup; 447 - 448 - if (child_pid == 0) { 449 - zclose(sock_fds[0]); 450 - return child(sock_fds[1], bpffs_opts, cb); 451 - 452 - } else { 453 - zclose(sock_fds[1]); 454 - return parent(child_pid, bpffs_opts, sock_fds[0]); 455 - } 456 - 457 - cleanup: 458 - zclose(sock_fds[0]); 459 - zclose(sock_fds[1]); 460 - if (child_pid > 0) 461 - (void)kill(child_pid, SIGKILL); 462 - } 463 - 464 - static int userns_map_create(int mnt_fd) 465 - { 466 - LIBBPF_OPTS(bpf_map_create_opts, map_opts); 467 - int err, token_fd = -1, map_fd = -1; 468 - __u64 old_caps = 0; 469 - 470 - /* create BPF token from BPF FS mount */ 471 - token_fd = bpf_token_create(mnt_fd, NULL); 472 - if (!ASSERT_GT(token_fd, 0, "token_create")) { 473 - err = -EINVAL; 474 - goto cleanup; 475 - } 476 - 477 - /* while inside non-init userns, we need both a BPF token *and* 478 - * CAP_BPF inside current userns to create privileged map; let's test 479 - * that neither BPF token alone nor namespaced CAP_BPF is sufficient 480 - */ 481 - err = drop_priv_caps(&old_caps); 482 - if (!ASSERT_OK(err, "drop_caps")) 483 - goto cleanup; 484 - 485 - /* no token, no CAP_BPF -> fail */ 486 - map_opts.token_fd = 0; 487 - map_fd = bpf_map_create(BPF_MAP_TYPE_STACK, "wo_token_wo_bpf", 0, 8, 1, &map_opts); 488 - if (!ASSERT_LT(map_fd, 0, "stack_map_wo_token_wo_cap_bpf_should_fail")) { 489 - err = -EINVAL; 490 - goto cleanup; 491 - } 492 - 493 - /* token without CAP_BPF -> fail */ 494 - map_opts.token_fd = token_fd; 495 - map_fd = bpf_map_create(BPF_MAP_TYPE_STACK, "w_token_wo_bpf", 0, 8, 1, &map_opts); 496 - if (!ASSERT_LT(map_fd, 0, "stack_map_w_token_wo_cap_bpf_should_fail")) { 497 - err = -EINVAL; 498 - goto cleanup; 499 - } 500 - 501 - /* get back effective local CAP_BPF (and CAP_SYS_ADMIN) */ 502 - err = restore_priv_caps(old_caps); 503 - if (!ASSERT_OK(err, "restore_caps")) 504 - goto cleanup; 505 - 506 - /* CAP_BPF without token -> fail */ 507 - map_opts.token_fd = 0; 508 - map_fd = bpf_map_create(BPF_MAP_TYPE_STACK, "wo_token_w_bpf", 0, 8, 1, &map_opts); 509 - if (!ASSERT_LT(map_fd, 0, "stack_map_wo_token_w_cap_bpf_should_fail")) { 510 - err = -EINVAL; 511 - goto cleanup; 512 - } 513 - 514 - /* finally, namespaced CAP_BPF + token -> success */ 515 - map_opts.token_fd = token_fd; 516 - map_fd = bpf_map_create(BPF_MAP_TYPE_STACK, "w_token_w_bpf", 0, 8, 1, &map_opts); 517 - if (!ASSERT_GT(map_fd, 0, "stack_map_w_token_w_cap_bpf")) { 518 - err = -EINVAL; 519 - goto cleanup; 520 - } 521 - 522 - cleanup: 523 - zclose(token_fd); 524 - zclose(map_fd); 525 - return err; 526 - } 527 - 528 - static int userns_btf_load(int mnt_fd) 529 - { 530 - LIBBPF_OPTS(bpf_btf_load_opts, btf_opts); 531 - int err, token_fd = -1, btf_fd = -1; 532 - const void *raw_btf_data; 533 - struct btf *btf = NULL; 534 - __u32 raw_btf_size; 535 - __u64 old_caps = 0; 536 - 537 - /* create BPF token from BPF FS mount */ 538 - token_fd = bpf_token_create(mnt_fd, NULL); 539 - if (!ASSERT_GT(token_fd, 0, "token_create")) { 540 - err = -EINVAL; 541 - goto cleanup; 542 - } 543 - 544 - /* while inside non-init userns, we need both a BPF token *and* 545 - * CAP_BPF inside current userns to create privileged map; let's test 546 - * that neither BPF token alone nor namespaced CAP_BPF is sufficient 547 - */ 548 - err = drop_priv_caps(&old_caps); 549 - if (!ASSERT_OK(err, "drop_caps")) 550 - goto cleanup; 551 - 552 - /* setup a trivial BTF data to load to the kernel */ 553 - btf = btf__new_empty(); 554 - if (!ASSERT_OK_PTR(btf, "empty_btf")) 555 - goto cleanup; 556 - 557 - ASSERT_GT(btf__add_int(btf, "int", 4, 0), 0, "int_type"); 558 - 559 - raw_btf_data = btf__raw_data(btf, &raw_btf_size); 560 - if (!ASSERT_OK_PTR(raw_btf_data, "raw_btf_data")) 561 - goto cleanup; 562 - 563 - /* no token + no CAP_BPF -> failure */ 564 - btf_opts.token_fd = 0; 565 - btf_fd = bpf_btf_load(raw_btf_data, raw_btf_size, &btf_opts); 566 - if (!ASSERT_LT(btf_fd, 0, "no_token_no_cap_should_fail")) 567 - goto cleanup; 568 - 569 - /* token + no CAP_BPF -> failure */ 570 - btf_opts.token_fd = token_fd; 571 - btf_fd = bpf_btf_load(raw_btf_data, raw_btf_size, &btf_opts); 572 - if (!ASSERT_LT(btf_fd, 0, "token_no_cap_should_fail")) 573 - goto cleanup; 574 - 575 - /* get back effective local CAP_BPF (and CAP_SYS_ADMIN) */ 576 - err = restore_priv_caps(old_caps); 577 - if (!ASSERT_OK(err, "restore_caps")) 578 - goto cleanup; 579 - 580 - /* token + CAP_BPF -> success */ 581 - btf_opts.token_fd = token_fd; 582 - btf_fd = bpf_btf_load(raw_btf_data, raw_btf_size, &btf_opts); 583 - if (!ASSERT_GT(btf_fd, 0, "token_and_cap_success")) 584 - goto cleanup; 585 - 586 - err = 0; 587 - cleanup: 588 - btf__free(btf); 589 - zclose(btf_fd); 590 - zclose(token_fd); 591 - return err; 592 - } 593 - 594 - static int userns_prog_load(int mnt_fd) 595 - { 596 - LIBBPF_OPTS(bpf_prog_load_opts, prog_opts); 597 - int err, token_fd = -1, prog_fd = -1; 598 - struct bpf_insn insns[] = { 599 - /* bpf_jiffies64() requires CAP_BPF */ 600 - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_jiffies64), 601 - /* bpf_get_current_task() requires CAP_PERFMON */ 602 - BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_current_task), 603 - /* r0 = 0; exit; */ 604 - BPF_MOV64_IMM(BPF_REG_0, 0), 605 - BPF_EXIT_INSN(), 606 - }; 607 - size_t insn_cnt = ARRAY_SIZE(insns); 608 - __u64 old_caps = 0; 609 - 610 - /* create BPF token from BPF FS mount */ 611 - token_fd = bpf_token_create(mnt_fd, NULL); 612 - if (!ASSERT_GT(token_fd, 0, "token_create")) { 613 - err = -EINVAL; 614 - goto cleanup; 615 - } 616 - 617 - /* validate we can successfully load BPF program with token; this 618 - * being XDP program (CAP_NET_ADMIN) using bpf_jiffies64() (CAP_BPF) 619 - * and bpf_get_current_task() (CAP_PERFMON) helpers validates we have 620 - * BPF token wired properly in a bunch of places in the kernel 621 - */ 622 - prog_opts.token_fd = token_fd; 623 - prog_opts.expected_attach_type = BPF_XDP; 624 - prog_fd = bpf_prog_load(BPF_PROG_TYPE_XDP, "token_prog", "GPL", 625 - insns, insn_cnt, &prog_opts); 626 - if (!ASSERT_GT(prog_fd, 0, "prog_fd")) { 627 - err = -EPERM; 628 - goto cleanup; 629 - } 630 - 631 - /* no token + caps -> failure */ 632 - prog_opts.token_fd = 0; 633 - prog_fd = bpf_prog_load(BPF_PROG_TYPE_XDP, "token_prog", "GPL", 634 - insns, insn_cnt, &prog_opts); 635 - if (!ASSERT_EQ(prog_fd, -EPERM, "prog_fd_eperm")) { 636 - err = -EPERM; 637 - goto cleanup; 638 - } 639 - 640 - err = drop_priv_caps(&old_caps); 641 - if (!ASSERT_OK(err, "drop_caps")) 642 - goto cleanup; 643 - 644 - /* no caps + token -> failure */ 645 - prog_opts.token_fd = token_fd; 646 - prog_fd = bpf_prog_load(BPF_PROG_TYPE_XDP, "token_prog", "GPL", 647 - insns, insn_cnt, &prog_opts); 648 - if (!ASSERT_EQ(prog_fd, -EPERM, "prog_fd_eperm")) { 649 - err = -EPERM; 650 - goto cleanup; 651 - } 652 - 653 - /* no caps + no token -> definitely a failure */ 654 - prog_opts.token_fd = 0; 655 - prog_fd = bpf_prog_load(BPF_PROG_TYPE_XDP, "token_prog", "GPL", 656 - insns, insn_cnt, &prog_opts); 657 - if (!ASSERT_EQ(prog_fd, -EPERM, "prog_fd_eperm")) { 658 - err = -EPERM; 659 - goto cleanup; 660 - } 661 - 662 - err = 0; 663 - cleanup: 664 - zclose(prog_fd); 665 - zclose(token_fd); 666 - return err; 667 - } 668 - 669 - static int userns_obj_priv_map(int mnt_fd) 670 - { 671 - LIBBPF_OPTS(bpf_object_open_opts, opts); 672 - char buf[256]; 673 - struct priv_map *skel; 674 - int err, token_fd; 675 - 676 - skel = priv_map__open_and_load(); 677 - if (!ASSERT_ERR_PTR(skel, "obj_tokenless_load")) { 678 - priv_map__destroy(skel); 679 - return -EINVAL; 680 - } 681 - 682 - /* use bpf_token_path to provide BPF FS path */ 683 - snprintf(buf, sizeof(buf), "/proc/self/fd/%d", mnt_fd); 684 - opts.bpf_token_path = buf; 685 - skel = priv_map__open_opts(&opts); 686 - if (!ASSERT_OK_PTR(skel, "obj_token_path_open")) 687 - return -EINVAL; 688 - 689 - err = priv_map__load(skel); 690 - priv_map__destroy(skel); 691 - if (!ASSERT_OK(err, "obj_token_path_load")) 692 - return -EINVAL; 693 - 694 - /* create token and pass it through bpf_token_fd */ 695 - token_fd = bpf_token_create(mnt_fd, NULL); 696 - if (!ASSERT_GT(token_fd, 0, "create_token")) 697 - return -EINVAL; 698 - 699 - opts.bpf_token_path = NULL; 700 - opts.bpf_token_fd = token_fd; 701 - skel = priv_map__open_opts(&opts); 702 - if (!ASSERT_OK_PTR(skel, "obj_token_fd_open")) 703 - return -EINVAL; 704 - 705 - /* we can close our token FD, bpf_object owns dup()'ed FD now */ 706 - close(token_fd); 707 - 708 - err = priv_map__load(skel); 709 - priv_map__destroy(skel); 710 - if (!ASSERT_OK(err, "obj_token_fd_load")) 711 - return -EINVAL; 712 - 713 - return 0; 714 - } 715 - 716 - static int userns_obj_priv_prog(int mnt_fd) 717 - { 718 - LIBBPF_OPTS(bpf_object_open_opts, opts); 719 - char buf[256]; 720 - struct priv_prog *skel; 721 - int err; 722 - 723 - skel = priv_prog__open_and_load(); 724 - if (!ASSERT_ERR_PTR(skel, "obj_tokenless_load")) { 725 - priv_prog__destroy(skel); 726 - return -EINVAL; 727 - } 728 - 729 - /* use bpf_token_path to provide BPF FS path */ 730 - snprintf(buf, sizeof(buf), "/proc/self/fd/%d", mnt_fd); 731 - opts.bpf_token_path = buf; 732 - skel = priv_prog__open_opts(&opts); 733 - if (!ASSERT_OK_PTR(skel, "obj_token_path_open")) 734 - return -EINVAL; 735 - 736 - err = priv_prog__load(skel); 737 - priv_prog__destroy(skel); 738 - if (!ASSERT_OK(err, "obj_token_path_load")) 739 - return -EINVAL; 740 - 741 - return 0; 742 - } 743 - 744 - /* this test is called with BPF FS that doesn't delegate BPF_BTF_LOAD command, 745 - * which should cause struct_ops application to fail, as BTF won't be uploaded 746 - * into the kernel, even if STRUCT_OPS programs themselves are allowed 747 - */ 748 - static int validate_struct_ops_load(int mnt_fd, bool expect_success) 749 - { 750 - LIBBPF_OPTS(bpf_object_open_opts, opts); 751 - char buf[256]; 752 - struct dummy_st_ops_success *skel; 753 - int err; 754 - 755 - snprintf(buf, sizeof(buf), "/proc/self/fd/%d", mnt_fd); 756 - opts.bpf_token_path = buf; 757 - skel = dummy_st_ops_success__open_opts(&opts); 758 - if (!ASSERT_OK_PTR(skel, "obj_token_path_open")) 759 - return -EINVAL; 760 - 761 - err = dummy_st_ops_success__load(skel); 762 - dummy_st_ops_success__destroy(skel); 763 - if (expect_success) { 764 - if (!ASSERT_OK(err, "obj_token_path_load")) 765 - return -EINVAL; 766 - } else /* expect failure */ { 767 - if (!ASSERT_ERR(err, "obj_token_path_load")) 768 - return -EINVAL; 769 - } 770 - 771 - return 0; 772 - } 773 - 774 - static int userns_obj_priv_btf_fail(int mnt_fd) 775 - { 776 - return validate_struct_ops_load(mnt_fd, false /* should fail */); 777 - } 778 - 779 - static int userns_obj_priv_btf_success(int mnt_fd) 780 - { 781 - return validate_struct_ops_load(mnt_fd, true /* should succeed */); 782 - } 783 - 784 - #define TOKEN_ENVVAR "LIBBPF_BPF_TOKEN_PATH" 785 - #define TOKEN_BPFFS_CUSTOM "/bpf-token-fs" 786 - 787 - static int userns_obj_priv_implicit_token(int mnt_fd) 788 - { 789 - LIBBPF_OPTS(bpf_object_open_opts, opts); 790 - struct dummy_st_ops_success *skel; 791 - int err; 792 - 793 - /* before we mount BPF FS with token delegation, struct_ops skeleton 794 - * should fail to load 795 - */ 796 - skel = dummy_st_ops_success__open_and_load(); 797 - if (!ASSERT_ERR_PTR(skel, "obj_tokenless_load")) { 798 - dummy_st_ops_success__destroy(skel); 799 - return -EINVAL; 800 - } 801 - 802 - /* mount custom BPF FS over /sys/fs/bpf so that libbpf can create BPF 803 - * token automatically and implicitly 804 - */ 805 - err = sys_move_mount(mnt_fd, "", AT_FDCWD, "/sys/fs/bpf", MOVE_MOUNT_F_EMPTY_PATH); 806 - if (!ASSERT_OK(err, "move_mount_bpffs")) 807 - return -EINVAL; 808 - 809 - /* disable implicit BPF token creation by setting 810 - * LIBBPF_BPF_TOKEN_PATH envvar to empty value, load should fail 811 - */ 812 - err = setenv(TOKEN_ENVVAR, "", 1 /*overwrite*/); 813 - if (!ASSERT_OK(err, "setenv_token_path")) 814 - return -EINVAL; 815 - skel = dummy_st_ops_success__open_and_load(); 816 - if (!ASSERT_ERR_PTR(skel, "obj_token_envvar_disabled_load")) { 817 - unsetenv(TOKEN_ENVVAR); 818 - dummy_st_ops_success__destroy(skel); 819 - return -EINVAL; 820 - } 821 - unsetenv(TOKEN_ENVVAR); 822 - 823 - /* now the same struct_ops skeleton should succeed thanks to libppf 824 - * creating BPF token from /sys/fs/bpf mount point 825 - */ 826 - skel = dummy_st_ops_success__open_and_load(); 827 - if (!ASSERT_OK_PTR(skel, "obj_implicit_token_load")) 828 - return -EINVAL; 829 - 830 - dummy_st_ops_success__destroy(skel); 831 - 832 - /* now disable implicit token through empty bpf_token_path, should fail */ 833 - opts.bpf_token_path = ""; 834 - skel = dummy_st_ops_success__open_opts(&opts); 835 - if (!ASSERT_OK_PTR(skel, "obj_empty_token_path_open")) 836 - return -EINVAL; 837 - 838 - err = dummy_st_ops_success__load(skel); 839 - dummy_st_ops_success__destroy(skel); 840 - if (!ASSERT_ERR(err, "obj_empty_token_path_load")) 841 - return -EINVAL; 842 - 843 - /* now disable implicit token through negative bpf_token_fd, should fail */ 844 - opts.bpf_token_path = NULL; 845 - opts.bpf_token_fd = -1; 846 - skel = dummy_st_ops_success__open_opts(&opts); 847 - if (!ASSERT_OK_PTR(skel, "obj_neg_token_fd_open")) 848 - return -EINVAL; 849 - 850 - err = dummy_st_ops_success__load(skel); 851 - dummy_st_ops_success__destroy(skel); 852 - if (!ASSERT_ERR(err, "obj_neg_token_fd_load")) 853 - return -EINVAL; 854 - 855 - return 0; 856 - } 857 - 858 - static int userns_obj_priv_implicit_token_envvar(int mnt_fd) 859 - { 860 - LIBBPF_OPTS(bpf_object_open_opts, opts); 861 - struct dummy_st_ops_success *skel; 862 - int err; 863 - 864 - /* before we mount BPF FS with token delegation, struct_ops skeleton 865 - * should fail to load 866 - */ 867 - skel = dummy_st_ops_success__open_and_load(); 868 - if (!ASSERT_ERR_PTR(skel, "obj_tokenless_load")) { 869 - dummy_st_ops_success__destroy(skel); 870 - return -EINVAL; 871 - } 872 - 873 - /* mount custom BPF FS over custom location, so libbpf can't create 874 - * BPF token implicitly, unless pointed to it through 875 - * LIBBPF_BPF_TOKEN_PATH envvar 876 - */ 877 - rmdir(TOKEN_BPFFS_CUSTOM); 878 - if (!ASSERT_OK(mkdir(TOKEN_BPFFS_CUSTOM, 0777), "mkdir_bpffs_custom")) 879 - goto err_out; 880 - err = sys_move_mount(mnt_fd, "", AT_FDCWD, TOKEN_BPFFS_CUSTOM, MOVE_MOUNT_F_EMPTY_PATH); 881 - if (!ASSERT_OK(err, "move_mount_bpffs")) 882 - goto err_out; 883 - 884 - /* even though we have BPF FS with delegation, it's not at default 885 - * /sys/fs/bpf location, so we still fail to load until envvar is set up 886 - */ 887 - skel = dummy_st_ops_success__open_and_load(); 888 - if (!ASSERT_ERR_PTR(skel, "obj_tokenless_load2")) { 889 - dummy_st_ops_success__destroy(skel); 890 - goto err_out; 891 - } 892 - 893 - err = setenv(TOKEN_ENVVAR, TOKEN_BPFFS_CUSTOM, 1 /*overwrite*/); 894 - if (!ASSERT_OK(err, "setenv_token_path")) 895 - goto err_out; 896 - 897 - /* now the same struct_ops skeleton should succeed thanks to libppf 898 - * creating BPF token from custom mount point 899 - */ 900 - skel = dummy_st_ops_success__open_and_load(); 901 - if (!ASSERT_OK_PTR(skel, "obj_implicit_token_load")) 902 - goto err_out; 903 - 904 - dummy_st_ops_success__destroy(skel); 905 - 906 - /* now disable implicit token through empty bpf_token_path, envvar 907 - * will be ignored, should fail 908 - */ 909 - opts.bpf_token_path = ""; 910 - skel = dummy_st_ops_success__open_opts(&opts); 911 - if (!ASSERT_OK_PTR(skel, "obj_empty_token_path_open")) 912 - goto err_out; 913 - 914 - err = dummy_st_ops_success__load(skel); 915 - dummy_st_ops_success__destroy(skel); 916 - if (!ASSERT_ERR(err, "obj_empty_token_path_load")) 917 - goto err_out; 918 - 919 - /* now disable implicit token through negative bpf_token_fd, envvar 920 - * will be ignored, should fail 921 - */ 922 - opts.bpf_token_path = NULL; 923 - opts.bpf_token_fd = -1; 924 - skel = dummy_st_ops_success__open_opts(&opts); 925 - if (!ASSERT_OK_PTR(skel, "obj_neg_token_fd_open")) 926 - goto err_out; 927 - 928 - err = dummy_st_ops_success__load(skel); 929 - dummy_st_ops_success__destroy(skel); 930 - if (!ASSERT_ERR(err, "obj_neg_token_fd_load")) 931 - goto err_out; 932 - 933 - rmdir(TOKEN_BPFFS_CUSTOM); 934 - unsetenv(TOKEN_ENVVAR); 935 - return 0; 936 - err_out: 937 - rmdir(TOKEN_BPFFS_CUSTOM); 938 - unsetenv(TOKEN_ENVVAR); 939 - return -EINVAL; 940 - } 941 - 942 - #define bit(n) (1ULL << (n)) 943 - 944 - void test_token(void) 945 - { 946 - if (test__start_subtest("map_token")) { 947 - struct bpffs_opts opts = { 948 - .cmds_str = "map_create", 949 - .maps_str = "stack", 950 - }; 951 - 952 - subtest_userns(&opts, userns_map_create); 953 - } 954 - if (test__start_subtest("btf_token")) { 955 - struct bpffs_opts opts = { 956 - .cmds = 1ULL << BPF_BTF_LOAD, 957 - }; 958 - 959 - subtest_userns(&opts, userns_btf_load); 960 - } 961 - if (test__start_subtest("prog_token")) { 962 - struct bpffs_opts opts = { 963 - .cmds_str = "PROG_LOAD", 964 - .progs_str = "XDP", 965 - .attachs_str = "xdp", 966 - }; 967 - 968 - subtest_userns(&opts, userns_prog_load); 969 - } 970 - if (test__start_subtest("obj_priv_map")) { 971 - struct bpffs_opts opts = { 972 - .cmds = bit(BPF_MAP_CREATE), 973 - .maps = bit(BPF_MAP_TYPE_QUEUE), 974 - }; 975 - 976 - subtest_userns(&opts, userns_obj_priv_map); 977 - } 978 - if (test__start_subtest("obj_priv_prog")) { 979 - struct bpffs_opts opts = { 980 - .cmds = bit(BPF_PROG_LOAD), 981 - .progs = bit(BPF_PROG_TYPE_KPROBE), 982 - .attachs = ~0ULL, 983 - }; 984 - 985 - subtest_userns(&opts, userns_obj_priv_prog); 986 - } 987 - if (test__start_subtest("obj_priv_btf_fail")) { 988 - struct bpffs_opts opts = { 989 - /* disallow BTF loading */ 990 - .cmds = bit(BPF_MAP_CREATE) | bit(BPF_PROG_LOAD), 991 - .maps = bit(BPF_MAP_TYPE_STRUCT_OPS), 992 - .progs = bit(BPF_PROG_TYPE_STRUCT_OPS), 993 - .attachs = ~0ULL, 994 - }; 995 - 996 - subtest_userns(&opts, userns_obj_priv_btf_fail); 997 - } 998 - if (test__start_subtest("obj_priv_btf_success")) { 999 - struct bpffs_opts opts = { 1000 - /* allow BTF loading */ 1001 - .cmds = bit(BPF_BTF_LOAD) | bit(BPF_MAP_CREATE) | bit(BPF_PROG_LOAD), 1002 - .maps = bit(BPF_MAP_TYPE_STRUCT_OPS), 1003 - .progs = bit(BPF_PROG_TYPE_STRUCT_OPS), 1004 - .attachs = ~0ULL, 1005 - }; 1006 - 1007 - subtest_userns(&opts, userns_obj_priv_btf_success); 1008 - } 1009 - if (test__start_subtest("obj_priv_implicit_token")) { 1010 - struct bpffs_opts opts = { 1011 - /* allow BTF loading */ 1012 - .cmds = bit(BPF_BTF_LOAD) | bit(BPF_MAP_CREATE) | bit(BPF_PROG_LOAD), 1013 - .maps = bit(BPF_MAP_TYPE_STRUCT_OPS), 1014 - .progs = bit(BPF_PROG_TYPE_STRUCT_OPS), 1015 - .attachs = ~0ULL, 1016 - }; 1017 - 1018 - subtest_userns(&opts, userns_obj_priv_implicit_token); 1019 - } 1020 - if (test__start_subtest("obj_priv_implicit_token_envvar")) { 1021 - struct bpffs_opts opts = { 1022 - /* allow BTF loading */ 1023 - .cmds = bit(BPF_BTF_LOAD) | bit(BPF_MAP_CREATE) | bit(BPF_PROG_LOAD), 1024 - .maps = bit(BPF_MAP_TYPE_STRUCT_OPS), 1025 - .progs = bit(BPF_PROG_TYPE_STRUCT_OPS), 1026 - .attachs = ~0ULL, 1027 - }; 1028 - 1029 - subtest_userns(&opts, userns_obj_priv_implicit_token_envvar); 1030 - } 1031 - }
-13
tools/testing/selftests/bpf/progs/priv_map.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */ 3 - 4 - #include "vmlinux.h" 5 - #include <bpf/bpf_helpers.h> 6 - 7 - char _license[] SEC("license") = "GPL"; 8 - 9 - struct { 10 - __uint(type, BPF_MAP_TYPE_QUEUE); 11 - __uint(max_entries, 1); 12 - __type(value, __u32); 13 - } priv_map SEC(".maps");
-13
tools/testing/selftests/bpf/progs/priv_prog.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* Copyright (c) 2023 Meta Platforms, Inc. and affiliates. */ 3 - 4 - #include "vmlinux.h" 5 - #include <bpf/bpf_helpers.h> 6 - 7 - char _license[] SEC("license") = "GPL"; 8 - 9 - SEC("kprobe") 10 - int kprobe_prog(void *ctx) 11 - { 12 - return 1; 13 - }