-
Notifications
You must be signed in to change notification settings - Fork 15
fix(cli): clear LD_PRELOAD after one-shot-token library loads #1232
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -198,6 +198,7 @@ fn init_token_list(state: &mut TokenState) { | |||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| state.initialized = true; | ||||||||||||||||||||||||||||||||||||||||
| clear_ld_preload(state.debug_enabled); | ||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
|
|
@@ -225,6 +226,26 @@ fn init_token_list(state: &mut TokenState) { | |||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
| state.initialized = true; | ||||||||||||||||||||||||||||||||||||||||
| clear_ld_preload(state.debug_enabled); | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| /// Unset LD_PRELOAD and LD_LIBRARY_PATH from the environment so child processes | ||||||||||||||||||||||||||||||||||||||||
| /// don't inherit them. The library is already loaded in this process's address space, | ||||||||||||||||||||||||||||||||||||||||
| /// so getenv interception continues to work. This fixes Deno 2.x's scoped --allow-run | ||||||||||||||||||||||||||||||||||||||||
| /// permissions which reject spawning subprocesses when LD_PRELOAD is set. | ||||||||||||||||||||||||||||||||||||||||
| /// See: https://github.com/github/gh-aw-firewall/issues/1001 | ||||||||||||||||||||||||||||||||||||||||
| fn clear_ld_preload(debug_enabled: bool) { | ||||||||||||||||||||||||||||||||||||||||
| // SAFETY: unsetenv is a standard POSIX function. We pass valid C strings. | ||||||||||||||||||||||||||||||||||||||||
| unsafe { | ||||||||||||||||||||||||||||||||||||||||
| let ld_preload = CString::new("LD_PRELOAD").unwrap(); | ||||||||||||||||||||||||||||||||||||||||
| libc::unsetenv(ld_preload.as_ptr()); | ||||||||||||||||||||||||||||||||||||||||
| let ld_library_path = CString::new("LD_LIBRARY_PATH").unwrap(); | ||||||||||||||||||||||||||||||||||||||||
| libc::unsetenv(ld_library_path.as_ptr()); | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+241
to
+243
|
||||||||||||||||||||||||||||||||||||||||
| libc::unsetenv(ld_preload.as_ptr()); | |
| let ld_library_path = CString::new("LD_LIBRARY_PATH").unwrap(); | |
| libc::unsetenv(ld_library_path.as_ptr()); | |
| let rc_preload = libc::unsetenv(ld_preload.as_ptr()); | |
| if debug_enabled && rc_preload != 0 { | |
| eprintln!( | |
| "[one-shot-token] WARNING: Failed to unset LD_PRELOAD (libc::unsetenv returned {})", | |
| rc_preload | |
| ); | |
| } | |
| let ld_library_path = CString::new("LD_LIBRARY_PATH").unwrap(); | |
| let rc_ld_library_path = libc::unsetenv(ld_library_path.as_ptr()); | |
| if debug_enabled && rc_ld_library_path != 0 { | |
| eprintln!( | |
| "[one-shot-token] WARNING: Failed to unset LD_LIBRARY_PATH (libc::unsetenv returned {})", | |
| rc_ld_library_path | |
| ); | |
| } |
Copilot
AI
Mar 11, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test mutates process-wide environment variables (LD_PRELOAD, LD_LIBRARY_PATH) but doesn't save and restore their previous values. If the test runner (or other tests) relies on either variable, this can cause hard-to-diagnose cross-test interference. Consider capturing the previous values (including the "unset" case) and restoring them in a drop guard / finally-style cleanup at the end of the test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling
clear_ld_preload()duringinit_token_list()runs on the first interceptedgetenv()call (even for non-sensitive vars likePATH). In the entrypoint flow, intermediary processes (e.g.,capsh/shell wrappers) are likely to callgetenv()beforeexec-ing the real workload; unsettingLD_PRELOADat that point can prevent the library from being preloaded into the final command at all (sinceLD_PRELOADmust be present atexecvetime) and can also remove protection before any sensitive tokens have been cached/unset. Consider delaying theLD_PRELOAD/LD_LIBRARY_PATHcleanup until after the first sensitive token has been accessed and removed from the environment (e.g., gate on a new state flag and trigger after successfully handling a sensitive token), rather than during initialization.This issue also appears on line 239 of the same file.