• Andreas Gruenbacher's avatar
    gfs2: Fix occasional glock use-after-free · fb9132e8
    Andreas Gruenbacher authored
    [ Upstream commit 9287c645 ]
    
    This patch has to do with the life cycle of glocks and buffers.  When
    gfs2 metadata or journaled data is queued to be written, a gfs2_bufdata
    object is assigned to track the buffer, and that is queued to various
    lists, including the glock's gl_ail_list to indicate it's on the active
    items list.  Once the page associated with the buffer has been written,
    it is removed from the ail list, but its life isn't over until a revoke
    has been successfully written.
    
    So after the block is written, its bufdata object is moved from the
    glock's gl_ail_list to a file-system-wide list of pending revokes,
    sd_log_le_revoke.  At that point the glock still needs to track how many
    revokes it contributed to that list (in gl_revokes) so that things like
    glock go_sync can ensure all the metadata has been not only written, but
    also revoked before the glock is granted to a different node.  This is
    to guarantee journal replay doesn't replay the block once the glock has
    been granted to another node.
    
    Ross Lagerwall recently discovered a race in which an inode could be
    evicted, and its glock freed after its ail list had been synced, but
    while it still had unwritten revokes on the sd_log_le_revoke list.  The
    evict decremented the glock reference count to zero, which allowed the
    glock to be freed.  After the revoke was written, function
    revoke_lo_after_commit tried to adjust the glock's gl_revokes counter
    and clear its GLF_LFLUSH flag, at which time it referenced the freed
    glock.
    
    This patch fixes the problem by incrementing the glock reference count
    in gfs2_add_revoke when the glock's first bufdata object is moved from
    the glock to the global revokes list. Later, when the glock's last such
    bufdata object is freed, the reference count is decremented. This
    guarantees that whichever process finishes last (the revoke writing or
    the evict) will properly free the glock, and neither will reference the
    glock after it has been freed.
    Reported-by: default avatarRoss Lagerwall <ross.lagerwall@citrix.com>
    Signed-off-by: default avatarAndreas Gruenbacher <agruenba@redhat.com>
    Signed-off-by: default avatarBob Peterson <rpeterso@redhat.com>
    Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
    fb9132e8
log.c 28.2 KB