diff options
Diffstat (limited to 'tools/lib/bpf/libbpf.c')
-rw-r--r-- | tools/lib/bpf/libbpf.c | 34 |
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 | ||
531 | static int | 533 | static int |
532 | bpf_object__init_maps_name(struct bpf_object *obj, int maps_shndx) | 534 | bpf_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); |
679 | out: | 681 | out: |
680 | return err; | 682 | return err; |
681 | } | 683 | } |
@@ -697,7 +699,8 @@ bpf_object__find_prog_by_idx(struct bpf_object *obj, int idx) | |||
697 | static int | 699 | static int |
698 | bpf_program__collect_reloc(struct bpf_program *prog, | 700 | bpf_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 | } |