From b00299ca13882cc65fe1c36408b5e57a654ac437 Mon Sep 17 00:00:00 2001
From: atvanguard <93arpit@gmail.com>
Date: Tue, 21 Apr 2020 09:50:44 +0530
Subject: [PATCH] fix: Validator list could be invalid making the node crash
 (2.13)

---
 consensus/bor/bor.go      | 21 +++++++++++++++------
 consensus/bor/snapshot.go |  3 +++
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/consensus/bor/bor.go b/consensus/bor/bor.go
index a33681c1d..58754c594 100644
--- a/consensus/bor/bor.go
+++ b/consensus/bor/bor.go
@@ -346,12 +346,9 @@ func (c *Bor) verifyHeader(chain consensus.ChainReader, header *types.Header, pa
 	if header.Time > uint64(time.Now().Unix()) {
 		return consensus.ErrFutureBlock
 	}
-	// Check that the extra-data contains both the vanity and signature
-	if len(header.Extra) < extraVanity {
-		return errMissingVanity
-	}
-	if len(header.Extra) < extraVanity+extraSeal {
-		return errMissingSignature
+
+	if err := validateHeaderExtraField(header.Extra); err != nil {
+		return err
 	}
 
 	// check extr adata
@@ -387,6 +384,18 @@ func (c *Bor) verifyHeader(chain consensus.ChainReader, header *types.Header, pa
 	return c.verifyCascadingFields(chain, header, parents)
 }
 
+// validateHeaderExtraField validates that the extra-data contains both the vanity and signature.
+// header.Extra = header.Vanity + header.ProducerBytes (optional) + header.Seal
+func validateHeaderExtraField(extraBytes []byte) error {
+	if len(extraBytes) < extraVanity {
+		return errMissingVanity
+	}
+	if len(extraBytes) < extraVanity+extraSeal {
+		return errMissingSignature
+	}
+	return nil
+}
+
 // verifyCascadingFields verifies all the header fields that are not standalone,
 // rather depend on a batch of previous headers. The caller may optionally pass
 // in a batch of parents (ascending order) to avoid looking those up from the
diff --git a/consensus/bor/snapshot.go b/consensus/bor/snapshot.go
index d2f0e82ff..8f197f335 100644
--- a/consensus/bor/snapshot.go
+++ b/consensus/bor/snapshot.go
@@ -185,6 +185,9 @@ func (s *Snapshot) apply(headers []*types.Header) (*Snapshot, error) {
 
 		// change validator set and change proposer
 		if number > 0 && (number+1)%s.config.Sprint == 0 {
+			if err := validateHeaderExtraField(header.Extra); err != nil {
+				return nil, err
+			}
 			validatorBytes := header.Extra[extraVanity : len(header.Extra)-extraSeal]
 
 			// get validators from headers and use that for new validator set
-- 
GitLab