Skip to content

fix: skip /tmp extraction when profiling libraries are installed#529

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 9 commits into
mainfrom
r1viollet/fix-tmp-extraction
Apr 2, 2026
Merged

fix: skip /tmp extraction when profiling libraries are installed#529
gh-worker-dd-mergequeue-cf854d[bot] merged 9 commits into
mainfrom
r1viollet/fix-tmp-extraction

Conversation

@r1viollet

@r1viollet r1viollet commented Mar 30, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

When ddprof is installed as a package, skip writing executables and shared libraries to /tmp. Security scanners like CrowdStrike Falcon flag new executables in /tmp, and the extraction is pointless when
the files already sit in standard system paths.

The loader constructor tries dlopen with the bare library name before falling back to /tmp extraction. After a successful bare-name dlopen, it verifies the loaded library's build version matches via a
new ddprof_profiling_version() symbol to prevent version mismatches between a stale system install and the injected library.

Version macros (VER_MAJ/MIN/PATCH/REV) are now propagated to all profiling library targets so the version string is consistent across the loader, embedded lib, and shared lib.

Two bugs affecting Alpine Linux (musl) are also fixed:

ensure_loader_symbols_promoted() failed on musl. The loader re-opens itself with RTLD_NOLOAD | RTLD_GLOBAL to promote ddprof_lib_state (initial-exec TLS) to global scope before loading the embedded .so.
On musl, RTLD_NOLOAD with a bare SONAME always fails because musl tracks loaded libraries by full path, not SONAME. Fixed by using dladdr() to obtain the loader's actual on-disk path at runtime.

ddprof binary not found when using an installed libdd_profiling-embedded.so. The standalone embedded lib does not contain the ddprof binary (profiler_exe_data() returns size=0), so the previous fallback
left DD_PROFILING_NATIVE_DDPROF_EXE unset. The loader now searches for ddprof relative to its own path: <loader_dir>/../bin/ddprof (package install layout) and <loader_dir>/ddprof (flat build layout),
falling back to extraction from the loader's own embedded data.

The loader() constructor is refactored into three helpers (try_load_installed_profiling_lib, setup_ddprof_exe_for_installed_lib, load_embedded_profiling_lib) and a new test (loader_installed_lib-ut.sh)
covers both path layouts.

Motivation

fix for the following issue

Additional Notes

This now requires the library + the executable to be installed
exe should be:

  • in same directory ./
  • in ../bin/

How to test the change?

Describe here in detail how the change can be validated. This is a great section to call out specific tests you've added or improved, or to acknowledge code sections which are particularly difficult to test.

@r1viollet
r1viollet marked this pull request as ready for review March 30, 2026 11:30
@r1viollet
r1viollet requested a review from nsavoire as a code owner March 30, 2026 11:30
Comment thread src/lib/loader.c Outdated
Comment thread src/lib/loader.c Outdated
Comment thread src/lib/dd_profiling.cc Outdated
@nsavoire

Copy link
Copy Markdown
Collaborator

exec_ddprof gains a similar PATH fallback (execvp), scoped to only fire when no explicit exe path was set, avoiding version mismatches between the extracted .so and a different ddprof binary found in PATH.

I don't see this part ?

@r1viollet

Copy link
Copy Markdown
Collaborator Author

exec_ddprof gains a similar PATH fallback (execvp), scoped to only fire when no explicit exe path was set, avoiding version mismatches between the extracted .so and a different ddprof binary found in PATH.

I don't see this part ?

sorry, I removed that part, I am not sure we want this

@r1viollet

Copy link
Copy Markdown
Collaborator Author

Setting as draft until I get time to get back to this and fix some of the comments from Nicolas.

@r1viollet
r1viollet marked this pull request as draft March 30, 2026 12:56
Comment thread src/lib/loader.c Outdated
Comment thread src/lib/dd_profiling.cc Outdated
Comment thread test/version_mismatch-ut.sh
When ddprof is installed as a package, skip writing executables and
shared libraries to /tmp. Security scanners like CrowdStrike Falcon
flag new executables in /tmp, and the extraction is pointless when the
files already sit in standard system paths.

The loader constructor tries dlopen with the bare library name before
falling back to /tmp extraction. After a successful bare-name dlopen,
it verifies the loaded library's build version matches via a new
ddprof_profiling_version() symbol to prevent version mismatches between
a stale system install and the injected library.

Version macros (VER_MAJ/MIN/PATCH/REV) are now propagated to all
profiling library targets so the version string is consistent across
the loader, embedded lib, and shared lib.

Based on original work by Xavier Roche <[email protected]>.

Co-Authored-By: Xavier Roche <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@r1viollet
r1viollet force-pushed the r1viollet/fix-tmp-extraction branch from 26099e7 to a95cde6 Compare March 31, 2026 13:40
r1viollet and others added 2 commits March 31, 2026 16:59
…alled lib

Split the monolithic loader() constructor into three focused helpers:
- try_load_installed_profiling_lib(): silent dlopen + version check
- setup_ddprof_exe_for_installed_lib(): find ddprof via relative paths
- load_embedded_profiling_lib(): extract lib+exe to /tmp

Fix ensure_loader_symbols_promoted() to use dladdr() for the RTLD_NOLOAD
call so it works on musl (which tracks libs by full path, not SONAME).

Fix exe discovery when using an installed libdd_profiling-embedded.so:
the standalone lib does not embed the ddprof binary, so the loader now
searches for it relative to its own path:
  1. <loader_dir>/../bin/ddprof  (standard install layout)
  2. <loader_dir>/ddprof         (flat build/dev layout)
with a fallback to extracting from the loader's own embedded data.

Add loader_installed_lib-ut.sh to test both layout cases.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@r1viollet
r1viollet marked this pull request as ready for review March 31, 2026 16:58
@r1viollet

Copy link
Copy Markdown
Collaborator Author

this would require a documentation update once we merge

Comment thread test/CMakeLists.txt
r1viollet and others added 2 commits April 1, 2026 09:35
dladdr lives in libdl.so. Like dlopen/dlsym, it may be absent when the
loader is dlopen'd into a process that has not yet loaded libdl (e.g.
Ubuntu 16 minimal environments), causing an "undefined symbol: dladdr"
crash at load time.

Add a weak declaration and NULL-guard every call site.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This speeds up the install test (avoiding a copy of a large ddprof exe)
Comment thread src/lib/loader.c Outdated
Comment thread src/lib/loader.c
Comment thread src/lib/loader.c Outdated
Comment thread src/lib/loader.c Outdated
Adjust following comments from Nicolas in PR #529
Comment thread src/lib/loader.c Outdated
@r1viollet
r1viollet requested a review from nsavoire April 1, 2026 10:35
Comment thread src/lib/loader.c Outdated
This can be the case on old libc versions
@r1viollet
r1viollet requested a review from nsavoire April 1, 2026 15:10
Comment thread src/lib/loader.c
// non-NULL handle — installed library found and version matches
// NULL — library not found or version mismatch (fell back OK)
// (void *)-1 — version mismatch but dlclose failed; caller must abort
static void *try_load_installed_profiling_lib() {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After putting some more thoughts, I think that the strategy "dlopen lib, check version, dlclose if mismatch" is dangerous:
in LD_PRELOAD mode, dlopen will trigger start of dpprof and memory allocation profiling, I am not sure just dlclos'ing the lib is enough. I fear some stale state might be left.

Remove all dlclose usage from the loader constructor — it is unsafe
this early and hard to ensure proper cleanup. On version mismatch,
warn but proceed with the installed library.

Restructure the loader flow to check for the ddprof executable
(relative to the loader's path) before attempting to dlopen the
installed libdd_profiling-embedded.so. This avoids loading a library
we cannot safely unload if the exe turns out to be missing.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@nsavoire
nsavoire force-pushed the r1viollet/fix-tmp-extraction branch from 68ebfa2 to 6282c69 Compare April 2, 2026 13:10
@r1viollet

Copy link
Copy Markdown
Collaborator Author

thanks for adjusting! So simple warning for now, no dlclose 👍

@r1viollet

Copy link
Copy Markdown
Collaborator Author

/merge

@gh-worker-devflow-routing-ef8351

gh-worker-devflow-routing-ef8351 Bot commented Apr 2, 2026

Copy link
Copy Markdown

View all feedbacks in Devflow UI.

2026-04-02 13:41:03 UTC ℹ️ Start processing command /merge


2026-04-02 13:41:08 UTC ℹ️ MergeQueue: pull request added to the queue

The expected merge time in main is approximately 18m (p90).


2026-04-02 13:57:23 UTC ℹ️ MergeQueue: This merge request was merged

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants