All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrii Nakryiko <andrii.nakryiko@gmail.com>
To: Jiri Olsa <olsajiri@gmail.com>
Cc: Alan Maguire <alan.maguire@oracle.com>,
	acme@kernel.org, dwarves@vger.kernel.org, andrii@kernel.org,
	bpf@vger.kernel.org
Subject: Re: [PATCH dwarves] dwarves: zero-initialize struct cu in cu__new() to prevent incorrect BTF types
Date: Fri, 21 Oct 2022 09:35:50 -0700	[thread overview]
Message-ID: <CAEf4BzbtRqkcx8CHBqdXXWmWLeX-zsrEYMy_CgL7i48PTYjCNg@mail.gmail.com> (raw)
In-Reply-To: <Y1LJlPBQauNS/xkX@krava>

On Fri, Oct 21, 2022 at 9:32 AM Jiri Olsa <olsajiri@gmail.com> wrote:
>
> On Fri, Oct 21, 2022 at 04:02:03PM +0100, Alan Maguire wrote:
> > BTF deduplication was throwing some strange results, where core kernel
> > data types were failing to deduplicate due to the return values
> > of function type members being void (0) instead of the actual type
> > (unsigned int).  An example of this can be seen below, where
> > "struct dst_ops" was failing to deduplicate between kernel and
> > module:
> >
> > struct dst_ops {
> >         short unsigned int family;
> >         unsigned int gc_thresh;
> >         int (*gc)(struct dst_ops *);
> >         struct dst_entry * (*check)(struct dst_entry *, __u32);
> >         unsigned int (*default_advmss)(const struct dst_entry *);
> >         unsigned int (*mtu)(const struct dst_entry *);
> > ...
> >
> > struct dst_ops___2 {
> >         short unsigned int family;
> >         unsigned int gc_thresh;
> >         int (*gc)(struct dst_ops___2 *);
> >         struct dst_entry___2 * (*check)(struct dst_entry___2 *, __u32);
> >         void (*default_advmss)(const struct dst_entry___2 *);
> >         void (*mtu)(const struct dst_entry___2 *);
> > ...
> >
> > This was seen with
> >
> > bcc648a10cbc ("btf_encoder: Encode DW_TAG_unspecified_type returning routines as void")
> >
> > ...which rewrites the return value as 0 (void) when it is marked
> > as matching DW_TAG_unspecified_type:
> >
> > static int32_t btf_encoder__tag_type(struct btf_encoder *encoder, uint32_t type_id_off, uint32_t tag_type)
> > {
> >        if (tag_type == 0)
> >                return 0;
> >
> >        if (encoder->cu->unspecified_type.tag && tag_type == encoder->cu->unspecified_type.type) {
> >                // No provision for encoding this, turn it into void.
> >                return 0;
> >        }
> >
> >        return type_id_off + tag_type;
> > }
> >
> > However the odd thing was that on further examination, the unspecified type
> > was not being set, so why was this logic being tripped?  Futher debugging
> > showed that the encoder->cu->unspecified_type.tag value was garbage, and
> > the type id happened to collide with "unsigned int"; as a result we
> > were replacing unsigned ints with void return values, and since this
> > was being done to function type members in structs, it triggered a
> > type mismatch which failed deduplication between kernel and module.
> >
> > The fix is simply to calloc() the cu in cu__new() instead.
> >
> > Fixes: bcc648a10cbc ("btf_encoder: Encode DW_TAG_unspecified_type returning routines as void")
> > Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
>
> awesome, this fixes the missing dedup I was seeing
> with current pahole:
>
>         $ bpftool btf dump file ./vmlinux.test | grep "STRUCT 'task_struct'" | wc -l
>         69
>
> with this patch:
>
>         $ bpftool btf dump file ./vmlinux.test | grep "STRUCT 'task_struct'" | wc -l
>         1
>

Nice and a great catch! I generally try to stick to calloc() in libbpf
exactly so I don't have to worry about stuff like this.

Acked-by: Andrii Nakryiko <andrii@kernel.org>

>
> Acked-by: Jiri Olsa <jolsa@kernel.org>
>
> thanks,
> jirka
>
>
> > ---
> >  dwarves.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/dwarves.c b/dwarves.c
> > index fbebc1d..424381d 100644
> > --- a/dwarves.c
> > +++ b/dwarves.c
> > @@ -626,7 +626,7 @@ struct cu *cu__new(const char *name, uint8_t addr_size,
> >                  const unsigned char *build_id, int build_id_len,
> >                  const char *filename, bool use_obstack)
> >  {
> > -     struct cu *cu = malloc(sizeof(*cu) + build_id_len);
> > +     struct cu *cu = calloc(1, sizeof(*cu) + build_id_len);
> >
> >       if (cu != NULL) {
> >               uint32_t void_id;
> > --
> > 2.31.1
> >

  reply	other threads:[~2022-10-21 16:36 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-21 15:02 [PATCH dwarves] dwarves: zero-initialize struct cu in cu__new() to prevent incorrect BTF types Alan Maguire
2022-10-21 16:32 ` Jiri Olsa
2022-10-21 16:35   ` Andrii Nakryiko [this message]
2022-10-21 18:37     ` Arnaldo Carvalho de Melo
2022-10-21 20:12       ` Alan Maguire

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=CAEf4BzbtRqkcx8CHBqdXXWmWLeX-zsrEYMy_CgL7i48PTYjCNg@mail.gmail.com \
    --to=andrii.nakryiko@gmail.com \
    --cc=acme@kernel.org \
    --cc=alan.maguire@oracle.com \
    --cc=andrii@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=dwarves@vger.kernel.org \
    --cc=olsajiri@gmail.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.