mirror of
https://github.com/hashicorp/vault.git
synced 2026-02-18 18:38:08 -05:00
pkcs7: fix slice out-of-bounds panic (#24891)
* pkcs7: fix slice out-of-bounds panic * changelog * fix tests * add test case to capture panic; found in fuzzing * add fuzz test
This commit is contained in:
parent
80f85a05f6
commit
3fffae9452
3 changed files with 42 additions and 6 deletions
3
changelog/24891.txt
Normal file
3
changelog/24891.txt
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
```release-note:bug
|
||||
helper/pkcs7: Fix slice out-of-bounds panic
|
||||
```
|
||||
|
|
@ -149,14 +149,14 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
|
|||
for ber[offset] >= 0x80 {
|
||||
tag = tag*128 + ber[offset] - 0x80
|
||||
offset++
|
||||
if offset > berLen {
|
||||
if offset >= berLen {
|
||||
return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached")
|
||||
}
|
||||
}
|
||||
// jvehent 20170227: this doesn't appear to be used anywhere...
|
||||
// tag = tag*128 + ber[offset] - 0x80
|
||||
offset++
|
||||
if offset > berLen {
|
||||
if offset >= berLen {
|
||||
return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached")
|
||||
}
|
||||
}
|
||||
|
|
@ -172,7 +172,7 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
|
|||
var length int
|
||||
l := ber[offset]
|
||||
offset++
|
||||
if offset > berLen {
|
||||
if offset >= berLen {
|
||||
return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached")
|
||||
}
|
||||
indefinite := false
|
||||
|
|
@ -192,7 +192,7 @@ func readObject(ber []byte, offset int) (asn1Object, int, error) {
|
|||
for i := 0; i < numberOfBytes; i++ {
|
||||
length = length*256 + (int)(ber[offset])
|
||||
offset++
|
||||
if offset > berLen {
|
||||
if offset >= berLen {
|
||||
return nil, 0, errors.New("ber2der: cannot move offset forward, end of ber data reached")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,38 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
// FuzzReadObject is a fuzz test that will generate random input data in an
|
||||
// attempt to find crash-causing inputs
|
||||
// https://go.dev/doc/security/fuzz
|
||||
func FuzzReadObject(f *testing.F) {
|
||||
// seed corpus used to guide the fuzzing engine
|
||||
seedCorpus := []struct {
|
||||
input []byte
|
||||
offset int
|
||||
}{
|
||||
{[]byte{0x30, 0x85}, 0},
|
||||
{[]byte{0x30, 0x84, 0x80, 0x0, 0x0, 0x0}, 0},
|
||||
{[]byte{0x30, 0x82, 0x0, 0x1}, 0},
|
||||
{[]byte{0x30, 0x80, 0x1, 0x2, 0x1, 0x2}, 0},
|
||||
{[]byte{0x30, 0x80, 0x1, 0x2}, 0},
|
||||
{[]byte{0x30, 0x03, 0x01, 0x02}, 0},
|
||||
{[]byte{0x30}, 0},
|
||||
{[]byte("?0"), 0},
|
||||
}
|
||||
for _, tc := range seedCorpus {
|
||||
f.Add(tc.input, tc.offset) // Use f.Add to provide a seed corpus
|
||||
}
|
||||
f.Fuzz(func(t *testing.T, ber []byte, offset int) {
|
||||
if offset < 0 {
|
||||
return
|
||||
}
|
||||
_, _, err := readObject(ber, offset)
|
||||
if err != nil {
|
||||
t.Log(ber, offset)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestBer2Der(t *testing.T) {
|
||||
// indefinite length fixture
|
||||
ber := []byte{0x30, 0x80, 0x02, 0x01, 0x01, 0x00, 0x00}
|
||||
|
|
@ -44,13 +76,14 @@ func TestBer2Der_Negatives(t *testing.T) {
|
|||
Input []byte
|
||||
ErrorContains string
|
||||
}{
|
||||
{[]byte{0x30, 0x85}, "tag length too long"},
|
||||
{[]byte{0x30, 0x85}, "end of ber data reached"},
|
||||
{[]byte{0x30, 0x84, 0x80, 0x0, 0x0, 0x0}, "length is negative"},
|
||||
{[]byte{0x30, 0x82, 0x0, 0x1}, "length has leading zero"},
|
||||
{[]byte{0x30, 0x80, 0x1, 0x2, 0x1, 0x2}, "Invalid BER format"},
|
||||
{[]byte{0x30, 0x80, 0x1, 0x2}, "BER tag length is more than available data"},
|
||||
{[]byte{0x30, 0x80, 0x1, 0x2}, "end of ber data reached"},
|
||||
{[]byte{0x30, 0x03, 0x01, 0x02}, "length is more than available data"},
|
||||
{[]byte{0x30}, "end of ber data reached"},
|
||||
{[]byte("?0"), "end of ber data reached"},
|
||||
}
|
||||
|
||||
for _, fixture := range fixtures {
|
||||
|
|
|
|||
Loading…
Reference in a new issue