From: khizmax Date: Fri, 1 Jan 2016 13:42:10 +0000 (+0300) Subject: Fixed rare memory-use-after-free X-Git-Tag: v2.1.0~5 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=a65ad2a40bb9df12f0ed404c9684d214d877a57a;p=libcds.git Fixed rare memory-use-after-free --- diff --git a/cds/intrusive/impl/lazy_list.h b/cds/intrusive/impl/lazy_list.h index 6fe3838d..412dca82 100644 --- a/cds/intrusive/impl/lazy_list.h +++ b/cds/intrusive/impl/lazy_list.h @@ -256,10 +256,8 @@ namespace cds { namespace intrusive { assert( pPred->m_pNext.load(memory_model::memory_order_relaxed).ptr() == pCur ); node_type * pNext = pCur->m_pNext.load(memory_model::memory_order_relaxed).ptr(); - //pCur->m_pNext.store( marked_node_ptr( pNext, 1), memory_model::memory_order_release) ; // logically deleting - pCur->m_pNext.store( marked_node_ptr( pHead, 1 ), memory_model::memory_order_release ) ; // logical removal + back-link for search + pCur->m_pNext.store( marked_node_ptr( pHead, 1 ), memory_model::memory_order_release ); // logical removal + back-link for search pPred->m_pNext.store( marked_node_ptr( pNext ), memory_model::memory_order_release); // physically deleting - //pCur->m_pNext.store( marked_node_ptr( pHead, 1 ), memory_model::memory_order_release ) ; // back-link for search } void retire_node( node_type * pNode ) @@ -1125,15 +1123,12 @@ namespace cds { namespace intrusive { template void search( node_type * pHead, const Q& key, position& pos, Compare cmp ) { - const node_type * pTail = &m_Tail; + node_type const* pTail = &m_Tail; marked_node_ptr pCur( pHead ); marked_node_ptr pPrev( pHead ); - back_off bkoff; - - while ( pCur.ptr() != pTail ) - { + while ( pCur.ptr() != pTail ) { if ( pCur.ptr() != pHead ) { if ( cmp( *node_traits::to_value_ptr( *pCur.ptr() ), key ) >= 0 ) break; @@ -1142,14 +1137,12 @@ namespace cds { namespace intrusive { pos.guards.copy( position::guard_prev_item, position::guard_current_item ); pPrev = pCur; - for (;;) { - pCur = pPrev->m_pNext.load(memory_model::memory_order_relaxed); - pos.guards.assign( position::guard_current_item, node_traits::to_value_ptr( pCur.ptr() )); - if ( pCur == pPrev->m_pNext.load(memory_model::memory_order_acquire) ) - break; - bkoff(); - } + pCur = pos.guards.protect( position::guard_current_item, pPrev->m_pNext, + []( marked_node_ptr p ) { return node_traits::to_value_ptr( p.ptr()); } + ); assert( pCur.ptr() != nullptr ); + if ( pCur->is_marked()) + pCur = pHead; } pos.pCur = pCur.ptr(); diff --git a/cds/intrusive/lazy_list_rcu.h b/cds/intrusive/lazy_list_rcu.h index ea9ccbe0..08409bb6 100644 --- a/cds/intrusive/lazy_list_rcu.h +++ b/cds/intrusive/lazy_list_rcu.h @@ -201,7 +201,7 @@ namespace cds { namespace intrusive { { assert( pPred->m_pNext.load(memory_model::memory_order_relaxed).ptr() == pCur ); - pNode->m_pNext.store( marked_node_ptr(pCur), memory_model::memory_order_relaxed ); + pNode->m_pNext.store( marked_node_ptr(pCur), memory_model::memory_order_release ); pPred->m_pNext.store( marked_node_ptr(pNode), memory_model::memory_order_release ); } @@ -211,7 +211,7 @@ namespace cds { namespace intrusive { assert( pCur != &m_Tail ); node_type * pNext = pCur->m_pNext.load(memory_model::memory_order_relaxed).ptr(); - pCur->m_pNext.store( marked_node_ptr( pHead, 1 ), memory_model::memory_order_relaxed ); // logical deletion + back-link for search + pCur->m_pNext.store( marked_node_ptr( pHead, 1 ), memory_model::memory_order_release ); // logical deletion + back-link for search pPred->m_pNext.store( marked_node_ptr( pNext ), memory_model::memory_order_release); // physically deleting } @@ -1110,6 +1110,8 @@ namespace cds { namespace intrusive { while ( pCur != pTail && ( pCur == pHead || cmp( *node_traits::to_value_ptr( *pCur.ptr()), key ) < 0 )) { pPrev = pCur; pCur = pCur->m_pNext.load(memory_model::memory_order_acquire); + if ( pCur->is_marked()) + pCur = pHead; } pos.pCur = pCur.ptr();