From ede504400f583763f23500b4cd1c03367e63b371 Mon Sep 17 00:00:00 2001 From: Nitish Tiwari Date: Fri, 12 Jan 2018 18:16:30 +0530 Subject: [PATCH] Add validation of xlMeta ErasureInfo field (#5389) --- cmd/xl-v1-metadata.go | 13 +++++++++--- cmd/xl-v1-metadata_test.go | 42 ++++++++++++++++++++++++++++++++++++++ cmd/xl-v1-utils.go | 2 +- 3 files changed, 53 insertions(+), 4 deletions(-) diff --git a/cmd/xl-v1-metadata.go b/cmd/xl-v1-metadata.go index 9a715db64..7a65cc737 100644 --- a/cmd/xl-v1-metadata.go +++ b/cmd/xl-v1-metadata.go @@ -266,18 +266,25 @@ func newXLMetaV1(object string, dataBlocks, parityBlocks int) (xlMeta xlMetaV1) } // IsValid - tells if the format is sane by validating the version -// string and format style. +// string, format and erasure info fields. func (m xlMetaV1) IsValid() bool { - return isXLMetaValid(m.Version, m.Format) + return isXLMetaFormatValid(m.Version, m.Format) && + isXLMetaErasureInfoValid(m.Erasure.DataBlocks, m.Erasure.ParityBlocks) } // Verifies if the backend format metadata is sane by validating // the version string and format style. -func isXLMetaValid(version, format string) bool { +func isXLMetaFormatValid(version, format string) bool { return ((version == xlMetaVersion || version == xlMetaVersion100) && format == xlMetaFormat) } +// Verifies if the backend format metadata is sane by validating +// the ErasureInfo, i.e. data and parity blocks. +func isXLMetaErasureInfoValid(data, parity int) bool { + return ((data >= parity) && (data != 0) && (parity != 0)) +} + // Converts metadata to object info. func (m xlMetaV1) ToObjectInfo(bucket, object string) ObjectInfo { objInfo := ObjectInfo{ diff --git a/cmd/xl-v1-metadata_test.go b/cmd/xl-v1-metadata_test.go index 3de561970..beadfafd3 100644 --- a/cmd/xl-v1-metadata_test.go +++ b/cmd/xl-v1-metadata_test.go @@ -368,3 +368,45 @@ func TestPickValidXLMeta(t *testing.T) { } } } + +func TestIsXLMetaFormatValid(t *testing.T) { + tests := []struct { + name int + version string + format string + want bool + }{ + {1, "123", "fs", false}, + {2, "123", xlMetaFormat, false}, + {3, xlMetaVersion, "test", false}, + {4, xlMetaVersion100, "hello", false}, + {5, xlMetaVersion, xlMetaFormat, true}, + {6, xlMetaVersion100, xlMetaFormat, true}, + } + for _, tt := range tests { + if got := isXLMetaFormatValid(tt.version, tt.format); got != tt.want { + t.Errorf("Test %d: Expected %v but received %v", tt.name, got, tt.want) + } + } +} + +func TestIsXLMetaErasureInfoValid(t *testing.T) { + tests := []struct { + name int + data int + parity int + want bool + }{ + {1, 5, 6, false}, + {2, 5, 5, true}, + {3, 0, 5, false}, + {4, 5, 0, false}, + {5, 5, 0, false}, + {6, 5, 4, true}, + } + for _, tt := range tests { + if got := isXLMetaErasureInfoValid(tt.data, tt.parity); got != tt.want { + t.Errorf("Test %d: Expected %v but received %v", tt.name, got, tt.want) + } + } +} diff --git a/cmd/xl-v1-utils.go b/cmd/xl-v1-utils.go index 1a8062716..768cb1b6f 100644 --- a/cmd/xl-v1-utils.go +++ b/cmd/xl-v1-utils.go @@ -269,7 +269,7 @@ func readXLMetaStat(disk StorageAPI, bucket string, object string) (si statInfo, xlFormat := parseXLFormat(xlMetaBuf) // Validate if the xl.json we read is sane, return corrupted format. - if !isXLMetaValid(xlVersion, xlFormat) { + if !isXLMetaFormatValid(xlVersion, xlFormat) { // For version mismatchs and unrecognized format, return corrupted format. return si, nil, errors2.Trace(errCorruptedFormat) }