Added cc: stable and Reported-by: line, and merged<br><br><div class="gmail_quote">On Thu, Dec 3, 2009 at 7:09 AM, Jeff Layton <span dir="ltr">&lt;<a href="mailto:jlayton@redhat.com">jlayton@redhat.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">The scenario is this:<br>
<br>
The kernel gets EREMOTE and starts chasing a DFS referral at mount time.<br>
The tcon reference is put, which puts the session reference too, but<br>
neither pointer is zeroed out.<br>
<br>
The mount gets retried (goto try_mount_again) with new mount info.<br>
Session setup fails fails and rc ends up being non-zero. The code then<br>
falls through to the end and tries to put the previously freed tcon<br>
pointer again.<br>
<br>
Fix this by moving the initialization of the rc variable and the tcon,<br>
pSesInfo and srvTcp pointers below the try_mount_again label. Also, add<br>
a FreeXid() before the goto to prevent xid &quot;leaks&quot;.<br>
<br>
Signed-off-by: Jeff Layton &lt;<a href="mailto:jlayton@redhat.com">jlayton@redhat.com</a>&gt;<br>
---<br>
 fs/cifs/connect.c |   13 +++++++++----<br>
 1 files changed, 9 insertions(+), 4 deletions(-)<br>
<br>
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c<br>
index 63ea83f..3bbcaa7 100644<br>
--- a/fs/cifs/connect.c<br>
+++ b/fs/cifs/connect.c<br>
@@ -2287,12 +2287,12 @@ int<br>
 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,<br>
                char *mount_data_global, const char *devname)<br>
 {<br>
-       int rc = 0;<br>
+       int rc;<br>
        int xid;<br>
        struct smb_vol *volume_info;<br>
-       struct cifsSesInfo *pSesInfo = NULL;<br>
-       struct cifsTconInfo *tcon = NULL;<br>
-       struct TCP_Server_Info *srvTcp = NULL;<br>
+       struct cifsSesInfo *pSesInfo;<br>
+       struct cifsTconInfo *tcon;<br>
+       struct TCP_Server_Info *srvTcp;<br>
        char   *full_path;<br>
        char *mount_data = mount_data_global;<br>
 #ifdef CONFIG_CIFS_DFS_UPCALL<br>
@@ -2301,6 +2301,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,<br>
        int referral_walks_count = 0;<br>
 try_mount_again:<br>
 #endif<br>
+       rc = 0;<br>
+       tcon = NULL;<br>
+       pSesInfo = NULL;<br>
+       srvTcp = NULL;<br>
        full_path = NULL;<br>
<br>
        xid = GetXid();<br>
@@ -2597,6 +2601,7 @@ remote_path_check:<br>
<br>
                        cleanup_volume_info(&amp;volume_info);<br>
                        referral_walks_count++;<br>
+                       FreeXid(xid);<br>
                        goto try_mount_again;<br>
                }<br>
 #else /* No DFS support, return error on mount */<br>
<font color="#888888">--<br>
1.6.5.2<br>
<br>
</font></blockquote></div><br><br clear="all"><br>-- <br>Thanks,<br><br>Steve<br>