Commit d2775984 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files


Daniel Borkmann says:

====================
pull-request: bpf 2020-10-22

1) Fix enforcing NULL check in verifier for new helper return types of
   RET_PTR_TO_{BTF_ID,MEM_OR_BTF_ID}_OR_NULL, from Martin KaFai Lau.

2) Fix bpf_redirect_neigh() helper API before it becomes frozen by adding
   nexthop information as argument, from Toke Høiland-Jørgensen.

3) Guard & fix compilation of bpf_tail_call_static() when __bpf__ arch is
   not defined by compiler or clang too old, from Daniel Borkmann.

4) Remove misplaced break after return in attach_type_to_prog_type(), from
   Tom Rix.
====================

Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents d9b0e599 3652c9a1
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -3244,7 +3244,8 @@ R: KP Singh <kpsingh@chromium.org>
L:	netdev@vger.kernel.org
L:	bpf@vger.kernel.org
S:	Supported
Q:	https://patchwork.ozlabs.org/project/netdev/list/?delegate=77147
W:	https://bpf.io/
Q:	https://patchwork.kernel.org/project/netdevbpf/list/?delegate=121173
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf.git
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git
F:	Documentation/bpf/
+9 −0
Original line number Diff line number Diff line
@@ -607,12 +607,21 @@ struct bpf_skb_data_end {
	void *data_end;
};

struct bpf_nh_params {
	u32 nh_family;
	union {
		u32 ipv4_nh;
		struct in6_addr ipv6_nh;
	};
};

struct bpf_redirect_info {
	u32 flags;
	u32 tgt_index;
	void *tgt_value;
	struct bpf_map *map;
	u32 kern_flags;
	struct bpf_nh_params nh;
};

DECLARE_PER_CPU(struct bpf_redirect_info, bpf_redirect_info);
+18 −4
Original line number Diff line number Diff line
@@ -3677,15 +3677,19 @@ union bpf_attr {
 * 	Return
 * 		The id is returned or 0 in case the id could not be retrieved.
 *
 * long bpf_redirect_neigh(u32 ifindex, u64 flags)
 * long bpf_redirect_neigh(u32 ifindex, struct bpf_redir_neigh *params, int plen, u64 flags)
 * 	Description
 * 		Redirect the packet to another net device of index *ifindex*
 * 		and fill in L2 addresses from neighboring subsystem. This helper
 * 		is somewhat similar to **bpf_redirect**\ (), except that it
 * 		populates L2 addresses as well, meaning, internally, the helper
 * 		performs a FIB lookup based on the skb's networking header to
 * 		get the address of the next hop and then relies on the neighbor
 * 		lookup for the L2 address of the nexthop.
 * 		relies on the neighbor lookup for the L2 address of the nexthop.
 *
 * 		The helper will perform a FIB lookup based on the skb's
 * 		networking header to get the address of the next hop, unless
 * 		this is supplied by the caller in the *params* argument. The
 * 		*plen* argument indicates the len of *params* and should be set
 * 		to 0 if *params* is NULL.
 *
 * 		The *flags* argument is reserved and must be 0. The helper is
 * 		currently only supported for tc BPF program types, and enabled
@@ -4906,6 +4910,16 @@ struct bpf_fib_lookup {
	__u8	dmac[6];     /* ETH_ALEN */
};

struct bpf_redir_neigh {
	/* network family for lookup (AF_INET, AF_INET6) */
	__u32 nh_family;
	/* network address of nexthop; skips fib lookup to find gateway */
	union {
		__be32		ipv4_nh;
		__u32		ipv6_nh[4];  /* in6_addr; network order */
	};
};

enum bpf_task_fd_type {
	BPF_FD_TYPE_RAW_TRACEPOINT,	/* tp name */
	BPF_FD_TYPE_TRACEPOINT,		/* tp name */
+0 −1
Original line number Diff line number Diff line
@@ -2913,7 +2913,6 @@ attach_type_to_prog_type(enum bpf_attach_type attach_type)
	case BPF_CGROUP_INET_INGRESS:
	case BPF_CGROUP_INET_EGRESS:
		return BPF_PROG_TYPE_CGROUP_SKB;
		break;
	case BPF_CGROUP_INET_SOCK_CREATE:
	case BPF_CGROUP_INET_SOCK_RELEASE:
	case BPF_CGROUP_INET4_POST_BIND:
+5 −6
Original line number Diff line number Diff line
@@ -5133,24 +5133,19 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
				regs[BPF_REG_0].id = ++env->id_gen;
		} 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) {
		mark_reg_known_zero(env, regs, BPF_REG_0);
		regs[BPF_REG_0].type = PTR_TO_SOCKET_OR_NULL;
		regs[BPF_REG_0].id = ++env->id_gen;
	} else if (fn->ret_type == RET_PTR_TO_SOCK_COMMON_OR_NULL) {
		mark_reg_known_zero(env, regs, BPF_REG_0);
		regs[BPF_REG_0].type = PTR_TO_SOCK_COMMON_OR_NULL;
		regs[BPF_REG_0].id = ++env->id_gen;
	} else if (fn->ret_type == RET_PTR_TO_TCP_SOCK_OR_NULL) {
		mark_reg_known_zero(env, regs, BPF_REG_0);
		regs[BPF_REG_0].type = PTR_TO_TCP_SOCK_OR_NULL;
		regs[BPF_REG_0].id = ++env->id_gen;
	} else if (fn->ret_type == RET_PTR_TO_ALLOC_MEM_OR_NULL) {
		mark_reg_known_zero(env, regs, BPF_REG_0);
		regs[BPF_REG_0].type = PTR_TO_MEM_OR_NULL;
		regs[BPF_REG_0].id = ++env->id_gen;
		regs[BPF_REG_0].mem_size = meta.mem_size;
	} else if (fn->ret_type == RET_PTR_TO_MEM_OR_BTF_ID_OR_NULL ||
		   fn->ret_type == RET_PTR_TO_MEM_OR_BTF_ID) {
@@ -5199,6 +5194,9 @@ static int check_helper_call(struct bpf_verifier_env *env, int func_id, int insn
		return -EINVAL;
	}

	if (reg_type_may_be_null(regs[BPF_REG_0].type))
		regs[BPF_REG_0].id = ++env->id_gen;

	if (is_ptr_cast_function(func_id)) {
		/* For release_reference() */
		regs[BPF_REG_0].ref_obj_id = meta.ref_obj_id;
@@ -7212,7 +7210,8 @@ static void mark_ptr_or_null_reg(struct bpf_func_state *state,
				 struct bpf_reg_state *reg, u32 id,
				 bool is_null)
{
	if (reg_type_may_be_null(reg->type) && reg->id == id) {
	if (reg_type_may_be_null(reg->type) && reg->id == id &&
	    !WARN_ON_ONCE(!reg->id)) {
		/* Old offset (both fixed and variable parts) should
		 * have been known-zero, because we don't allow pointer
		 * arithmetic on pointers that might be NULL.
Loading