lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <Z0caqvFFmkL9I6lk@x1>
Date: Wed, 27 Nov 2024 10:12:10 -0300
From: Arnaldo Carvalho de Melo <acme@...nel.org>
To: Namhyung Kim <namhyung@...nel.org>
Cc: Linus Torvalds <torvalds@...ux-foundation.org>,
	Ian Rogers <irogers@...gle.com>,
	Kan Liang <kan.liang@...ux.intel.com>,
	Peter Zijlstra <peterz@...radead.org>,
	Ingo Molnar <mingo@...nel.org>, LKML <linux-kernel@...r.kernel.org>,
	linux-perf-users@...r.kernel.org
Subject: Re: [GIT PULL] perf-tools changes for v6.13

On Tue, Nov 26, 2024 at 07:25:08PM -0800, Namhyung Kim wrote:
> On Tue, Nov 26, 2024 at 09:59:44PM -0300, Arnaldo Carvalho de Melo wrote:
> > On Tue, Nov 26, 2024 at 04:00:12PM -0800, Namhyung Kim wrote:
> > > On Tue, Nov 26, 2024 at 03:33:10PM -0800, Linus Torvalds wrote:
> > > > Hmm. Has the default search path for the vmlinux image changed?

> > > I don't think so.

> > > > Doing profiling with this, I get

> > > >     openat(AT_FDCWD, "vmlinux", O_RDONLY)   = 5

> > > > which is very very wrong for my kernel build - it basically picks up
> > > > the vmlinux image from the build directory, which has absolutely
> > > > *nothign* to do with the image that is being run at the moment.

> > > Sure, at least it should match the build-id before use.

> > I tried it here and at first I reproduced Linus results, which I found

I understand it now, first, when I tried to reproduce Linus case I did a
'perf record' with the most recent code, the one failing for Linus, but
then when I tried to test it with v6.1, trying to bisect it, perf v6.1
couldn't process the perf.data file generated "in the future", by
v6.12-rc6 + perf-tools:

# perf report -v
file uses a more recent and unsupported ABI (8 bytes extra)
incompatible file format (rerun with -v to learn more)
#

So I did another 'perf record' and used that perf.data, that had no
problems all the way to v6.12-rc6, it works, the bug was introduced
recently making it not able to checking the build-id in the vmlinux
file, as there is nothing to compare it with, no build-id in the
perf.data file.

root@...ber:/home/acme/git/perf-tools# perf -v
perf version 6.12.gb50ecc5aca4d
root@...ber:/home/acme/git/perf-tools# perf record -a sleep 2s
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 2.442 MB perf.data (8953 samples) ]
root@...ber:/home/acme/git/perf-tools# perf -v ; strace -e openat -o /tmp/strace.output perf report -vv |& grep -A5 "^Looking at the vmlinux_path" ; grep '"vmlinux"' -B1 -A10 /tmp/strace.output 
perf version 6.12.gb50ecc5aca4d
Looking at the vmlinux_path (8 entries long)
Using vmlinux for symbols
<SNIP>
root@...ber:/home/acme/git/perf-tools#

So I redid the bisection, this time doing a fresh perf record at each
step and got to:

⬢ [acme@...lbox linux]$ git bisect bad
ae39ba16554eb4a2d97f752847e93aa428438912 is the first bad commit
commit ae39ba16554eb4a2d97f752847e93aa428438912 (HEAD)
Author: Ian Rogers <irogers@...gle.com>
Date:   Mon Sep 9 13:37:37 2024 -0700

    perf inject: Fix build ID injection
    
    Build ID injection wasn't inserting a sample ID and aligning events to
    64 bytes rather than 8. No sample ID means events are unordered and two
    different build_id events for the same path, as happens when a file is
    replaced, can't be differentiated.
    
    Add in sample ID insertion for the build_id events alongside some
    refactoring. The refactoring better aligns the function arguments for
    different use cases, such as synthesizing build_id events without
    needing to have a dso. The misc bits are explicitly passed as with
    callchains the maps/dsos may span user and kernel land, so using
    sample->cpumode isn't good enough.
    
    Signed-off-by: Ian Rogers <irogers@...gle.com>
    Acked-by: Namhyung Kim <namhyung@...nel.org>
    Cc: Adrian Hunter <adrian.hunter@...el.com>
    Cc: Alexander Shishkin <alexander.shishkin@...ux.intel.com>
    Cc: Anne Macedo <retpolanne@...teo.net>
    Cc: Casey Chen <cachen@...estorage.com>
    Cc: Colin Ian King <colin.i.king@...il.com>
    Cc: Ingo Molnar <mingo@...hat.com>
    Cc: Jiri Olsa <jolsa@...nel.org>
    Cc: Kan Liang <kan.liang@...ux.intel.com>
    Cc: Mark Rutland <mark.rutland@....com>
    Cc: Peter Zijlstra <peterz@...radead.org>
    Cc: Sun Haiyong <sunhaiyong@...ngson.cn>
    Link: https://lore.kernel.org/r/20240909203740.143492-2-irogers@google.com
    Signed-off-by: Arnaldo Carvalho de Melo <acme@...hat.com>

⬢ [acme@...lbox linux]$ git tag --contains ae39ba16554eb4a2d97f752847e93aa428438912 | grep ^v6.
v6.12
v6.12-rc1
v6.12-rc2
v6.12-rc3
v6.12-rc4
v6.12-rc5
v6.12-rc6
v6.12-rc7
⬢ [acme@...lbox linux]$

Which matches what Namhyung found. A plain revert doesn't work,
Namhyung's patch below fixes it for me, with it:

# perf -v ; perf record -a sleep 2s ; perf buildid-list | grep 'vmlinux\|kallsyms' ; perf report -vv |& grep -A2 "^Looking at the vmlinux_path"
perf version 6.12.g25425b03a8d7
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 2.095 MB perf.data (3738 samples) ]
55152ddca5da77ca62deb3dd0db105e82b3711e0 [kernel.kallsyms]
Looking at the vmlinux_path (8 entries long)
symsrc__init: build id mismatch for vmlinux.
symsrc__init: cannot get elf header.
#

It refuses that bogus "vmlinux" in the current directory, and since my
machine has no matching vmlinux, it fallbacks to recording the running
kernel build id as "[kernel.kallsyms]" and will use it for resolving
symbols.

If I install the matching vmlinux using 'dnf debuginfo-install kernel':

# perf -v ; perf record -a sleep 2s ; perf report -vv |& grep -A2 "^Looking at the vmlinux_path"
perf version 6.12.g25425b03a8d7
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 2.116 MB perf.data (4278 samples) ]
Looking at the vmlinux_path (8 entries long)
symsrc__init: build id mismatch for vmlinux.
Using /usr/lib/debug/lib/modules/6.11.8-200.fc40.x86_64/vmlinux for symbols
# file /usr/lib/debug/lib/modules/6.11.8-200.fc40.x86_64/vmlinux
/usr/lib/debug/lib/modules/6.11.8-200.fc40.x86_64/vmlinux: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=55152ddca5da77ca62deb3dd0db105e82b3711e0, with debug_info, not stripped
# perf buildid-list -h -k

 Usage: perf buildid-list [<options>]

    -k, --kernel          Show current kernel build id

root@...ber:/home/acme/git/perf-tools# perf buildid-list -k
55152ddca5da77ca62deb3dd0db105e82b3711e0
root@...ber:/home/acme/git/perf-tools#

It will find the right file and use it.

So, for Namhyung's patch below:

Tested-by: Arnaldo Carvalho de Melo <acme@...hat.com>

Now to write another 'perf test' to cover this...

- Arnaldo

> > very strange, then I tried to bisect it, and all the previous versions
> > were producing this:
> > 
> > root@...ber:/home/acme/git/perf-tools# perf -v ; perf report -vv |& grep -A5 "^Looking at the vmlinux_path"
> > perf version 6.12.gb50ecc5aca4d
> > Looking at the vmlinux_path (8 entries long)
> > symsrc__init: build id mismatch for vmlinux.
> > symsrc__init: cannot get elf header.
> > overlapping maps:
> >  ffffffffc034b75c-ffffffffc034b89b 0 bpf_prog_40ddf486530245f5_sd_devices
> >  ffffffffc0000000-ffffffffff000000 7fffc0004000 vmlinux
> > root@...ber:/home/acme/git/perf-tools#
> > 
> > Which is what I got from the perf-tools branch you asked him to pull.
> > 
> > The algorithm in perf is similar to the one in pahole (that stole it
> > from perf):
> > 
> > root@...ber:/home/acme/git/perf-tools# strace -e openat pahole --running_kernel_vmlinux |& tail -12
> > openat(AT_FDCWD, "/sys/kernel/notes", O_RDONLY) = 3
> > openat(AT_FDCWD, "vmlinux", O_RDONLY)   = 3
> > openat(AT_FDCWD, "/boot/vmlinux", O_RDONLY) = -1 ENOENT (No such file or directory)
> > openat(AT_FDCWD, "/boot/vmlinux-6.11.8-200.fc40.x86_64", O_RDONLY) = -1 ENOENT (No such file or directory)
> > openat(AT_FDCWD, "/usr/lib/debug/boot/vmlinux-6.11.8-200.fc40.x86_64", O_RDONLY) = -1 ENOENT (No such file or directory)
> > openat(AT_FDCWD, "/lib/modules/6.11.8-200.fc40.x86_64/build/vmlinux", O_RDONLY) = -1 ENOENT (No such file or directory)
> > openat(AT_FDCWD, "/usr/lib/debug/lib/modules/6.11.8-200.fc40.x86_64/vmlinux", O_RDONLY) = -1 ENOENT (No such file or directory)
> > openat(AT_FDCWD, "/usr/lib/debug/boot/vmlinux-6.11.8-200.fc40.x86_64.debug", O_RDONLY) = -1 ENOENT (No such file or directory)
> > openat(AT_FDCWD, "/root/.cache/debuginfod_client/55152ddca5da77ca62deb3dd0db105e82b3711e0/debuginfo", O_RDONLY) = -1 ENOENT (No such file or directory)
> > pahole: couldn't find a vmlinux that matches the running kernel
> > HINT: Maybe you're inside a container or missing a debuginfo package?
> > +++ exited with 1 +++
> > root@...ber:/home/acme/git/perf-tools#
> > 
> > The one in perf does very much the same:
> > 
> > root@...ber:/home/acme/git/perf-tools# perf -v ; strace -e openat -o /tmp/strace.output perf report -vv |& grep -A5 "^Looking at the vmlinux_path" ; grep '"vmlinux"' -B1 -A10 /tmp/strace.output 
> > perf version 6.12.gb50ecc5aca4d
> > Looking at the vmlinux_path (8 entries long)
> > symsrc__init: build id mismatch for vmlinux.
> > symsrc__init: cannot get elf header.
> > overlapping maps:
> >  ffffffffc034b75c-ffffffffc034b89b 0 bpf_prog_40ddf486530245f5_sd_devices
> >  ffffffffc0000000-ffffffffff000000 7fffc0004000 vmlinux
> > openat(AT_FDCWD, "/root/.debug/.build-id/55/152ddca5da77ca62deb3dd0db105e82b3711e0/elf", O_RDONLY) = -1 ENOENT (No such file or directory)
> > openat(AT_FDCWD, "vmlinux", O_RDONLY)   = 142
> > openat(AT_FDCWD, "/boot/vmlinux", O_RDONLY) = -1 ENOENT (No such file or directory)
> > openat(AT_FDCWD, "/boot/vmlinux-6.11.8-200.fc40.x86_64", O_RDONLY) = -1 ENOENT (No such file or directory)
> > openat(AT_FDCWD, "/usr/lib/debug/boot/vmlinux-6.11.8-200.fc40.x86_64", O_RDONLY) = -1 ENOENT (No such file or directory)
> > openat(AT_FDCWD, "/lib/modules/6.11.8-200.fc40.x86_64/build/vmlinux", O_RDONLY) = -1 ENOENT (No such file or directory)
> > openat(AT_FDCWD, "/usr/lib/debug/lib/modules/6.11.8-200.fc40.x86_64/vmlinux", O_RDONLY) = -1 ENOENT (No such file or directory)
> > openat(AT_FDCWD, "/usr/lib/debug/boot/vmlinux-6.11.8-200.fc40.x86_64.debug", O_RDONLY) = -1 ENOENT (No such file or directory)
> > openat(AT_FDCWD, "/root/.debug/.build-id/55/152ddca5da77ca62deb3dd0db105e82b3711e0/kallsyms", O_RDONLY) = 142
> > openat(AT_FDCWD, "/sys/kernel/notes", O_RDONLY) = 142
> > openat(AT_FDCWD, "/proc/kcore", O_RDONLY) = 142
> > openat(AT_FDCWD, "/proc/kallsyms", O_RDONLY) = 142
> > root@...ber:/home/acme/git/perf-tools# 
> > root@...ber:/home/acme/git/perf-tools# perf buildid-list -h -k
> > 
> >  Usage: perf buildid-list [<options>]
> > 
> >     -k, --kernel          Show current kernel build id
> > 
> > root@...ber:/home/acme/git/perf-tools# perf buildid-list -k
> > 55152ddca5da77ca62deb3dd0db105e82b3711e0
> > root@...ber:/home/acme/git/perf-tools# file vmlinux 
> > vmlinux: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, BuildID[sha1]=e86cad482822bd4b4caabb01e7cd00161fd51a38, with debug_info, not stripped
> > root@...ber:/home/acme/git/perf-tools#
> > 
> > And it ends up using /proc/kallsyms
> > 
> > Today I did some bisects, etc, but even with at first reproducing what
> > Linus described, i.e. it used the non-matching vmlinux in the current
> > directory to resolve symbols, I couldn't reproduce it after trying to
> > bisect it :-\
> >  
> > > > So now I need to point "perf report" at the actual image, which I
> > > > didn't need to do before.
> > > 
> > > Ok, I'll try to reproduce it and take a look.
> > 
> > Hope you root cause this, late in this part of the world, going AFK now.
> 
> I think it's a bug in perf record since v6.12.  I found the build-id
> event in the header area is broken.  Can you verify if this works?
> 
> Thanks,
> Namhyung
> 
> ---8<---
> >From 62ebc7de4c306d99f39af847bee4a2aab05b0f93 Mon Sep 17 00:00:00 2001
> From: Namhyung Kim <namhyung@...nel.org>
> Date: Tue, 26 Nov 2024 19:13:31 -0800
> Subject: [PATCH] perf tools: Fix build-id event recording
> 
> The build-id events written at the end of the record session are broken
> due to unexpected data.  The write_buildid() writes the fixed length
> event first and then variable length filename.
> 
> But a recent change made it write more data in the padding area
> accidentally.  So readers of the event see zero-filled data for the
> next entry and treat it incorrectly.   This resulted in wrong kernel
> symbols because the kernel DSO loaded a random vmlinux image in the
> path as it didn't have a valid build-id.
> 
> Fixes: ae39ba16554e ("perf inject: Fix build ID injection")
> Reported-by: Linus Torvalds <torvalds@...ux-foundation.org>
> Signed-off-by: Namhyung Kim <namhyung@...nel.org>
> ---
>  tools/perf/util/build-id.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
> index 8982f68e7230cd64..e763e8d99a4367d7 100644
> --- a/tools/perf/util/build-id.c
> +++ b/tools/perf/util/build-id.c
> @@ -277,7 +277,7 @@ static int write_buildid(const char *name, size_t name_len, struct build_id *bid
>  	struct perf_record_header_build_id b;
>  	size_t len;
>  
> -	len = sizeof(b) + name_len + 1;
> +	len = name_len + 1;
>  	len = PERF_ALIGN(len, sizeof(u64));
>  
>  	memset(&b, 0, sizeof(b));
> @@ -286,7 +286,7 @@ static int write_buildid(const char *name, size_t name_len, struct build_id *bid
>  	misc |= PERF_RECORD_MISC_BUILD_ID_SIZE;
>  	b.pid = pid;
>  	b.header.misc = misc;
> -	b.header.size = len;
> +	b.header.size = sizeof(b) + len;
>  
>  	err = do_write(fd, &b, sizeof(b));
>  	if (err < 0)
> -- 
> 2.47.0.338.g60cca15819-goog
> 

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ