From 6394046b024e657d83cd5a52eb9b94ffda75dd27 Mon Sep 17 00:00:00 2001 From: "Theo Gaige (Schneider Electric)" Date: Thu, 21 May 2026 12:09:39 +0200 Subject: [PATCH] go: patch CVE-2026-39817 Backport patch from [1] mentionned in [2] [1] https://go.dev/cl/767520 [2] https://security-tracker.debian.org/tracker/CVE-2026-39817 (From OE-Core rev: f88c0ff79cf5838f8d0c31ecacc35faf56059d03) Signed-off-by: Theo Gaige (Schneider Electric) Reviewed-by: Bruno Vernay Signed-off-by: Jeremy Rosen Signed-off-by: Paul Barker --- meta/recipes-devtools/go/go-1.22.12.inc | 1 + .../go/go/CVE-2026-39817.patch | 105 ++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 meta/recipes-devtools/go/go/CVE-2026-39817.patch diff --git a/meta/recipes-devtools/go/go-1.22.12.inc b/meta/recipes-devtools/go/go-1.22.12.inc index 9a7695e754..f06b974e04 100644 --- a/meta/recipes-devtools/go/go-1.22.12.inc +++ b/meta/recipes-devtools/go/go-1.22.12.inc @@ -46,6 +46,7 @@ SRC_URI += "\ file://CVE-2026-32283.patch \ file://CVE-2026-32289.patch \ file://CVE-2026-33811.patch \ + file://CVE-2026-39817.patch \ " SRC_URI[main.sha256sum] = "012a7e1f37f362c0918c1dfa3334458ac2da1628c4b9cf4d9ca02db986e17d71" diff --git a/meta/recipes-devtools/go/go/CVE-2026-39817.patch b/meta/recipes-devtools/go/go/CVE-2026-39817.patch new file mode 100644 index 0000000000..103fbedb7a --- /dev/null +++ b/meta/recipes-devtools/go/go/CVE-2026-39817.patch @@ -0,0 +1,105 @@ +From 7d35508ad684c808ec11fb6ef3ab27f9258a9418 Mon Sep 17 00:00:00 2001 +From: Damien Neil +Date: Wed, 15 Apr 2026 16:27:23 -0400 +Subject: [PATCH] cmd/pack: refuse to extract files with directory components + +Do not write to /etc/passwd when running "go tool pack x evil.a" +on an archive containing a file named /etc/passwd. + +Fixes #78778 + +Change-Id: I4cf69b81af62321ffbb41ace679672a86a6a6964 +Reviewed-on: https://go-review.googlesource.com/c/go/+/767520 +Reviewed-by: Nicholas Husin +LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com +Reviewed-by: Nicholas Husin + +CVE: CVE-2026-39817 +Upstream-Status: Backport [https://github.com/golang/go/commit/7409ada33f99c0d74db2b0389c51a15de116e48d] +Signed-off-by: Theo Gaige (Schneider Electric) +--- + src/cmd/pack/pack.go | 5 +++++ + src/cmd/pack/pack_test.go | 44 +++++++++++++++++++++++++++++++++++++++ + 2 files changed, 49 insertions(+) + +diff --git a/src/cmd/pack/pack.go b/src/cmd/pack/pack.go +index 412ea36d60..2fe0258f01 100644 +--- a/src/cmd/pack/pack.go ++++ b/src/cmd/pack/pack.go +@@ -135,6 +135,11 @@ func openArchive(name string, mode int, files []string) *Archive { + if err != nil { + log.Fatal(err) + } ++ for _, f := range a.Entries { ++ if !filepath.IsLocal(f.Name) || filepath.Base(f.Name) != f.Name { ++ log.Fatalf("%q: invalid name", f.Name) ++ } ++ } + return &Archive{ + a: a, + files: files, +diff --git a/src/cmd/pack/pack_test.go b/src/cmd/pack/pack_test.go +index c3a63424dd..c4a8c78cbf 100644 +--- a/src/cmd/pack/pack_test.go ++++ b/src/cmd/pack/pack_test.go +@@ -6,6 +6,7 @@ package main + + import ( + "bufio" ++ "bytes" + "cmd/internal/archive" + "fmt" + "internal/testenv" +@@ -409,6 +410,49 @@ func TestRWithNonexistentFile(t *testing.T) { + run(packPath(t), "r", "p.a", "p.o") // should succeed + } + ++func TestOutputPathSanitization(t *testing.T) { ++ dir := t.TempDir() ++ ++ // Create pack.a containing a file named "longpathname". ++ // Note that "go tool pack" requires that all files be at least 8 bytes long. ++ const validPathName = "longpathname" ++ if err := os.WriteFile(dir+"/"+validPathName, make([]byte, 8), 0o666); err != nil { ++ t.Fatal(err) ++ } ++ doRun(t, dir, packPath(t), "grc", "pack.a", validPathName) ++ ++ // Create evil.a from pack.a, replacing "longpathname" with "out/pathname". ++ b, err := os.ReadFile(dir + "/pack.a") ++ if err != nil { ++ t.Fatal(err) ++ } ++ idx := bytes.Index(b, []byte(validPathName)) ++ if idx < 0 { ++ t.Fatalf("%v not found in pack.a", validPathName) ++ } ++ copy(b[idx:], "out/") ++ os.WriteFile(dir+"/evil.a", b, 0o666) ++ ++ // Extract evil.a. It should fail and not extract a file to /out. ++ os.Mkdir(dir+"/out", 0o777) ++ ++ cmd := testenv.Command(t, packPath(t), "x", "evil.a") ++ cmd.Dir = dir ++ _, err = cmd.CombinedOutput() ++ if err == nil { ++ t.Errorf("pack x evil.a: unexpected success") ++ } ++ ++ ents, err := os.ReadDir(dir + "/out") ++ if err != nil { ++ t.Error(err) ++ } ++ for _, e := range ents { ++ t.Errorf("unexpected file in /out: %q", e.Name()) ++ } ++ ++} ++ + // doRun runs a program in a directory and returns the output. + func doRun(t *testing.T, dir string, args ...string) string { + cmd := testenv.Command(t, args[0], args[1:]...) +-- +2.43.0 +