• Steve French's avatar
    SMB3: EBADF/EIO errors in rename/open caused by race condition in smb2_compound_op · 0a55cf74
    Steve French authored
    There is  a race condition in smb2_compound_op:
    
    after_close:
    	num_rqst++;
    
    	if (cfile) {
    		cifsFileInfo_put(cfile); // sends SMB2_CLOSE to the server
    		cfile = NULL;
    
    This is triggered by smb2_query_path_info operation that happens during
    revalidate_dentry. In smb2_query_path_info, get_readable_path is called to
    load the cfile, increasing the reference counter. If in the meantime, this
    reference becomes the very last, this call to cifsFileInfo_put(cfile) will
    trigger a SMB2_CLOSE request sent to the server just before sending this compound
    request – and so then the compound request fails either with EBADF/EIO depending
    on the timing at the server, because the handle is already closed.
    
    In the first scenario, the race seems to be happening between smb2_query_path_info
    triggered by the rename operation, and between “cleanup” of asynchronous writes – while
    fsync(fd) likely waits for the asynchronous writes to complete, releasing the writeback
    structures can happen after the close(fd) call. So the EBADF/EIO errors will pop up if
    the timing is such that:
    1) There are still outstanding references after close(fd) in the writeback structures
    2) smb2_query_path_info successfully fetches the cfile, increasing the refcounter by 1
    3) All writeback structures release the same cfile, reducing refcounter to 1
    4) smb2_compound_op is called with that cfile
    
    In the second scenario, the race seems to be similar – here open triggers the
    smb2_query_path_info operation, and if all other threads in the meantime decrease the
    refcounter to 1 similarly to the first scenario, again SMB2_CLOSE will be sent to the
    server just before issuing the compound request. This case is harder to reproduce.
    
    See https://bugzilla.samba.org/show_bug.cgi?id=15051
    
    Cc: stable@vger.kernel.org
    Fixes: 8de9e86c ("cifs: create a helper to find a writeable handle by path name")
    Signed-off-by: default avatarOndrej Hubsch <ohubsch@purestorage.com>
    Reviewed-by: default avatarRonnie Sahlberg <lsahlber@redhat.com>
    Reviewed-by: default avatarPaulo Alcantara (SUSE) <pc@cjr.nz>
    Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
    0a55cf74
smb2inode.c 20.2 KB