aboutsummaryrefslogtreecommitdiffstats
path: root/tools/lib/bpf/libbpf.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/lib/bpf/libbpf.c')
-rw-r--r--tools/lib/bpf/libbpf.c34
1 files 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 {
201 Elf_Data *data; 201 Elf_Data *data;
202 } *reloc; 202 } *reloc;
203 int nr_reloc; 203 int nr_reloc;
204 int maps_shndx;
204 } efile; 205 } efile;
205 /* 206 /*
206 * All loaded bpf_object is linked in a list, which is 207 * 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,
350 */ 351 */
351 obj->efile.obj_buf = obj_buf; 352 obj->efile.obj_buf = obj_buf;
352 obj->efile.obj_buf_sz = obj_buf_sz; 353 obj->efile.obj_buf_sz = obj_buf_sz;
354 obj->efile.maps_shndx = -1;
353 355
354 obj->loaded = false; 356 obj->loaded = false;
355 357
@@ -529,12 +531,12 @@ bpf_object__init_maps(struct bpf_object *obj, void *data,
529} 531}
530 532
531static int 533static int
532bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx) 534bpf_object__init_maps_name(struct bpf_object *obj)
533{ 535{
534 int i; 536 int i;
535 Elf_Data *symbols = obj->efile.symbols; 537 Elf_Data *symbols = obj->efile.symbols;
536 538
537 if (!symbols || maps_shndx < 0) 539 if (!symbols || obj->efile.maps_shndx < 0)
538 return -EINVAL; 540 return -EINVAL;
539 541
540 for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) { 542 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)
544 546
545 if (!gelf_getsym(symbols, i, &sym)) 547 if (!gelf_getsym(symbols, i, &sym))
546 continue; 548 continue;
547 if (sym.st_shndx != maps_shndx) 549 if (sym.st_shndx != obj->efile.maps_shndx)
548 continue; 550 continue;
549 551
550 map_name = elf_strptr(obj->efile.elf, 552 map_name = elf_strptr(obj->efile.elf,
@@ -572,7 +574,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
572 Elf *elf = obj->efile.elf; 574 Elf *elf = obj->efile.elf;
573 GElf_Ehdr *ep = &obj->efile.ehdr; 575 GElf_Ehdr *ep = &obj->efile.ehdr;
574 Elf_Scn *scn = NULL; 576 Elf_Scn *scn = NULL;
575 int idx = 0, err = 0, maps_shndx = -1; 577 int idx = 0, err = 0;
576 578
577 /* Elf is corrupted/truncated, avoid calling elf_strptr. */ 579 /* Elf is corrupted/truncated, avoid calling elf_strptr. */
578 if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL)) { 580 if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL)) {
@@ -625,7 +627,7 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
625 else if (strcmp(name, "maps") == 0) { 627 else if (strcmp(name, "maps") == 0) {
626 err = bpf_object__init_maps(obj, data->d_buf, 628 err = bpf_object__init_maps(obj, data->d_buf,
627 data->d_size); 629 data->d_size);
628 maps_shndx = idx; 630 obj->efile.maps_shndx = idx;
629 } else if (sh.sh_type == SHT_SYMTAB) { 631 } else if (sh.sh_type == SHT_SYMTAB) {
630 if (obj->efile.symbols) { 632 if (obj->efile.symbols) {
631 pr_warning("bpf: multiple SYMTAB in %s\n", 633 pr_warning("bpf: multiple SYMTAB in %s\n",
@@ -674,8 +676,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
674 pr_warning("Corrupted ELF file: index of strtab invalid\n"); 676 pr_warning("Corrupted ELF file: index of strtab invalid\n");
675 return LIBBPF_ERRNO__FORMAT; 677 return LIBBPF_ERRNO__FORMAT;
676 } 678 }
677 if (maps_shndx >= 0) 679 if (obj->efile.maps_shndx >= 0)
678 err = bpf_object__init_maps_name(obj, maps_shndx); 680 err = bpf_object__init_maps_name(obj);
679out: 681out:
680 return err; 682 return err;
681} 683}
@@ -697,7 +699,8 @@ bpf_object__find_prog_by_idx(struct bpf_object *obj, int idx)
697static int 699static int
698bpf_program__collect_reloc(struct bpf_program *prog, 700bpf_program__collect_reloc(struct bpf_program *prog,
699 size_t nr_maps, GElf_Shdr *shdr, 701 size_t nr_maps, GElf_Shdr *shdr,
700 Elf_Data *data, Elf_Data *symbols) 702 Elf_Data *data, Elf_Data *symbols,
703 int maps_shndx)
701{ 704{
702 int i, nrels; 705 int i, nrels;
703 706
@@ -724,9 +727,6 @@ bpf_program__collect_reloc(struct bpf_program *prog,
724 return -LIBBPF_ERRNO__FORMAT; 727 return -LIBBPF_ERRNO__FORMAT;
725 } 728 }
726 729
727 insn_idx = rel.r_offset / sizeof(struct bpf_insn);
728 pr_debug("relocation: insn_idx=%u\n", insn_idx);
729
730 if (!gelf_getsym(symbols, 730 if (!gelf_getsym(symbols,
731 GELF_R_SYM(rel.r_info), 731 GELF_R_SYM(rel.r_info),
732 &sym)) { 732 &sym)) {
@@ -735,6 +735,15 @@ bpf_program__collect_reloc(struct bpf_program *prog,
735 return -LIBBPF_ERRNO__FORMAT; 735 return -LIBBPF_ERRNO__FORMAT;
736 } 736 }
737 737
738 if (sym.st_shndx != maps_shndx) {
739 pr_warning("Program '%s' contains non-map related relo data pointing to section %u\n",
740 prog->section_name, sym.st_shndx);
741 return -LIBBPF_ERRNO__RELOC;
742 }
743
744 insn_idx = rel.r_offset / sizeof(struct bpf_insn);
745 pr_debug("relocation: insn_idx=%u\n", insn_idx);
746
738 if (insns[insn_idx].code != (BPF_LD | BPF_IMM | BPF_DW)) { 747 if (insns[insn_idx].code != (BPF_LD | BPF_IMM | BPF_DW)) {
739 pr_warning("bpf: relocation: invalid relo for insns[%d].code 0x%x\n", 748 pr_warning("bpf: relocation: invalid relo for insns[%d].code 0x%x\n",
740 insn_idx, insns[insn_idx].code); 749 insn_idx, insns[insn_idx].code);
@@ -863,7 +872,8 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
863 872
864 err = bpf_program__collect_reloc(prog, nr_maps, 873 err = bpf_program__collect_reloc(prog, nr_maps,
865 shdr, data, 874 shdr, data,
866 obj->efile.symbols); 875 obj->efile.symbols,
876 obj->efile.maps_shndx);
867 if (err) 877 if (err)
868 return err; 878 return err;
869 } 879 }