209 lines
6.5 KiB
Diff
209 lines
6.5 KiB
Diff
From 8eddf81239a58bbdbb700c8cc46e8e671b20108c Mon Sep 17 00:00:00 2001
|
|
From: "Bryan C. Mills" <bcmills@google.com>
|
|
Date: Sat, 13 May 2023 02:15:16 +0800
|
|
Subject: [PATCH 2/4] [Backport] cmd/go: disallow package directories
|
|
containing newlines
|
|
|
|
Offering: Cloud Core Network
|
|
CVE: CVE-2023-29402
|
|
Reference: https://go-review.googlesource.com/c/go/+/501218
|
|
|
|
Directory or file paths containing newlines may cause tools (such as
|
|
cmd/cgo) that emit "//line" or "#line" -directives to write part of
|
|
the path into non-comment lines in generated source code. If those
|
|
lines contain valid Go code, it may be injected into the resulting
|
|
binary.
|
|
|
|
(Note that Go import paths and file paths within module zip files
|
|
already could not contain newlines.)
|
|
|
|
Thanks to Juho Nurminen of Mattermost for reporting this issue.
|
|
|
|
Note: The upstream does not submit this change to go1.17 according to the rules of MinorReleases.
|
|
Corego3.x are based on go1.17.8. Therefore, it need to submit the change to corego3.x.
|
|
|
|
Edited-by: tangxi t00586138
|
|
|
|
Updates #60167.
|
|
Fixes #60515.
|
|
Fixes CVE-2023-29402.
|
|
|
|
Change-Id: If55d0400c02beb7a5da5eceac60f1abeac99f064
|
|
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1882606
|
|
Reviewed-by: Roland Shoemaker <bracewell@google.com>
|
|
Run-TryBot: Roland Shoemaker <bracewell@google.com>
|
|
Reviewed-by: Russ Cox <rsc@google.com>
|
|
Reviewed-by: Damien Neil <dneil@google.com>
|
|
(cherry picked from commit 41f9046495564fc728d6f98384ab7276450ac7e2)
|
|
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1902229
|
|
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1904343
|
|
Reviewed-by: Michael Knyszek <mknyszek@google.com>
|
|
Reviewed-by: Bryan Mills <bcmills@google.com>
|
|
Reviewed-on: https://go-review.googlesource.com/c/go/+/501218
|
|
Run-TryBot: David Chase <drchase@google.com>
|
|
Auto-Submit: Michael Knyszek <mknyszek@google.com>
|
|
TryBot-Result: Gopher Robot <gobot@golang.org>
|
|
Signed-off-by: Tang Xi tangxi6@huawei.com
|
|
|
|
---
|
|
src/cmd/go/internal/load/pkg.go | 4 +
|
|
src/cmd/go/internal/work/exec.go | 6 ++
|
|
src/cmd/go/script_test.go | 1 +
|
|
.../go/testdata/script/build_cwd_newline.txt | 100 ++++++++++++++++++
|
|
4 files changed, 111 insertions(+)
|
|
create mode 100644 src/cmd/go/testdata/script/build_cwd_newline.txt
|
|
|
|
diff --git a/src/cmd/go/internal/load/pkg.go b/src/cmd/go/internal/load/pkg.go
|
|
index a83cc9a812..d4da86dbe8 100644
|
|
--- a/src/cmd/go/internal/load/pkg.go
|
|
+++ b/src/cmd/go/internal/load/pkg.go
|
|
@@ -1897,6 +1897,10 @@ func (p *Package) load(ctx context.Context, opts PackageOpts, path string, stk *
|
|
setError(fmt.Errorf("invalid input directory name %q", name))
|
|
return
|
|
}
|
|
+ if strings.ContainsAny(p.Dir, "\r\n") {
|
|
+ setError(fmt.Errorf("invalid package directory %q", p.Dir))
|
|
+ return
|
|
+ }
|
|
|
|
// Build list of imported packages and full dependency list.
|
|
imports := make([]*Package, 0, len(p.Imports))
|
|
diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
|
|
index 5a225fb9f1..2eb8bd681c 100644
|
|
--- a/src/cmd/go/internal/work/exec.go
|
|
+++ b/src/cmd/go/internal/work/exec.go
|
|
@@ -503,6 +503,12 @@ func (b *Builder) build(ctx context.Context, a *Action) (err error) {
|
|
b.Print(a.Package.ImportPath + "\n")
|
|
}
|
|
|
|
+ if p.Error != nil {
|
|
+ // Don't try to build anything for packages with errors. There may be a
|
|
+ // problem with the inputs that makes the package unsafe to build.
|
|
+ return p.Error
|
|
+ }
|
|
+
|
|
if a.Package.BinaryOnly {
|
|
p.Stale = true
|
|
p.StaleReason = "binary-only packages are no longer supported"
|
|
diff --git a/src/cmd/go/script_test.go b/src/cmd/go/script_test.go
|
|
index 639e907db0..80b93566ea 100644
|
|
--- a/src/cmd/go/script_test.go
|
|
+++ b/src/cmd/go/script_test.go
|
|
@@ -181,6 +181,7 @@ func (ts *testScript) setup() {
|
|
"devnull=" + os.DevNull,
|
|
"goversion=" + goVersion(ts),
|
|
":=" + string(os.PathListSeparator),
|
|
+ "newline=\n",
|
|
}
|
|
if !testenv.HasExternalNetwork() {
|
|
ts.env = append(ts.env, "TESTGONETWORK=panic", "TESTGOVCS=panic")
|
|
diff --git a/src/cmd/go/testdata/script/build_cwd_newline.txt b/src/cmd/go/testdata/script/build_cwd_newline.txt
|
|
new file mode 100644
|
|
index 0000000000..61c6966b02
|
|
--- /dev/null
|
|
+++ b/src/cmd/go/testdata/script/build_cwd_newline.txt
|
|
@@ -0,0 +1,100 @@
|
|
+[windows] skip 'filesystem normalizes / to \'
|
|
+[plan9] skip 'filesystem disallows \n in paths'
|
|
+
|
|
+# If the directory path containing a package to be built includes a newline,
|
|
+# the go command should refuse to even try to build the package.
|
|
+
|
|
+env DIR=$WORK${/}${newline}'package main'${newline}'func main() { panic("uh-oh")'${newline}'/*'
|
|
+
|
|
+mkdir $DIR
|
|
+cd $DIR
|
|
+exec pwd
|
|
+cp $WORK/go.mod ./go.mod
|
|
+cp $WORK/main.go ./main.go
|
|
+cp $WORK/main_test.go ./main_test.go
|
|
+
|
|
+! go build -o $devnull .
|
|
+stderr 'package example: invalid package directory .*uh-oh'
|
|
+
|
|
+! go build -o $devnull main.go
|
|
+stderr 'package command-line-arguments: invalid package directory .*uh-oh'
|
|
+
|
|
+! go run .
|
|
+stderr 'package example: invalid package directory .*uh-oh'
|
|
+
|
|
+! go run main.go
|
|
+stderr 'package command-line-arguments: invalid package directory .*uh-oh'
|
|
+
|
|
+! go test .
|
|
+stderr 'package example: invalid package directory .*uh-oh'
|
|
+
|
|
+! go test -v main.go main_test.go
|
|
+stderr 'package command-line-arguments: invalid package directory .*uh-oh'
|
|
+
|
|
+
|
|
+# Since we do preserve $PWD (or set it appropriately) for commands, and we do
|
|
+# not resolve symlinks unnecessarily, referring to the contents of the unsafe
|
|
+# directory via a safe symlink should be ok, and should not inject the data from
|
|
+# the symlink target path.
|
|
+
|
|
+[!symlink] stop 'remainder of test checks symlink behavior'
|
|
+[short] stop 'links and runs binaries'
|
|
+
|
|
+symlink $WORK${/}link -> $DIR
|
|
+
|
|
+go run $WORK${/}link${/}main.go
|
|
+! stdout panic
|
|
+! stderr panic
|
|
+stderr '^ok$'
|
|
+
|
|
+go test -v $WORK${/}link${/}main.go $WORK${/}link${/}main_test.go
|
|
+! stdout panic
|
|
+! stderr panic
|
|
+stdout '^ok$' # 'go test' combines the test's stdout into stderr
|
|
+
|
|
+cd $WORK/link
|
|
+
|
|
+! go run $DIR${/}main.go
|
|
+stderr 'package command-line-arguments: invalid package directory .*uh-oh'
|
|
+
|
|
+go run .
|
|
+! stdout panic
|
|
+! stderr panic
|
|
+stderr '^ok$'
|
|
+
|
|
+go run main.go
|
|
+! stdout panic
|
|
+! stderr panic
|
|
+stderr '^ok$'
|
|
+
|
|
+go test -v
|
|
+! stdout panic
|
|
+! stderr panic
|
|
+stdout '^ok$' # 'go test' combines the test's stdout into stderr
|
|
+
|
|
+go test -v .
|
|
+! stdout panic
|
|
+! stderr panic
|
|
+stdout '^ok$' # 'go test' combines the test's stdout into stderr
|
|
+
|
|
+
|
|
+-- $WORK/go.mod --
|
|
+module example
|
|
+go 1.19
|
|
+-- $WORK/main.go --
|
|
+package main
|
|
+
|
|
+import "C"
|
|
+
|
|
+func main() {
|
|
+ /* nothing here */
|
|
+ println("ok")
|
|
+}
|
|
+-- $WORK/main_test.go --
|
|
+package main
|
|
+
|
|
+import "testing"
|
|
+
|
|
+func TestMain(*testing.M) {
|
|
+ main()
|
|
+}
|
|
--
|
|
2.33.0
|
|
|