Skip to content

Commit fea90a9

Browse files
liam-laiLiam Lai
andauthored
RIN-02 Panic Due to Integer Overflow in Signature Size Calculation (#401)
* RIN-02 Panic Due to Integer Overflow in Signature Size Calculation * assert the error * simply overflow check * simply overflow check --------- Co-authored-by: Liam Lai <[email protected]>
1 parent 95e108c commit fea90a9

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

core/vm/privacy/ringct.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,20 @@ func (r *RingSignature) Serialize() ([]byte, error) {
176176
}
177177

178178
func computeSignatureSize(numRing int, ringSize int) int {
179+
const MaxInt = int(^uint(0) >> 1)
180+
181+
if numRing < 0 || ringSize < 0 {
182+
return -1
183+
}
184+
185+
// Calculate term and check for overflow
186+
187+
term := numRing * ringSize * 65
188+
189+
if term < 0 || term < numRing || term < ringSize {
190+
return -1
191+
}
192+
179193
return 8 + 8 + 32 + 32 + numRing*ringSize*32 + numRing*ringSize*33 + numRing*33
180194
}
181195

@@ -200,7 +214,7 @@ func Deserialize(r []byte) (*RingSignature, error) {
200214
sig.NumRing = size_int
201215

202216
if len(r) != computeSignatureSize(sig.NumRing, sig.Size) {
203-
return nil, errors.New("incorrect ring size")
217+
return nil, fmt.Errorf("incorrect ring size, len r: %d, sig.NumRing: %d sig.Size: %d", len(r), sig.NumRing, sig.Size)
204218
}
205219

206220
m := r[offset : offset+32]

core/vm/privacy/ringct_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package privacy
22

33
import (
44
"bytes"
5+
"encoding/binary"
56
"fmt"
67
"testing"
78

@@ -48,6 +49,40 @@ func TestSign(t *testing.T) {
4849

4950
}
5051

52+
func TestDeserialize(t *testing.T) {
53+
numRing := 5
54+
ringSize := 10
55+
s := 5
56+
rings, privkeys, m, err := GenerateMultiRingParams(numRing, ringSize, s)
57+
58+
ringSignature, err := Sign(m, rings, privkeys, s)
59+
if err != nil {
60+
t.Error("Failed to create Ring signature")
61+
}
62+
63+
// A normal signature.
64+
sig, err := ringSignature.Serialize()
65+
if err != nil {
66+
t.Error("Failed to Serialize input Ring signature")
67+
}
68+
69+
// Modify the serialized signature s.t.
70+
// the new signature passes the length check
71+
// but triggers buffer overflow in Deserialize().
72+
// ringSize: 10 -> 56759212534490939
73+
// len(sig): 3495 -> 3804
74+
// 80 + 5 * (56759212534490939*65 + 33) = 18446744073709551616 + 3804
75+
bs := make([]byte, 8)
76+
binary.BigEndian.PutUint64(bs, 56759212534490939)
77+
for i := 0; i < 8; i++ {
78+
sig[i+8] = bs[i]
79+
}
80+
tail := make([]byte, 3804-len(sig))
81+
sig = append(sig, tail...)
82+
83+
_, err = Deserialize(sig)
84+
assert.EqualError(t, err, "incorrect ring size, len r: 3804, sig.NumRing: 5 sig.Size: 56759212534490939")
85+
}
5186
func TestPadTo32Bytes(t *testing.T) {
5287
arr := [44]byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34}
5388

0 commit comments

Comments
 (0)