CVE-2022-2584 (published 2022-12-27T22:15Z)

The dag-pb codec can panic when decoding invalid blocks.

CVSS v3 base score: 7.5, HIGH (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-119
cwe_name: Improper Restriction of Operations within the Bounds of a Memory Buffer
description: The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.
extended_description: 
            Certain languages allow direct addressing of memory locations and do not automatically ensure that these locations are valid for the memory buffer that is being referenced. This can cause read or write operations to be performed on memory locations that may be associated with other variables, data structures, or internal program data.
         
         

Fix information:
repo_url: https://github.com/ipld/go-codec-dagpb
commit_details: repo_url: https://github.com/ipld/go-codec-dagpb
author: Rod Vagg
author_date: 2022-03-11 11:27:13+11:00
msg: fix: use protowire for Links bytes decoding
repository: repo_url: https://github.com/ipld/go-codec-dagpb
repo_name: ipld/go-codec-dagpb
description: An implementation of the DAG-PB spec for Go
repo_language: Go
owner: ipld
file_changes: filename: compat_test.go
change_type: ModificationType.MODIFY
diff: @@ -32,6 +32,7 @@ type testCase struct {
 	expectedForm  string
 	encodeError   string
 	decodeError   string
+	testEncode    bool
 }
 
 var testCases = []testCase{
@@ -64,6 +65,13 @@ var testCases = []testCase{
 }`,
 		encodeError: "missing required fields: Links",
 	},
+	{
+		name:          "Data some, short",
+		node:          &pbNode{data: dataSome},
+		expectedBytes: "0a0500010203",
+		decodeError:   "unexpected EOF",
+		encodeError:   "missing required fields: Links",
+	},
 	{
 		name:          "Links zero",
 		node:          &pbNode{links: []pbLink{}},
@@ -113,6 +121,12 @@ var testCases = []testCase{
 }`,
 	},
 	{
+		name:          "Links Hash some, short",
+		node:          &pbNode{links: []pbLink{{hash: acid}}},
+		expectedBytes: "120b0a090155000500010203",
+		decodeError:   "unexpected EOF",
+		testEncode:    false,
+	}, {
 		name:          "Links Name zero",
 		node:          &pbNode{links: []pbLink{{name: zeroName, hasName: true}}},
 		expectedBytes: "12021200",
@@ -211,24 +225,26 @@ func verifyRoundTrip(t *testing.T, tc testCase) {
 		node := buildNode(*tc.node)
 		actualBytes, err = nodeToString(t, node)
 
-		if tc.encodeError != "" {
-			if err != nil {
-				if !strings.Contains(err.Error(), tc.encodeError) {
-					t.Fatalf("got unexpeced encode error: [%v] (expected [%v])", err.Error(), tc.encodeError)
+		if tc.testEncode {
+			if tc.encodeError != "" {
+				if err != nil {
+					if !strings.Contains(err.Error(), tc.encodeError) {
+						t.Fatalf("got unexpeced encode error: [%v] (expected [%v])", err.Error(), tc.encodeError)
+					}
+				} else {
+					t.Fatalf("did not get expected encode error: %v", tc.encodeError)
 				}
 			} else {
-				t.Fatalf("did not get expected encode error: %v", tc.encodeError)
-			}
-		} else {
-			if err != nil {
-				t.Fatal(err)
-			} else {
-				if actualBytes != tc.expectedBytes {
-					t.Logf(
-						"Expected bytes: [%v]\nGot: [%v]\n",
-						tc.expectedBytes,
-						actualBytes)
-					t.Error("Did not match")
+				if err != nil {
+					t.Fatal(err)
+				} else {
+					if actualBytes != tc.expectedBytes {
+						t.Logf(
+							"Expected bytes: [%v]\nGot: [%v]\n",
+							tc.expectedBytes,
+							actualBytes)
+						t.Error("Did not match")
+					}
 				}
 			}
 		}

programming_language: Go
filename: unmarshal.go
change_type: ModificationType.MODIFY
diff: @@ -98,7 +98,7 @@ func DecodeBytes(na ipld.NodeAssembler, src []byte) error {
 			haveData = true
 
 		case 2:
-			bytesLen, n := protowire.ConsumeVarint(remaining)
+			chunk, n := protowire.ConsumeBytes(remaining)
 			if n < 0 {
 				return protowire.ParseError(n)
 			}
@@ -123,10 +123,9 @@ func DecodeBytes(na ipld.NodeAssembler, src []byte) error {
 			if err != nil {
 				return err
 			}
-			if err := unmarshalLink(remaining[:bytesLen], curLink); err != nil {
+			if err := unmarshalLink(chunk, curLink); err != nil {
 				return err
 			}
-			remaining = remaining[bytesLen:]
 			if err := curLink.Finish(); err != nil {
 				return err
 			}

programming_language: Go