Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Browse files Browse the repository at this point in the history
Daniel Borkmann says:

====================
pull-request: bpf 2020-08-08

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

We've added 11 non-merge commits during the last 2 day(s) which contain
a total of 24 files changed, 216 insertions(+), 135 deletions(-).

The main changes are:

1) Fix UAPI for BPF map iterator before it gets frozen to allow for more
   extensions/customization in future, from Yonghong Song.

2) Fix selftests build to undo verbose build output, from Andrii Nakryiko.

3) Fix inlining compilation error on bpf_do_trace_printk() due to variable
   argument lists, from Stanislav Fomichev.

4) Fix an uninitialized pointer warning at btf__parse_raw() in libbpf,
   from Daniel T. Lee.

5) Fix several compilation warnings in selftests with regards to ignoring
   return value, from Jianlin Lv.

6) Fix interruptions by switching off timeout for BPF tests, from Jiri Benc.
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Aug 8, 2020
2 parents 7ee2492 + b8c1a30 commit 64cae2f
Show file tree
Hide file tree
Showing 24 changed files with 216 additions and 135 deletions.
11 changes: 0 additions & 11 deletions Documentation/bpf/bpf_design_QA.rst
Original file line number Diff line number Diff line change
Expand Up @@ -246,17 +246,6 @@ program is loaded the kernel will print warning message, so
this helper is only useful for experiments and prototypes.
Tracing BPF programs are root only.

Q: bpf_trace_printk() helper warning
------------------------------------
Q: When bpf_trace_printk() helper is used the kernel prints nasty
warning message. Why is that?

A: This is done to nudge program authors into better interfaces when
programs need to pass data to user space. Like bpf_perf_event_output()
can be used to efficiently stream data via perf ring buffer.
BPF maps can be used for asynchronous data sharing between kernel
and user space. bpf_trace_printk() should only be used for debugging.

Q: New functionality via kernel modules?
----------------------------------------
Q: Can BPF functionality such as new program or map types, new
Expand Down
10 changes: 6 additions & 4 deletions include/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1214,15 +1214,17 @@ struct bpf_iter_aux_info {
struct bpf_map *map;
};

typedef int (*bpf_iter_check_target_t)(struct bpf_prog *prog,
struct bpf_iter_aux_info *aux);
typedef int (*bpf_iter_attach_target_t)(struct bpf_prog *prog,
union bpf_iter_link_info *linfo,
struct bpf_iter_aux_info *aux);
typedef void (*bpf_iter_detach_target_t)(struct bpf_iter_aux_info *aux);

#define BPF_ITER_CTX_ARG_MAX 2
struct bpf_iter_reg {
const char *target;
bpf_iter_check_target_t check_target;
bpf_iter_attach_target_t attach_target;
bpf_iter_detach_target_t detach_target;
u32 ctx_arg_info_size;
enum bpf_iter_link_info req_linfo;
struct bpf_ctx_arg_aux ctx_arg_info[BPF_ITER_CTX_ARG_MAX];
const struct bpf_iter_seq_info *seq_info;
};
Expand Down
15 changes: 8 additions & 7 deletions include/uapi/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,12 @@ struct bpf_cgroup_storage_key {
__u32 attach_type; /* program attach type */
};

union bpf_iter_link_info {
struct {
__u32 map_fd;
} map;
};

/* BPF syscall commands, see bpf(2) man-page for details. */
enum bpf_cmd {
BPF_MAP_CREATE,
Expand Down Expand Up @@ -249,13 +255,6 @@ enum bpf_link_type {
MAX_BPF_LINK_TYPE,
};

enum bpf_iter_link_info {
BPF_ITER_LINK_UNSPEC = 0,
BPF_ITER_LINK_MAP_FD = 1,

MAX_BPF_ITER_LINK_INFO,
};

/* cgroup-bpf attach flags used in BPF_PROG_ATTACH command
*
* NONE(default): No further bpf programs allowed in the subtree.
Expand Down Expand Up @@ -623,6 +622,8 @@ union bpf_attr {
};
__u32 attach_type; /* attach type */
__u32 flags; /* extra flags */
__aligned_u64 iter_info; /* extra bpf_iter_link_info */
__u32 iter_info_len; /* iter_info length */
} link_create;

struct { /* struct used by BPF_LINK_UPDATE command */
Expand Down
58 changes: 29 additions & 29 deletions kernel/bpf/bpf_iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,8 +338,8 @@ static void bpf_iter_link_release(struct bpf_link *link)
struct bpf_iter_link *iter_link =
container_of(link, struct bpf_iter_link, link);

if (iter_link->aux.map)
bpf_map_put_with_uref(iter_link->aux.map);
if (iter_link->tinfo->reg_info->detach_target)
iter_link->tinfo->reg_info->detach_target(&iter_link->aux);
}

static void bpf_iter_link_dealloc(struct bpf_link *link)
Expand Down Expand Up @@ -390,15 +390,35 @@ bool bpf_link_is_iter(struct bpf_link *link)

int bpf_iter_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
{
union bpf_iter_link_info __user *ulinfo;
struct bpf_link_primer link_primer;
struct bpf_iter_target_info *tinfo;
struct bpf_iter_aux_info aux = {};
union bpf_iter_link_info linfo;
struct bpf_iter_link *link;
u32 prog_btf_id, target_fd;
u32 prog_btf_id, linfo_len;
bool existed = false;
struct bpf_map *map;
int err;

if (attr->link_create.target_fd || attr->link_create.flags)
return -EINVAL;

memset(&linfo, 0, sizeof(union bpf_iter_link_info));

ulinfo = u64_to_user_ptr(attr->link_create.iter_info);
linfo_len = attr->link_create.iter_info_len;
if (!ulinfo ^ !linfo_len)
return -EINVAL;

if (ulinfo) {
err = bpf_check_uarg_tail_zero(ulinfo, sizeof(linfo),
linfo_len);
if (err)
return err;
linfo_len = min_t(u32, linfo_len, sizeof(linfo));
if (copy_from_user(&linfo, ulinfo, linfo_len))
return -EFAULT;
}

prog_btf_id = prog->aux->attach_btf_id;
mutex_lock(&targets_mutex);
list_for_each_entry(tinfo, &targets, list) {
Expand All @@ -411,13 +431,6 @@ int bpf_iter_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
if (!existed)
return -ENOENT;

/* Make sure user supplied flags are target expected. */
target_fd = attr->link_create.target_fd;
if (attr->link_create.flags != tinfo->reg_info->req_linfo)
return -EINVAL;
if (!attr->link_create.flags && target_fd)
return -EINVAL;

link = kzalloc(sizeof(*link), GFP_USER | __GFP_NOWARN);
if (!link)
return -ENOMEM;
Expand All @@ -431,28 +444,15 @@ int bpf_iter_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
return err;
}

if (tinfo->reg_info->req_linfo == BPF_ITER_LINK_MAP_FD) {
map = bpf_map_get_with_uref(target_fd);
if (IS_ERR(map)) {
err = PTR_ERR(map);
goto cleanup_link;
}

aux.map = map;
err = tinfo->reg_info->check_target(prog, &aux);
if (tinfo->reg_info->attach_target) {
err = tinfo->reg_info->attach_target(prog, &linfo, &link->aux);
if (err) {
bpf_map_put_with_uref(map);
goto cleanup_link;
bpf_link_cleanup(&link_primer);
return err;
}

link->aux.map = map;
}

return bpf_link_settle(&link_primer);

cleanup_link:
bpf_link_cleanup(&link_primer);
return err;
}

static void init_seq_meta(struct bpf_iter_priv_data *priv_data,
Expand Down
2 changes: 1 addition & 1 deletion kernel/bpf/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1966,7 +1966,7 @@ void bpf_prog_array_delete_safe(struct bpf_prog_array *array,
* @index: the index of the program to replace
*
* Skips over dummy programs, by not counting them, when calculating
* the the position of the program to replace.
* the position of the program to replace.
*
* Return:
* * 0 - Success
Expand Down
37 changes: 29 additions & 8 deletions kernel/bpf/map_iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,21 @@ static struct bpf_iter_reg bpf_map_reg_info = {
.seq_info = &bpf_map_seq_info,
};

static int bpf_iter_check_map(struct bpf_prog *prog,
struct bpf_iter_aux_info *aux)
static int bpf_iter_attach_map(struct bpf_prog *prog,
union bpf_iter_link_info *linfo,
struct bpf_iter_aux_info *aux)
{
u32 key_acc_size, value_acc_size, key_size, value_size;
struct bpf_map *map = aux->map;
struct bpf_map *map;
bool is_percpu = false;
int err = -EINVAL;

if (!linfo->map.map_fd)
return -EBADF;

map = bpf_map_get_with_uref(linfo->map.map_fd);
if (IS_ERR(map))
return PTR_ERR(map);

if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
Expand All @@ -112,7 +121,7 @@ static int bpf_iter_check_map(struct bpf_prog *prog,
else if (map->map_type != BPF_MAP_TYPE_HASH &&
map->map_type != BPF_MAP_TYPE_LRU_HASH &&
map->map_type != BPF_MAP_TYPE_ARRAY)
return -EINVAL;
goto put_map;

key_acc_size = prog->aux->max_rdonly_access;
value_acc_size = prog->aux->max_rdwr_access;
Expand All @@ -122,19 +131,31 @@ static int bpf_iter_check_map(struct bpf_prog *prog,
else
value_size = round_up(map->value_size, 8) * num_possible_cpus();

if (key_acc_size > key_size || value_acc_size > value_size)
return -EACCES;
if (key_acc_size > key_size || value_acc_size > value_size) {
err = -EACCES;
goto put_map;
}

aux->map = map;
return 0;

put_map:
bpf_map_put_with_uref(map);
return err;
}

static void bpf_iter_detach_map(struct bpf_iter_aux_info *aux)
{
bpf_map_put_with_uref(aux->map);
}

DEFINE_BPF_ITER_FUNC(bpf_map_elem, struct bpf_iter_meta *meta,
struct bpf_map *map, void *key, void *value)

static const struct bpf_iter_reg bpf_map_elem_reg_info = {
.target = "bpf_map_elem",
.check_target = bpf_iter_check_map,
.req_linfo = BPF_ITER_LINK_MAP_FD,
.attach_target = bpf_iter_attach_map,
.detach_target = bpf_iter_detach_map,
.ctx_arg_info_size = 2,
.ctx_arg_info = {
{ offsetof(struct bpf_iter__bpf_map_elem, key),
Expand Down
2 changes: 1 addition & 1 deletion kernel/bpf/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -3883,7 +3883,7 @@ static int tracing_bpf_link_attach(const union bpf_attr *attr, struct bpf_prog *
return -EINVAL;
}

#define BPF_LINK_CREATE_LAST_FIELD link_create.flags
#define BPF_LINK_CREATE_LAST_FIELD link_create.iter_info_len
static int link_create(union bpf_attr *attr)
{
enum bpf_prog_type ptype;
Expand Down
2 changes: 1 addition & 1 deletion kernel/bpf/verifier.c
Original file line number Diff line number Diff line change
Expand Up @@ -8294,7 +8294,7 @@ static bool stacksafe(struct bpf_func_state *old,
if (old->stack[spi].slot_type[i % BPF_REG_SIZE] !=
cur->stack[spi].slot_type[i % BPF_REG_SIZE])
/* Ex: old explored (safe) state has STACK_SPILL in
* this stack slot, but current has has STACK_MISC ->
* this stack slot, but current has STACK_MISC ->
* this verifier states are not equivalent,
* return false to continue verification of this path
*/
Expand Down
2 changes: 1 addition & 1 deletion kernel/trace/bpf_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ static DEFINE_RAW_SPINLOCK(trace_printk_lock);

#define BPF_TRACE_PRINTK_SIZE 1024

static inline __printf(1, 0) int bpf_do_trace_printk(const char *fmt, ...)
static __printf(1, 0) int bpf_do_trace_printk(const char *fmt, ...)
{
static char buf[BPF_TRACE_PRINTK_SIZE];
unsigned long flags;
Expand Down
37 changes: 29 additions & 8 deletions net/core/bpf_sk_storage.c
Original file line number Diff line number Diff line change
Expand Up @@ -1384,18 +1384,39 @@ static int bpf_iter_init_sk_storage_map(void *priv_data,
return 0;
}

static int bpf_iter_check_map(struct bpf_prog *prog,
struct bpf_iter_aux_info *aux)
static int bpf_iter_attach_map(struct bpf_prog *prog,
union bpf_iter_link_info *linfo,
struct bpf_iter_aux_info *aux)
{
struct bpf_map *map = aux->map;
struct bpf_map *map;
int err = -EINVAL;

if (!linfo->map.map_fd)
return -EBADF;

map = bpf_map_get_with_uref(linfo->map.map_fd);
if (IS_ERR(map))
return PTR_ERR(map);

if (map->map_type != BPF_MAP_TYPE_SK_STORAGE)
return -EINVAL;
goto put_map;

if (prog->aux->max_rdonly_access > map->value_size)
return -EACCES;
if (prog->aux->max_rdonly_access > map->value_size) {
err = -EACCES;
goto put_map;
}

aux->map = map;
return 0;

put_map:
bpf_map_put_with_uref(map);
return err;
}

static void bpf_iter_detach_map(struct bpf_iter_aux_info *aux)
{
bpf_map_put_with_uref(aux->map);
}

static const struct seq_operations bpf_sk_storage_map_seq_ops = {
Expand All @@ -1414,8 +1435,8 @@ static const struct bpf_iter_seq_info iter_seq_info = {

static struct bpf_iter_reg bpf_sk_storage_map_reg_info = {
.target = "bpf_sk_storage_map",
.check_target = bpf_iter_check_map,
.req_linfo = BPF_ITER_LINK_MAP_FD,
.attach_target = bpf_iter_attach_map,
.detach_target = bpf_iter_detach_map,
.ctx_arg_info_size = 2,
.ctx_arg_info = {
{ offsetof(struct bpf_iter__bpf_sk_storage_map, sk),
Expand Down
9 changes: 6 additions & 3 deletions tools/bpf/bpftool/iter.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
static int do_pin(int argc, char **argv)
{
DECLARE_LIBBPF_OPTS(bpf_iter_attach_opts, iter_opts);
union bpf_iter_link_info linfo;
const char *objfile, *path;
struct bpf_program *prog;
struct bpf_object *obj;
Expand All @@ -36,6 +37,11 @@ static int do_pin(int argc, char **argv)
map_fd = map_parse_fd(&argc, &argv);
if (map_fd < 0)
return -1;

memset(&linfo, 0, sizeof(linfo));
linfo.map.map_fd = map_fd;
iter_opts.link_info = &linfo;
iter_opts.link_info_len = sizeof(linfo);
}
}

Expand All @@ -57,9 +63,6 @@ static int do_pin(int argc, char **argv)
goto close_obj;
}

if (map_fd >= 0)
iter_opts.map_fd = map_fd;

link = bpf_program__attach_iter(prog, &iter_opts);
if (IS_ERR(link)) {
err = PTR_ERR(link);
Expand Down
1 change: 1 addition & 0 deletions tools/bpf/resolve_btfids/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,7 @@ static int sets_patch(struct object *obj)

next = rb_next(next);
}
return 0;
}

static int symbols_patch(struct object *obj)
Expand Down
Loading

0 comments on commit 64cae2f

Please sign in to comment.