mirror of
https://github.com/moby/buildkit.git
synced 2026-08-04 14:50:21 +00:00
When git runs as root under sudo it consults SUDO_UID to decide whether a repository's ownership can be trusted, additionally granting access to repositories owned by the user who invoked sudo. GitCLI builds a restricted environment for the git subprocess and did not forward SUDO_UID, so commands such as `sudo docker build` tripped git's "detected dubious ownership" check and silently lost commit provenance: the build still succeeds but prints "current commit information was not captured by the build". Forward SUDO_UID (only when present) on the host git config path enabled via WithHostGitConfig, i.e. client-side local git inspection. The default isolated path used by daemon-side callers is left untouched so it does not pick up host environment. This matches git's own default behavior under sudo: it does not disable safe.directory checks and is not equivalent to safe.directory=*; it merely lets git trust repositories owned by the invoking user. Only SUDO_UID is forwarded (git's ownership check is uid-based and never consults SUDO_GID). Fixes the root cause for docker/buildx#3855. buildx inspects the build context through this GitCLI with WithHostGitConfig enabled, so buildx picks the fix up via a moby/buildkit dependency bump with no buildx-side code change. Signed-off-by: MohammadHasan Akbari <jarqvi.jarqvi@gmail.com>
72 lines
2.4 KiB
Go
72 lines
2.4 KiB
Go
package gitutil
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"os/exec"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestGetGitSSHCommandUsesConfigPath(t *testing.T) {
|
|
cmd := getGitSSHCommand("")
|
|
require.Equal(t, "ssh -F "+os.DevNull+" -o StrictHostKeyChecking=no", cmd)
|
|
|
|
cmd = getGitSSHCommand("/known-hosts")
|
|
require.Equal(t, "ssh -F "+os.DevNull+" -o UserKnownHostsFile=/known-hosts", cmd)
|
|
}
|
|
|
|
func TestGitCLIConfigEnv(t *testing.T) {
|
|
t.Setenv("HOME", "/tmp/home")
|
|
t.Setenv("XDG_CONFIG_HOME", "/tmp/xdg")
|
|
t.Setenv("USERPROFILE", `C:\Users\tester`)
|
|
t.Setenv("HOMEDRIVE", "C:")
|
|
t.Setenv("HOMEPATH", `\Users\tester`)
|
|
t.Setenv("GIT_CONFIG_GLOBAL", "/tmp/global-gitconfig")
|
|
t.Setenv("GIT_CONFIG_SYSTEM", "/tmp/system-gitconfig")
|
|
t.Setenv("SUDO_UID", "1000")
|
|
|
|
t.Run("isolated by default", func(t *testing.T) {
|
|
var got []string
|
|
cli := NewGitCLI(WithExec(func(ctx context.Context, cmd *exec.Cmd) error {
|
|
got = append([]string(nil), cmd.Env...)
|
|
return nil
|
|
}))
|
|
_, err := cli.Run(context.Background(), "status")
|
|
require.NoError(t, err)
|
|
require.Contains(t, got, "GIT_CONFIG_NOSYSTEM=1")
|
|
require.Contains(t, got, "HOME="+os.DevNull)
|
|
require.Contains(t, got, "GIT_CONFIG_GLOBAL="+os.DevNull)
|
|
require.NotContains(t, got, "HOME=/tmp/home")
|
|
require.NotContains(t, got, "XDG_CONFIG_HOME=/tmp/xdg")
|
|
require.NotContains(t, got, "GIT_CONFIG_GLOBAL=/tmp/global-gitconfig")
|
|
require.NotContains(t, got, "GIT_CONFIG_SYSTEM=/tmp/system-gitconfig")
|
|
require.NotContains(t, got, "SUDO_UID=1000")
|
|
})
|
|
|
|
t.Run("host git config opt-in", func(t *testing.T) {
|
|
var got []string
|
|
cli := NewGitCLI(
|
|
WithHostGitConfig(),
|
|
WithExec(func(ctx context.Context, cmd *exec.Cmd) error {
|
|
got = append([]string(nil), cmd.Env...)
|
|
return nil
|
|
}),
|
|
)
|
|
_, err := cli.Run(context.Background(), "status")
|
|
require.NoError(t, err)
|
|
require.NotContains(t, got, "GIT_CONFIG_NOSYSTEM=1")
|
|
require.NotContains(t, got, "HOME="+os.DevNull)
|
|
require.NotContains(t, got, "GIT_CONFIG_GLOBAL="+os.DevNull)
|
|
require.Contains(t, got, "HOME=/tmp/home")
|
|
require.Contains(t, got, "XDG_CONFIG_HOME=/tmp/xdg")
|
|
require.Contains(t, got, `USERPROFILE=C:\Users\tester`)
|
|
require.Contains(t, got, "HOMEDRIVE=C:")
|
|
require.Contains(t, got, `HOMEPATH=\Users\tester`)
|
|
require.Contains(t, got, "GIT_CONFIG_GLOBAL=/tmp/global-gitconfig")
|
|
require.Contains(t, got, "GIT_CONFIG_SYSTEM=/tmp/system-gitconfig")
|
|
require.Contains(t, got, "SUDO_UID=1000")
|
|
})
|
|
}
|