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 2018-07-28

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

The main changes are:

1) API fixes for libbpf's BTF mapping of map key/value types in order
   to make them compatible with iproute2's BPF_ANNOTATE_KV_PAIR()
   markings, from Martin.

2) Fix AF_XDP to not report POLLIN prematurely by using the non-cached
   consumer pointer of the RX queue, from Björn.

3) Fix __xdp_return() to check for NULL pointer after the rhashtable
   lookup that retrieves the allocator object, from Taehee.

4) Fix x86-32 JIT to adjust ebp register in prologue and epilogue
   by 4 bytes which got removed from overall stack usage, from Wang.

5) Fix bpf_skb_load_bytes_relative() length check to use actual
   packet length, from Daniel.

6) Fix uninitialized return code in libbpf bpf_perf_event_read_simple()
   handler, from Thomas.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Jul 29, 2018
2 parents b075340 + 71eb525 commit 958b4cd
Show file tree
Hide file tree
Showing 15 changed files with 225 additions and 90 deletions.
8 changes: 4 additions & 4 deletions arch/x86/net/bpf_jit_comp32.c
Original file line number Diff line number Diff line change
Expand Up @@ -1441,8 +1441,8 @@ static void emit_prologue(u8 **pprog, u32 stack_depth)

/* sub esp,STACK_SIZE */
EMIT2_off32(0x81, 0xEC, STACK_SIZE);
/* sub ebp,SCRATCH_SIZE+4+12*/
EMIT3(0x83, add_1reg(0xE8, IA32_EBP), SCRATCH_SIZE + 16);
/* sub ebp,SCRATCH_SIZE+12*/
EMIT3(0x83, add_1reg(0xE8, IA32_EBP), SCRATCH_SIZE + 12);
/* xor ebx,ebx */
EMIT2(0x31, add_2reg(0xC0, IA32_EBX, IA32_EBX));

Expand Down Expand Up @@ -1475,8 +1475,8 @@ static void emit_epilogue(u8 **pprog, u32 stack_depth)
/* mov edx,dword ptr [ebp+off]*/
EMIT3(0x8B, add_2reg(0x40, IA32_EBP, IA32_EDX), STACK_VAR(r0[1]));

/* add ebp,SCRATCH_SIZE+4+12*/
EMIT3(0x83, add_1reg(0xC0, IA32_EBP), SCRATCH_SIZE + 16);
/* add ebp,SCRATCH_SIZE+12*/
EMIT3(0x83, add_1reg(0xC0, IA32_EBP), SCRATCH_SIZE + 12);

/* mov ebx,dword ptr [ebp-12]*/
EMIT3(0x8B, add_2reg(0x40, IA32_EBP, IA32_EBX), -12);
Expand Down
2 changes: 1 addition & 1 deletion kernel/bpf/arraymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ static int array_map_check_btf(const struct bpf_map *map, const struct btf *btf,
return -EINVAL;

value_type = btf_type_id_size(btf, &btf_value_id, &value_size);
if (!value_type || value_size > map->value_size)
if (!value_type || value_size != map->value_size)
return -EINVAL;

return 0;
Expand Down
14 changes: 13 additions & 1 deletion kernel/bpf/btf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1519,9 +1519,9 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,
{
bool is_union = BTF_INFO_KIND(t->info) == BTF_KIND_UNION;
const struct btf_member *member;
u32 meta_needed, last_offset;
struct btf *btf = env->btf;
u32 struct_size = t->size;
u32 meta_needed;
u16 i;

meta_needed = btf_type_vlen(t) * sizeof(*member);
Expand All @@ -1534,6 +1534,7 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,

btf_verifier_log_type(env, t, NULL);

last_offset = 0;
for_each_member(i, t, member) {
if (!btf_name_offset_valid(btf, member->name_off)) {
btf_verifier_log_member(env, t, member,
Expand All @@ -1555,13 +1556,24 @@ static s32 btf_struct_check_meta(struct btf_verifier_env *env,
return -EINVAL;
}

/*
* ">" instead of ">=" because the last member could be
* "char a[0];"
*/
if (last_offset > member->offset) {
btf_verifier_log_member(env, t, member,
"Invalid member bits_offset");
return -EINVAL;
}

if (BITS_ROUNDUP_BYTES(member->offset) > struct_size) {
btf_verifier_log_member(env, t, member,
"Memmber bits_offset exceeds its struct size");
return -EINVAL;
}

btf_verifier_log_member(env, t, member, NULL);
last_offset = member->offset;
}

return meta_needed;
Expand Down
12 changes: 7 additions & 5 deletions net/core/filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1712,24 +1712,26 @@ static const struct bpf_func_proto bpf_skb_load_bytes_proto = {
BPF_CALL_5(bpf_skb_load_bytes_relative, const struct sk_buff *, skb,
u32, offset, void *, to, u32, len, u32, start_header)
{
u8 *end = skb_tail_pointer(skb);
u8 *net = skb_network_header(skb);
u8 *mac = skb_mac_header(skb);
u8 *ptr;

if (unlikely(offset > 0xffff || len > skb_headlen(skb)))
if (unlikely(offset > 0xffff || len > (end - mac)))
goto err_clear;

switch (start_header) {
case BPF_HDR_START_MAC:
ptr = skb_mac_header(skb) + offset;
ptr = mac + offset;
break;
case BPF_HDR_START_NET:
ptr = skb_network_header(skb) + offset;
ptr = net + offset;
break;
default:
goto err_clear;
}

if (likely(ptr >= skb_mac_header(skb) &&
ptr + len <= skb_tail_pointer(skb))) {
if (likely(ptr >= mac && ptr + len <= end)) {
memcpy(to, ptr, len);
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion net/core/lwt_bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ static int bpf_parse_prog(struct nlattr *attr, struct bpf_lwt_prog *prog,
if (!tb[LWT_BPF_PROG_FD] || !tb[LWT_BPF_PROG_NAME])
return -EINVAL;

prog->name = nla_memdup(tb[LWT_BPF_PROG_NAME], GFP_KERNEL);
prog->name = nla_memdup(tb[LWT_BPF_PROG_NAME], GFP_ATOMIC);
if (!prog->name)
return -ENOMEM;

Expand Down
3 changes: 2 additions & 1 deletion net/core/xdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,8 @@ static void __xdp_return(void *data, struct xdp_mem_info *mem, bool napi_direct,
rcu_read_lock();
/* mem->id is valid, checked in xdp_rxq_info_reg_mem_model() */
xa = rhashtable_lookup(mem_id_ht, &mem->id, mem_id_rht_params);
xa->zc_alloc->free(xa->zc_alloc, handle);
if (!WARN_ON_ONCE(!xa))
xa->zc_alloc->free(xa->zc_alloc, handle);
rcu_read_unlock();
default:
/* Not possible, checked in xdp_rxq_info_reg_mem_model() */
Expand Down
2 changes: 1 addition & 1 deletion net/xdp/xsk_queue.h
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ static inline bool xskq_full_desc(struct xsk_queue *q)

static inline bool xskq_empty_desc(struct xsk_queue *q)
{
return xskq_nb_free(q, q->prod_tail, 1) == q->nentries;
return xskq_nb_free(q, q->prod_tail, q->nentries) == q->nentries;
}

void xskq_set_umem(struct xsk_queue *q, struct xdp_umem_props *umem_props);
Expand Down
2 changes: 1 addition & 1 deletion tools/include/uapi/linux/btf.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ struct btf_type {
*/
#define BTF_INT_ENCODING(VAL) (((VAL) & 0x0f000000) >> 24)
#define BTF_INT_OFFSET(VAL) (((VAL & 0x00ff0000)) >> 16)
#define BTF_INT_BITS(VAL) ((VAL) & 0x0000ffff)
#define BTF_INT_BITS(VAL) ((VAL) & 0x000000ff)

/* Attributes stored in the BTF_INT_ENCODING */
#define BTF_INT_SIGNED (1 << 0)
Expand Down
39 changes: 18 additions & 21 deletions tools/lib/bpf/btf.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
/* Copyright (c) 2018 Facebook */

#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
Expand All @@ -27,13 +26,13 @@ struct btf {
struct btf_type **types;
const char *strings;
void *nohdr_data;
uint32_t nr_types;
uint32_t types_size;
uint32_t data_size;
__u32 nr_types;
__u32 types_size;
__u32 data_size;
int fd;
};

static const char *btf_name_by_offset(const struct btf *btf, uint32_t offset)
static const char *btf_name_by_offset(const struct btf *btf, __u32 offset)
{
if (offset < btf->hdr->str_len)
return &btf->strings[offset];
Expand All @@ -45,7 +44,7 @@ static int btf_add_type(struct btf *btf, struct btf_type *t)
{
if (btf->types_size - btf->nr_types < 2) {
struct btf_type **new_types;
u32 expand_by, new_size;
__u32 expand_by, new_size;

if (btf->types_size == BTF_MAX_NR_TYPES)
return -E2BIG;
Expand All @@ -72,7 +71,7 @@ static int btf_add_type(struct btf *btf, struct btf_type *t)
static int btf_parse_hdr(struct btf *btf, btf_print_fn_t err_log)
{
const struct btf_header *hdr = btf->hdr;
u32 meta_left;
__u32 meta_left;

if (btf->data_size < sizeof(struct btf_header)) {
elog("BTF header not found\n");
Expand Down Expand Up @@ -151,7 +150,7 @@ static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log)

while (next_type < end_type) {
struct btf_type *t = next_type;
uint16_t vlen = BTF_INFO_VLEN(t->info);
__u16 vlen = BTF_INFO_VLEN(t->info);
int err;

next_type += sizeof(*t);
Expand Down Expand Up @@ -190,8 +189,7 @@ static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log)
return 0;
}

static const struct btf_type *btf_type_by_id(const struct btf *btf,
uint32_t type_id)
const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id)
{
if (type_id > btf->nr_types)
return NULL;
Expand All @@ -209,7 +207,7 @@ static bool btf_type_is_void_or_null(const struct btf_type *t)
return !t || btf_type_is_void(t);
}

static int64_t btf_type_size(const struct btf_type *t)
static __s64 btf_type_size(const struct btf_type *t)
{
switch (BTF_INFO_KIND(t->info)) {
case BTF_KIND_INT:
Expand All @@ -226,15 +224,15 @@ static int64_t btf_type_size(const struct btf_type *t)

#define MAX_RESOLVE_DEPTH 32

int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id)
__s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
{
const struct btf_array *array;
const struct btf_type *t;
uint32_t nelems = 1;
int64_t size = -1;
__u32 nelems = 1;
__s64 size = -1;
int i;

t = btf_type_by_id(btf, type_id);
t = btf__type_by_id(btf, type_id);
for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t);
i++) {
size = btf_type_size(t);
Expand All @@ -259,7 +257,7 @@ int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id)
return -EINVAL;
}

t = btf_type_by_id(btf, type_id);
t = btf__type_by_id(btf, type_id);
}

if (size < 0)
Expand All @@ -271,9 +269,9 @@ int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id)
return nelems * size;
}

int32_t btf__find_by_name(const struct btf *btf, const char *type_name)
__s32 btf__find_by_name(const struct btf *btf, const char *type_name)
{
uint32_t i;
__u32 i;

if (!strcmp(type_name, "void"))
return 0;
Expand Down Expand Up @@ -302,10 +300,9 @@ void btf__free(struct btf *btf)
free(btf);
}

struct btf *btf__new(uint8_t *data, uint32_t size,
btf_print_fn_t err_log)
struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log)
{
uint32_t log_buf_size = 0;
__u32 log_buf_size = 0;
char *log_buf = NULL;
struct btf *btf;
int err;
Expand Down
10 changes: 6 additions & 4 deletions tools/lib/bpf/btf.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,21 @@
#ifndef __BPF_BTF_H
#define __BPF_BTF_H

#include <stdint.h>
#include <linux/types.h>

#define BTF_ELF_SEC ".BTF"

struct btf;
struct btf_type;

typedef int (*btf_print_fn_t)(const char *, ...)
__attribute__((format(printf, 1, 2)));

void btf__free(struct btf *btf);
struct btf *btf__new(uint8_t *data, uint32_t size, btf_print_fn_t err_log);
int32_t btf__find_by_name(const struct btf *btf, const char *type_name);
int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id);
struct btf *btf__new(__u8 *data, __u32 size, btf_print_fn_t err_log);
__s32 btf__find_by_name(const struct btf *btf, const char *type_name);
const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 id);
__s64 btf__resolve_size(const struct btf *btf, __u32 type_id);
int btf__fd(const struct btf *btf);

#endif
Loading

0 comments on commit 958b4cd

Please sign in to comment.