Vulnerability: Denial of service in github.com/ethereum/go-ethereum ### Impact

A DoS vulnerability can make a LES server crash via malicious `GetProofsV2` request from a connected LES client.

### Patches

The vulnerability was patched in https://github.com/ethereum/go-ethereum/pull/21896. 

### Workarounds

This vulnerability only concerns users explicitly enabling `les` server; disabling `les` prevents the exploit. 
It can also be patched by manually applying the patch in https://github.com/ethereum/go-ethereum/pull/21896. 


### For more information
If you have any questions or comments about this advisory:
* Open an issue in [go-ethereum](https://github.com/ethereum/go-ethereum)
* Email us at [security@ethereum.org](mailto:security@ethereum.org)
Vulnerability ID: GHSA-r33q-22hv-j29q
CWE: CWE-400
Severity score: 6.5
Project: https://github.com/ethereum/go-ethereum
Published: 2021-06-29
File: les/server_handler.go
Commit message: les: fix GetProofsV2 bug (#21896)
Commit author: Felföldi Zsolt

Vulnerable version (before fix):
 func (h *serverHandler) handleMsg(p *clientPeer, wg *sync.WaitGroup) error { 		var ( 			lastBHash common.Hash 			root      common.Hash 		) 		reqCnt := len(req.Reqs) 		if accept(req.ReqID, uint64(reqCnt), MaxProofsFetch) { func (h *serverHandler) handleMsg(p *clientPeer, wg *sync.WaitGroup) error { 						return 					} 					// Look up the root hash belonging to the request 					var ( 						header *types.Header 						trie   state.Trie 					) 					if request.BHash != lastBHash { 						root, lastBHash = common.Hash{}, request.BHash  func (h *serverHandler) handleMsg(p *clientPeer, wg *sync.WaitGroup) error { 					// Open the account or storage trie for the request 					statedb := h.blockchain.StateCache()  					switch len(request.AccKey) { 					case 0: 						// No account key specified, open an account trie

Fixed version (after fix):
 func (h *serverHandler) handleMsg(p *clientPeer, wg *sync.WaitGroup) error { 		var ( 			lastBHash common.Hash 			root      common.Hash 			header    *types.Header 		) 		reqCnt := len(req.Reqs) 		if accept(req.ReqID, uint64(reqCnt), MaxProofsFetch) { func (h *serverHandler) handleMsg(p *clientPeer, wg *sync.WaitGroup) error { 						return 					} 					// Look up the root hash belonging to the request 					if request.BHash != lastBHash { 						root, lastBHash = common.Hash{}, request.BHash  func (h *serverHandler) handleMsg(p *clientPeer, wg *sync.WaitGroup) error { 					// Open the account or storage trie for the request 					statedb := h.blockchain.StateCache()  					var trie state.Trie 					switch len(request.AccKey) { 					case 0: 						// No account key specified, open an account trie

Patch:
patch: @@ -610,6 +610,7 @@ func (h *serverHandler) handleMsg(p *clientPeer, wg *sync.WaitGroup) error {
 		var (
 			lastBHash common.Hash
 			root      common.Hash
+			header    *types.Header
 		)
 		reqCnt := len(req.Reqs)
 		if accept(req.ReqID, uint64(reqCnt), MaxProofsFetch) {
@@ -624,10 +625,6 @@ func (h *serverHandler) handleMsg(p *clientPeer, wg *sync.WaitGroup) error {
 						return
 					}
 					// Look up the root hash belonging to the request
-					var (
-						header *types.Header
-						trie   state.Trie
-					)
 					if request.BHash != lastBHash {
 						root, lastBHash = common.Hash{}, request.BHash
 
@@ -654,6 +651,7 @@ func (h *serverHandler) handleMsg(p *clientPeer, wg *sync.WaitGroup) error {
 					// Open the account or storage trie for the request
 					statedb := h.blockchain.StateCache()
 
+					var trie state.Trie
 					switch len(request.AccKey) {
 					case 0:
 						// No account key specified, open an account trie
path: les/server_handler.go