Commit df975da4 authored by David S. Miller's avatar David S. Miller

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Daniel Borkmann says:

====================
pull-request: bpf 2018-11-01

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

The main changes are:

1) Fix tcp_bpf_recvmsg() to return -EAGAIN instead of 0 in non-blocking
   case when no data is available yet, from John.

2) Fix a compilation error in libbpf_attach_type_by_name() when compiled
   with clang 3.8, from Andrey.

3) Fix a partial copy of map pointer on scalar alu and remove id
   generation for RET_PTR_TO_MAP_VALUE return types, from Daniel.

4) Add unlimited memlock limit for kernel selftest's flow_dissector_load
   program, from Yonghong.

5) Fix ping for some BPF shell based kselftests where distro does not
   ship "ping -6" anymore, from Li.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e2acdddd dfeb8f4c
...@@ -51,6 +51,9 @@ struct bpf_reg_state { ...@@ -51,6 +51,9 @@ struct bpf_reg_state {
* PTR_TO_MAP_VALUE_OR_NULL * PTR_TO_MAP_VALUE_OR_NULL
*/ */
struct bpf_map *map_ptr; struct bpf_map *map_ptr;
/* Max size from any of the above. */
unsigned long raw;
}; };
/* Fixed part of pointer offset, pointer types only */ /* Fixed part of pointer offset, pointer types only */
s32 off; s32 off;
......
...@@ -2852,10 +2852,6 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn ...@@ -2852,10 +2852,6 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
regs[BPF_REG_0].type = NOT_INIT; regs[BPF_REG_0].type = NOT_INIT;
} else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL || } else if (fn->ret_type == RET_PTR_TO_MAP_VALUE_OR_NULL ||
fn->ret_type == RET_PTR_TO_MAP_VALUE) { fn->ret_type == RET_PTR_TO_MAP_VALUE) {
if (fn->ret_type == RET_PTR_TO_MAP_VALUE)
regs[BPF_REG_0].type = PTR_TO_MAP_VALUE;
else
regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL;
/* There is no offset yet applied, variable or fixed */ /* There is no offset yet applied, variable or fixed */
mark_reg_known_zero(env, regs, BPF_REG_0); mark_reg_known_zero(env, regs, BPF_REG_0);
/* remember map_ptr, so that check_map_access() /* remember map_ptr, so that check_map_access()
...@@ -2868,7 +2864,12 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn ...@@ -2868,7 +2864,12 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
return -EINVAL; return -EINVAL;
} }
regs[BPF_REG_0].map_ptr = meta.map_ptr; regs[BPF_REG_0].map_ptr = meta.map_ptr;
regs[BPF_REG_0].id = ++env->id_gen; if (fn->ret_type == RET_PTR_TO_MAP_VALUE) {
regs[BPF_REG_0].type = PTR_TO_MAP_VALUE;
} else {
regs[BPF_REG_0].type = PTR_TO_MAP_VALUE_OR_NULL;
regs[BPF_REG_0].id = ++env->id_gen;
}
} else if (fn->ret_type == RET_PTR_TO_SOCKET_OR_NULL) { } else if (fn->ret_type == RET_PTR_TO_SOCKET_OR_NULL) {
int id = acquire_reference_state(env, insn_idx); int id = acquire_reference_state(env, insn_idx);
if (id < 0) if (id < 0)
...@@ -3046,7 +3047,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, ...@@ -3046,7 +3047,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
dst_reg->umax_value = umax_ptr; dst_reg->umax_value = umax_ptr;
dst_reg->var_off = ptr_reg->var_off; dst_reg->var_off = ptr_reg->var_off;
dst_reg->off = ptr_reg->off + smin_val; dst_reg->off = ptr_reg->off + smin_val;
dst_reg->range = ptr_reg->range; dst_reg->raw = ptr_reg->raw;
break; break;
} }
/* A new variable offset is created. Note that off_reg->off /* A new variable offset is created. Note that off_reg->off
...@@ -3076,10 +3077,11 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, ...@@ -3076,10 +3077,11 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
} }
dst_reg->var_off = tnum_add(ptr_reg->var_off, off_reg->var_off); dst_reg->var_off = tnum_add(ptr_reg->var_off, off_reg->var_off);
dst_reg->off = ptr_reg->off; dst_reg->off = ptr_reg->off;
dst_reg->raw = ptr_reg->raw;
if (reg_is_pkt_pointer(ptr_reg)) { if (reg_is_pkt_pointer(ptr_reg)) {
dst_reg->id = ++env->id_gen; dst_reg->id = ++env->id_gen;
/* something was added to pkt_ptr, set range to zero */ /* something was added to pkt_ptr, set range to zero */
dst_reg->range = 0; dst_reg->raw = 0;
} }
break; break;
case BPF_SUB: case BPF_SUB:
...@@ -3108,7 +3110,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, ...@@ -3108,7 +3110,7 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
dst_reg->var_off = ptr_reg->var_off; dst_reg->var_off = ptr_reg->var_off;
dst_reg->id = ptr_reg->id; dst_reg->id = ptr_reg->id;
dst_reg->off = ptr_reg->off - smin_val; dst_reg->off = ptr_reg->off - smin_val;
dst_reg->range = ptr_reg->range; dst_reg->raw = ptr_reg->raw;
break; break;
} }
/* A new variable offset is created. If the subtrahend is known /* A new variable offset is created. If the subtrahend is known
...@@ -3134,11 +3136,12 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env, ...@@ -3134,11 +3136,12 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
} }
dst_reg->var_off = tnum_sub(ptr_reg->var_off, off_reg->var_off); dst_reg->var_off = tnum_sub(ptr_reg->var_off, off_reg->var_off);
dst_reg->off = ptr_reg->off; dst_reg->off = ptr_reg->off;
dst_reg->raw = ptr_reg->raw;
if (reg_is_pkt_pointer(ptr_reg)) { if (reg_is_pkt_pointer(ptr_reg)) {
dst_reg->id = ++env->id_gen; dst_reg->id = ++env->id_gen;
/* something was added to pkt_ptr, set range to zero */ /* something was added to pkt_ptr, set range to zero */
if (smin_val < 0) if (smin_val < 0)
dst_reg->range = 0; dst_reg->raw = 0;
} }
break; break;
case BPF_AND: case BPF_AND:
......
...@@ -145,6 +145,7 @@ int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, ...@@ -145,6 +145,7 @@ int tcp_bpf_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
ret = err; ret = err;
goto out; goto out;
} }
copied = -EAGAIN;
} }
ret = copied; ret = copied;
out: out:
......
...@@ -2084,19 +2084,19 @@ void bpf_program__set_expected_attach_type(struct bpf_program *prog, ...@@ -2084,19 +2084,19 @@ void bpf_program__set_expected_attach_type(struct bpf_program *prog,
prog->expected_attach_type = type; prog->expected_attach_type = type;
} }
#define BPF_PROG_SEC_IMPL(string, ptype, eatype, atype) \ #define BPF_PROG_SEC_IMPL(string, ptype, eatype, is_attachable, atype) \
{ string, sizeof(string) - 1, ptype, eatype, atype } { string, sizeof(string) - 1, ptype, eatype, is_attachable, atype }
/* Programs that can NOT be attached. */ /* Programs that can NOT be attached. */
#define BPF_PROG_SEC(string, ptype) BPF_PROG_SEC_IMPL(string, ptype, 0, -EINVAL) #define BPF_PROG_SEC(string, ptype) BPF_PROG_SEC_IMPL(string, ptype, 0, 0, 0)
/* Programs that can be attached. */ /* Programs that can be attached. */
#define BPF_APROG_SEC(string, ptype, atype) \ #define BPF_APROG_SEC(string, ptype, atype) \
BPF_PROG_SEC_IMPL(string, ptype, 0, atype) BPF_PROG_SEC_IMPL(string, ptype, 0, 1, atype)
/* Programs that must specify expected attach type at load time. */ /* Programs that must specify expected attach type at load time. */
#define BPF_EAPROG_SEC(string, ptype, eatype) \ #define BPF_EAPROG_SEC(string, ptype, eatype) \
BPF_PROG_SEC_IMPL(string, ptype, eatype, eatype) BPF_PROG_SEC_IMPL(string, ptype, eatype, 1, eatype)
/* Programs that can be attached but attach type can't be identified by section /* Programs that can be attached but attach type can't be identified by section
* name. Kept for backward compatibility. * name. Kept for backward compatibility.
...@@ -2108,6 +2108,7 @@ static const struct { ...@@ -2108,6 +2108,7 @@ static const struct {
size_t len; size_t len;
enum bpf_prog_type prog_type; enum bpf_prog_type prog_type;
enum bpf_attach_type expected_attach_type; enum bpf_attach_type expected_attach_type;
int is_attachable;
enum bpf_attach_type attach_type; enum bpf_attach_type attach_type;
} section_names[] = { } section_names[] = {
BPF_PROG_SEC("socket", BPF_PROG_TYPE_SOCKET_FILTER), BPF_PROG_SEC("socket", BPF_PROG_TYPE_SOCKET_FILTER),
...@@ -2198,7 +2199,7 @@ int libbpf_attach_type_by_name(const char *name, ...@@ -2198,7 +2199,7 @@ int libbpf_attach_type_by_name(const char *name,
for (i = 0; i < ARRAY_SIZE(section_names); i++) { for (i = 0; i < ARRAY_SIZE(section_names); i++) {
if (strncmp(name, section_names[i].sec, section_names[i].len)) if (strncmp(name, section_names[i].sec, section_names[i].len))
continue; continue;
if (section_names[i].attach_type == -EINVAL) if (!section_names[i].is_attachable)
return -EINVAL; return -EINVAL;
*attach_type = section_names[i].attach_type; *attach_type = section_names[i].attach_type;
return 0; return 0;
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
#include <bpf/bpf.h> #include <bpf/bpf.h>
#include <bpf/libbpf.h> #include <bpf/libbpf.h>
#include "bpf_rlimit.h"
const char *cfg_pin_path = "/sys/fs/bpf/flow_dissector"; const char *cfg_pin_path = "/sys/fs/bpf/flow_dissector";
const char *cfg_map_name = "jmp_table"; const char *cfg_map_name = "jmp_table";
bool cfg_attach = true; bool cfg_attach = true;
......
...@@ -10,7 +10,7 @@ wait_for_ip() ...@@ -10,7 +10,7 @@ wait_for_ip()
echo -n "Wait for testing link-local IP to become available " echo -n "Wait for testing link-local IP to become available "
for _i in $(seq ${MAX_PING_TRIES}); do for _i in $(seq ${MAX_PING_TRIES}); do
echo -n "." echo -n "."
if ping -6 -q -c 1 -W 1 ff02::1%${TEST_IF} >/dev/null 2>&1; then if $PING6 -c 1 -W 1 ff02::1%${TEST_IF} >/dev/null 2>&1; then
echo " OK" echo " OK"
return return
fi fi
...@@ -58,5 +58,6 @@ BPF_PROG_OBJ="${DIR}/test_skb_cgroup_id_kern.o" ...@@ -58,5 +58,6 @@ BPF_PROG_OBJ="${DIR}/test_skb_cgroup_id_kern.o"
BPF_PROG_SECTION="cgroup_id_logger" BPF_PROG_SECTION="cgroup_id_logger"
BPF_PROG_ID=0 BPF_PROG_ID=0
PROG="${DIR}/test_skb_cgroup_id_user" PROG="${DIR}/test_skb_cgroup_id_user"
type ping6 >/dev/null 2>&1 && PING6="ping6" || PING6="ping -6"
main main
...@@ -4,7 +4,8 @@ set -eu ...@@ -4,7 +4,8 @@ set -eu
ping_once() ping_once()
{ {
ping -${1} -q -c 1 -W 1 ${2%%/*} >/dev/null 2>&1 type ping${1} >/dev/null 2>&1 && PING="ping${1}" || PING="ping -${1}"
$PING -q -c 1 -W 1 ${2%%/*} >/dev/null 2>&1
} }
wait_for_ip() wait_for_ip()
......
This diff is collapsed.
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