linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: linux-kernel@vger.kernel.org, Wang Nan <wangnan0@huawei.com>,
	"David S. Miller" <davem@davemloft.net>,
	Brendan Gregg <brendan.d.gregg@gmail.com>,
	Daniel Borkmann <daniel@iogearbox.net>,
	He Kuang <hekuang@huawei.com>, Jiri Olsa <jolsa@kernel.org>,
	Li Zefan <lizefan@huawei.com>,
	Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>,
	Namhyung Kim <namhyung@kernel.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Will Deacon <will.deacon@arm.com>,
	pi3orama@163.com, Arnaldo Carvalho de Melo <acme@redhat.com>
Subject: [PATCH 22/26] perf bpf: Check relocation target section
Date: Tue, 26 Jan 2016 16:19:11 -0300	[thread overview]
Message-ID: <1453835955-14224-23-git-send-email-acme@kernel.org> (raw)
In-Reply-To: <1453835955-14224-1-git-send-email-acme@kernel.org>

From: Wang Nan <wangnan0@huawei.com>

Libbpf should check the target section before doing relocation to ensure
the relocation is correct. If not, a bug in LLVM causes an error. See
[1].  Also, if an incorrect BPF script uses both global variable and
map, global variable whould be treated as map and be relocated without
error.

This patch saves the id of the map section into obj->efile and compare
target section of a relocation symbol against it during relocation.

Previous patch introduces a test case about this problem.  After this
patch:

  # ~/perf test BPF
  37: Test BPF filter                                          :
  37.1: Test basic BPF filtering                               : Ok
  37.2: Test BPF prologue generation                           : Ok
  37.3: Test BPF relocation checker                            : Ok

  # perf test -v BPF
  ...
  37.3: Test BPF relocation checker                            :
  ...
  libbpf: loading object '[bpf_relocation_test]' from buffer
  libbpf: section .strtab, size 126, link 0, flags 0, type=3
  libbpf: section .text, size 0, link 0, flags 6, type=1
  libbpf: section .data, size 0, link 0, flags 3, type=1
  libbpf: section .bss, size 0, link 0, flags 3, type=8
  libbpf: section func=sys_write, size 104, link 0, flags 6, type=1
  libbpf: found program func=sys_write
  libbpf: section .relfunc=sys_write, size 16, link 10, flags 0, type=9
  libbpf: section maps, size 16, link 0, flags 3, type=1
  libbpf: maps in [bpf_relocation_test]: 16 bytes
  libbpf: section license, size 4, link 0, flags 3, type=1
  libbpf: license of [bpf_relocation_test] is GPL
  libbpf: section version, size 4, link 0, flags 3, type=1
  libbpf: kernel version of [bpf_relocation_test] is 40400
  libbpf: section .symtab, size 144, link 1, flags 0, type=2
  libbpf: map 0 is "my_table"
  libbpf: collecting relocating info for: 'func=sys_write'
  libbpf: Program 'func=sys_write' contains non-map related relo data pointing to section 65522
  bpf: failed to load buffer
  Compile BPF program failed.
  test child finished with 0
  ---- end ----
  Test BPF filter subtest 2: Ok

[1] https://llvm.org/bugs/show_bug.cgi?id=26243

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: He Kuang <hekuang@huawei.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Li Zefan <lizefan@huawei.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1453715801-7732-3-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/lib/bpf/libbpf.c | 34 ++++++++++++++++++++++------------
 1 file changed, 22 insertions(+), 12 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 8334a5a9d5d7..7e543c3102d4 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -201,6 +201,7 @@ struct bpf_object {
 			Elf_Data *data;
 		} *reloc;
 		int nr_reloc;
+		int maps_shndx;
 	} efile;
 	/*
 	 * All loaded bpf_object is linked in a list, which is
@@ -350,6 +351,7 @@ static struct bpf_object *bpf_object__new(const char *path,
 	 */
 	obj->efile.obj_buf = obj_buf;
 	obj->efile.obj_buf_sz = obj_buf_sz;
+	obj->efile.maps_shndx = -1;
 
 	obj->loaded = false;
 
@@ -529,12 +531,12 @@ bpf_object__init_maps(struct bpf_object *obj, void *data,
 }
 
 static int
-bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx)
+bpf_object__init_maps_name(struct bpf_object *obj)
 {
 	int i;
 	Elf_Data *symbols = obj->efile.symbols;
 
-	if (!symbols || maps_shndx < 0)
+	if (!symbols || obj->efile.maps_shndx < 0)
 		return -EINVAL;
 
 	for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) {
@@ -544,7 +546,7 @@ bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx)
 
 		if (!gelf_getsym(symbols, i, &sym))
 			continue;
-		if (sym.st_shndx != maps_shndx)
+		if (sym.st_shndx != obj->efile.maps_shndx)
 			continue;
 
 		map_name = elf_strptr(obj->efile.elf,
@@ -572,7 +574,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
 	Elf *elf = obj->efile.elf;
 	GElf_Ehdr *ep = &obj->efile.ehdr;
 	Elf_Scn *scn = NULL;
-	int idx = 0, err = 0, maps_shndx = -1;
+	int idx = 0, err = 0;
 
 	/* Elf is corrupted/truncated, avoid calling elf_strptr. */
 	if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL)) {
@@ -625,7 +627,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
 		else if (strcmp(name, "maps") == 0) {
 			err = bpf_object__init_maps(obj, data->d_buf,
 						    data->d_size);
-			maps_shndx = idx;
+			obj->efile.maps_shndx = idx;
 		} else if (sh.sh_type == SHT_SYMTAB) {
 			if (obj->efile.symbols) {
 				pr_warning("bpf: multiple SYMTAB in %s\n",
@@ -674,8 +676,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
 		pr_warning("Corrupted ELF file: index of strtab invalid\n");
 		return LIBBPF_ERRNO__FORMAT;
 	}
-	if (maps_shndx >= 0)
-		err = bpf_object__init_maps_name(obj, maps_shndx);
+	if (obj->efile.maps_shndx >= 0)
+		err = bpf_object__init_maps_name(obj);
 out:
 	return err;
 }
@@ -697,7 +699,8 @@ bpf_object__find_prog_by_idx(struct bpf_object *obj, int idx)
 static int
 bpf_program__collect_reloc(struct bpf_program *prog,
 			   size_t nr_maps, GElf_Shdr *shdr,
-			   Elf_Data *data, Elf_Data *symbols)
+			   Elf_Data *data, Elf_Data *symbols,
+			   int maps_shndx)
 {
 	int i, nrels;
 
@@ -724,9 +727,6 @@ bpf_program__collect_reloc(struct bpf_program *prog,
 			return -LIBBPF_ERRNO__FORMAT;
 		}
 
-		insn_idx = rel.r_offset / sizeof(struct bpf_insn);
-		pr_debug("relocation: insn_idx=%u\n", insn_idx);
-
 		if (!gelf_getsym(symbols,
 				 GELF_R_SYM(rel.r_info),
 				 &sym)) {
@@ -735,6 +735,15 @@ bpf_program__collect_reloc(struct bpf_program *prog,
 			return -LIBBPF_ERRNO__FORMAT;
 		}
 
+		if (sym.st_shndx != maps_shndx) {
+			pr_warning("Program '%s' contains non-map related relo data pointing to section %u\n",
+				   prog->section_name, sym.st_shndx);
+			return -LIBBPF_ERRNO__RELOC;
+		}
+
+		insn_idx = rel.r_offset / sizeof(struct bpf_insn);
+		pr_debug("relocation: insn_idx=%u\n", insn_idx);
+
 		if (insns[insn_idx].code != (BPF_LD | BPF_IMM | BPF_DW)) {
 			pr_warning("bpf: relocation: invalid relo for insns[%d].code 0x%x\n",
 				   insn_idx, insns[insn_idx].code);
@@ -863,7 +872,8 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
 
 		err = bpf_program__collect_reloc(prog, nr_maps,
 						 shdr, data,
-						 obj->efile.symbols);
+						 obj->efile.symbols,
+						 obj->efile.maps_shndx);
 		if (err)
 			return err;
 	}
-- 
2.5.0

  parent reply	other threads:[~2016-01-26 19:19 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-01-26 19:18 [PATCH 00/26] perf/core improvements and fixes Arnaldo Carvalho de Melo
2016-01-26 19:18 ` [PATCH 01/26] perf pmu: Fix misleadingly indented assignment (whitespace) Arnaldo Carvalho de Melo
2016-01-26 19:18 ` [PATCH 02/26] perf symbols: Do not read symbols/data from device files Arnaldo Carvalho de Melo
2016-01-26 19:18 ` [PATCH 03/26] perf stat: Making several helper functions static Arnaldo Carvalho de Melo
2016-01-26 19:18 ` [PATCH 04/26] perf hists: Remove parent filter check in DSO filter function Arnaldo Carvalho de Melo
2016-01-26 19:18 ` [PATCH 05/26] perf hists: Cleanup filtering functions Arnaldo Carvalho de Melo
2016-01-26 19:18 ` [PATCH 06/26] perf tools: Document the perf sysctls Arnaldo Carvalho de Melo
2016-01-26 19:18 ` [PATCH 07/26] perf annotate: Rename 'colors.code' to 'colors.jump_arrows' Arnaldo Carvalho de Melo
2016-01-26 19:18 ` [PATCH 08/26] perf config: Document variables for 'colors' section in man page Arnaldo Carvalho de Melo
2016-01-26 19:18 ` [PATCH 09/26] perf config: Document variables for 'tui' and 'gtk' sections " Arnaldo Carvalho de Melo
2016-01-26 19:18 ` [PATCH 10/26] perf config: Document 'buildid.dir' variable " Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 11/26] perf config: Document variables for 'annotate' section " Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 12/26] perf config: Document 'hist.percentage' variable " Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 13/26] perf sort: Provide a way to find out if per-thread bucketing is in place Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 14/26] perf hists browser: Only 'Zoom into thread' only when sort order has 'pid' Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 15/26] perf hists browser: Only offer symbol scripting when a symbol is under the cursor Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 16/26] perf hists browser: Offer 'Zoom into DSO'/'Map details' only when sort order has 'dso' Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 17/26] perf hists browser: Be a bit more strict about presenting CPU socket zoom Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 18/26] perf hists browser: Offer non-symbol specific menu options for --sort without 'sym' Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 19/26] perf machine: Introduce machine__find_kernel_symbol_by_name() Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 20/26] perf test: Fixup aliases checking in the 'vmlinux matches kallsyms' test Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 21/26] perf test: Add libbpf relocation checker Arnaldo Carvalho de Melo
2016-01-26 19:19 ` Arnaldo Carvalho de Melo [this message]
2016-01-26 19:19 ` [PATCH 23/26] tools build: Allow subprojects select all feature checkers Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 24/26] perf build: Select all feature checkers for feature-dump Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 25/26] perf hists browser: Skip scripting when perf.data file not available Arnaldo Carvalho de Melo
2016-01-26 19:19 ` [PATCH 26/26] perf cpumap: Auto initialize cpu__max_{node,cpu} Arnaldo Carvalho de Melo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1453835955-14224-23-git-send-email-acme@kernel.org \
    --to=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=brendan.d.gregg@gmail.com \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=hekuang@huawei.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=lizefan@huawei.com \
    --cc=masami.hiramatsu.pt@hitachi.com \
    --cc=mingo@kernel.org \
    --cc=namhyung@kernel.org \
    --cc=peterz@infradead.org \
    --cc=pi3orama@163.com \
    --cc=wangnan0@huawei.com \
    --cc=will.deacon@arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).