From c33d0497b028637f49cc3eb3096d3af1ffa98ee8 Mon Sep 17 00:00:00 2001 From: Eduard Bagdasaryan Date: Mon, 27 Jul 2020 15:28:31 +0000 Subject: [PATCH] Fix livelocking in peerDigestHandleReply (#698) peerDigestHandleReply() was missing a premature EOF check. The existing peerDigestFetchedEnough() cannot detect EOF because it does not have access to receivedData.length used to indicate the EOF condition. We did not adjust peerDigestFetchedEnough() because it is abused to check both post-I/O state and the state after each digest processing step. The latter invocations lack access to receivedData.length and should not really bother with EOF anyway. --- src/peer_digest.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/peer_digest.cc b/src/peer_digest.cc index 9a2abc38ad..8d6becffea 100644 --- a/src/peer_digest.cc +++ b/src/peer_digest.cc @@ -484,6 +484,15 @@ peerDigestHandleReply(void *data, StoreIOBuffer receivedData) } while (cbdataReferenceValid(fetch) && prevstate != fetch->state && fetch->bufofs > 0); + // Check for EOF here, thus giving the parser one extra run. We could avoid this overhead by + // checking at the beginning of this function. However, in this case, we would have to require + // that the parser does not regard EOF as a special condition (it is true now but may change + // in the future). + if (!receivedData.length) { // EOF + peerDigestFetchAbort(fetch, fetch->buf, "premature end of digest reply"); + return; + } + /* Update the copy offset */ fetch->offset += receivedData.length; -- 2.47.2