Fixed rare memory-use-after-free
authorkhizmax <libcds.dev@gmail.com>
Fri, 1 Jan 2016 13:42:10 +0000 (16:42 +0300)
committerkhizmax <libcds.dev@gmail.com>
Fri, 1 Jan 2016 13:42:10 +0000 (16:42 +0300)
cds/intrusive/impl/lazy_list.h
cds/intrusive/lazy_list_rcu.h

index 6fe3838d2229154ad8820d0520d98c6dad1c0c6f..412dca82ffa6d0ec02591c042a94605612ada9ca 100644 (file)
@@ -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 <typename Q, typename Compare>
         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();
index ea9ccbe048f931f33081b310e500571c9ac073a7..08409bb689cfa8dffb8693e19cf24914be67ff82 100644 (file)
@@ -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();