diff options
| author | Archana Polampalli <archana.polampalli@windriver.com> | 2025-01-08 05:54:20 +0000 |
|---|---|---|
| committer | Steve Sakoman <steve@sakoman.com> | 2025-01-18 06:21:02 -0800 |
| commit | 0c88d20540f0513c3d79d10f34132b2296ac246c (patch) | |
| tree | 246daee0e389be0f6fbe8910c19a1d5496f5eedb /meta | |
| parent | f700dcdc1d7db04c126a42f1d8f9588ad295f09c (diff) | |
| download | poky-0c88d20540f0513c3d79d10f34132b2296ac246c.tar.gz | |
go: Fix CVE-2024-34156
Calling Decoder.Decode on a message which contains deeply nested structures can
cause a panic due to stack exhaustion. This is a follow-up to CVE-2022-30635.
Reference:
https://nvd.nist.gov/vuln/detail/CVE-2024-34156
Upstream-patch:
https://github.com/golang/go/commit/2092294f2b097c5828f4eace6c98a322c1510b01
(From OE-Core rev: 3aeeee86a53cee14bb1a6a485f8781459b6f2ffc)
Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
Signed-off-by: Steve Sakoman <steve@sakoman.com>
Diffstat (limited to 'meta')
| -rw-r--r-- | meta/recipes-devtools/go/go-1.17.13.inc | 1 | ||||
| -rw-r--r-- | meta/recipes-devtools/go/go-1.21/CVE-2024-34156.patch | 150 |
2 files changed, 151 insertions, 0 deletions
diff --git a/meta/recipes-devtools/go/go-1.17.13.inc b/meta/recipes-devtools/go/go-1.17.13.inc index 11bd2afde0..53ca869221 100644 --- a/meta/recipes-devtools/go/go-1.17.13.inc +++ b/meta/recipes-devtools/go/go-1.17.13.inc | |||
| @@ -59,6 +59,7 @@ SRC_URI += "\ | |||
| 59 | file://CVE-2024-24789.patch \ | 59 | file://CVE-2024-24789.patch \ |
| 60 | file://CVE-2024-24791.patch \ | 60 | file://CVE-2024-24791.patch \ |
| 61 | file://CVE-2024-34155.patch \ | 61 | file://CVE-2024-34155.patch \ |
| 62 | file://CVE-2024-34156.patch \ | ||
| 62 | " | 63 | " |
| 63 | SRC_URI[main.sha256sum] = "a1a48b23afb206f95e7bbaa9b898d965f90826f6f1d1fc0c1d784ada0cd300fd" | 64 | SRC_URI[main.sha256sum] = "a1a48b23afb206f95e7bbaa9b898d965f90826f6f1d1fc0c1d784ada0cd300fd" |
| 64 | 65 | ||
diff --git a/meta/recipes-devtools/go/go-1.21/CVE-2024-34156.patch b/meta/recipes-devtools/go/go-1.21/CVE-2024-34156.patch new file mode 100644 index 0000000000..d8a915d6e9 --- /dev/null +++ b/meta/recipes-devtools/go/go-1.21/CVE-2024-34156.patch | |||
| @@ -0,0 +1,150 @@ | |||
| 1 | From 2092294f2b097c5828f4eace6c98a322c1510b01 Mon Sep 17 00:00:00 2001 | ||
| 2 | From: Roland Shoemaker <bracewell@google.com> | ||
| 3 | Date: Fri, 3 May 2024 09:21:39 -0400 | ||
| 4 | Subject: [PATCH] encoding/gob: cover missed cases when checking ignore depth | ||
| 5 | |||
| 6 | This change makes sure that we are properly checking the ignored field | ||
| 7 | recursion depth in decIgnoreOpFor consistently. This prevents stack | ||
| 8 | exhaustion when attempting to decode a message that contains an | ||
| 9 | extremely deeply nested struct which is ignored. | ||
| 10 | |||
| 11 | Thanks to Md Sakib Anwar of The Ohio State University (anwar.40@osu.edu) | ||
| 12 | for reporting this issue. | ||
| 13 | |||
| 14 | Updates #69139 | ||
| 15 | Fixes #69144 | ||
| 16 | Fixes CVE-2024-34156 | ||
| 17 | |||
| 18 | Change-Id: Iacce06be95a5892b3064f1c40fcba2e2567862d6 | ||
| 19 | Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1440 | ||
| 20 | Reviewed-by: Russ Cox <rsc@google.com> | ||
| 21 | Reviewed-by: Damien Neil <dneil@google.com> | ||
| 22 | (cherry picked from commit f0a11f9b3aaa362cb1d05e095e3c8d421d4f087f) | ||
| 23 | Reviewed-on: https://go-internal-review.googlesource.com/c/go/+/1580 | ||
| 24 | Reviewed-by: Tatiana Bradley <tatianabradley@google.com> | ||
| 25 | Reviewed-on: https://go-review.googlesource.com/c/go/+/611182 | ||
| 26 | TryBot-Bypass: Dmitri Shuralyov <dmitshur@google.com> | ||
| 27 | Reviewed-by: Michael Pratt <mpratt@google.com> | ||
| 28 | Auto-Submit: Dmitri Shuralyov <dmitshur@google.com> | ||
| 29 | Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> | ||
| 30 | |||
| 31 | CVE: CVE-2024-34156 | ||
| 32 | |||
| 33 | Upstream-Status: Backport [https://github.com/golang/go/commit/2092294f2b097c5828f4eace6c98a322c1510b01] | ||
| 34 | |||
| 35 | Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com> | ||
| 36 | --- | ||
| 37 | src/encoding/gob/decode.go | 19 +++++++++++-------- | ||
| 38 | src/encoding/gob/decoder.go | 2 ++ | ||
| 39 | src/encoding/gob/gobencdec_test.go | 14 ++++++++++++++ | ||
| 40 | 3 files changed, 27 insertions(+), 8 deletions(-) | ||
| 41 | |||
| 42 | diff --git a/src/encoding/gob/decode.go b/src/encoding/gob/decode.go | ||
| 43 | index 0e0ec75..92d64cb 100644 | ||
| 44 | --- a/src/encoding/gob/decode.go | ||
| 45 | +++ b/src/encoding/gob/decode.go | ||
| 46 | @@ -874,8 +874,11 @@ func (dec *Decoder) decOpFor(wireId typeId, rt reflect.Type, name string, inProg | ||
| 47 | var maxIgnoreNestingDepth = 10000 | ||
| 48 | |||
| 49 | // decIgnoreOpFor returns the decoding op for a field that has no destination. | ||
| 50 | -func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp, depth int) *decOp { | ||
| 51 | - if depth > maxIgnoreNestingDepth { | ||
| 52 | +func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp) *decOp { | ||
| 53 | + // Track how deep we've recursed trying to skip nested ignored fields. | ||
| 54 | + dec.ignoreDepth++ | ||
| 55 | + defer func() { dec.ignoreDepth-- }() | ||
| 56 | + if dec.ignoreDepth > maxIgnoreNestingDepth { | ||
| 57 | error_(errors.New("invalid nesting depth")) | ||
| 58 | } | ||
| 59 | // If this type is already in progress, it's a recursive type (e.g. map[string]*T). | ||
| 60 | @@ -901,7 +904,7 @@ func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp, | ||
| 61 | errorf("bad data: undefined type %s", wireId.string()) | ||
| 62 | case wire.ArrayT != nil: | ||
| 63 | elemId := wire.ArrayT.Elem | ||
| 64 | - elemOp := dec.decIgnoreOpFor(elemId, inProgress, depth+1) | ||
| 65 | + elemOp := dec.decIgnoreOpFor(elemId, inProgress) | ||
| 66 | op = func(i *decInstr, state *decoderState, value reflect.Value) { | ||
| 67 | state.dec.ignoreArray(state, *elemOp, wire.ArrayT.Len) | ||
| 68 | } | ||
| 69 | @@ -909,15 +912,15 @@ func (dec *Decoder) decIgnoreOpFor(wireId typeId, inProgress map[typeId]*decOp, | ||
| 70 | case wire.MapT != nil: | ||
| 71 | keyId := dec.wireType[wireId].MapT.Key | ||
| 72 | elemId := dec.wireType[wireId].MapT.Elem | ||
| 73 | - keyOp := dec.decIgnoreOpFor(keyId, inProgress, depth+1) | ||
| 74 | - elemOp := dec.decIgnoreOpFor(elemId, inProgress, depth+1) | ||
| 75 | + keyOp := dec.decIgnoreOpFor(keyId, inProgress) | ||
| 76 | + elemOp := dec.decIgnoreOpFor(elemId, inProgress) | ||
| 77 | op = func(i *decInstr, state *decoderState, value reflect.Value) { | ||
| 78 | state.dec.ignoreMap(state, *keyOp, *elemOp) | ||
| 79 | } | ||
| 80 | |||
| 81 | case wire.SliceT != nil: | ||
| 82 | elemId := wire.SliceT.Elem | ||
| 83 | - elemOp := dec.decIgnoreOpFor(elemId, inProgress, depth+1) | ||
| 84 | + elemOp := dec.decIgnoreOpFor(elemId, inProgress) | ||
| 85 | op = func(i *decInstr, state *decoderState, value reflect.Value) { | ||
| 86 | state.dec.ignoreSlice(state, *elemOp) | ||
| 87 | } | ||
| 88 | @@ -1078,7 +1081,7 @@ func (dec *Decoder) compileSingle(remoteId typeId, ut *userTypeInfo) (engine *de | ||
| 89 | func (dec *Decoder) compileIgnoreSingle(remoteId typeId) *decEngine { | ||
| 90 | engine := new(decEngine) | ||
| 91 | engine.instr = make([]decInstr, 1) // one item | ||
| 92 | - op := dec.decIgnoreOpFor(remoteId, make(map[typeId]*decOp), 0) | ||
| 93 | + op := dec.decIgnoreOpFor(remoteId, make(map[typeId]*decOp)) | ||
| 94 | ovfl := overflow(dec.typeString(remoteId)) | ||
| 95 | engine.instr[0] = decInstr{*op, 0, nil, ovfl} | ||
| 96 | engine.numInstr = 1 | ||
| 97 | @@ -1123,7 +1126,7 @@ func (dec *Decoder) compileDec(remoteId typeId, ut *userTypeInfo) (engine *decEn | ||
| 98 | localField, present := srt.FieldByName(wireField.Name) | ||
| 99 | // TODO(r): anonymous names | ||
| 100 | if !present || !isExported(wireField.Name) { | ||
| 101 | - op := dec.decIgnoreOpFor(wireField.Id, make(map[typeId]*decOp), 0) | ||
| 102 | + op := dec.decIgnoreOpFor(wireField.Id, make(map[typeId]*decOp)) | ||
| 103 | engine.instr[fieldnum] = decInstr{*op, fieldnum, nil, ovfl} | ||
| 104 | continue | ||
| 105 | } | ||
| 106 | diff --git a/src/encoding/gob/decoder.go b/src/encoding/gob/decoder.go | ||
| 107 | index b476aaa..8fab2fd 100644 | ||
| 108 | --- a/src/encoding/gob/decoder.go | ||
| 109 | +++ b/src/encoding/gob/decoder.go | ||
| 110 | @@ -34,6 +34,8 @@ type Decoder struct { | ||
| 111 | freeList *decoderState // list of free decoderStates; avoids reallocation | ||
| 112 | countBuf []byte // used for decoding integers while parsing messages | ||
| 113 | err error | ||
| 114 | + // ignoreDepth tracks the depth of recursively parsed ignored fields | ||
| 115 | + ignoreDepth int | ||
| 116 | } | ||
| 117 | |||
| 118 | // NewDecoder returns a new decoder that reads from the io.Reader. | ||
| 119 | diff --git a/src/encoding/gob/gobencdec_test.go b/src/encoding/gob/gobencdec_test.go | ||
| 120 | index 1b52ecc..2b5f2a8 100644 | ||
| 121 | --- a/src/encoding/gob/gobencdec_test.go | ||
| 122 | +++ b/src/encoding/gob/gobencdec_test.go | ||
| 123 | @@ -806,6 +806,8 @@ func TestIngoreDepthLimit(t *testing.T) { | ||
| 124 | defer func() { maxIgnoreNestingDepth = oldNestingDepth }() | ||
| 125 | b := new(bytes.Buffer) | ||
| 126 | enc := NewEncoder(b) | ||
| 127 | + | ||
| 128 | + // Nested slice | ||
| 129 | typ := reflect.TypeOf(int(0)) | ||
| 130 | nested := reflect.ArrayOf(1, typ) | ||
| 131 | for i := 0; i < 100; i++ { | ||
| 132 | @@ -819,4 +821,16 @@ func TestIngoreDepthLimit(t *testing.T) { | ||
| 133 | if err := dec.Decode(&output); err == nil || err.Error() != expectedErr { | ||
| 134 | t.Errorf("Decode didn't fail with depth limit of 100: want %q, got %q", expectedErr, err) | ||
| 135 | } | ||
| 136 | + | ||
| 137 | + // Nested struct | ||
| 138 | + nested = reflect.StructOf([]reflect.StructField{{Name: "F", Type: typ}}) | ||
| 139 | + for i := 0; i < 100; i++ { | ||
| 140 | + nested = reflect.StructOf([]reflect.StructField{{Name: "F", Type: nested}}) | ||
| 141 | + } | ||
| 142 | + badStruct = reflect.New(reflect.StructOf([]reflect.StructField{{Name: "F", Type: nested}})) | ||
| 143 | + enc.Encode(badStruct.Interface()) | ||
| 144 | + dec = NewDecoder(b) | ||
| 145 | + if err := dec.Decode(&output); err == nil || err.Error() != expectedErr { | ||
| 146 | + t.Errorf("Decode didn't fail with depth limit of 100: want %q, got %q", expectedErr, err) | ||
| 147 | + } | ||
| 148 | } | ||
| 149 | -- | ||
| 150 | 2.40.0 | ||
