golang/0022-fix-CVE-2020-29509-CVE-2020-29511.patch
jingrui d2049ce1ac golang: sync cve fix
Signed-off-by: jingrui <jingrui@huawei.com>
2021-01-18 17:40:01 +08:00

119 lines
3.5 KiB
Diff

From 96ffe2941c07e4a6b92357b6eb8739304f839bef Mon Sep 17 00:00:00 2001
From: jingrui <jingrui@huawei.com>
Date: Wed, 23 Dec 2020 15:58:14 +0800
Subject: [PATCH 1/2] encoding/xml: handle leading, trailing, or double colons
in names
Before this change, <:name> would parse as <name>, which could cause
issues in applications that rely on the parse-encode cycle to
round-trip. Similarly, <x name:=""> would parse as expected but then
have the attribute dropped when serializing because its name was empty.
Finally, <a:b:c> would parse and get serialized incorrectly. All these
values are invalid XML, but to minimize the impact of this change, we
parse them whole into Name.Local.
This issue was reported by Juho Nurminen of Mattermost as it leads to
round-trip mismatches. See #43168. It's not being fixed in a security
release because round-trip stability is not a currently supported
security property of encoding/xml, and we don't believe these fixes
would be sufficient to reliably guarantee it in the future.
Fixes CVE-2020-29509
Fixes CVE-2020-29511
Updates #43168
Conflict: NA
Reference: https://go-review.googlesource.com/c/go/+/277892
Change-Id: I68321c4d867305046f664347192948a889af3c7f
Signed-off-by: jingrui <jingrui@huawei.com>
---
src/encoding/xml/xml.go | 5 ++--
src/encoding/xml/xml_test.go | 58 ++++++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/src/encoding/xml/xml.go b/src/encoding/xml/xml.go
index ca059440a1..073ceee1b2 100644
--- a/src/encoding/xml/xml.go
+++ b/src/encoding/xml/xml.go
@@ -1152,8 +1152,9 @@ func (d *Decoder) nsname() (name Name, ok bool) {
if !ok {
return
}
- i := strings.Index(s, ":")
- if i < 0 {
+ if strings.Count(s, ":") > 1 {
+ name.Local = s
+ } else if i := strings.Index(s, ":"); i < 1 || i > len(s)-2 {
name.Local = s
} else {
name.Space = s[0:i]
diff --git a/src/encoding/xml/xml_test.go b/src/encoding/xml/xml_test.go
index ee4ffa2420..eef4dc3001 100644
--- a/src/encoding/xml/xml_test.go
+++ b/src/encoding/xml/xml_test.go
@@ -898,3 +898,61 @@ func TestTokenUnmarshaler(t *testing.T) {
d := NewTokenDecoder(tokReader{})
d.Decode(&Failure{})
}
+
+func testRoundTrip(t *testing.T, input string) {
+ t.Logf("input: %q", input)
+ d := NewDecoder(strings.NewReader(input))
+ var tokens []Token
+ var buf bytes.Buffer
+ e := NewEncoder(&buf)
+ for {
+ tok, err := d.Token()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ t.Fatalf("invalid input: %v", err)
+ }
+ if err := e.EncodeToken(tok); err != nil {
+ t.Fatalf("failed to re-encode input: %v", err)
+ }
+ tokens = append(tokens, CopyToken(tok))
+ }
+ if err := e.Flush(); err != nil {
+ t.Fatal(err)
+ }
+ t.Logf("output: %q", buf.String())
+
+ d = NewDecoder(&buf)
+ for {
+ tok, err := d.Token()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ t.Fatalf("failed to decode output: %v", err)
+ }
+ if len(tokens) == 0 {
+ t.Fatalf("unexpected token: %#v", tok)
+ }
+ a, b := tokens[0], tok
+ if !reflect.DeepEqual(a, b) {
+ t.Fatalf("token mismatch: %#v vs %#v", a, b)
+ }
+ tokens = tokens[1:]
+ }
+ if len(tokens) > 0 {
+ t.Fatalf("lost tokens: %#v", tokens)
+ }
+}
+
+func TestRoundTrip(t *testing.T) {
+ tests := map[string]string{
+ "leading colon": `<::Test ::foo="bar"><:::Hello></:::Hello><Hello></Hello></::Test>`,
+ "trailing colon": `<foo abc:="x"></foo>`,
+ "double colon": `<x:y:foo></x:y:foo>`,
+ }
+ for name, input := range tests {
+ t.Run(name, func(t *testing.T) { testRoundTrip(t, input) })
+ }
+}
--
2.17.1