#37351 [BC-Insight] Resubscribe Deadlocks When Unsubscribing Within An Unblock Channel

Submitted on Dec 2nd 2024 at 17:36:30 UTC by @CertiK for Attackathon | Ethereum Protocol

  • Report ID: #37351

  • Report Type: Blockchain/DLT

  • Report severity: Insight

  • Target: https://github.com/ledgerwatch/erigon

  • Impacts:

    • (Specifications) A bug in specifications with no direct impact on client implementations

Description

Brief/Intro

ResubscribeErr located in Ethereum client Erigon ( https://github.com/erigontech/erigon ) is intended to perform event subscription. It waits for the subscription to fail and calls fn again. This process repeats until Unsubscribe is called or the active subscription ends successfully. The resub goroutine needs to live long enough to read from the unsub channel. Otherwise, an Unsubscribe call deadlocks when writing to the unblock unsub channel.

Vulnerability Details

Affected Codebase: https://github.com/erigontech/erigon/tree/v2.61.0-beta1

In the event package, the ResubscribeErr() function is utilized to track the active subscription until Unsubscribe is called or the active subscription ends successfully:

https://github.com/erigontech/erigon/blob/v2.61.0-beta1/event/subscription.go#L117

As mentioned in the geth (go-ethereum) PR: https://github.com/ethereum/go-ethereum/pull/28359

Please note the unblock channel is used for unsubscribing, which is initialized with an inner goroutine call.

Impact Details

If not properly structured in the resubscribe scenario, an Unsubscribe call can deadlock when attempting to write to the unblock unsub channel.

References

  • https://github.com/erigontech/erigon/blob/v2.61.0-beta1

  • https://github.com/ethereum/go-ethereum/pull/28359

Proof of Concept

Proof of Concept

For simplicity, we can reuse the test from geth (go-ethereum) (https://github.com/ethereum/go-ethereum/pull/28359) to verify the issue:

The test result shows a fatal error of all goroutines are asleep - deadlock! as follows:

Was this helpful?