Fix env-var "a" collision in R front-end shell wrapper by avoiding -e in kernel launch - #756
Open
ajalon1 wants to merge 4 commits into
Open
Fix env-var "a" collision in R front-end shell wrapper by avoiding -e in kernel launch#756ajalon1 wants to merge 4 commits into
ajalon1 wants to merge 4 commits into
Conversation
…launch
On Unix-likes, R's own front-end (`$(R RHOME)/bin/R`) is a POSIX shell
script whose `-e`/`-f`/`--file=` argument handling reuses a plain,
unexported local shell variable literally named `a` to hold the encoded
expression text before it execs into the real R binary. Since POSIX
shells retain a variable's exported attribute once inherited from the
environment, this silently clobbers a pre-existing exported environment
variable named `a` for the entire lifetime of the R process.
IRkernel's generated kernelspec launches R via `-e "IRkernel::main()"`,
so any Jupyter user with an environment variable literally named `a`
had it permanently corrupted at kernel startup (e.g. Sys.getenv("a")
would return "IRkernel::main()" instead of the real value).
Fix: on Unix-likes, installspec() now generates a kernelspec that
launches via a small `sh -c` wrapper piping the startup expression into
R's stdin, instead of passing it via `-e`, which sidesteps the
vulnerable code path entirely. Windows is unaffected (R's front-end
there is a compiled executable, not a shell script) and keeps its
original launch mechanism.
Fixes IRkernel#755
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #755.
Problem
On Unix-likes, R's own front-end (
$(R RHOME)/bin/R) is a POSIX shell script. Its-e/-f/--file=argument handling reuses a plain, unexported local shell variable literally namedato hold the encoded expression text before itexecs into the real R binary:Because POSIX shells retain a variable's exported attribute once it's inherited from the environment, if the shell was launched with an env var already named
a(e.g. a user-set container/notebook env var), this plain reassignment silently overwrites it with the encoded-etext — and the clobbered value is inherited by the real R process via the trailingexec, for the entire lifetime of that R session.IRkernel's generated kernelspec launches R via
["R", "--slave", "-e", "IRkernel::main()", "--args", "{connection_file}"]— exactly this vulnerable code path. So any Jupyter user with an environment variable literally namedagets it permanently corrupted the moment their kernel starts:Sys.getenv("a")returns"IRkernel::main()"instead of the real value. Renaming toA,b, etc. is unaffected. See #755 for the full root-cause writeup and repro.Fix
On Unix-likes,
installspec()now generates a kernelspec that launches via a smallsh -cwrapper pipingIRkernel::main()into R's stdin, instead of passing it via-e:This sidesteps the
-e/-f/--file=code path in R's front-end entirely, so thea-variable collision never happens. Windows is untouched — R's front-end there is a compiled executable rather than a shell script, so it isn't subject to this bug, and there's noshon a plain Windows R install to run the wrapper anyway.Testing
Verified locally against a real R install (Alpine
R=4.6.0-r0, though the front-end script logic is version/platform-independent for Unix-likes):Also confirmed the exact
sh -cstring this patch'ssprintf()/shQuote()call generates for a realinstallspec()call, and ran it end-to-end with the same env vars set, with the same passing result.I'm aware this project's had a quiet stretch, looks like three years or so. I'm happy to adjust the approach if maintainers have a preferred direction, or if there's a reason this hasn't been a priority -- already have a workaround in our own platform. But, I wanted to file this as a self-contained, backward-compatible fix in case it's useful.
🤖 PR description generated with Claude Code