lkml.org 
[lkml]   [2010]   [Jan]   [5]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[03/39] cifs: NULL out tcon, pSesInfo, and srvTcp pointers when chasing DFS referrals
    2.6.31-stable review patch.  If anyone has any objections, please let us know.

    ------------------

    From: Jeff Layton <jlayton@redhat.com>

    commit a2934c7b363ddcc001964f2444649f909e583bef upstream.

    The scenario is this:

    The kernel gets EREMOTE and starts chasing a DFS referral at mount time.
    The tcon reference is put, which puts the session reference too, but
    neither pointer is zeroed out.

    The mount gets retried (goto try_mount_again) with new mount info.
    Session setup fails fails and rc ends up being non-zero. The code then
    falls through to the end and tries to put the previously freed tcon
    pointer again. Oops at: cifs_put_smb_ses+0x14/0xd0

    Fix this by moving the initialization of the rc variable and the tcon,
    pSesInfo and srvTcp pointers below the try_mount_again label. Also, add
    a FreeXid() before the goto to prevent xid "leaks".

    Signed-off-by: Jeff Layton <jlayton@redhat.com>
    Reported-by: Gustavo Carvalho Homem <gustavo@angulosolido.pt>
    Signed-off-by: Steve French <sfrench@us.ibm.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    fs/cifs/connect.c | 13 +++++++++----
    1 file changed, 9 insertions(+), 4 deletions(-)

    --- a/fs/cifs/connect.c
    +++ b/fs/cifs/connect.c
    @@ -2267,12 +2267,12 @@ int
    cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
    char *mount_data_global, const char *devname)
    {
    - int rc = 0;
    + int rc;
    int xid;
    struct smb_vol *volume_info;
    - struct cifsSesInfo *pSesInfo = NULL;
    - struct cifsTconInfo *tcon = NULL;
    - struct TCP_Server_Info *srvTcp = NULL;
    + struct cifsSesInfo *pSesInfo;
    + struct cifsTconInfo *tcon;
    + struct TCP_Server_Info *srvTcp;
    char *full_path;
    char *mount_data = mount_data_global;
    #ifdef CONFIG_CIFS_DFS_UPCALL
    @@ -2281,6 +2281,10 @@ cifs_mount(struct super_block *sb, struc
    int referral_walks_count = 0;
    try_mount_again:
    #endif
    + rc = 0;
    + tcon = NULL;
    + pSesInfo = NULL;
    + srvTcp = NULL;
    full_path = NULL;

    xid = GetXid();
    @@ -2577,6 +2581,7 @@ remote_path_check:

    cleanup_volume_info(&volume_info);
    referral_walks_count++;
    + FreeXid(xid);
    goto try_mount_again;
    }
    #else /* No DFS support, return error on mount */



    \
     
     \ /
      Last update: 2010-01-05 21:09    [W:0.020 / U:126.324 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site