On Mon, Nov 19, 2018 at 5:28 PM Quentin Monnet
<quentin.mon...@netronome.com> wrote:
>
> In order to compare BPF map symbol type correctly in regard to the
> latest LLVM, commit 7a04dd84a7f9 ("bpf: check map symbol type properly
> with newer llvm compiler") compares map symbol type to both NOTYPE and
> OBJECT. To do so, it first retrieves the type from "sym.st_info" and
> stores it into a temporary variable.
>
> However, the type is collected from the symbol "sym" before this latter
> symbol is actually updated. gelf_getsym() is called after that and
> updates "sym", and when comparison with OBJECT or NOTYPE happens it is
> done on the type of the symbol collected in the previous passage of the
> loop (or on an uninitialised symbol on the first passage). This may
> eventually break map collection from the ELF file.
>
> Fix this by assigning the type to the temporary variable only after the
> call to gelf_getsym().
>
> Fixes: 7a04dd84a7f9 ("bpf: check map symbol type properly with newer llvm 
> compiler")
> Reported-by: Ron Philip <ron.phi...@netronome.com>
> Signed-off-by: Quentin Monnet <quentin.mon...@netronome.com>
> Reviewed-by: Jiong Wang <jiong.w...@netronome.com>

Thanks for the fix!
Acked-by: Yonghong Song <y...@fb.com>

> ---
>  lib/bpf.c | 10 +++++++---
>  1 file changed, 7 insertions(+), 3 deletions(-)
>
> diff --git a/lib/bpf.c b/lib/bpf.c
> index 45f279fa4a41..6aff8f7bad7f 100644
> --- a/lib/bpf.c
> +++ b/lib/bpf.c
> @@ -1758,11 +1758,12 @@ static const char *bpf_map_fetch_name(struct 
> bpf_elf_ctx *ctx, int which)
>         int i;
>
>         for (i = 0; i < ctx->sym_num; i++) {
> -               int type = GELF_ST_TYPE(sym.st_info);
> +               int type;
>
>                 if (gelf_getsym(ctx->sym_tab, i, &sym) != &sym)
>                         continue;
>
> +               type = GELF_ST_TYPE(sym.st_info);
>                 if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
>                     (type != STT_NOTYPE && type != STT_OBJECT) ||
>                     sym.st_shndx != ctx->sec_maps ||
> @@ -1851,11 +1852,12 @@ static int bpf_map_num_sym(struct bpf_elf_ctx *ctx)
>         GElf_Sym sym;
>
>         for (i = 0; i < ctx->sym_num; i++) {
> -               int type = GELF_ST_TYPE(sym.st_info);
> +               int type;
>
>                 if (gelf_getsym(ctx->sym_tab, i, &sym) != &sym)
>                         continue;
>
> +               type = GELF_ST_TYPE(sym.st_info);
>                 if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
>                     (type != STT_NOTYPE && type != STT_OBJECT) ||
>                     sym.st_shndx != ctx->sec_maps)
> @@ -1931,10 +1933,12 @@ static int bpf_map_verify_all_offs(struct bpf_elf_ctx 
> *ctx, int end)
>                  * the table again.
>                  */
>                 for (i = 0; i < ctx->sym_num; i++) {
> -                       int type = GELF_ST_TYPE(sym.st_info);
> +                       int type;
>
>                         if (gelf_getsym(ctx->sym_tab, i, &sym) != &sym)
>                                 continue;
> +
> +                       type = GELF_ST_TYPE(sym.st_info);
>                         if (GELF_ST_BIND(sym.st_info) != STB_GLOBAL ||
>                             (type != STT_NOTYPE && type != STT_OBJECT) ||
>                             sym.st_shndx != ctx->sec_maps)
> --
> 2.7.4
>

Reply via email to