Skip to content

fix(terraform): avoid race on GIT_TERMINAL_PROMPT in remote module resolver#10956

Open
abidedavana wants to merge 1 commit into
aquasecurity:mainfrom
abidedavana:fix/git-terminal-prompt-race
Open

fix(terraform): avoid race on GIT_TERMINAL_PROMPT in remote module resolver#10956
abidedavana wants to merge 1 commit into
aquasecurity:mainfrom
abidedavana:fix/git-terminal-prompt-race

Conversation

@abidedavana

Copy link
Copy Markdown

…solver

Setting and restoring the process-global GIT_TERMINAL_PROMPT around each download races with concurrent downloads: a deferred restore can re-enable the git credential prompt while another clone is still running, and the original value read by a second goroutine may be lost. Set the variable once, on the first remote download, and do not restore it.

Fixes #10833

Description

This fixes the race on GIT_TERMINAL_PROMPT described in #10833.

remoteResolver.download() used to save the current value of GIT_TERMINAL_PROMPT, set it to 0, and restore the old value with a defer. The variable is process-global, so when downloads run concurrently (for example trivy image, where layers are scanned in parallel) two calls can step on each other:

  • one goroutine's deferred restore turns the prompt back on while another goroutine's git clone is still running, so git can hang waiting for credentials instead of failing fast
  • the second goroutine reads 0 as the "original" value and restores that, so the user's real value is lost for the rest of the process

go-getter doesn't let you pass an env var for a single git call (discussed in the issue), so the fix sets GIT_TERMINAL_PROMPT=0 once with sync.OnceValue, on the first remote download, and doesn't restore it. Nothing touches the environment unless a remote module actually gets downloaded. This is the approach suggested in the issue discussion.

It's the same kind of fix as #10843, which fixed a race on the global getter.Getters in the same function.

Before: concurrent module downloads can re-enable git's interactive prompt mid-clone (scan hangs on repos that ask for credentials), and the original GIT_TERMINAL_PROMPT value can be silently lost.

After: the prompt is disabled once for the lifetime of the process, only when a remote download happens. There is no restore, so there's nothing left to race.

About tests: I didn't add a new one. Because of the sync.Once, any check of the env var inside the test binary depends on test order (once another test triggers the download path, a later assertion fails), and testing the setter on its own would just test os.Setenv. The existing integration tests in the resolvers package already run download() end to end, and they pass:

(on Linux, including TestResolveModuleFromCache and TestResolveModuleFromCacheWithDifferentSubdir). golangci-lint v2.12.2 with --build-tags=integration is also clean on the package.

Related issues

Checklist

  • I've read the guidelines for contributing to this repository.
  • I've followed the conventions in the PR title.
  • I've added tests that prove my fix is effective or that my feature works.
  • I've updated the documentation with the relevant information (if needed).
  • I've added usage information (if the PR introduces new options)
  • I've included a "before" and "after" example to the description (if the PR is a user interface change).

…solver

Setting and restoring the process-global GIT_TERMINAL_PROMPT around each
download races with concurrent downloads: a deferred restore can re-enable
the git credential prompt while another clone is still running, and the
original value read by a second goroutine may be lost. Set the variable
once, on the first remote download, and do not restore it.

Fixes aquasecurity#10833
@abidedavana
abidedavana requested a review from nikpivkin as a code owner July 12, 2026 05:35
@CLAassistant

CLAassistant commented Jul 12, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(terraform): GIT_TERMINAL_PROMPT save/restore race in remote module resolver

2 participants