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

crypto/types: CompactUnmarshal naively assumes bytes sent in will always be Uvarint encoded and crashes if negative #9165

Closed
2 of 4 tasks
odeke-em opened this issue Apr 22, 2021 · 0 comments · Fixed by #9196

Comments

@odeke-em
Copy link
Collaborator

Summary of Bug

I audited this code

func CompactUnmarshal(bz []byte) (*CompactBitArray, error) {
if len(bz) < 2 {
return nil, errors.New("compact bit array: invalid compact unmarshal size")
} else if bytes.Equal(bz, []byte("null")) {
return NewCompactBitArray(0), nil
}
size, n := binary.Uvarint(bz)
bz = bz[n:]
if len(bz) != int(size+7)/8 {
return nil, errors.New("compact bit array: invalid compact unmarshal size")
}
bA := &CompactBitArray{uint32(size % 8), bz}
return bA, nil
}

and look at this code

size, n := binary.Uvarint(bz)
bz = bz[n:]

all one needs to do is pass in bad bytes for the size and that'll be returned in n which is naively passed to a slice and hence a crash :-(

for example here is an excerpt that'll crash https://play.golang.org/p/UMRoxgM1sL7 or inlined

package main

import "encoding/binary"

func main() {
	bz := []byte{0xd7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01}
	size, n := binary.Uvarint(bz)
	bz = bz[n:]
	println(size, n)
}

which crashes with

panic: runtime error: slice bounds out of range [-11:]

goroutine 1 [running]:
main.main()
	/tmp/sandbox752607808/prog.go:8 +0xc6

In fact, I wrote a fuzz pass and it found 6 crashes in less than 4 seconds, it took me 5 seconds to read and figure it out as a human

$ go-fuzz
2021/04/21 18:22:11 workers: 8, corpus: 16 (1s ago), crashers: 6, restarts: 1/0, execs: 0 (0/sec), cover: 0, uptime: 3s
2021/04/21 18:22:14 workers: 8, corpus: 16 (4s ago), crashers: 7, restarts: 1/0, execs: 0 (0/sec), cover: 24, uptime: 6s

Remedy

We shouldn't be naively slicing here, we should return an error in these situations

Version

bffcae5


For Admin Use

  • Not duplicate issue
  • Appropriate labels applied
  • Appropriate contributors tagged
  • Contributor assigned/self-assigned

/cc @cuonglm

@mergify mergify bot closed this as completed in #9196 Apr 26, 2021
mergify bot pushed a commit that referenced this issue Apr 26, 2021
…x,SetIndex (#9196)

Fixes unchecked negative index access that'd cause panics, in CompactBitArray's:
* CompactUnmarshal, which blindly used the result of binary.Uvarint
* GetIndex
* SetIndex

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

Successfully merging a pull request may close this issue.

1 participant