Rebase to 1.10rc2

Fix CVE-2018-6574
Resolves: BZ#1543561, BZ#1543562
This commit is contained in:
Jakub Čajka 2018-02-08 14:50:08 +01:00
parent 13bb238b09
commit 5f45ed12c2
4 changed files with 89 additions and 61 deletions

1
.gitignore vendored
View File

@ -48,3 +48,4 @@
/go1.10beta1.src.tar.gz /go1.10beta1.src.tar.gz
/go1.10beta2.src.tar.gz /go1.10beta2.src.tar.gz
/go1.10rc1.src.tar.gz /go1.10rc1.src.tar.gz
/go1.10rc2.src.tar.gz

View File

@ -1,4 +1,4 @@
From b17b0c7d9b1d7bffd90a83fb887c66b421193eb8 Mon Sep 17 00:00:00 2001 From 09581ca4826b6d67b1c3a3c8597038b28a37f52d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jakub=20=C4=8Cajka?= <jcajka@redhat.com> From: =?UTF-8?q?Jakub=20=C4=8Cajka?= <jcajka@redhat.com>
Date: Fri, 5 Jan 2018 13:38:55 +0100 Date: Fri, 5 Jan 2018 13:38:55 +0100
Subject: [PATCH] cmd/go/internal/work : improve pkgconfig support to work with Subject: [PATCH] cmd/go/internal/work : improve pkgconfig support to work with
@ -10,50 +10,78 @@ Fix interfacing with latest(1.4+) pkgconf versions, as they have change the outp
Change-Id: I55301bb564b07128d5564ec1454dd247f84a95c3 Change-Id: I55301bb564b07128d5564ec1454dd247f84a95c3
--- ---
src/cmd/go/internal/work/build_test.go | 15 ++++++- src/cmd/go/internal/work/build_test.go | 44 +++++++++++++++++---
src/cmd/go/internal/work/exec.go | 79 +++++++++++++++++++++++++--------- src/cmd/go/internal/work/exec.go | 75 +++++++++++++++++++++++-----------
2 files changed, 72 insertions(+), 22 deletions(-) 2 files changed, 90 insertions(+), 29 deletions(-)
diff --git a/src/cmd/go/internal/work/build_test.go b/src/cmd/go/internal/work/build_test.go diff --git a/src/cmd/go/internal/work/build_test.go b/src/cmd/go/internal/work/build_test.go
index 3f5ba37c64..be9857ade7 100644 index 3f5ba37c64..c3c63a97a4 100644
--- a/src/cmd/go/internal/work/build_test.go --- a/src/cmd/go/internal/work/build_test.go
+++ b/src/cmd/go/internal/work/build_test.go +++ b/src/cmd/go/internal/work/build_test.go
@@ -43,10 +43,23 @@ func TestSplitPkgConfigOutput(t *testing.T) { @@ -39,14 +39,46 @@ func TestSplitPkgConfigOutput(t *testing.T) {
{[]byte(`-r:foo -L/usr/white\ space/lib -lfoo\ bar -lbar\ baz`), []string{"-r:foo", "-L/usr/white space/lib", "-lfoo bar", "-lbar baz"}}, for _, test := range []struct {
{[]byte(`-lextra\ fun\ arg\\`), []string{`-lextra fun arg\`}}, in []byte
{[]byte(`broken flag\`), []string{"broken", "flag"}}, want []string
+ {[]byte(`extra broken flag \`), []string{"extra", "broken", "flag"}}, + pass bool
{[]byte("\textra whitespace\r\n"), []string{"extra", "whitespace"}}, }{
{[]byte(" \r\n "), nil}, - {[]byte(`-r:foo -L/usr/white\ space/lib -lfoo\ bar -lbar\ baz`), []string{"-r:foo", "-L/usr/white space/lib", "-lfoo bar", "-lbar baz"}},
+ {[]byte(`"-r:foo" "-L/usr/white space/lib" "-lfoo bar" "-lbar baz"`), []string{"-r:foo", "-L/usr/white space/lib", "-lfoo bar", "-lbar baz"}}, - {[]byte(`-lextra\ fun\ arg\\`), []string{`-lextra fun arg\`}},
+ {[]byte(`"-lextra fun arg\\"`), []string{`-lextra fun arg\`}}, - {[]byte(`broken flag\`), []string{"broken", "flag"}},
+ {[]byte(`" \r\n "`), []string{` \r\n `}}, - {[]byte("\textra whitespace\r\n"), []string{"extra", "whitespace"}},
+ {[]byte(`""`), nil}, - {[]byte(" \r\n "), nil},
+ {[]byte(`-fPIC -I/test/include/foo -DQUOTED='"/test/share/doc"'`), []string{"-fPIC", "-I/test/include/foo", "-DQUOTED=\"/test/share/doc\""}}, + {[]byte(`-r:foo -L/usr/white\ space/lib -lfoo\ bar -lbar\ baz`), []string{"-r:foo", "-L/usr/white space/lib", "-lfoo bar", "-lbar baz"}, true},
+ {[]byte(`-fPIC -I/test/include/foo -DQUOTED="/test/share/doc"`), []string{"-fPIC", "-I/test/include/foo", "-DQUOTED=/test/share/doc"}}, + {[]byte(`-lextra\ fun\ arg\\`), []string{`-lextra fun arg\`}, true},
+ {[]byte(`-fPIC -I/test/include/foo -DQUOTED=\"/test/share/doc\"`), []string{"-fPIC", "-I/test/include/foo", "-DQUOTED=\"/test/share/doc\""}}, + {[]byte(`broken flag\`), []string{"broken", "flag"}, true},
+ {[]byte(`-fPIC -I/test/include/foo -DQUOTED='/test/share/doc'`), []string{"-fPIC", "-I/test/include/foo", "-DQUOTED=/test/share/doc"}}, + {[]byte(`extra broken flag \`), []string{"extra", "broken", "flag"}, true},
+ {[]byte(`-Dhello=10 -Dworld=+32 -DDEFINED_FROM_PKG_CONFIG=hello\ world`), []string{"-Dhello=10", "-Dworld=+32", "-DDEFINED_FROM_PKG_CONFIG=hello world"}}, + {[]byte(`\`), nil, true},
+ {[]byte("\textra whitespace\r\n"), []string{"extra", "whitespace"}, true},
+ {[]byte(" \r\n "), nil, true},
+ {[]byte(`"-r:foo" "-L/usr/white space/lib" "-lfoo bar" "-lbar baz"`), []string{"-r:foo", "-L/usr/white space/lib", "-lfoo bar", "-lbar baz"}, true},
+ {[]byte(`"-lextra fun arg\\"`), []string{`-lextra fun arg\`}, true},
+ {[]byte(`" \r\n\ "`), []string{` \r\n\ `}, true},
+ {[]byte(`""`), nil, true},
+ {[]byte(``), nil, true},
+ {[]byte(`"\\"`), []string{`\`}, true},
+ {[]byte(`"\x"`), []string{`\x`}, true},
+ {[]byte(`"\\x"`), []string{`\x`}, true},
+ {[]byte(`'\\'`), []string{`\`}, true},
+ {[]byte(`'\x'`), []string{`\x`}, true},
+ {[]byte(`"\\x"`), []string{`\x`}, true},
+ {[]byte(`-fPIC -I/test/include/foo -DQUOTED='"/test/share/doc"'`), []string{"-fPIC", "-I/test/include/foo", `-DQUOTED="/test/share/doc"`}, true},
+ {[]byte(`-fPIC -I/test/include/foo -DQUOTED="/test/share/doc"`), []string{"-fPIC", "-I/test/include/foo", "-DQUOTED=/test/share/doc"}, true},
+ {[]byte(`-fPIC -I/test/include/foo -DQUOTED=\"/test/share/doc\"`), []string{"-fPIC", "-I/test/include/foo", `-DQUOTED="/test/share/doc"`}, true},
+ {[]byte(`-fPIC -I/test/include/foo -DQUOTED='/test/share/doc'`), []string{"-fPIC", "-I/test/include/foo", "-DQUOTED=/test/share/doc"}, true},
+ {[]byte(`-DQUOTED='/te\st/share/d\oc'`), []string{`-DQUOTED=/te\st/share/d\oc`}, true},
+ {[]byte(`-Dhello=10 -Dworld=+32 -DDEFINED_FROM_PKG_CONFIG=hello\ world`), []string{"-Dhello=10", "-Dworld=+32", "-DDEFINED_FROM_PKG_CONFIG=hello world"}, true},
+ {[]byte(`" \r\n `), nil, false},
+ {[]byte(`"-r:foo" "-L/usr/white space/lib "-lfoo bar" "-lbar baz"`), nil, false},
+ {[]byte(`"-lextra fun arg\\`), nil, false},
} { } {
- got := splitPkgConfigOutput(test.in) - got := splitPkgConfigOutput(test.in)
+ got, err := splitPkgConfigOutput(test.in) + got, err := splitPkgConfigOutput(test.in)
+ if err != nil { + if err != nil {
+ if test.pass {
+ t.Errorf("splitPkgConfigOutput(%v) = %v; function returned error %v", test.in, got, err) + t.Errorf("splitPkgConfigOutput(%v) = %v; function returned error %v", test.in, got, err)
+ }
+ if got != nil {
+ t.Errorf("splitPkgConfigOutput failed with error %v and output has been non nil %v", err, got)
+ }
+ continue
+ } + }
if !reflect.DeepEqual(got, test.want) { if !reflect.DeepEqual(got, test.want) {
t.Errorf("splitPkgConfigOutput(%v) = %v; want %v", test.in, got, test.want) t.Errorf("splitPkgConfigOutput(%v) = %v; want %v", test.in, got, test.want)
} }
diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go
index 60e2a3aa48..c5a438aac9 100644 index a5ab75f6a8..8774be1385 100644
--- a/src/cmd/go/internal/work/exec.go --- a/src/cmd/go/internal/work/exec.go
+++ b/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go
@@ -855,36 +855,67 @@ func (b *Builder) PkgconfigCmd() string { @@ -900,36 +900,62 @@ func (b *Builder) PkgconfigCmd() string {
} }
// splitPkgConfigOutput parses the pkg-config output into a slice of // splitPkgConfigOutput parses the pkg-config output into a slice of
-// flags. pkg-config always uses \ to escape special characters. -// flags. pkg-config always uses \ to escape special characters.
-func splitPkgConfigOutput(out []byte) []string { -func splitPkgConfigOutput(out []byte) []string {
+// flags. Implementing algorithm from pkgconf/libpkgconf/argvsplit.c +// flags. This implements the algorithm from pkgconf/libpkgconf/argvsplit.c
+func splitPkgConfigOutput(out []byte) ([]string, error) { +func splitPkgConfigOutput(out []byte) ([]string, error) {
if len(out) == 0 { if len(out) == 0 {
- return nil - return nil
@ -62,26 +90,26 @@ index 60e2a3aa48..c5a438aac9 100644
var flags []string var flags []string
- flag := make([]byte, len(out)) - flag := make([]byte, len(out))
- r, w := 0, 0 - r, w := 0, 0
+ flag := make([]byte, 0, len(out)) - for r < len(out) {
+ r := 0
+ escaped := false
+ var quote byte = 0
+
for r < len(out) {
- switch out[r] { - switch out[r] {
- case ' ', '\t', '\r', '\n': - case ' ', '\t', '\r', '\n':
- if w > 0 { - if w > 0 {
- flags = append(flags, string(flag[:w])) - flags = append(flags, string(flag[:w]))
+ flag := make([]byte, 0, len(out))
+ escaped := false
+ quote := byte(0)
+
+ for _, c := range out {
+ if escaped { + if escaped {
+ if quote == '"' { + if quote == '"' || quote == '\'' {
+ switch out[r] { + switch c {
+ case '$', '`', '"', '\\': + case '$', '`', '"', '\\':
+ default: + default:
+ flag = append(flag, '\\') + flag = append(flag, '\\')
+ } + }
+ flag = append(flag, out[r]) + flag = append(flag, c)
+ } else { + } else {
+ flag = append(flag, out[r]) + flag = append(flag, c)
} }
- w = 0 - w = 0
- case '\\': - case '\\':
@ -93,39 +121,36 @@ index 60e2a3aa48..c5a438aac9 100644
- w++ - w++
+ escaped = false + escaped = false
+ } else if quote != 0 { + } else if quote != 0 {
+ if out[r] == quote { + if c == quote {
+ quote = 0 + quote = 0
+ } else { + } else {
+ switch out[r] { + switch c {
+ case '\\': + case '\\':
+ if quote == '\'' {
+ break
+ }
+ escaped = true + escaped = true
+ default: + default:
+ flag = append(flag, out[r]) + flag = append(flag, c)
+ } + }
+ } }
+ } else if !(strings.IndexByte(" \t\n\v\f\r", out[r]) >= 0) { + } else if strings.IndexByte(" \t\n\v\f\r", c) < 0 {
+ switch out[r] { + switch c {
+ case '\\': + case '\\':
+ escaped = true + escaped = true
+ case '\'', '"': + case '\'', '"':
+ quote = out[r] + quote = c
+ default: + default:
+ flag = append(flag, out[r]) + flag = append(flag, c)
} + }
+ } else if len(flag) != 0 { + } else if len(flag) != 0 {
+ flags = append(flags, string(flag)) + flags = append(flags, string(flag))
+ flag = flag[:0] + flag = flag[:0]
} }
r++ - r++
} }
- if w > 0 { - if w > 0 {
- flags = append(flags, string(flag[:w])) - flags = append(flags, string(flag[:w]))
+ +
+ if quote != 0 { + if quote != 0 {
+ return flags, errors.New("unterminated quoted string in pkgconf output " + string(out)) + return nil, errors.New("unterminated quoted string in pkgconf output ")
+ } else if len(flag) != 0 { + } else if len(flag) != 0 {
+ flags = append(flags, string(flag)) + flags = append(flags, string(flag))
} }
@ -135,21 +160,18 @@ index 60e2a3aa48..c5a438aac9 100644
} }
// Calls pkg-config if needed and returns the cflags/ldflags needed to build the package. // Calls pkg-config if needed and returns the cflags/ldflags needed to build the package.
@@ -899,7 +930,13 @@ func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string, @@ -948,7 +974,10 @@ func (b *Builder) getPkgConfigFlags(p *load.Package) (cflags, ldflags []string,
return return nil, nil, errPrintedOutput
} }
if len(out) > 0 { if len(out) > 0 {
- cflags = splitPkgConfigOutput(out) - cflags = splitPkgConfigOutput(out)
+ cflags, err = splitPkgConfigOutput(out) + cflags, err = splitPkgConfigOutput(out)
+ if err != nil { + if err != nil {
+ b.showOutput(nil, p.Dir, b.PkgconfigCmd()+" --libs "+strings.Join(pkgs, " "), string(out)) + return nil, nil, err
+ b.Print(err.Error() + "\n")
+ err = errPrintedOutput
+ return
+ } + }
if err := checkCompilerFlags("CFLAGS", "pkg-config --cflags", cflags); err != nil {
return nil, nil, err
} }
out, err = b.runOut(p.Dir, p.ImportPath, nil, b.PkgconfigCmd(), "--libs", pkgs)
if err != nil {
-- --
2.14.3 2.14.3

View File

@ -102,11 +102,11 @@
%endif %endif
%global go_api 1.10 %global go_api 1.10
%global go_version 1.10rc1 %global go_version 1.10rc2
Name: golang Name: golang
Version: 1.10 Version: 1.10
Release: 0.rc1.1%{?dist}.1 Release: 0.rc2.1%{?dist}
Summary: The Go Programming Language Summary: The Go Programming Language
# source tree includes several copies of Mark.Twain-Tom.Sawyer.txt under Public Domain # source tree includes several copies of Mark.Twain-Tom.Sawyer.txt under Public Domain
License: BSD and Public Domain License: BSD and Public Domain
@ -547,6 +547,11 @@ fi
%endif %endif
%changelog %changelog
* Thu Feb 08 2018 Jakub Čajka <jcajka@redhat.com> - 1.10-0.rc2.1
- Rebase to 1.10rc2
- Fix CVE-2018-6574
- Resolves: BZ#1543561, BZ#1543562
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.10-0.rc1.1.1 * Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1.10-0.rc1.1.1
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild - Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild

View File

@ -1 +1 @@
SHA512 (go1.10rc1.src.tar.gz) = 097fae8c161338922bd1b5e6d8e990eaa47aaa034daab56a2d8edc7a1750bfcc16d80fb5a4b2a5a9b444d29cdc926d0cfaf258052e6b891abd634c37edcd0421 SHA512 (go1.10rc2.src.tar.gz) = 7610ff51fa2f333d939b61c8b120684a7dd33cf370e76ec68e4eb5ee8bd85ec9b9517b609ae661a0a8a00263994ee898bb6ed9c3e16a8e8fe62def3e70b9071e