From 4233042a89ffd1ee2a29bd638831ebbfcf1de31b Mon Sep 17 00:00:00 2001 From: gggevorgyan Date: Wed, 11 Jan 2023 11:46:58 +0400 Subject: [PATCH 1/2] fix: for critical issue #19916 (influxdb server crashed when reading a corrupt file) Added check on indexOfsStart, to make index slice length fit in int32, and count should have >0 value otherwise it is corruption. - [ ] CHANGELOG.md updated - [*] Rebased/mergable - [*] Tests pass - [*] Sign [CLA](https://influxdata.com/community/cla/) (if not already signed) --- tsdb/engine/tsm1/reader.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tsdb/engine/tsm1/reader.go b/tsdb/engine/tsm1/reader.go index 424f35f0629..306e7b21f34 100644 --- a/tsdb/engine/tsm1/reader.go +++ b/tsdb/engine/tsm1/reader.go @@ -1233,6 +1233,10 @@ func (d *indirectIndex) UnmarshalBinary(b []byte) error { return fmt.Errorf("indirectIndex: not enough data for index entries count") } count := int32(binary.BigEndian.Uint16(b[i : i+indexCountSize])) + + if count <= 0 { + return fmt.Errorf("indirectIndex: the count should have >0 value") + } i += indexCountSize // Find the min time for the block @@ -1350,7 +1354,7 @@ func (m *mmapAccessor) init() (*indirectIndex, error) { indexOfsPos := len(m.b) - 8 indexStart := binary.BigEndian.Uint64(m.b[indexOfsPos : indexOfsPos+8]) - if indexStart >= uint64(indexOfsPos) { + if indexStart >= uint64(indexOfsPos) || (uint64(indexOfsPos)-indexStart) > math.MaxInt32 { return nil, fmt.Errorf("mmapAccessor: invalid indexStart") } From 96fa8173869340ce1c0d4b2b8be45788b2748462 Mon Sep 17 00:00:00 2001 From: Gevorg Gevorgyan Date: Mon, 19 Feb 2024 14:53:45 +0400 Subject: [PATCH 2/2] fix: Improved error message to reflect count in it --- tsdb/engine/tsm1/reader.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tsdb/engine/tsm1/reader.go b/tsdb/engine/tsm1/reader.go index 306e7b21f34..590d0dc7cb4 100644 --- a/tsdb/engine/tsm1/reader.go +++ b/tsdb/engine/tsm1/reader.go @@ -1235,7 +1235,7 @@ func (d *indirectIndex) UnmarshalBinary(b []byte) error { count := int32(binary.BigEndian.Uint16(b[i : i+indexCountSize])) if count <= 0 { - return fmt.Errorf("indirectIndex: the count should have >0 value") + return fmt.Errorf("invalid index %d; count must be greater than 0", count) } i += indexCountSize