bpftrace: link test data source binary without host runtime

The build host HOME directory check recently added to OE-Core's
buildpaths QA test flags the ptest gtest binary:

WARNING: bpftrace-0.25.1-r0 do_package_qa: QA Issue: File
/usr/lib/bpftrace/ptest/tests/bpftrace_test in package bpftrace-ptest
contains a reference to the build host HOME directory. [buildpaths]

WARNING: bpftrace-0.25.1-r0 do_package_qa: QA Issue: File
/usr/lib/bpftrace/ptest/tests/.debug/bpftrace_test in package
bpftrace-dbg contains a reference to the build host HOME directory.
[buildpaths]

cmake/BuildBPF.cmake links the intermediate DWARF carrier binary
data_source_exe with the plain build host gcc, which bakes the host
dynamic loader's absolute path into the PT_INTERP segment. With a
distro gcc that is an innocuous /lib64/ld-linux-x86-64.so.2, but when
the host toolchain is a buildtools-extended/SDK gcc installed under
the build user's home directory (as on the autobuilder workers), it
is a $HOME-prefixed path like

  /srv/pokybuild/.../buildtools/sysroots/x86_64-pokysdk-linux/lib/ld-linux-x86-64.so.2

The executable is then embedded byte-for-byte into bpftrace_test via
embed()/xxd (tests/data/CMakeLists.txt), so the path ends up in the
test binary's .rodata, triggering the bpftrace-ptest warning. And
because cmake/Embed.tmpl declares the embedded blob as a constexpr
array, gcc additionally copies its contents into .debug_info as
DW_AT_const_value, which is how the same string survives
objcopy --only-keep-debug into the split debug file, triggering the
bpftrace-dbg warning. This is the same embedding mechanism that
previously leaked TMPDIR paths, fixed for the compile step by the
DEBUG_PREFIX_MAP patch; the link step was still leaking.

The tests only write this binary to a temp file and use it as a
uprobe target (tests/dwarf_common.h), parsing its DWARF and symbols;
it is never executed. So link it with -nostdlib -no-pie -Wl,--entry=0:
no interpreter, no host crt objects, no dynamic segment, and thus
nothing host-specific in the embedded blob. Function symbols, DWARF
type information and the pahole -J BTF encoding step are unaffected,
and the field_analyser_dwarf ptests still pass.

Because the object is now linked -nostdlib it must not reference the
libc stack-protector runtime. Host gcc toolchains that default to
-fstack-protector-strong (e.g. Debian/Ubuntu and the Yocto
autobuilder workers) otherwise leave an undefined reference and the
link fails:

  ld: data_source.o: in function `main':
  data_source.c:212: undefined reference to `__stack_chk_fail'
  collect2: error: ld returned 1 exit status

Compile the object and link the binary with -fno-stack-protector; the
canary is irrelevant to a DWARF/BTF carrier that is never run.

Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
This commit is contained in:
Khem Raj
2026-07-02 23:04:39 -07:00
parent ebde9459c8
commit e8b8f3ddd9
2 changed files with 79 additions and 0 deletions
@@ -0,0 +1,78 @@
From: Khem Raj <khem.raj@oss.qualcomm.com>
Date: Thu, 2 Jul 2026 15:30:00 -0700
Subject: [PATCH] cmake/BuildBPF.cmake: link data source binary without host
runtime
The `bpf()` helper links the intermediate DWARF carrier binary
(data_source_exe) with the plain host gcc:
${GCC} -g -o data_source_exe data_source.o
and the resulting executable is then embedded byte-for-byte into
bpftrace_test via embed()/xxd (tests/data/CMakeLists.txt). Linking it as
a regular dynamic executable bakes host-toolchain artifacts into it:
* PT_INTERP: the absolute path of the host toolchain's dynamic
loader. With a vendored/SDK toolchain (e.g. Yocto
buildtools-extended installed under the build user's home) this is
an absolute build-host path such as
/srv/pokybuild/.../buildtools/sysroots/x86_64-pokysdk-linux/lib/ld-linux-x86-64.so.2
* crt startup objects (crt1.o, crti.o, crtbegin.o) including whatever
debug info the host libc was built with.
Since the embedded blob carries these strings into the packaged test
binary, the build is not reproducible across hosts and leaks build host
paths, flagged by OE's buildpaths QA check:
WARNING: bpftrace-0.25.1-r0 do_package_qa: QA Issue: File
/usr/lib/bpftrace/ptest/tests/bpftrace_test in package bpftrace-ptest
contains a reference to the build host HOME directory. [buildpaths]
The binary only serves as a DWARF/BTF container: the tests write it to
a temp file and use it as a uprobe target (tests/dwarf_common.h), which
parses debug info and symbols but never executes it. So link it with
-nostdlib -no-pie: no interpreter, no dynamic segment, no host crt
code. -Wl,--entry=0 silences the "cannot find entry symbol _start"
warning. All function symbols, DWARF type information and the
pahole -J BTF encoding step are unaffected.
Because the object is now linked -nostdlib, it must not emit references
to the libc stack-protector runtime. Host gcc toolchains that default to
-fstack-protector-strong (e.g. Debian/Ubuntu, the Yocto autobuilders)
otherwise leave an undefined reference and the link fails:
ld: data_source.o: in function `main':
data_source.c:212: undefined reference to `__stack_chk_fail'
collect2: error: ld returned 1 exit status
Compile the object (and link the binary) with -fno-stack-protector; the
canary is irrelevant to a DWARF/BTF carrier that is never run.
Upstream-Status: Pending
Signed-off-by: Khem Raj <khem.raj@oss.qualcomm.com>
---
cmake/BuildBPF.cmake | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/cmake/BuildBPF.cmake b/cmake/BuildBPF.cmake
index cb8cd68..8aa059f 100644
--- a/cmake/BuildBPF.cmake
+++ b/cmake/BuildBPF.cmake
@@ -90,7 +90,7 @@ function(bpf NAME)
OUTPUT ${ARG_OBJECT}
DEPENDS ${ARG_SOURCE} ${ARG_DEPENDS}
# See above: fresh compilation and the use of `gcc`.
- COMMAND ${GCC} -Wno-attributes -g -I ${CMAKE_CURRENT_BINARY_DIR} -c ${CMAKE_CURRENT_SOURCE_DIR}/${ARG_SOURCE} -o ${CMAKE_CURRENT_BINARY_DIR}/${ARG_OBJECT}
+ COMMAND ${GCC} -Wno-attributes -fno-stack-protector -g -I ${CMAKE_CURRENT_BINARY_DIR} -c ${CMAKE_CURRENT_SOURCE_DIR}/${ARG_SOURCE} -o ${CMAKE_CURRENT_BINARY_DIR}/${ARG_OBJECT}
COMMAND cmake -E env LLVM_OBJCOPY=${LLVM_OBJCOPY} ${PAHOLE} -J ${CMAKE_CURRENT_BINARY_DIR}/${ARG_OBJECT}
VERBATIM
)
@@ -107,7 +107,7 @@ function(bpf NAME)
add_custom_command(
OUTPUT ${ARG_BINARY}
DEPENDS ${ARG_SOURCE} ${NAME}_gen_object
- COMMAND ${GCC} -g -o ${CMAKE_CURRENT_BINARY_DIR}/${ARG_BINARY} ${CMAKE_CURRENT_BINARY_DIR}/${ARG_OBJECT}
+ COMMAND ${GCC} -g -fno-stack-protector -nostdlib -no-pie -Wl,--entry=0 -o ${CMAKE_CURRENT_BINARY_DIR}/${ARG_BINARY} ${CMAKE_CURRENT_BINARY_DIR}/${ARG_OBJECT}
COMMAND cmake -E env LLVM_OBJCOPY=${LLVM_OBJCOPY} ${PAHOLE} -J ${CMAKE_CURRENT_BINARY_DIR}/${ARG_BINARY}
VERBATIM
)
@@ -19,6 +19,7 @@ SRC_URI = "git://github.com/iovisor/bpftrace;branch=release/0.25.x;protocol=http
file://run-ptest \ file://run-ptest \
file://0002-CMakeLists.txt-allow-to-set-BISON_FLAGS-like-l.patch \ file://0002-CMakeLists.txt-allow-to-set-BISON_FLAGS-like-l.patch \
file://0001-cmake-BuildBPF.cmake-introduce-DEBUG_PREFIX_MAP.patch \ file://0001-cmake-BuildBPF.cmake-introduce-DEBUG_PREFIX_MAP.patch \
file://0003-cmake-BuildBPF.cmake-link-data-source-binary-without.patch \
" "
SRCREV = "e491811e5d648288c01f42ce087967b271f504a0" SRCREV = "e491811e5d648288c01f42ce087967b271f504a0"