-
Notifications
You must be signed in to change notification settings - Fork 18k
os/exec: expose a config that allows LookPath and Command to take in relative paths #53962
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
Comments
The package docs say: Code that insists on including results from relative path entries can instead override the error using an errors.Is check:
and
Before adding such overrides, make sure you understand the security implications of doing so. See https://go.dev/blog/path-security for more information. Those build environments should be able to add those three lines (the if statement) at the appropriate call sites to produce the "config" that is desired in just the call sites where it is appropriate. If that's not an option, or if some other override is needed, can you say more about why that's not enough? |
This proposal has been added to the active column of the proposals project |
We are currently facing a similar issue at Uber - the main issue is that sometimes the code that does these relative path lookups are not necessarily owned/maintained by us. For example, there are code generators that expect some plugins that are essentially artifacts produced during build to be part of the PATH. Currently these are relative paths because Bazel Files only expose relative paths from the sandbox. |
@sywhang thanks for the information. What does the PATH look like when running under Bazel Files? Is it all locations relative to the current directory? Does that mean you can't chdir anywhere else without breaking your PATH? A global override is probably a mistake, because you'd want to limit the effect to specific parts of a program. |
Change https://go.dev/cl/419794 mentions this issue: |
@rsc our build infrastructure compiles some code generators which then gets used to compile other parts of the monorepo. These code generators are sometimes invoking other code generator "plugin"s which gets outputted to some arbitrary location in the Bazel sandbox. These locations reported by Bazel rules are relative to the Bazel sandbox. These tools get invoked via Bazel rule build step so we don't chdir. FWIW, we unblocked ourselves with a hack to test out Go 1.19 - we injected bash scripts before running any of these code generators to find the absolute paths to these plugins and put them on PATH, but it would be still nice if there were workarounds for these controlled sandboxed build environments that can be assumed "safe". We also discussed potentially asking Bazel to report absolute paths to files generated, but that would go against the whole philosophy of having hermetic builds in Bazel. Agreed that global override is not necessary here -- we want to be able to disable it just for these specific code generators whose effect/lifetime is well-known in advance. |
To give an example, this is a command Bazel calls during a build
You can see that Bazel first This design is intentional so actions don't accidentally read or execute any files outside the sandbox. The absolute path of the sandbox changes from machine to machine, even from build to build on the same machine. By not assuming any absolute path, Bazel can schedule this action to a remote build machine and get back the build result. By managing One solution is so change all programs that Bazel calls to allow passing a path to any other programs that they need to run. For example, all code generators that want to call The other is like @sywhang said, we can hack all Bazel rules and append |
The change in 1.19 only affects the os/exec package when there are relative paths in the Note that your example of a command line only has absolute paths on It's not obvious to me why adding |
Upon further reflection, I think it is appropriate to provide a GODEBUG opt-out for this change. We do the same in the crypto/* packages when we retire insecure algorithms and protocol versions, so that people affected by the improved security have a way to opt out without modifying their code at all. This change feels a bit like those. Since the Go 1.19 release is imminent (next week), I've gone ahead and added the GODEBUG opt-out in CL 419794. Clearly there must be a little more to your example. Since GOROOT is a relative path, I wonder if something is adding $GOROOT/bin to $PATH. Or perhaps the value of the -sdk flag (the same relative path) is being added. That would cause a look for 'go' or 'gofmt' to fail:
The new GODEBUG restores the old behavior:
It would also suffice to invoke the binary directly by using filepath.Join(GOROOT, "bin/go"):
|
The changes are likely to break users, and we need to make it easy to unbreak without code changes. For golang#43724. Fixes golang#53962. Change-Id: I105c5d6c801d354467e0cefd268189c18846858e Reviewed-on: https://go-review.googlesource.com/c/go/+/419794 Reviewed-by: Bryan Mills <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Russ Cox <[email protected]>
…Go 1.19 See the comment in the script. refs golang/go#53962 used by make test-platform breaks the test on Go 1.19
With Go 1.19, os/exec no longer accepts relative paths as part of PATH. Reading through https://github.com/golang/go/issues/43724, the suggested workaround is to export the paths as absolute paths.
However, In some build environments (i.e. Bazel), paths to executables that are compiled during build time are passed around as relative paths for hermetic builds.
Would it be possible for Go runtime to expose some type of configuration (maybe via environment variable?) that allows relative path lookups in os/exec?
The text was updated successfully, but these errors were encountered: