| From 451766789f646617157c725e20c955d4a9a70d4e Mon Sep 17 00:00:00 2001 |
| From: Roland Shoemaker <bracewell@google.com> |
| Date: Mon, 6 Feb 2023 10:03:44 -0800 |
| Subject: [PATCH] net/http: update bundled golang.org/x/net/http2 |
| |
| Disable cmd/internal/moddeps test, since this update includes PRIVATE |
| track fixes. |
| |
| Fixes CVE-2022-41723 |
| Fixes #58355 |
| Updates #57855 |
| |
| Change-Id: Ie870562a6f6e44e4e8f57db6a0dde1a41a2b090c |
| Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1728939 |
| Reviewed-by: Damien Neil <dneil@google.com> |
| Reviewed-by: Julie Qiu <julieqiu@google.com> |
| Reviewed-by: Tatiana Bradley <tatianabradley@google.com> |
| Run-TryBot: Roland Shoemaker <bracewell@google.com> |
| Reviewed-on: https://go-review.googlesource.com/c/go/+/468118 |
| TryBot-Result: Gopher Robot <gobot@golang.org> |
| Run-TryBot: Michael Pratt <mpratt@google.com> |
| Auto-Submit: Michael Pratt <mpratt@google.com> |
| Reviewed-by: Than McIntosh <thanm@google.com> |
| |
| Upstream-Status: Backport [https://github.com/golang/go/commit/5c3e11bd0b5c0a86e5beffcd4339b86a902b21c3] |
| CVE: CVE-2022-41723 |
| Signed-off-by: Shubham Kulkarni <skulkarni@mvista.com> |
| --- |
| src/vendor/golang.org/x/net/http2/hpack/hpack.go | 79 +++++++++++++++--------- |
| 1 file changed, 49 insertions(+), 30 deletions(-) |
| |
| diff --git a/src/vendor/golang.org/x/net/http2/hpack/hpack.go b/src/vendor/golang.org/x/net/http2/hpack/hpack.go |
| index 85f18a2..02e80e3 100644 |
| --- a/src/vendor/golang.org/x/net/http2/hpack/hpack.go |
| +++ b/src/vendor/golang.org/x/net/http2/hpack/hpack.go |
| @@ -359,6 +359,7 @@ func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error { |
| |
| var hf HeaderField |
| wantStr := d.emitEnabled || it.indexed() |
| + var undecodedName undecodedString |
| if nameIdx > 0 { |
| ihf, ok := d.at(nameIdx) |
| if !ok { |
| @@ -366,15 +367,27 @@ func (d *Decoder) parseFieldLiteral(n uint8, it indexType) error { |
| } |
| hf.Name = ihf.Name |
| } else { |
| - hf.Name, buf, err = d.readString(buf, wantStr) |
| + undecodedName, buf, err = d.readString(buf) |
| if err != nil { |
| return err |
| } |
| } |
| - hf.Value, buf, err = d.readString(buf, wantStr) |
| + undecodedValue, buf, err := d.readString(buf) |
| if err != nil { |
| return err |
| } |
| + if wantStr { |
| + if nameIdx <= 0 { |
| + hf.Name, err = d.decodeString(undecodedName) |
| + if err != nil { |
| + return err |
| + } |
| + } |
| + hf.Value, err = d.decodeString(undecodedValue) |
| + if err != nil { |
| + return err |
| + } |
| + } |
| d.buf = buf |
| if it.indexed() { |
| d.dynTab.add(hf) |
| @@ -459,46 +472,52 @@ func readVarInt(n byte, p []byte) (i uint64, remain []byte, err error) { |
| return 0, origP, errNeedMore |
| } |
| |
| -// readString decodes an hpack string from p. |
| +// readString reads an hpack string from p. |
| // |
| -// wantStr is whether s will be used. If false, decompression and |
| -// []byte->string garbage are skipped if s will be ignored |
| -// anyway. This does mean that huffman decoding errors for non-indexed |
| -// strings past the MAX_HEADER_LIST_SIZE are ignored, but the server |
| -// is returning an error anyway, and because they're not indexed, the error |
| -// won't affect the decoding state. |
| -func (d *Decoder) readString(p []byte, wantStr bool) (s string, remain []byte, err error) { |
| +// It returns a reference to the encoded string data to permit deferring decode costs |
| +// until after the caller verifies all data is present. |
| +func (d *Decoder) readString(p []byte) (u undecodedString, remain []byte, err error) { |
| if len(p) == 0 { |
| - return "", p, errNeedMore |
| + return u, p, errNeedMore |
| } |
| isHuff := p[0]&128 != 0 |
| strLen, p, err := readVarInt(7, p) |
| if err != nil { |
| - return "", p, err |
| + return u, p, err |
| } |
| if d.maxStrLen != 0 && strLen > uint64(d.maxStrLen) { |
| - return "", nil, ErrStringLength |
| + // Returning an error here means Huffman decoding errors |
| + // for non-indexed strings past the maximum string length |
| + // are ignored, but the server is returning an error anyway |
| + // and because the string is not indexed the error will not |
| + // affect the decoding state. |
| + return u, nil, ErrStringLength |
| } |
| if uint64(len(p)) < strLen { |
| - return "", p, errNeedMore |
| - } |
| - if !isHuff { |
| - if wantStr { |
| - s = string(p[:strLen]) |
| - } |
| - return s, p[strLen:], nil |
| + return u, p, errNeedMore |
| } |
| + u.isHuff = isHuff |
| + u.b = p[:strLen] |
| + return u, p[strLen:], nil |
| +} |
| |
| - if wantStr { |
| - buf := bufPool.Get().(*bytes.Buffer) |
| - buf.Reset() // don't trust others |
| - defer bufPool.Put(buf) |
| - if err := huffmanDecode(buf, d.maxStrLen, p[:strLen]); err != nil { |
| - buf.Reset() |
| - return "", nil, err |
| - } |
| +type undecodedString struct { |
| + isHuff bool |
| + b []byte |
| +} |
| + |
| +func (d *Decoder) decodeString(u undecodedString) (string, error) { |
| + if !u.isHuff { |
| + return string(u.b), nil |
| + } |
| + buf := bufPool.Get().(*bytes.Buffer) |
| + buf.Reset() // don't trust others |
| + var s string |
| + err := huffmanDecode(buf, d.maxStrLen, u.b) |
| + if err == nil { |
| s = buf.String() |
| - buf.Reset() // be nice to GC |
| } |
| - return s, p[strLen:], nil |
| + buf.Reset() // be nice to GC |
| + bufPool.Put(buf) |
| + return s, err |
| } |
| -- |
| 2.7.4 |