Commit 10a3b7c1 authored by David S. Miller's avatar David S. Miller
Browse files


Daniel Borkmann says:

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

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

We've added 23 non-merge commits during the last 4 day(s) which contain
a total of 32 files changed, 421 insertions(+), 141 deletions(-).

The main changes are:

1) Fix sock_ops ctx access splat due to register override, from John Fastabend.

2) Batch of various fixes to libbpf, bpftool, and selftests when testing build
   in 32-bit mode, from Andrii Nakryiko.

3) Fix vmlinux.h generation on ARM by mapping GCC built-in types (__Poly*_t)
   to equivalent ones clang can work with, from Jean-Philippe Brucker.

4) Fix build_id lookup in bpf_get_stackid() helper by walking all NOTE ELF
   sections instead of just first, from Jiri Olsa.

5) Avoid use of __builtin_offsetof() in libbpf for CO-RE, from Yonghong Song.

6) Fix segfault in test_mmap due to inconsistent length params, from Jianlin Lv.

7) Don't override errno in libbpf when logging errors, from Toke Høiland-Jørgensen.

8) Fix v4_to_v6 sockaddr conversion in sk_lookup test, from Stanislav Fomichev.

9) Add link to bpf-helpers(7) man page to BPF doc, from Joe Stringer.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c6165cf0 4fccd2ff
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -36,6 +36,12 @@ Two sets of Questions and Answers (Q&A) are maintained.
   bpf_devel_QA


Helper functions
================

* `bpf-helpers(7)`_ maintains a list of helpers available to eBPF programs.


Program types
=============

@@ -79,4 +85,5 @@ Other
.. _networking-filter: ../networking/filter.rst
.. _man-pages: https://www.kernel.org/doc/man-pages/
.. _bpf(2): https://man7.org/linux/man-pages/man2/bpf.2.html
.. _bpf-helpers(7): https://man7.org/linux/man-pages/man7/bpf-helpers.7.html
.. _BPF and XDP Reference Guide: https://docs.cilium.io/en/latest/bpf/
+14 −10
Original line number Diff line number Diff line
@@ -213,11 +213,13 @@ static int stack_map_get_build_id_32(void *page_addr,

	phdr = (Elf32_Phdr *)(page_addr + sizeof(Elf32_Ehdr));

	for (i = 0; i < ehdr->e_phnum; ++i)
		if (phdr[i].p_type == PT_NOTE)
			return stack_map_parse_build_id(page_addr, build_id,
	for (i = 0; i < ehdr->e_phnum; ++i) {
		if (phdr[i].p_type == PT_NOTE &&
		    !stack_map_parse_build_id(page_addr, build_id,
					      page_addr + phdr[i].p_offset,
					phdr[i].p_filesz);
					      phdr[i].p_filesz))
			return 0;
	}
	return -EINVAL;
}

@@ -236,11 +238,13 @@ static int stack_map_get_build_id_64(void *page_addr,

	phdr = (Elf64_Phdr *)(page_addr + sizeof(Elf64_Ehdr));

	for (i = 0; i < ehdr->e_phnum; ++i)
		if (phdr[i].p_type == PT_NOTE)
			return stack_map_parse_build_id(page_addr, build_id,
	for (i = 0; i < ehdr->e_phnum; ++i) {
		if (phdr[i].p_type == PT_NOTE &&
		    !stack_map_parse_build_id(page_addr, build_id,
					      page_addr + phdr[i].p_offset,
					phdr[i].p_filesz);
					      phdr[i].p_filesz))
			return 0;
	}
	return -EINVAL;
}

+4 −4
Original line number Diff line number Diff line
@@ -8913,10 +8913,6 @@ static int dev_xdp_attach(struct net_device *dev, struct netlink_ext_ack *extack
		NL_SET_ERR_MSG(extack, "Active program does not match expected");
		return -EEXIST;
	}
	if ((flags & XDP_FLAGS_UPDATE_IF_NOEXIST) && cur_prog) {
		NL_SET_ERR_MSG(extack, "XDP program already attached");
		return -EBUSY;
	}

	/* put effective new program into new_prog */
	if (link)
@@ -8927,6 +8923,10 @@ static int dev_xdp_attach(struct net_device *dev, struct netlink_ext_ack *extack
		enum bpf_xdp_mode other_mode = mode == XDP_MODE_SKB
					       ? XDP_MODE_DRV : XDP_MODE_SKB;

		if ((flags & XDP_FLAGS_UPDATE_IF_NOEXIST) && cur_prog) {
			NL_SET_ERR_MSG(extack, "XDP program already attached");
			return -EBUSY;
		}
		if (!offload && dev_xdp_prog(dev, other_mode)) {
			NL_SET_ERR_MSG(extack, "Native and generic XDP can't be active at the same time");
			return -EEXIST;
+62 −13
Original line number Diff line number Diff line
@@ -8317,15 +8317,31 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
/* Helper macro for adding read access to tcp_sock or sock fields. */
#define SOCK_OPS_GET_FIELD(BPF_FIELD, OBJ_FIELD, OBJ)			      \
	do {								      \
		int fullsock_reg = si->dst_reg, reg = BPF_REG_9, jmp = 2;     \
		BUILD_BUG_ON(sizeof_field(OBJ, OBJ_FIELD) >		      \
			     sizeof_field(struct bpf_sock_ops, BPF_FIELD));   \
		if (si->dst_reg == reg || si->src_reg == reg)		      \
			reg--;						      \
		if (si->dst_reg == reg || si->src_reg == reg)		      \
			reg--;						      \
		if (si->dst_reg == si->src_reg) {			      \
			*insn++ = BPF_STX_MEM(BPF_DW, si->src_reg, reg,	      \
					  offsetof(struct bpf_sock_ops_kern,  \
					  temp));			      \
			fullsock_reg = reg;				      \
			jmp += 2;					      \
		}							      \
		*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(			      \
						struct bpf_sock_ops_kern,     \
						is_fullsock),		      \
				      si->dst_reg, si->src_reg,		      \
				      fullsock_reg, si->src_reg,	      \
				      offsetof(struct bpf_sock_ops_kern,      \
					       is_fullsock));		      \
		*insn++ = BPF_JMP_IMM(BPF_JEQ, si->dst_reg, 0, 2);	      \
		*insn++ = BPF_JMP_IMM(BPF_JEQ, fullsock_reg, 0, jmp);	      \
		if (si->dst_reg == si->src_reg)				      \
			*insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,	      \
				      offsetof(struct bpf_sock_ops_kern,      \
				      temp));				      \
		*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(			      \
						struct bpf_sock_ops_kern, sk),\
				      si->dst_reg, si->src_reg,		      \
@@ -8334,6 +8350,49 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
						       OBJ_FIELD),	      \
				      si->dst_reg, si->dst_reg,		      \
				      offsetof(OBJ, OBJ_FIELD));	      \
		if (si->dst_reg == si->src_reg)	{			      \
			*insn++ = BPF_JMP_A(1);				      \
			*insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,	      \
				      offsetof(struct bpf_sock_ops_kern,      \
				      temp));				      \
		}							      \
	} while (0)

#define SOCK_OPS_GET_SK()							      \
	do {								      \
		int fullsock_reg = si->dst_reg, reg = BPF_REG_9, jmp = 1;     \
		if (si->dst_reg == reg || si->src_reg == reg)		      \
			reg--;						      \
		if (si->dst_reg == reg || si->src_reg == reg)		      \
			reg--;						      \
		if (si->dst_reg == si->src_reg) {			      \
			*insn++ = BPF_STX_MEM(BPF_DW, si->src_reg, reg,	      \
					  offsetof(struct bpf_sock_ops_kern,  \
					  temp));			      \
			fullsock_reg = reg;				      \
			jmp += 2;					      \
		}							      \
		*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(			      \
						struct bpf_sock_ops_kern,     \
						is_fullsock),		      \
				      fullsock_reg, si->src_reg,	      \
				      offsetof(struct bpf_sock_ops_kern,      \
					       is_fullsock));		      \
		*insn++ = BPF_JMP_IMM(BPF_JEQ, fullsock_reg, 0, jmp);	      \
		if (si->dst_reg == si->src_reg)				      \
			*insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,	      \
				      offsetof(struct bpf_sock_ops_kern,      \
				      temp));				      \
		*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(			      \
						struct bpf_sock_ops_kern, sk),\
				      si->dst_reg, si->src_reg,		      \
				      offsetof(struct bpf_sock_ops_kern, sk));\
		if (si->dst_reg == si->src_reg)	{			      \
			*insn++ = BPF_JMP_A(1);				      \
			*insn++ = BPF_LDX_MEM(BPF_DW, reg, si->src_reg,	      \
				      offsetof(struct bpf_sock_ops_kern,      \
				      temp));				      \
		}							      \
	} while (0)

#define SOCK_OPS_GET_TCP_SOCK_FIELD(FIELD) \
@@ -8620,17 +8679,7 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
		SOCK_OPS_GET_TCP_SOCK_FIELD(bytes_acked);
		break;
	case offsetof(struct bpf_sock_ops, sk):
		*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
						struct bpf_sock_ops_kern,
						is_fullsock),
				      si->dst_reg, si->src_reg,
				      offsetof(struct bpf_sock_ops_kern,
					       is_fullsock));
		*insn++ = BPF_JMP_IMM(BPF_JEQ, si->dst_reg, 0, 1);
		*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(
						struct bpf_sock_ops_kern, sk),
				      si->dst_reg, si->src_reg,
				      offsetof(struct bpf_sock_ops_kern, sk));
		SOCK_OPS_GET_SK();
		break;
	}
	return insn - insn_buf;
+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ static int dump_prog_id_as_func_ptr(const struct btf_dumper *d,
	if (!info->btf_id || !info->nr_func_info ||
	    btf__get_from_id(info->btf_id, &prog_btf))
		goto print;
	finfo = (struct bpf_func_info *)info->func_info;
	finfo = u64_to_ptr(info->func_info);
	func_type = btf__type_by_id(prog_btf, finfo->type_id);
	if (!func_type || !btf_is_func(func_type))
		goto print;
Loading