fix(startup): scope collector git trust
- commit
- a948576e5394b048c0e26d4e2e6b912c388a1183
- author
- brice · · 2026-07-14 09:46 UTC
- parent
- 862d933
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +46 -1
M internal/logging/first_presentation_collector_test.go +45 -0
| @@ -1,6 +1,7 @@ | |||
| 1 | 1 | package logging | |
| 2 | 2 | ||
| 3 | 3 | import ( | |
| 4 | + | "encoding/json" | |
| 4 | 5 | "os" | |
| 5 | 6 | "os/exec" | |
| 6 | 7 | "path/filepath" | |
| @@ -147,6 +148,50 @@ func TestFirstPresentationCollectorSanitizesMachineLocalValues(t *testing.T) { | |||
| 147 | 148 | } | |
| 148 | 149 | } | |
| 149 | 150 | ||
| 151 | + | func TestFirstPresentationCollectorReadsProvenanceWithScopedGitSafeDirectory(t *testing.T) { | |
| 152 | + | repoRoot, err := filepath.Abs(filepath.Join("..", "..")) | |
| 153 | + | require.NoError(t, err) | |
| 154 | + | temp := t.TempDir() | |
| 155 | + | runtime := filepath.Join(temp, "cef-147-runtime") | |
| 156 | + | require.NoError(t, os.Mkdir(runtime, 0o755)) | |
| 157 | + | binary := filepath.Join(temp, "dumber") | |
| 158 | + | require.NoError(t, os.WriteFile(binary, collectorTestBinary(validFirstPresentationLog), 0o755)) | |
| 159 | + | gitDir := filepath.Join(temp, "bin") | |
| 160 | + | require.NoError(t, os.Mkdir(gitDir, 0o755)) | |
| 161 | + | git := filepath.Join(gitDir, "git") | |
| 162 | + | require.NoError(t, os.WriteFile(git, []byte(`#!/bin/sh | |
| 163 | + | if [ "$1" = "-c" ] && [ "$2" = "safe.directory=$EXPECTED_SAFE_DIRECTORY" ] && [ "$3" = "rev-parse" ] && [ "$4" = "HEAD" ]; then | |
| 164 | + | echo 0123456789abcdef0123456789abcdef01234567 | |
| 165 | + | exit 0 | |
| 166 | + | fi | |
| 167 | + | echo "fatal: detected dubious ownership in repository" >&2 | |
| 168 | + | exit 128 | |
| 169 | + | `), 0o755)) | |
| 170 | + | ||
| 171 | + | output := filepath.Join(temp, "artifacts") | |
| 172 | + | cmd := exec.Command(filepath.Join(repoRoot, "scripts", "collect_first_presentation.sh")) | |
| 173 | + | cmd.Dir = repoRoot | |
| 174 | + | cmd.Env = append(os.Environ(), | |
| 175 | + | "DISPLAY=:test", | |
| 176 | + | "DUMBER_CEF_DIR="+runtime, | |
| 177 | + | "DUMBER_FIRST_PRESENTATION_BIN="+binary, | |
| 178 | + | "DUMBER_FIRST_PRESENTATION_OUTPUT="+output, | |
| 179 | + | "DUMBER_FIRST_PRESENTATION_TIMEOUT_SECONDS=1", | |
| 180 | + | "EXPECTED_SAFE_DIRECTORY="+repoRoot, | |
| 181 | + | "PATH="+gitDir+":"+os.Getenv("PATH"), | |
| 182 | + | ) | |
| 183 | + | result, err := cmd.CombinedOutput() | |
| 184 | + | require.NoErrorf(t, err, "collector failed: %s", result) | |
| 185 | + | ||
| 186 | + | var metadata struct { | |
| 187 | + | MeasuredSourceRevision string `json:"measured_source_revision"` | |
| 188 | + | } | |
| 189 | + | contents, err := os.ReadFile(filepath.Join(output, "metadata.json")) | |
| 190 | + | require.NoError(t, err) | |
| 191 | + | require.NoError(t, json.Unmarshal(contents, &metadata)) | |
| 192 | + | require.Equal(t, "0123456789abcdef0123456789abcdef01234567", metadata.MeasuredSourceRevision) | |
| 193 | + | } | |
| 194 | + | ||
| 150 | 195 | func TestFirstPresentationCollectorRejectsInconsistentTiming(t *testing.T) { | |
| 151 | 196 | repoRoot, err := filepath.Abs(filepath.Join("..", "..")) | |
| 152 | 197 | require.NoError(t, err) | |
| @@ -1,6 +1,7 @@ | |||||
| 1 | package logging | 1 | package logging | ||
| 2 | 2 | ||||
| 3 | import ( | 3 | import ( | ||
| 4 | + | "encoding/json" | |||
| 4 | "os" | 5 | "os" | ||
| 5 | "os/exec" | 6 | "os/exec" | ||
| 6 | "path/filepath" | 7 | "path/filepath" | ||
| @@ -147,6 +148,50 @@ func TestFirstPresentationCollectorSanitizesMachineLocalValues(t *testing.T) { | |||||
| 147 | } | 148 | } | ||
| 148 | } | 149 | } | ||
| 149 | 150 | ||||
| 151 | + | func TestFirstPresentationCollectorReadsProvenanceWithScopedGitSafeDirectory(t *testing.T) { | |||
| 152 | + | repoRoot, err := filepath.Abs(filepath.Join("..", "..")) | |||
| 153 | + | require.NoError(t, err) | |||
| 154 | + | temp := t.TempDir() | |||
| 155 | + | runtime := filepath.Join(temp, "cef-147-runtime") | |||
| 156 | + | require.NoError(t, os.Mkdir(runtime, 0o755)) | |||
| 157 | + | binary := filepath.Join(temp, "dumber") | |||
| 158 | + | require.NoError(t, os.WriteFile(binary, collectorTestBinary(validFirstPresentationLog), 0o755)) | |||
| 159 | + | gitDir := filepath.Join(temp, "bin") | |||
| 160 | + | require.NoError(t, os.Mkdir(gitDir, 0o755)) | |||
| 161 | + | git := filepath.Join(gitDir, "git") | |||
| 162 | + | require.NoError(t, os.WriteFile(git, []byte(`#!/bin/sh | |||
| 163 | + | if [ "$1" = "-c" ] && [ "$2" = "safe.directory=$EXPECTED_SAFE_DIRECTORY" ] && [ "$3" = "rev-parse" ] && [ "$4" = "HEAD" ]; then | |||
| 164 | + | echo 0123456789abcdef0123456789abcdef01234567 | |||
| 165 | + | exit 0 | |||
| 166 | + | fi | |||
| 167 | + | echo "fatal: detected dubious ownership in repository" >&2 | |||
| 168 | + | exit 128 | |||
| 169 | + | `), 0o755)) | |||
| 170 | + | ||||
| 171 | + | output := filepath.Join(temp, "artifacts") | |||
| 172 | + | cmd := exec.Command(filepath.Join(repoRoot, "scripts", "collect_first_presentation.sh")) | |||
| 173 | + | cmd.Dir = repoRoot | |||
| 174 | + | cmd.Env = append(os.Environ(), | |||
| 175 | + | "DISPLAY=:test", | |||
| 176 | + | "DUMBER_CEF_DIR="+runtime, | |||
| 177 | + | "DUMBER_FIRST_PRESENTATION_BIN="+binary, | |||
| 178 | + | "DUMBER_FIRST_PRESENTATION_OUTPUT="+output, | |||
| 179 | + | "DUMBER_FIRST_PRESENTATION_TIMEOUT_SECONDS=1", | |||
| 180 | + | "EXPECTED_SAFE_DIRECTORY="+repoRoot, | |||
| 181 | + | "PATH="+gitDir+":"+os.Getenv("PATH"), | |||
| 182 | + | ) | |||
| 183 | + | result, err := cmd.CombinedOutput() | |||
| 184 | + | require.NoErrorf(t, err, "collector failed: %s", result) | |||
| 185 | + | ||||
| 186 | + | var metadata struct { | |||
| 187 | + | MeasuredSourceRevision string `json:"measured_source_revision"` | |||
| 188 | + | } | |||
| 189 | + | contents, err := os.ReadFile(filepath.Join(output, "metadata.json")) | |||
| 190 | + | require.NoError(t, err) | |||
| 191 | + | require.NoError(t, json.Unmarshal(contents, &metadata)) | |||
| 192 | + | require.Equal(t, "0123456789abcdef0123456789abcdef01234567", metadata.MeasuredSourceRevision) | |||
| 193 | + | } | |||
| 194 | + | ||||
| 150 | func TestFirstPresentationCollectorRejectsInconsistentTiming(t *testing.T) { | 195 | func TestFirstPresentationCollectorRejectsInconsistentTiming(t *testing.T) { | ||
| 151 | repoRoot, err := filepath.Abs(filepath.Join("..", "..")) | 196 | repoRoot, err := filepath.Abs(filepath.Join("..", "..")) | ||
| 152 | require.NoError(t, err) | 197 | require.NoError(t, err) | ||
M scripts/collect_first_presentation.sh +1 -1
| @@ -78,7 +78,7 @@ json.dump({ | |||
| 78 | 78 | "runtime": {"label": "cef", "version": os.environ.get("DUMBER_CEF_RUNTIME_VERSION", "147")}, | |
| 79 | 79 | "binary": {"label": "dumber", "sha256": binary_sha256}, | |
| 80 | 80 | "timeout_seconds": int(timeout), | |
| 81 | - | "measured_source_revision": subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip(), | |
| 81 | + | "measured_source_revision": subprocess.check_output(["git", "-c", f"safe.directory={os.getcwd()}", "rev-parse", "HEAD"], text=True).strip(), | |
| 82 | 82 | "upstream": {"module": upstream_module, "tag": upstream_tag, "revision": upstream_revision}, | |
| 83 | 83 | "fixed_environment": {"DUMBER_RENDER_STACK": "vulkan-dmabuf", "PUREGO_CEF2GTK_BACKEND": "gdk-dmabuf", "GSK_RENDERER": "vulkan"} | |
| 84 | 84 | }, open(path, "w"), indent=2, sort_keys=True) | |
| @@ -78,7 +78,7 @@ json.dump({ | |||||
| 78 | "runtime": {"label": "cef", "version": os.environ.get("DUMBER_CEF_RUNTIME_VERSION", "147")}, | 78 | "runtime": {"label": "cef", "version": os.environ.get("DUMBER_CEF_RUNTIME_VERSION", "147")}, | ||
| 79 | "binary": {"label": "dumber", "sha256": binary_sha256}, | 79 | "binary": {"label": "dumber", "sha256": binary_sha256}, | ||
| 80 | "timeout_seconds": int(timeout), | 80 | "timeout_seconds": int(timeout), | ||
| 81 | - | "measured_source_revision": subprocess.check_output(["git", "rev-parse", "HEAD"], text=True).strip(), | 81 | + | "measured_source_revision": subprocess.check_output(["git", "-c", f"safe.directory={os.getcwd()}", "rev-parse", "HEAD"], text=True).strip(), |
| 82 | "upstream": {"module": upstream_module, "tag": upstream_tag, "revision": upstream_revision}, | 82 | "upstream": {"module": upstream_module, "tag": upstream_tag, "revision": upstream_revision}, | ||
| 83 | "fixed_environment": {"DUMBER_RENDER_STACK": "vulkan-dmabuf", "PUREGO_CEF2GTK_BACKEND": "gdk-dmabuf", "GSK_RENDERER": "vulkan"} | 83 | "fixed_environment": {"DUMBER_RENDER_STACK": "vulkan-dmabuf", "PUREGO_CEF2GTK_BACKEND": "gdk-dmabuf", "GSK_RENDERER": "vulkan"} | ||
| 84 | }, open(path, "w"), indent=2, sort_keys=True) | 84 | }, open(path, "w"), indent=2, sort_keys=True) | ||