From f365b3275efd732f4fdcef113c37514243cffc8a Mon Sep 17 00:00:00 2001 From: Eric Chiang Date: Tue, 8 Oct 2019 08:56:32 -0700 Subject: [PATCH] attest: ensure parsing event can't allocated unbounded memory Add a sanity check to ensure the measurement log actually contains as much data as the event size reports. --- attest/eventlog.go | 19 +++++++++++++++++-- attest/eventlog_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/attest/eventlog.go b/attest/eventlog.go index 750d3b0..ef56324 100644 --- a/attest/eventlog.go +++ b/attest/eventlog.go @@ -480,11 +480,23 @@ type rawEventHeader struct { EventSize uint32 } -func parseRawEvent(r io.Reader) (event rawEvent, err error) { +type eventSizeErr struct { + eventSize uint32 + logSize int +} + +func (e *eventSizeErr) Error() string { + return fmt.Sprintf("event data size (%d bytes) is greater than remaining measurement log (%d bytes)", e.eventSize, e.logSize) +} + +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, &eventSizeErr{h.EventSize, r.Len()} + } data := make([]byte, int(h.EventSize)) if _, err := io.ReadFull(r, data); err != nil { return event, err @@ -504,7 +516,7 @@ type rawEvent2Header struct { Type uint32 } -func parseRawEvent2(r io.Reader) (event rawEvent, err error) { +func parseRawEvent2(r *bytes.Buffer) (event rawEvent, err error) { var h rawEvent2Header if err = binary.Read(r, binary.LittleEndian, &h); err != nil { return event, err @@ -543,6 +555,9 @@ func parseRawEvent2(r io.Reader) (event rawEvent, err error) { if err = binary.Read(r, binary.LittleEndian, &eventSize); err != nil { return event, err } + if eventSize > uint32(r.Len()) { + return event, &eventSizeErr{eventSize, r.Len()} + } event.data = make([]byte, int(eventSize)) if _, err := io.ReadFull(r, event.data); err != nil { return event, err diff --git a/attest/eventlog_test.go b/attest/eventlog_test.go index ccf2fe6..d34b68f 100644 --- a/attest/eventlog_test.go +++ b/attest/eventlog_test.go @@ -122,3 +122,29 @@ func testEventLog(t *testing.T, testdata string) { } } } + +func TestParseEventLogEventSizeTooLarge(t *testing.T) { + data := []byte{ + // PCR index + 0x30, 0x34, 0x39, 0x33, + // type + 0x36, 0x30, 0x30, 0x32, + + // Digest + 0x31, 0x39, 0x36, 0x33, 0x39, 0x34, 0x34, 0x37, 0x39, 0x32, + 0x31, 0x32, 0x32, 0x37, 0x39, 0x30, 0x34, 0x30, 0x31, 0x6d, + + // Even size (3.183 GB) + 0xbd, 0xbf, 0xef, 0x47, + + // "event data" + 0x00, 0x00, 0x00, 0x00, + } + + // If this doesn't panic, the test passed + // TODO(ericchiang): use errors.As once go-attestation switches to Go 1.13. + _, err := ParseEventLog(data) + if err == nil { + t.Fatalf("expected parsing invalid event log to fail") + } +}