All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jiri Olsa <olsajiri@gmail.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>, Hao Luo <haoluo@google.com>,
	Andrew Morton <akpm@linux-foundation.org>,
	Alexander Viro <viro@zeniv.linux.org.uk>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Matthew Wilcox <willy@infradead.org>,
	bpf@vger.kernel.org, linux-mm@kvack.org,
	linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
	linux-perf-users@vger.kernel.org, Martin KaFai Lau <kafai@fb.com>,
	Song Liu <songliubraving@fb.com>, Yonghong Song <yhs@fb.com>,
	John Fastabend <john.fastabend@gmail.com>,
	KP Singh <kpsingh@chromium.org>,
	Stanislav Fomichev <sdf@google.com>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Namhyung Kim <namhyung@gmail.com>,
	Dave Chinner <david@fromorbit.com>
Subject: Re: [PATCHv3 bpf-next 5/9] selftests/bpf: Add read_buildid function
Date: Fri, 31 Mar 2023 00:05:28 +0200	[thread overview]
Message-ID: <ZCYHqBECVe4SAEr4@krava> (raw)
In-Reply-To: <CAEf4BzZpXK0_k0Z8BmAB1-Edpc_BZYsu5wt9XVEJ4ryAxDYewA@mail.gmail.com>

On Thu, Mar 16, 2023 at 03:23:03PM -0700, Andrii Nakryiko wrote:
> On Thu, Mar 16, 2023 at 10:03 AM Jiri Olsa <jolsa@kernel.org> wrote:
> >
> > Adding read_build_id function that parses out build id from
> > specified binary.
> >
> > It will replace extract_build_id and also be used in following
> > changes.
> >
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>

I'll send this separatelly as bpf/selftests fix so doesn't get lost

> > ---
> >  tools/testing/selftests/bpf/trace_helpers.c | 86 +++++++++++++++++++++
> >  tools/testing/selftests/bpf/trace_helpers.h |  5 ++
> >  2 files changed, 91 insertions(+)
> >
> > diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
> > index 934bf28fc888..72b38a41f574 100644
> > --- a/tools/testing/selftests/bpf/trace_helpers.c
> > +++ b/tools/testing/selftests/bpf/trace_helpers.c
> > @@ -11,6 +11,9 @@
> >  #include <linux/perf_event.h>
> >  #include <sys/mman.h>
> >  #include "trace_helpers.h"
> > +#include <linux/limits.h>
> > +#include <libelf.h>
> > +#include <gelf.h>
> >
> >  #define TRACEFS_PIPE   "/sys/kernel/tracing/trace_pipe"
> >  #define DEBUGFS_PIPE   "/sys/kernel/debug/tracing/trace_pipe"
> > @@ -234,3 +237,86 @@ ssize_t get_rel_offset(uintptr_t addr)
> >         fclose(f);
> >         return -EINVAL;
> >  }
> > +
> > +static int
> > +parse_build_id_buf(const void *note_start, Elf32_Word note_size,
> > +                  char *build_id)
> 
> nit: single line

ok

> 
> should we pass buffer size instead of assuming at least BPF_BUILD_ID_SIZE below?

ok

> 
> > +{
> > +       Elf32_Word note_offs = 0, new_offs;
> > +
> > +       while (note_offs + sizeof(Elf32_Nhdr) < note_size) {
> > +               Elf32_Nhdr *nhdr = (Elf32_Nhdr *)(note_start + note_offs);
> > +
> > +               if (nhdr->n_type == 3 && nhdr->n_namesz == sizeof("GNU") &&
> > +                   !strcmp((char *)(nhdr + 1), "GNU") && nhdr->n_descsz > 0 &&
> > +                   nhdr->n_descsz <= BPF_BUILD_ID_SIZE) {
> > +                       memcpy(build_id, note_start + note_offs +
> > +                              ALIGN(sizeof("GNU"), 4) + sizeof(Elf32_Nhdr), nhdr->n_descsz);
> > +                       memset(build_id + nhdr->n_descsz, 0, BPF_BUILD_ID_SIZE - nhdr->n_descsz);
> > +                       return (int) nhdr->n_descsz;
> > +               }
> > +
> > +               new_offs = note_offs + sizeof(Elf32_Nhdr) +
> > +                          ALIGN(nhdr->n_namesz, 4) + ALIGN(nhdr->n_descsz, 4);
> > +               if (new_offs >= note_size)
> > +                       break;
> 
> while condition() above would handle this, so this check appears not necessary?
> 
> so just assign note_offs directly?

good idea, it will simplify that

> 
> 
> > +               note_offs = new_offs;
> > +       }
> > +
> > +       return -EINVAL;
> 
> nit: -ENOENT or -ESRCH?

I kept the same error as is in kernel, but ENOENT makes more sense

> 
> > +}
> > +
> > +/* Reads binary from *path* file and returns it in the *build_id*
> > + * which is expected to be at least BPF_BUILD_ID_SIZE bytes.
> > + * Returns size of build id on success. On error the error value
> > + * is returned.
> > + */
> > +int read_build_id(const char *path, char *build_id)
> > +{
> > +       int fd, err = -EINVAL;
> > +       Elf *elf = NULL;
> > +       GElf_Ehdr ehdr;
> > +       size_t max, i;
> > +
> > +       fd = open(path, O_RDONLY | O_CLOEXEC);
> > +       if (fd < 0)
> > +               return -errno;
> > +
> > +       (void)elf_version(EV_CURRENT);
> > +
> > +       elf = elf_begin(fd, ELF_C_READ, NULL);
> 
> ELF_C_READ_MMAP ?

ok

> 
> > +       if (!elf)
> > +               goto out;
> > +       if (elf_kind(elf) != ELF_K_ELF)
> > +               goto out;
> > +       if (gelf_getehdr(elf, &ehdr) == NULL)
> 
> nit: !gelf_getehdr()

ok

> 
> > +               goto out;
> > +       if (ehdr.e_ident[EI_CLASS] != ELFCLASS64)
> > +               goto out;
> 
> does this have to be 64-bit specific?... you are using gelf stuff, you
> can be bitness-agnostic here

right, I don't think it's needed, will check

> 
> > +
> > +       for (i = 0; i < ehdr.e_phnum; i++) {
> > +               GElf_Phdr mem, *phdr;
> > +               char *data;
> > +
> > +               phdr = gelf_getphdr(elf, i, &mem);
> > +               if (!phdr)
> > +                       goto out;
> > +               if (phdr->p_type != PT_NOTE)
> > +                       continue;
> 
> I don't know where ELF + build ID spec is (if at all), but it seems to
> always be in the ".note.gnu.build-id" section, so should we check the
> name here?

this section name is not manadatory as stated in
  https://fedoraproject.org/wiki/RolandMcGrath/BuildID

  The new section is canonically called .note.gnu.build-id, but the name is not normative,
  and the section can be merged with other SHT_NOTE sections. The ELF note headers give
  name "GNU" and type 3 (NT_GNU_BUILD_ID) for a build ID note.

> 
> 
> > +               data = elf_rawfile(elf, &max);
> > +               if (!data)
> > +                       goto out;
> > +               if (phdr->p_offset >= max || (phdr->p_offset + phdr->p_memsz >= max))
> 
> `phdr->p_offset + phdr->p_memsz == max` would be fine, no?

right, will change

thanks,
jirka

> 
> > +                       goto out;
> > +               err = parse_build_id_buf(data + phdr->p_offset, phdr->p_memsz, build_id);
> > +               if (err > 0)
> > +                       goto out;
> > +               err = -EINVAL;
> > +       }
> > +
> > +out:
> > +       if (elf)
> > +               elf_end(elf);
> > +       close(fd);
> > +       return err;
> > +}
> > diff --git a/tools/testing/selftests/bpf/trace_helpers.h b/tools/testing/selftests/bpf/trace_helpers.h
> > index 53efde0e2998..bc3b92057033 100644
> > --- a/tools/testing/selftests/bpf/trace_helpers.h
> > +++ b/tools/testing/selftests/bpf/trace_helpers.h
> > @@ -4,6 +4,9 @@
> >
> >  #include <bpf/libbpf.h>
> >
> > +#define __ALIGN_MASK(x, mask)  (((x)+(mask))&~(mask))
> > +#define ALIGN(x, a)            __ALIGN_MASK(x, (typeof(x))(a)-1)
> > +
> >  struct ksym {
> >         long addr;
> >         char *name;
> > @@ -23,4 +26,6 @@ void read_trace_pipe(void);
> >  ssize_t get_uprobe_offset(const void *addr);
> >  ssize_t get_rel_offset(uintptr_t addr);
> >
> > +int read_build_id(const char *path, char *build_id);
> > +
> >  #endif
> > --
> > 2.39.2
> >

  reply	other threads:[~2023-03-30 22:07 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-16 17:01 [PATCHv3 bpf-next 0/9] mm/bpf/perf: Store build id in file object Jiri Olsa
2023-03-16 17:01 ` [PATCHv3 bpf-next 1/9] mm: " Jiri Olsa
2023-03-16 22:07   ` Andrii Nakryiko
2023-03-16 17:01 ` [PATCHv3 bpf-next 2/9] perf: Use file object build id in perf_event_mmap_event Jiri Olsa
2023-03-16 17:01 ` [PATCHv3 bpf-next 3/9] bpf: Use file object build id in stackmap Jiri Olsa
2023-03-16 22:07   ` Andrii Nakryiko
2023-03-16 17:01 ` [PATCHv3 bpf-next 4/9] bpf: Switch BUILD_ID_SIZE_MAX to enum Jiri Olsa
2023-03-16 22:07   ` Andrii Nakryiko
2023-03-16 17:01 ` [PATCHv3 bpf-next 5/9] selftests/bpf: Add read_buildid function Jiri Olsa
2023-03-16 22:23   ` Andrii Nakryiko
2023-03-30 22:05     ` Jiri Olsa [this message]
2023-03-16 17:01 ` [PATCHv3 bpf-next 6/9] selftests/bpf: Add err.h header Jiri Olsa
2023-03-16 22:24   ` Andrii Nakryiko
2023-03-16 17:01 ` [PATCHv3 bpf-next 7/9] selftests/bpf: Replace extract_build_id with read_build_id Jiri Olsa
2023-03-16 17:01 ` [PATCHv3 bpf-next 8/9] selftests/bpf: Add iter_task_vma_buildid test Jiri Olsa
2023-03-16 22:31   ` Andrii Nakryiko
2023-03-16 17:01 ` [PATCHv3 bpf-next 9/9] selftests/bpf: Add file_build_id test Jiri Olsa
2023-03-16 19:59   ` Daniel Borkmann
2023-03-16 22:36   ` Andrii Nakryiko
2023-03-16 17:34 ` [PATCHv3 bpf-next 0/9] mm/bpf/perf: Store build id in file object Matthew Wilcox
2023-03-16 17:50   ` Ian Rogers
2023-03-16 21:51     ` Andrii Nakryiko
2023-03-17  3:51       ` Matthew Wilcox
2023-03-17 16:33         ` Andrii Nakryiko
2023-03-17 21:14           ` Al Viro
2023-03-17 21:21             ` Al Viro
2023-03-18  6:08               ` Andrii Nakryiko
2023-03-18  8:34                 ` Jiri Olsa
2023-03-18  8:33   ` Jiri Olsa
2023-03-18 15:16     ` Matthew Wilcox
2023-03-18 17:40       ` Jiri Olsa
2023-03-22 15:45       ` Arnaldo Carvalho de Melo
2023-03-31 18:19         ` Andrii Nakryiko
2023-03-31 18:36           ` Matthew Wilcox
2023-03-31 20:27             ` Andrii Nakryiko

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=ZCYHqBECVe4SAEr4@krava \
    --to=olsajiri@gmail.com \
    --cc=acme@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=andrii.nakryiko@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=david@fromorbit.com \
    --cc=haoluo@google.com \
    --cc=john.fastabend@gmail.com \
    --cc=kafai@fb.com \
    --cc=kpsingh@chromium.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=namhyung@gmail.com \
    --cc=peterz@infradead.org \
    --cc=sdf@google.com \
    --cc=songliubraving@fb.com \
    --cc=viro@zeniv.linux.org.uk \
    --cc=willy@infradead.org \
    --cc=yhs@fb.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.