Commit a2934c7b authored by Jeff Layton's avatar Jeff Layton Committed by Steve French

cifs: NULL out tcon, pSesInfo, and srvTcp pointers when chasing DFS referrals

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: default avatarJeff Layton <jlayton@redhat.com>
Reported-by: default avatarGustavo Carvalho Homem <gustavo@angulosolido.pt>
CC: stable <stable@kernel.org>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent 29e55363
...@@ -2287,12 +2287,12 @@ int ...@@ -2287,12 +2287,12 @@ int
cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
char *mount_data_global, const char *devname) char *mount_data_global, const char *devname)
{ {
int rc = 0; int rc;
int xid; int xid;
struct smb_vol *volume_info; struct smb_vol *volume_info;
struct cifsSesInfo *pSesInfo = NULL; struct cifsSesInfo *pSesInfo;
struct cifsTconInfo *tcon = NULL; struct cifsTconInfo *tcon;
struct TCP_Server_Info *srvTcp = NULL; struct TCP_Server_Info *srvTcp;
char *full_path; char *full_path;
char *mount_data = mount_data_global; char *mount_data = mount_data_global;
#ifdef CONFIG_CIFS_DFS_UPCALL #ifdef CONFIG_CIFS_DFS_UPCALL
...@@ -2301,6 +2301,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -2301,6 +2301,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
int referral_walks_count = 0; int referral_walks_count = 0;
try_mount_again: try_mount_again:
#endif #endif
rc = 0;
tcon = NULL;
pSesInfo = NULL;
srvTcp = NULL;
full_path = NULL; full_path = NULL;
xid = GetXid(); xid = GetXid();
...@@ -2597,6 +2601,7 @@ remote_path_check: ...@@ -2597,6 +2601,7 @@ remote_path_check:
cleanup_volume_info(&volume_info); cleanup_volume_info(&volume_info);
referral_walks_count++; referral_walks_count++;
FreeXid(xid);
goto try_mount_again; goto try_mount_again;
} }
#else /* No DFS support, return error on mount */ #else /* No DFS support, return error on mount */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment