From: Ihor Solodrai <ihor.solodrai@linux.dev>
To: Jiangshan Yi <yijiangshan@kylinos.cn>,
ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
eddyz87@gmail.com, memxor@gmail.com
Cc: martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev,
jolsa@kernel.org, emil@etsalapatis.com, paul.chaignon@gmail.com,
bpf@vger.kernel.org, linux-kernel@vger.kernel.org,
13667453960@163.com
Subject: Re: [PATCH] tools/resolve_btfids: fix OUTPUT leakage from kselftest causing corrupted build paths
Date: Thu, 16 Jul 2026 16:45:27 -0700 [thread overview]
Message-ID: <0ffd26d2-a5f1-4c4c-9f4a-13809f9eb94e@linux.dev> (raw)
In-Reply-To: <20260716085733.1761196-1-yijiangshan@kylinos.cn>
On 7/16/26 1:57 AM, Jiangshan Yi wrote:
> When building kselftest-all, the kselftest Makefile passes OUTPUT as a
> command-line variable to each test directory:
>
> tools/testing/selftests/Makefile:
> $(MAKE) OUTPUT=$$BUILD/$$TARGET -C $$TARGET
>
> GNU Make automatically exports command-line variables to all sub-makes.
> This OUTPUT propagates through the entire build chain:
>
> kselftest/mm (OUTPUT=.../selftests/mm)
> -> gen_mods_dir -> page_frag (kernel module build)
> -> tools/bpf/resolve_btfids (host tool dependency)
>
> The resolve_btfids Makefile uses a conditional assignment:
>
> OUTPUT ?= $(srctree)/tools/bpf/resolve_btfids/
>
> However, ?= cannot override a variable inherited from a parent build's
> command line or environment. The inherited OUTPUT points to the wrong
> directory (the mm selftest directory) and lacks a trailing slash.
>
> The tools/build Makefile.build system concatenates $(OUTPUT) with
> filenames without a separating slash in its pattern rules:
>
> $(OUTPUT)%.o: %.c FORCE
>
> When OUTPUT lacks a trailing '/', this produces corrupted paths such
> as ".../selftests/mmmain.o" instead of ".../selftests/mm/main.o".
> Meanwhile, the resolve_btfids Makefile itself uses $(OUTPUT)/filename
> (with an explicit slash), so the HOSTLD step produces the file at a
> different path than where the LINK step looks for it:
>
> HOSTLD produces: .../selftests/mmresolve_btfids-in.o (no slash)
> LINK looks for: .../selftests/mm/resolve_btfids-in.o (with slash)
>
> This results in a linker error:
>
> ld: cannot find .../resolve_btfids-in.o: No such file or directory
>
> Fix this by checking the origin of OUTPUT. When it is "command line"
> or "environment" (indicating leakage from a parent build such as
> kselftest), use 'override' to reset it to the correct directory. When
> built normally via the kernel build system, OUTPUT is set by
> scripts/Makefile.include with origin "file" from the O= parameter,
> which is correct and remains unaffected.
>
> The fix can be reproduced and verified with:
>
> make -C tools/bpf/resolve_btfids clean
> # Before fix: fails with corrupted paths
> make OUTPUT=/path/to/selftests/mm -C tools/bpf/resolve_btfids
> # After fix: succeeds, artifacts in resolve_btfids directory
>
> # Also test environment variable leakage:
> OUTPUT=/path/to/selftests/mm make -C tools/bpf/resolve_btfids
>
> Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
> ---
> tools/bpf/resolve_btfids/Makefile | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/tools/bpf/resolve_btfids/Makefile b/tools/bpf/resolve_btfids/Makefile
> index 7672208f65e4..eee88c73fd7a 100644
> --- a/tools/bpf/resolve_btfids/Makefile
> +++ b/tools/bpf/resolve_btfids/Makefile
> @@ -26,6 +26,22 @@ HOSTAR ?= ar
> HOSTPKG_CONFIG ?= pkg-config
> CROSS_COMPILE =
>
> +# If OUTPUT was inherited from a parent build's command line (e.g. from
> +# kselftest), it points to the wrong directory and may lack a trailing
> +# slash. The tools/build Makefile.build concatenates $(OUTPUT) with
> +# filenames without a separating slash ($(OUTPUT)%.o), so a missing
> +# trailing '/' produces corrupted paths such as "mmmain.o" instead of
> +# "mm/main.o", and the linker cannot find resolve_btfids-in.o.
> +#
> +# When built via the kernel build system, OUTPUT is set by
> +# scripts/Makefile.include (origin "file") from the O= parameter, which
> +# is correct. Only a command-line origin indicates leakage from a
> +# parent build and needs to be reset. Both "command line" and
> +# "environment" origins indicate leakage; "file" (set by Makefile.include
> +# from O=) and "undefined" are legitimate and must not be overridden.
> +ifneq ($(filter command line environment,$(origin OUTPUT)),)
> +override OUTPUT := $(srctree)/tools/bpf/resolve_btfids/
> +endif
> OUTPUT ?= $(srctree)/tools/bpf/resolve_btfids/
This seems to be a real bug, but the proposed diff is just wrong.
It doesn't even fix the case you target.
The `override` runs in the outer make, but the corruption happens in
the nested sub-make (resolve_btfids/Makefile:105):
$(BINARY_IN): fixdep FORCE prepare | $(OUTPUT)
$(Q)$(MAKE) $(build)=resolve_btfids
Try this:
$ cat parent.mk
ifneq ($(filter command line environment,$(origin OUTPUT)),)
override OUTPUT := /correct/
endif
export OUTPUT
all: ; @$(MAKE) --no-print-directory -f child.mk
$ cat child.mk
all: ; @echo "OUTPUT=[$(OUTPUT)] -> $(OUTPUT)main.o"
$ make -f parent.mk OUTPUT=/leaked/mm
OUTPUT=[/leaked/mm] -> /leaked/mmmain.o # override invisible; still broken
Your standalone repro probably only succeeds on a dirty tree.
Have you tried testing from clean?
Also bpf/Makefile:440 and hid/Makefile:159 deliberately pass
OUTPUT=$(HOST_BUILD_DIR)/resolve_btfids/ on the command line.
And so the patch breaks those too:
$ mkdir -p /tmp/o/resolve_btfids && make -C tools/bpf/resolve_btfids clean \
&& make -C tools/bpf/resolve_btfids OUTPUT=/tmp/o/resolve_btfids/
...
make[1]: *** No rule to make target '.../resolve_btfids/fixdep'. Stop.
make: *** [.../tools/build/Makefile.include:15: fixdep] Error 2
I think a proper fix is to figure out a way to avoid generic OUTPUT to
fall through to resolve_btids (somewhere in selftests/lib.mk
probably).
Please make sure to test your change properly before submitting.
pw-bot: cr
>
> LIBBPF_SRC := $(srctree)/tools/lib/bpf/
next prev parent reply other threads:[~2026-07-16 23:45 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-16 8:57 [PATCH] tools/resolve_btfids: fix OUTPUT leakage from kselftest causing corrupted build paths Jiangshan Yi
2026-07-16 9:09 ` sashiko-bot
2026-07-16 23:45 ` Ihor Solodrai [this message]
2026-07-17 10:14 ` Jiangshan Yi
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=0ffd26d2-a5f1-4c4c-9f4a-13809f9eb94e@linux.dev \
--to=ihor.solodrai@linux.dev \
--cc=13667453960@163.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=paul.chaignon@gmail.com \
--cc=song@kernel.org \
--cc=yijiangshan@kylinos.cn \
--cc=yonghong.song@linux.dev \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox