• Nick Piggin's avatar
    buffer: memorder fix · 54710f60
    Nick Piggin authored
    unlock_buffer(), like unlock_page(), must not clear the lock without
    ensuring that the critical section is closed.
    
    
    Mingming later sent the same patch, saying:
    
    We are running SDET benchmark and saw double free issue for ext3 extended
    attributes block, which complains the same xattr block already being freed (in
    ext3_xattr_release_block()).  The problem could also been triggered by
    multiple threads loop untar/rm a kernel tree.
    
    The race is caused by missing a memory barrier at unlock_buffer() before the
    lock bit being cleared, resulting in possible concurrent h_refcounter update. 
    That causes a reference counter leak, then later leads to the double free that
    we have seen.
    
    Inside unlock_buffer(), there is a memory barrier is placed *after* the lock
    bit is being cleared, however, there is no memory barrier *before* the bit is
    cleared.  On some arch the h_refcount update instruction and the clear bit
    instruction could be reordered, thus leave the critical section re-entered.
    
    The race is like this: For example, if the h_refcount is initialized as 1,
    
    cpu 0:                                   cpu1
    54710f60
buffer.c 80.2 KB