Skip to content

Commit

Permalink
cifs: fix error handling in mount-time DFS referral chasing code
Browse files Browse the repository at this point in the history
If the referral is malformed or the hostname can't be resolved, then
the current code generates an oops. Fix it to handle these errors
gracefully.

Reported-by: Sandro Mathys <sm@sandro-mathys.ch>
Acked-by: Igor Mammedov <niallain@gmail.com>
CC: Stable <stable@kernel.org>
Signed-off-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>
  • Loading branch information
Jeff Layton authored and Steve French committed Jul 28, 2009
1 parent fc013a5 commit 7b91e26
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
12 changes: 9 additions & 3 deletions fs/cifs/cifs_dfs_ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void cifs_dfs_release_automount_timer(void)
* i.e. strips from UNC trailing path that is not part of share
* name and fixup missing '\' in the begining of DFS node refferal
* if neccessary.
* Returns pointer to share name on success or NULL on error.
* Returns pointer to share name on success or ERR_PTR on error.
* Caller is responsible for freeing returned string.
*/
static char *cifs_get_share_name(const char *node_name)
Expand All @@ -68,7 +68,7 @@ static char *cifs_get_share_name(const char *node_name)
UNC = kmalloc(len+2 /*for term null and additional \ if it's missed */,
GFP_KERNEL);
if (!UNC)
return NULL;
return ERR_PTR(-ENOMEM);

/* get share name and server name */
if (node_name[1] != '\\') {
Expand All @@ -87,7 +87,7 @@ static char *cifs_get_share_name(const char *node_name)
cERROR(1, ("%s: no server name end in node name: %s",
__func__, node_name));
kfree(UNC);
return NULL;
return ERR_PTR(-EINVAL);
}

/* find sharename end */
Expand Down Expand Up @@ -133,6 +133,12 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
return ERR_PTR(-EINVAL);

*devname = cifs_get_share_name(ref->node_name);
if (IS_ERR(*devname)) {
rc = PTR_ERR(*devname);
*devname = NULL;
goto compose_mount_options_err;
}

rc = dns_resolve_server_name_to_ip(*devname, &srvIP);
if (rc != 0) {
cERROR(1, ("%s: Failed to resolve server part of %s to IP: %d",
Expand Down
13 changes: 10 additions & 3 deletions fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -2544,20 +2544,27 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,

if (mount_data != mount_data_global)
kfree(mount_data);

mount_data = cifs_compose_mount_options(
cifs_sb->mountdata, full_path + 1,
referrals, &fake_devname);
kfree(fake_devname);

free_dfs_info_array(referrals, num_referrals);
kfree(fake_devname);
kfree(full_path);

if (IS_ERR(mount_data)) {
rc = PTR_ERR(mount_data);
mount_data = NULL;
goto mount_fail_check;
}

if (tcon)
cifs_put_tcon(tcon);
else if (pSesInfo)
cifs_put_smb_ses(pSesInfo);

cleanup_volume_info(&volume_info);
FreeXid(xid);
kfree(full_path);
referral_walks_count++;
goto try_mount_again;
}
Expand Down

0 comments on commit 7b91e26

Please sign in to comment.