Commit f3dcee93 authored by Andrii Nakryiko's avatar Andrii Nakryiko Committed by Alexei Starovoitov

libbpf: Wire up token_fd into feature probing logic

Adjust feature probing callbacks to take into account optional token_fd.
In unprivileged contexts, some feature detectors would fail to detect
kernel support just because BPF program, BPF map, or BTF object can't be
loaded due to privileged nature of those operations. So when BPF object
is loaded with BPF token, this token should be used for feature probing.

This patch is setting support for this scenario, but we don't yet pass
non-zero token FD. This will be added in the next patch.

We also switched BPF cookie detector from using kprobe program to
tracepoint one, as tracepoint is somewhat less dangerous BPF program
type and has higher likelihood of being allowed through BPF token in the
future. This change has no effect on detection behavior.
Signed-off-by: default avatarAndrii Nakryiko <andrii@kernel.org>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarJohn Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20240124022127.2379740-25-andrii@kernel.org
parent 05f9cdd5
...@@ -103,7 +103,7 @@ int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts) ...@@ -103,7 +103,7 @@ int sys_bpf_prog_load(union bpf_attr *attr, unsigned int size, int attempts)
* [0] https://lore.kernel.org/bpf/20201201215900.3569844-1-guro@fb.com/ * [0] https://lore.kernel.org/bpf/20201201215900.3569844-1-guro@fb.com/
* [1] d05512618056 ("bpf: Add bpf_ktime_get_coarse_ns helper") * [1] d05512618056 ("bpf: Add bpf_ktime_get_coarse_ns helper")
*/ */
int probe_memcg_account(void) int probe_memcg_account(int token_fd)
{ {
const size_t attr_sz = offsetofend(union bpf_attr, attach_btf_obj_fd); const size_t attr_sz = offsetofend(union bpf_attr, attach_btf_obj_fd);
struct bpf_insn insns[] = { struct bpf_insn insns[] = {
...@@ -120,6 +120,9 @@ int probe_memcg_account(void) ...@@ -120,6 +120,9 @@ int probe_memcg_account(void)
attr.insns = ptr_to_u64(insns); attr.insns = ptr_to_u64(insns);
attr.insn_cnt = insn_cnt; attr.insn_cnt = insn_cnt;
attr.license = ptr_to_u64("GPL"); attr.license = ptr_to_u64("GPL");
attr.prog_token_fd = token_fd;
if (token_fd)
attr.prog_flags |= BPF_F_TOKEN_FD;
prog_fd = sys_bpf_fd(BPF_PROG_LOAD, &attr, attr_sz); prog_fd = sys_bpf_fd(BPF_PROG_LOAD, &attr, attr_sz);
if (prog_fd >= 0) { if (prog_fd >= 0) {
......
This diff is collapsed.
...@@ -6440,7 +6440,7 @@ static int probe_kern_arg_ctx_tag(void) ...@@ -6440,7 +6440,7 @@ static int probe_kern_arg_ctx_tag(void)
if (cached_result >= 0) if (cached_result >= 0)
return cached_result; return cached_result;
btf_fd = libbpf__load_raw_btf((char *)types, sizeof(types), strs, sizeof(strs)); btf_fd = libbpf__load_raw_btf((char *)types, sizeof(types), strs, sizeof(strs), 0);
if (btf_fd < 0) if (btf_fd < 0)
return 0; return 0;
...@@ -10606,7 +10606,7 @@ static const char *arch_specific_syscall_pfx(void) ...@@ -10606,7 +10606,7 @@ static const char *arch_specific_syscall_pfx(void)
#endif #endif
} }
int probe_kern_syscall_wrapper(void) int probe_kern_syscall_wrapper(int token_fd)
{ {
char syscall_name[64]; char syscall_name[64];
const char *ksys_pfx; const char *ksys_pfx;
......
...@@ -369,19 +369,21 @@ enum kern_feature_result { ...@@ -369,19 +369,21 @@ enum kern_feature_result {
struct kern_feature_cache { struct kern_feature_cache {
enum kern_feature_result res[__FEAT_CNT]; enum kern_feature_result res[__FEAT_CNT];
int token_fd;
}; };
bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id); bool feat_supported(struct kern_feature_cache *cache, enum kern_feature_id feat_id);
bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id); bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id);
int probe_kern_syscall_wrapper(void); int probe_kern_syscall_wrapper(int token_fd);
int probe_memcg_account(void); int probe_memcg_account(int token_fd);
int bump_rlimit_memlock(void); int bump_rlimit_memlock(void);
int parse_cpu_mask_str(const char *s, bool **mask, int *mask_sz); int parse_cpu_mask_str(const char *s, bool **mask, int *mask_sz);
int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz); int parse_cpu_mask_file(const char *fcpu, bool **mask, int *mask_sz);
int libbpf__load_raw_btf(const char *raw_types, size_t types_len, int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
const char *str_sec, size_t str_len); const char *str_sec, size_t str_len,
int token_fd);
int btf_load_into_kernel(struct btf *btf, char *log_buf, size_t log_sz, __u32 log_level); int btf_load_into_kernel(struct btf *btf, char *log_buf, size_t log_sz, __u32 log_level);
struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf); struct btf *btf_get_from_fd(int btf_fd, struct btf *base_btf);
......
...@@ -219,7 +219,8 @@ int libbpf_probe_bpf_prog_type(enum bpf_prog_type prog_type, const void *opts) ...@@ -219,7 +219,8 @@ int libbpf_probe_bpf_prog_type(enum bpf_prog_type prog_type, const void *opts)
} }
int libbpf__load_raw_btf(const char *raw_types, size_t types_len, int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
const char *str_sec, size_t str_len) const char *str_sec, size_t str_len,
int token_fd)
{ {
struct btf_header hdr = { struct btf_header hdr = {
.magic = BTF_MAGIC, .magic = BTF_MAGIC,
...@@ -229,6 +230,10 @@ int libbpf__load_raw_btf(const char *raw_types, size_t types_len, ...@@ -229,6 +230,10 @@ int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
.str_off = types_len, .str_off = types_len,
.str_len = str_len, .str_len = str_len,
}; };
LIBBPF_OPTS(bpf_btf_load_opts, opts,
.token_fd = token_fd,
.btf_flags = token_fd ? BPF_F_TOKEN_FD : 0,
);
int btf_fd, btf_len; int btf_fd, btf_len;
__u8 *raw_btf; __u8 *raw_btf;
...@@ -241,7 +246,7 @@ int libbpf__load_raw_btf(const char *raw_types, size_t types_len, ...@@ -241,7 +246,7 @@ int libbpf__load_raw_btf(const char *raw_types, size_t types_len,
memcpy(raw_btf + hdr.hdr_len, raw_types, hdr.type_len); memcpy(raw_btf + hdr.hdr_len, raw_types, hdr.type_len);
memcpy(raw_btf + hdr.hdr_len + hdr.type_len, str_sec, hdr.str_len); memcpy(raw_btf + hdr.hdr_len + hdr.type_len, str_sec, hdr.str_len);
btf_fd = bpf_btf_load(raw_btf, btf_len, NULL); btf_fd = bpf_btf_load(raw_btf, btf_len, &opts);
free(raw_btf); free(raw_btf);
return btf_fd; return btf_fd;
...@@ -271,7 +276,7 @@ static int load_local_storage_btf(void) ...@@ -271,7 +276,7 @@ static int load_local_storage_btf(void)
}; };
return libbpf__load_raw_btf((char *)types, sizeof(types), return libbpf__load_raw_btf((char *)types, sizeof(types),
strs, sizeof(strs)); strs, sizeof(strs), 0);
} }
static int probe_map_create(enum bpf_map_type map_type) static int probe_map_create(enum bpf_map_type map_type)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment