`RewindBlockIndex` reads `chainActive` (via `ChainActive()`) without holding `cs_main`:

https://github.com/bitcoin/bitcoin/blob/b2a6b0216192b6e8428f1a80b47f5178fccb961a/src/validation.cpp#L4314-L4331

(Please note that callers of `RewindBlockIndex` are _not_ allowed to hold `cs_main` since `RewindBlockIndex` indirectly calls `LimitValidationInterfaceQueue`.)
if (IsWitnessEnabled(m_chain[nHeight - 1], params.GetConsensus()) && !(m_chain[nHeight]->nStatus & BLOCK_OPT_WITNESS)) {
                break;
            }
            nHeight++;
        }
        tip = m_chain.Tip();
    }
    
    CValidationState state;
    
    while (!ShutdownRequested()) {
        {
            LOCK(cs_main);
            
            assert(tip == m_chain.Tip());
            if (tip == nullptr || tip->nHeight < nHeight) break;
            if (fPruneMode && !(tip->nStatus & BLOCK_HAVE_DATA)) {
                
                
                
                
                
                break;
            }
            
            if (!DisconnectTip(state, params, nullptr)) {
                return error("RewindBlockIndex: unable to disconnect block at height %i (%s)", tip->nHeight, FormatStateMessage(state));
            }