Skip to content

Commit 9b33c92

Browse files
authored
windows os/exec build checker (#24736)
1 parent f263457 commit 9b33c92

File tree

2 files changed

+96
-0
lines changed

2 files changed

+96
-0
lines changed

packaging/windows/build_prerelease.cmd

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22

33
echo GOPATH %GOPATH%
44

5+
:: check os/exec path fix is in place
6+
pushd %GOPATH%\src\github.com\keybase\client\packaging\windows
7+
go run osexeccheck.go
8+
IF %ERRORLEVEL% NEQ 0 (
9+
EXIT /B 1
10+
)
11+
popd
12+
513
:: CGO causes dll loading security vulnerabilities
614
set CGO_ENABLED=0
715
go env

packaging/windows/osexeccheck.go

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// On Windows, the default algorithm for searching for executable files involves looking in the current
2+
// directory first. Go reproduces this behavior in order to stay true to how the underlying OS works.
3+
// However, looking for executables in this order is a security problem, since attackers can induce
4+
// an admin to invoke a rogue script by naming it with a common executable name, like git or go. If the attacker
5+
// manages to get an admin to run `git` in a directory in which they have placed their own git.bat file
6+
// (which could do anything), then they have exploited the system.
7+
//
8+
// We want to ensure that when building our own Windows distribution of Keybase, that the behavior of looking
9+
// in the current diectory for an executable first is disabled. This test ensures that the os/exec package
10+
// has been suitably modified to get the correct more secure behavior.
11+
//
12+
// In order to fix an error from this checker, you must patch the os/exec package on the machine where this
13+
// check runs to remove the current directory search path. See https://go.dev/blog/path-security for more
14+
// discussion. Below is a patch showing the required change:
15+
//
16+
// diff --git a/src/os/exec/lp_windows.go b/src/os/exec/lp_windows.go
17+
// index e7a2cdf142..f4f0bec172 100644
18+
// --- a/src/os/exec/lp_windows.go
19+
// +++ b/src/os/exec/lp_windows.go
20+
// @@ -81,9 +81,6 @@ func LookPath(file string) (string, error) {
21+
// return "", &Error{file, err}
22+
// }
23+
// }
24+
// - if f, err := findExecutable(filepath.Join(".", file), exts); err == nil {
25+
// - return f, nil
26+
// - }
27+
// path := os.Getenv("path")
28+
// for _, dir := range filepath.SplitList(path) {
29+
// if f, err := findExecutable(filepath.Join(dir, file), exts); err == nil {
30+
31+
package main
32+
33+
import (
34+
"fmt"
35+
"log"
36+
"os"
37+
"os/exec"
38+
"path/filepath"
39+
"strings"
40+
)
41+
42+
const FailureOutput = "check failed"
43+
44+
func createBatFile() (string, error) {
45+
wd, err := os.Getwd()
46+
if err != nil {
47+
return "", fmt.Errorf("failed to get working directory: %w", err)
48+
}
49+
execPath := filepath.Join(wd, "go.bat")
50+
if err := os.WriteFile(execPath, []byte("@echo "+FailureOutput), 0777); err != nil {
51+
return "", fmt.Errorf("failed to write bat file: %w", err)
52+
}
53+
return execPath, nil
54+
}
55+
56+
func execGoCommand() error {
57+
cmd := exec.Command("go", "version")
58+
outbytes, err := cmd.CombinedOutput()
59+
if err != nil {
60+
return fmt.Errorf("failed to run go command: %w", err)
61+
}
62+
out := strings.TrimSpace(string(outbytes[:]))
63+
log.Printf("output: %s", out)
64+
if out == FailureOutput {
65+
return fmt.Errorf("Ran go.bat instead of go! In order to fix see the top comment in this source file")
66+
}
67+
return nil
68+
}
69+
70+
func run() error {
71+
path, err := createBatFile()
72+
if err != nil {
73+
log.Printf("error creating bat file: %s", err)
74+
return err
75+
}
76+
defer os.Remove(path)
77+
if err := execGoCommand(); err != nil {
78+
log.Printf("failed to execute go command: %s", err)
79+
return err
80+
}
81+
return nil
82+
}
83+
84+
func main() {
85+
if err := run(); err != nil {
86+
os.Exit(3)
87+
}
88+
}

0 commit comments

Comments
 (0)