Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InnerOp.CheckAgainstSpec is vulnerable to a divide by zero panic #240

Closed
odeke-em opened this issue Dec 5, 2023 · 1 comment
Closed

Comments

@odeke-em
Copy link
Contributor

odeke-em commented Dec 5, 2023

Noticed while auditing the code in 

ics23/go/ops.go

Line 147 in 74ce807

if len(op.Suffix)%int(spec.InnerSpec.ChildSize) != 0 {

that no validation was performed on the spec.InnerSpec.ChildSize and as of the latest code on the main branch at commit https://github.com/cosmos/ics23/blob/74ce807b7be39a7e0afb4e2efb8e28a57965f57b

Exhibit

package ics23_test

import (
	"testing"

	ics23 "github.com/cosmos/ics23/go"
)

func TestReproDivideByZero(t *testing.T) {
	prefix := []byte("anything")
	proof := &ics23.ExistenceProof{
		Leaf: &ics23.LeafOp{PrehashValue: 1, Length: 1, Prefix: prefix},
		Path: []*ics23.InnerOp{{Hash: 1}},
	}
	spec := &ics23.ProofSpec{
		LeafSpec:  &ics23.LeafOp{PrehashValue: 1, Length: 1, Prefix: prefix},
		InnerSpec: &ics23.InnerSpec{Hash: 1},
	}
	_ = proof.CheckAgainstSpec(spec)
}

which gives

$ go test -run=ReproDivide
--- FAIL: TestReproDivideByZero (0.00s)
panic: runtime error: integer divide by zero [recovered]
	panic: runtime error: integer divide by zero

goroutine 18 [running]:
testing.tRunner.func1.2({0x757a460, 0x7802870})
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/testing/testing.go:1631 +0x24a
testing.tRunner.func1()
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/testing/testing.go:1634 +0x377
panic({0x757a460?, 0x7802870?})
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/runtime/panic.go:763 +0x132
github.com/cosmos/ics23/go.(*InnerOp).CheckAgainstSpec(0xc000259e40, 0xc000058740, 0x1)
	/Users/emmanuelodeke/go/src/github.com/cosmos/ics23/go/ops.go:146 +0x252
github.com/cosmos/ics23/go.(*ExistenceProof).CheckAgainstSpec(0xc000058670, 0xc000173f40)
	/Users/emmanuelodeke/go/src/github.com/cosmos/ics23/go/proof.go:200 +0x1bb
github.com/cosmos/ics23/go_test.TestReproDivideByZero(0xc000256ea0?)
	/Users/emmanuelodeke/go/src/github.com/cosmos/ics23/go/repro_test.go:19 +0x1d3
testing.tRunner(0xc000256ea0, 0x75d4510)
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/testing/testing.go:1682 +0xfb
created by testing.(*T).Run in goroutine 1
	/Users/emmanuelodeke/go/src/go.googlesource.com/go/src/testing/testing.go:1735 +0x390
exit status 2
FAIL	github.com/cosmos/ics23/go	0.294s

Fix

@@ -142,6 +152,10 @@ func (op *InnerOp) CheckAgainstSpec(spec *ProofSpec, b int) error {
                return fmt.Errorf("innerOp prefix too long (%d)", len(op.Prefix))
        }
 
+       if spec.InnerSpec.ChildSize <= 0 {
+               return errors.New("spec.InnerSpec.ChildSize must be >= 1")
+       }
+

/cc @elias-orijtech @julienrbrt

@odeke-em
Copy link
Contributor Author

Fixed by #244

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant