From e07ae7631c8153e385c210357935812051eecde3 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Tue, 23 Aug 2016 22:21:29 +0200 Subject: [PATCH] Add more safety checks for Unpacker --- src/restic/pack/pack.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/restic/pack/pack.go b/src/restic/pack/pack.go index 78159dfa3..04b752123 100644 --- a/src/restic/pack/pack.go +++ b/src/restic/pack/pack.go @@ -235,7 +235,10 @@ type Unpacker struct { k *crypto.Key } -const preloadHeaderSize = 2048 +const ( + preloadHeaderSize = 2048 + maxHeaderSize = 16 * 1024 * 1024 +) // NewUnpacker returns a pointer to Unpacker which can be used to read // individual Blobs from a pack. @@ -264,6 +267,10 @@ func NewUnpacker(k *crypto.Key, ldr Loader) (*Unpacker, error) { length := int(binary.LittleEndian.Uint32(buf[p : p+bs])) buf = buf[:p] + if length > maxHeaderSize { + return nil, fmt.Errorf("header too large (%d bytes)", length) + } + // if the header is longer than the preloaded buffer, call the loader again. if length > len(buf) { buf = make([]byte, length) @@ -271,7 +278,10 @@ func NewUnpacker(k *crypto.Key, ldr Loader) (*Unpacker, error) { if err != nil { return nil, fmt.Errorf("Load at -%d failed: %v", len(buf), err) } - buf = buf[:n] + + if n != len(buf) { + return nil, fmt.Errorf("not enough header bytes read: wanted %v, got %v", len(buf), n) + } } buf = buf[len(buf)-length:]