Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
sudo: required
language: bash
dist: bionic
services:
- docker

env:
global:
- PROJECT_NAME='libbpf'
- AUTHOR_EMAIL="$(git log -1 --pretty=\"%aE\")"
- REPO_ROOT="$TRAVIS_BUILD_DIR"
- CI_ROOT="$REPO_ROOT/travis-ci"
- VMTEST_ROOT="$CI_ROOT/vmtest"

addons:
apt:
packages:
- qemu-kvm
- zstd
- binutils-dev
- elfutils
- libcap-dev
- libelf-dev
- libdw-dev

jobs:
include:
- stage: Builds & Tests
name: Kernel LATEST + selftests
language: bash
env: KERNEL=LATEST
script: $CI_ROOT/vmtest/run_vmtest.sh || travis_terminate 1
2 changes: 1 addition & 1 deletion include/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1394,7 +1394,7 @@ int btf_check_func_arg_match(struct bpf_verifier_env *env, int subprog,
struct bpf_reg_state *regs);
int btf_prepare_func_args(struct bpf_verifier_env *env, int subprog,
struct bpf_reg_state *reg);
int btf_check_type_match(struct bpf_verifier_env *env, struct bpf_prog *prog,
int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *prog,
struct btf *btf, const struct btf_type *t);

struct bpf_prog *bpf_prog_by_id(u32 id);
Expand Down
5 changes: 3 additions & 2 deletions include/linux/bpf_verifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,9 @@ static inline bool bpf_verifier_log_full(const struct bpf_verifier_log *log)

static inline bool bpf_verifier_log_needed(const struct bpf_verifier_log *log)
{
return (log->level && log->ubuf && !bpf_verifier_log_full(log)) ||
log->level == BPF_LOG_KERNEL;
return log &&
((log->level && log->ubuf && !bpf_verifier_log_full(log)) ||
log->level == BPF_LOG_KERNEL);
}

#define BPF_MAX_SUBPROGS 256
Expand Down
6 changes: 3 additions & 3 deletions kernel/bpf/btf.c
Original file line number Diff line number Diff line change
Expand Up @@ -4401,15 +4401,15 @@ static int btf_check_func_type_match(struct bpf_verifier_log *log,
}

/* Compare BTFs of given program with BTF of target program */
int btf_check_type_match(struct bpf_verifier_env *env, struct bpf_prog *prog,
int btf_check_type_match(struct bpf_verifier_log *log, const struct bpf_prog *prog,
struct btf *btf2, const struct btf_type *t2)
{
struct btf *btf1 = prog->aux->btf;
const struct btf_type *t1;
u32 btf_id = 0;

if (!prog->aux->func_info) {
bpf_log(&env->log, "Program extension requires BTF\n");
bpf_log(log, "Program extension requires BTF\n");
return -EINVAL;
}

Expand All @@ -4421,7 +4421,7 @@ int btf_check_type_match(struct bpf_verifier_env *env, struct bpf_prog *prog,
if (!t1 || !btf_type_is_func(t1))
return -EFAULT;

return btf_check_func_type_match(&env->log, btf1, t1, btf2, t2);
return btf_check_func_type_match(log, btf1, t1, btf2, t2);
}

/* Compare BTF of a function with given bpf_reg_state.
Expand Down
48 changes: 24 additions & 24 deletions kernel/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -11043,6 +11043,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
struct bpf_prog *prog = env->prog;
bool prog_extension = prog->type == BPF_PROG_TYPE_EXT;
struct bpf_prog *tgt_prog = prog->aux->linked_prog;
struct bpf_verifier_log *log = &env->log;
u32 btf_id = prog->aux->attach_btf_id;
const char prefix[] = "btf_trace_";
struct btf_func_model fmodel;
Expand Down Expand Up @@ -11070,23 +11071,23 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
return 0;

if (!btf_id) {
verbose(env, "Tracing programs must provide btf_id\n");
bpf_log(log, "Tracing programs must provide btf_id\n");
return -EINVAL;
}
btf = bpf_prog_get_target_btf(prog);
if (!btf) {
verbose(env,
bpf_log(log,
"FENTRY/FEXIT program can only be attached to another program annotated with BTF\n");
return -EINVAL;
}
t = btf_type_by_id(btf, btf_id);
if (!t) {
verbose(env, "attach_btf_id %u is invalid\n", btf_id);
bpf_log(log, "attach_btf_id %u is invalid\n", btf_id);
return -EINVAL;
}
tname = btf_name_by_offset(btf, t->name_off);
if (!tname) {
verbose(env, "attach_btf_id %u doesn't have a name\n", btf_id);
bpf_log(log, "attach_btf_id %u doesn't have a name\n", btf_id);
return -EINVAL;
}
if (tgt_prog) {
Expand All @@ -11098,34 +11099,34 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
break;
}
if (subprog == -1) {
verbose(env, "Subprog %s doesn't exist\n", tname);
bpf_log(log, "Subprog %s doesn't exist\n", tname);
return -EINVAL;
}
conservative = aux->func_info_aux[subprog].unreliable;
if (prog_extension) {
if (conservative) {
verbose(env,
bpf_log(log,
"Cannot replace static functions\n");
return -EINVAL;
}
if (!prog->jit_requested) {
verbose(env,
bpf_log(log,
"Extension programs should be JITed\n");
return -EINVAL;
}
env->ops = bpf_verifier_ops[tgt_prog->type];
prog->expected_attach_type = tgt_prog->expected_attach_type;
}
if (!tgt_prog->jited) {
verbose(env, "Can attach to only JITed progs\n");
bpf_log(log, "Can attach to only JITed progs\n");
return -EINVAL;
}
if (tgt_prog->type == prog->type) {
/* Cannot fentry/fexit another fentry/fexit program.
* Cannot attach program extension to another extension.
* It's ok to attach fentry/fexit to extension program.
*/
verbose(env, "Cannot recursively attach\n");
bpf_log(log, "Cannot recursively attach\n");
return -EINVAL;
}
if (tgt_prog->type == BPF_PROG_TYPE_TRACING &&
Expand All @@ -11147,13 +11148,13 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
* reasonable stack size. Hence extending fentry is not
* allowed.
*/
verbose(env, "Cannot extend fentry/fexit\n");
bpf_log(log, "Cannot extend fentry/fexit\n");
return -EINVAL;
}
key = ((u64)aux->id) << 32 | btf_id;
} else {
if (prog_extension) {
verbose(env, "Cannot replace kernel functions\n");
bpf_log(log, "Cannot replace kernel functions\n");
return -EINVAL;
}
key = btf_id;
Expand All @@ -11162,17 +11163,17 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
switch (prog->expected_attach_type) {
case BPF_TRACE_RAW_TP:
if (tgt_prog) {
verbose(env,
bpf_log(log,
"Only FENTRY/FEXIT progs are attachable to another BPF prog\n");
return -EINVAL;
}
if (!btf_type_is_typedef(t)) {
verbose(env, "attach_btf_id %u is not a typedef\n",
bpf_log(log, "attach_btf_id %u is not a typedef\n",
btf_id);
return -EINVAL;
}
if (strncmp(prefix, tname, sizeof(prefix) - 1)) {
verbose(env, "attach_btf_id %u points to wrong type name %s\n",
bpf_log(log, "attach_btf_id %u points to wrong type name %s\n",
btf_id, tname);
return -EINVAL;
}
Expand All @@ -11195,7 +11196,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
return 0;
case BPF_TRACE_ITER:
if (!btf_type_is_func(t)) {
verbose(env, "attach_btf_id %u is not a function\n",
bpf_log(log, "attach_btf_id %u is not a function\n",
btf_id);
return -EINVAL;
}
Expand All @@ -11206,8 +11207,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
prog->aux->attach_func_proto = t;
if (!bpf_iter_prog_supported(prog))
return -EINVAL;
ret = btf_distill_func_proto(&env->log, btf, t,
tname, &fmodel);
ret = btf_distill_func_proto(log, btf, t, tname, &fmodel);
return ret;
default:
if (!prog_extension)
Expand All @@ -11219,18 +11219,18 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
case BPF_TRACE_FEXIT:
prog->aux->attach_func_name = tname;
if (prog->type == BPF_PROG_TYPE_LSM) {
ret = bpf_lsm_verify_prog(&env->log, prog);
ret = bpf_lsm_verify_prog(log, prog);
if (ret < 0)
return ret;
}

if (!btf_type_is_func(t)) {
verbose(env, "attach_btf_id %u is not a function\n",
bpf_log(log, "attach_btf_id %u is not a function\n",
btf_id);
return -EINVAL;
}
if (prog_extension &&
btf_check_type_match(env, prog, btf, t))
btf_check_type_match(log, prog, btf, t))
return -EINVAL;
t = btf_type_by_id(btf, t->type);
if (!btf_type_is_func_proto(t))
Expand All @@ -11249,7 +11249,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
prog->aux->attach_func_proto = NULL;
t = NULL;
}
ret = btf_distill_func_proto(&env->log, btf, t,
ret = btf_distill_func_proto(log, btf, t,
tname, &tr->func.model);
if (ret < 0)
goto out;
Expand All @@ -11261,7 +11261,7 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
} else {
addr = kallsyms_lookup_name(tname);
if (!addr) {
verbose(env,
bpf_log(log,
"The address of function %s cannot be found\n",
tname);
ret = -ENOENT;
Expand Down Expand Up @@ -11291,12 +11291,12 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
break;
}
if (ret)
verbose(env, "%s is not sleepable\n",
bpf_log(log, "%s is not sleepable\n",
prog->aux->attach_func_name);
} else if (prog->expected_attach_type == BPF_MODIFY_RETURN) {
ret = check_attach_modify_return(prog, addr);
if (ret)
verbose(env, "%s() is not modifiable\n",
bpf_log(log, "%s() is not modifiable\n",
prog->aux->attach_func_name);
}
if (ret)
Expand Down
13 changes: 12 additions & 1 deletion tools/lib/bpf/bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -804,17 +804,28 @@ int bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len)
return err;
}

int bpf_raw_tracepoint_open(const char *name, int prog_fd)
int bpf_raw_tracepoint_open_opts(const char *name, int prog_fd,
struct bpf_raw_tracepoint_opts *opts)
{
union bpf_attr attr;

if (!OPTS_VALID(opts, bpf_raw_tracepoint_opts))
return -EINVAL;

memset(&attr, 0, sizeof(attr));
attr.raw_tracepoint.name = ptr_to_u64(name);
attr.raw_tracepoint.prog_fd = prog_fd;
attr.raw_tracepoint.tgt_prog_fd = OPTS_GET(opts, tgt_prog_fd, 0);
attr.raw_tracepoint.tgt_btf_id = OPTS_GET(opts, tgt_btf_id, 0);

return sys_bpf(BPF_RAW_TRACEPOINT_OPEN, &attr, sizeof(attr));
}

int bpf_raw_tracepoint_open(const char *name, int prog_fd)
{
return bpf_raw_tracepoint_open_opts(name, prog_fd, NULL);
}

int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf, __u32 log_buf_size,
bool do_log)
{
Expand Down
9 changes: 9 additions & 0 deletions tools/lib/bpf/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,16 @@ LIBBPF_API int bpf_obj_get_info_by_fd(int bpf_fd, void *info, __u32 *info_len);
LIBBPF_API int bpf_prog_query(int target_fd, enum bpf_attach_type type,
__u32 query_flags, __u32 *attach_flags,
__u32 *prog_ids, __u32 *prog_cnt);
struct bpf_raw_tracepoint_opts {
size_t sz; /* size of this struct for forward/backward compatibility */
int tgt_prog_fd; /* target program to attach to */
__u32 tgt_btf_id; /* BTF ID of target function */
};
#define bpf_raw_tracepoint_opts__last_field tgt_btf_id

LIBBPF_API int bpf_raw_tracepoint_open(const char *name, int prog_fd);
LIBBPF_API int bpf_raw_tracepoint_open_opts(const char *name, int prog_fd,
struct bpf_raw_tracepoint_opts *opts);
LIBBPF_API int bpf_load_btf(void *btf, __u32 btf_size, char *log_buf,
__u32 log_buf_size, bool do_log);
LIBBPF_API int bpf_task_fd_query(int pid, int fd, __u32 flags, char *buf,
Expand Down
1 change: 1 addition & 0 deletions tools/lib/bpf/libbpf.map
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ LIBBPF_0.1.0 {
LIBBPF_0.2.0 {
global:
bpf_program__section_name;
bpf_raw_tracepoint_open_opts;
perf_buffer__buffer_cnt;
perf_buffer__buffer_fd;
perf_buffer__epoll_fd;
Expand Down
Loading