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

parseRawEvent can allocate an unbounded amount of memory #126

Closed
brandonweeks opened this issue Oct 8, 2019 · 2 comments · Fixed by #127
Closed

parseRawEvent can allocate an unbounded amount of memory #126

brandonweeks opened this issue Oct 8, 2019 · 2 comments · Fixed by #127
Assignees

Comments

@brandonweeks
Copy link
Member

var h rawEventHeader
if err = binary.Read(r, binary.LittleEndian, &h); err != nil {
    return event, err
}
data := make([]byte, int(h.EventSize))

In this code path an attacker can control the number of allocated bytes. This can lead to a DoS attack by OOMing the process.

Example:

Mzk0MDIwMDYxOTYzOTQ0NzkyMTIyNzkwNDAxbUfvv70AMDAxNDM2MTM4MDUwNzk3MzkyNzA0NjU0
NDY2Njc5NDgyOTM0MDQyNDU3MjE3NzE0OTY4NzAzMjkwNDcyNjYwODgyNTg5MzgwMDE4NjE2MDY5
NzMxMTIzMTk=

Produces:

rawEventHeader{
    PCRIndex:0x30343933, 
    Type:0x36303032, 
    Digest:[20]uint8{0x31, 0x39, 0x36, 0x33, 0x39, 0x34, 0x34, 0x37, 0x39, 0x32, 0x31, 0x32, 0x32, 0x37, 0x39, 0x30, 0x34, 0x30, 0x31, 0x6d},
    EventSize:0xbdbfef47,
}

0xbdbfef47 being 3.183 GB.

It doesn't appear that the TCG EFI Protocol Specification defines a maximum size for an event. So it seems our options are either choosing an arbitrary maximum or reporting this to the TCG as undefined behavior.

@ericchiang
Copy link
Member

Nice catch :)

What about adding a check to ensure h.EventSize isn't bigger than the remaining bytes in the measurement log?

func parseRawEvent(r *bytes.Buffer) (event rawEvent, err error) {
	var h rawEventHeader
	if err = binary.Read(r, binary.LittleEndian, &h); err != nil {
		return event, err
	}
	if h.EventSize > uint32(r.Len()) {
		return event, fmt.Errorf("event size (%d) was greater than remaining bytes in measurement log (%d)", h.EventSize, r.Len())
	}
	data := make([]byte, int(h.EventSize))
	if _, err := io.ReadFull(r, data); err != nil {
		return event, err
	}
	return rawEvent{
		typ:     EventType(h.Type),
		data:    data,
		index:   int(h.PCRIndex),
		digests: [][]byte{h.Digest[:]},
	}, nil
}

@ericchiang
Copy link
Member

#127

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

Successfully merging a pull request may close this issue.

2 participants