BPF List
 help / color / mirror / Atom feed
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/


  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