[PATCH 3/3] cifs: To match file servers, make sure the server hostname matches

Kleber Souza kleber.souza at canonical.com
Wed Dec 15 15:37:31 UTC 2021


On 15.12.21 15:35, Tim Gardner wrote:
> From: Shyam Prasad N <sprasad at microsoft.com>
>
> BugLink: https://bugs.launchpad.net/bugs/1954926
>
> commit 7be3248f313930ff3d3436d4e9ddbe9fccc1f541 upstream.
>
> We generally rely on a bunch of factors to differentiate between servers.
> For example, IP address, port etc.
>
> For certain server types (like Azure), it is important to make sure
> that the server hostname matches too, even if the both hostnames currently
> resolve to the same IP address.
>
> Signed-off-by: Shyam Prasad N <sprasad at microsoft.com>
> Cc: stable at vger.kernel.org
> Signed-off-by: Steve French <stfrench at microsoft.com>
> Signed-off-by: Tim Gardner <tim.gardner at canonical.com>
The "(cherry picked|backported from commit ...)" is missing here. This seems
to have been picked up from a stable tree as a base, so a reference to that
commit would be good.

Kleber

> [rtg - backported by the Microsoft team. They dropped changes to
> fs/cifs/fs_connect.[ch], added a structure tag to fs/cifs/cifsglob.h: struct smb_vol,
> misc changes to fs/cifs/connect.c to reflect the intent of the original upstream patch]
> ---
>   fs/cifs/cifsglob.h |  1 +
>   fs/cifs/connect.c  | 38 ++++++++++++++++++++++++++++++--------
>   2 files changed, 31 insertions(+), 8 deletions(-)
>
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index 10934d4d5ce33..9607f623c1357 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -538,6 +538,7 @@ struct smb_vol {
>   	char *username;
>   	char *password;
>   	char *domainname;
> +	char *server_hostname;
>   	char *UNC;
>   	char *iocharset;  /* local code page for mapping to and from Unicode */
>   	char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index de188a8b282a5..dfcac2489b46b 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -1101,7 +1101,6 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
>   		 */
>   	}
>   
> -	kfree(server->hostname);
>   	kfree(server);
>   
>   	length = atomic_dec_return(&tcpSesAllocCount);
> @@ -1653,6 +1652,11 @@ cifs_parse_devname(const char *devname, struct smb_vol *vol)
>   	if (!pos)
>   		return -EINVAL;
>   
> +	/* record the server hostname */
> +	vol->server_hostname = kstrndup(devname + 2, pos - devname - 2, GFP_KERNEL);
> +	if (!vol->server_hostname)
> +		return -ENOMEM;
> +
>   	/* skip past delimiter */
>   	++pos;
>   
> @@ -2510,6 +2514,12 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
>   		goto cifs_parse_mount_err;
>   	}
>   #endif
> +
> +	if (!vol->server_hostname) {
> +		cifs_dbg(VFS, "CIFS mount error: Unable to parse server name in device string!\n");
> +		goto cifs_parse_mount_err;
> +	}
> +
>   	if (!vol->UNC) {
>   		cifs_dbg(VFS, "CIFS mount error: No usable UNC path provided in device string!\n");
>   		goto cifs_parse_mount_err;
> @@ -2712,6 +2722,9 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
>   	if (!net_eq(cifs_net_ns(server), current->nsproxy->net_ns))
>   		return 0;
>   
> +	if (strcasecmp(server->hostname, vol->server_hostname))
> +		return 0;
> +
>   	if (!match_address(server, addr,
>   			   (struct sockaddr *)&vol->srcaddr))
>   		return 0;
> @@ -2796,6 +2809,7 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
>   	kfree(server->session_key.response);
>   	server->session_key.response = NULL;
>   	server->session_key.len = 0;
> +	kfree(server->hostname);
>   
>   	task = xchg(&server->tsk, NULL);
>   	if (task)
> @@ -2821,14 +2835,15 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
>   		goto out_err;
>   	}
>   
> +	tcp_ses->hostname = kstrdup(volume_info->server_hostname, GFP_KERNEL);
> +	if (!tcp_ses->hostname) {
> +		rc = -ENOMEM;
> +		goto out_err;
> +	}
> +
>   	tcp_ses->ops = volume_info->ops;
>   	tcp_ses->vals = volume_info->vals;
>   	cifs_set_net_ns(tcp_ses, get_net(current->nsproxy->net_ns));
> -	tcp_ses->hostname = extract_hostname(volume_info->UNC);
> -	if (IS_ERR(tcp_ses->hostname)) {
> -		rc = PTR_ERR(tcp_ses->hostname);
> -		goto out_err_crypto_release;
> -	}
>   
>   	tcp_ses->noblockcnt = volume_info->rootfs;
>   	tcp_ses->noblocksnd = volume_info->noblocksnd || volume_info->rootfs;
> @@ -2942,8 +2957,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
>   
>   out_err:
>   	if (tcp_ses) {
> -		if (!IS_ERR(tcp_ses->hostname))
> -			kfree(tcp_ses->hostname);
> +		kfree(tcp_ses->hostname);
>   		if (tcp_ses->ssocket)
>   			sock_release(tcp_ses->ssocket);
>   		kfree(tcp_ses);
> @@ -4272,6 +4286,7 @@ cifs_cleanup_volume_info_contents(struct smb_vol *volume_info)
>   	kfree(volume_info->username);
>   	kzfree(volume_info->password);
>   	kfree(volume_info->UNC);
> +	kfree(volume_info->server_hostname);
>   	kfree(volume_info->domainname);
>   	kfree(volume_info->iocharset);
>   	kfree(volume_info->prepath);
> @@ -4541,6 +4556,12 @@ static int update_vol_info(const struct dfs_cache_tgt_iterator *tgt_it,
>   	kfree(vol->UNC);
>   	vol->UNC = new_unc;
>   
> +	if (fake_vol->server_hostname) {
> +		kfree(vol->server_hostname);
> +		vol->server_hostname = fake_vol->server_hostname;
> +		fake_vol->server_hostname = NULL;
> +	}
> +
>   	if (fake_vol->prepath) {
>   		kfree(vol->prepath);
>   		vol->prepath = fake_vol->prepath;
> @@ -5342,6 +5363,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
>   	vol_info->linux_uid = fsuid;
>   	vol_info->cred_uid = fsuid;
>   	vol_info->UNC = master_tcon->treeName;
> +	vol_info->server_hostname = master_tcon->ses->server->hostname;
>   	vol_info->retry = master_tcon->retry;
>   	vol_info->nocase = master_tcon->nocase;
>   	vol_info->nohandlecache = master_tcon->nohandlecache;





More information about the kernel-team mailing list