From 4fdf9b195c3a50fa3f0adf371875bdd9d78d25a2 Mon Sep 17 00:00:00 2001 From: Sunny Klair Date: Wed, 25 Oct 2017 18:12:13 -0400 Subject: [PATCH] Validate index TOC checksum on read --- Documentation/format/chunks.md | 2 +- block.go | 2 +- index.go | 17 +++++++++++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Documentation/format/chunks.md b/Documentation/format/chunks.md index 51ac1242c..3faae9b7d 100644 --- a/Documentation/format/chunks.md +++ b/Documentation/format/chunks.md @@ -2,7 +2,7 @@ The following describes the format of a single chunks file, which is created in the `chunks/` directory of a block. The maximum size per segment file is 512MiB. -Chunks in the files are referenced from the index by the in-file offset in the 4 LSB and the segment sequence number in the bigher 4 MSBs. +Chunks in the files are referenced from the index by the in-file offset in the 4 LSB and the segment sequence number in the higher 4 MSBs. ``` ┌────────────────────────────────────────┬──────────────────────┐ diff --git a/block.go b/block.go index 63b468f27..2bd1fd364 100644 --- a/block.go +++ b/block.go @@ -133,7 +133,7 @@ func writeMetaFile(dir string, meta *BlockMeta) error { return renameFile(tmp, path) } -// Block represents a directory of time series data covering a continous time range. +// Block represents a directory of time series data covering a continuous time range. type Block struct { mtx sync.RWMutex closing bool diff --git a/index.go b/index.go index c0680aa33..972aaa8bd 100644 --- a/index.go +++ b/index.go @@ -573,8 +573,9 @@ type indexReader struct { } var ( - errInvalidSize = fmt.Errorf("invalid size") - errInvalidFlag = fmt.Errorf("invalid flag") + errInvalidSize = fmt.Errorf("invalid size") + errInvalidFlag = fmt.Errorf("invalid flag") + errInvalidChecksum = fmt.Errorf("invalid checksum") ) // NewIndexReader returns a new IndexReader on the given directory. @@ -618,6 +619,11 @@ func newIndexReader(dir string) (*indexReader, error) { func (r *indexReader) readTOC() error { d := r.decbufAt(len(r.b) - indexTOCLen) + crc := newCRC32() + if _, err := crc.Write(d.get()[:d.len()-4]); err != nil { + return errors.Wrap(err, "write to hash") + } + r.toc.symbols = d.be64() r.toc.series = d.be64() r.toc.labelIndices = d.be64() @@ -625,9 +631,12 @@ func (r *indexReader) readTOC() error { r.toc.postings = d.be64() r.toc.postingsTable = d.be64() - // TODO(fabxc): validate checksum. + // Validate checksum + if d.be32() != crc.Sum32() { + return errors.Wrap(errInvalidChecksum, "TOC checksum") + } - return nil + return d.err() } func (r *indexReader) decbufAt(off int) decbuf {