Quellcode durchsuchen

Fix uint64->int overflow in table unmarshal (#461)

Damien Neil vor 8 Jahren
Ursprung
Commit
1ec9e17d4d
2 geänderte Dateien mit 13 neuen und 5 gelöschten Zeilen
  1. 9 1
      proto/all_test.go
  2. 4 4
      proto/table_unmarshal.go

+ 9 - 1
proto/all_test.go

@@ -1306,7 +1306,7 @@ func (*NNIMessage) Reset()         {}
 func (*NNIMessage) String() string { return "" }
 func (*NNIMessage) ProtoMessage()  {}
 
-type NMMessage struct {}
+type NMMessage struct{}
 
 func (*NMMessage) Reset()         {}
 func (*NMMessage) String() string { return "" }
@@ -1505,6 +1505,14 @@ func TestVarintOverflow(t *testing.T) {
 	}
 }
 
+func TestBytesWithInvalidLengthInGroup(t *testing.T) {
+	// Overflowing a 64-bit length should not be allowed.
+	b := []byte{0xbb, 0x30, 0xb2, 0x30, 0xb0, 0xb2, 0x83, 0xf1, 0xb0, 0xb2, 0xef, 0xbf, 0xbd, 0x01}
+	if err := Unmarshal(b, new(MyMessage)); err == nil {
+		t.Fatalf("Overflowed uint64 length without error")
+	}
+}
+
 func TestUnmarshalFuzz(t *testing.T) {
 	const N = 1000
 	seed := time.Now().UnixNano()

+ 4 - 4
proto/table_unmarshal.go

@@ -208,7 +208,7 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
 				b = b[8:]
 			case WireBytes:
 				m, k := decodeVarint(b)
-				if k == 0 || uint64(len(b)) < uint64(k)+m {
+				if k == 0 || uint64(len(b)-k) < m {
 					return io.ErrUnexpectedEOF
 				}
 				b = b[uint64(k)+m:]
@@ -1834,12 +1834,12 @@ func findEndGroup(b []byte) (int, int) {
 			}
 			i += k
 		case WireFixed32:
-			if i+4 > len(b) {
+			if len(b)-4 < i {
 				return -1, -1
 			}
 			i += 4
 		case WireFixed64:
-			if i+8 > len(b) {
+			if len(b)-8 < i {
 				return -1, -1
 			}
 			i += 8
@@ -1849,7 +1849,7 @@ func findEndGroup(b []byte) (int, int) {
 				return -1, -1
 			}
 			i += k
-			if i+int(m) > len(b) {
+			if uint64(len(b)-i) < m {
 				return -1, -1
 			}
 			i += int(m)