Message ID | 20211215143527.7088-4-tim.gardner@canonical.com |
---|---|
State | New |
Headers | show |
Series | CIFS stable updates | expand |
On 15.12.21 15:35, Tim Gardner wrote: > From: Shyam Prasad N <sprasad@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@microsoft.com> > Cc: stable@vger.kernel.org > Signed-off-by: Steve French <stfrench@microsoft.com> > Signed-off-by: Tim Gardner <tim.gardner@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;
On 12/15/21 8:37 AM, Kleber Souza wrote: > On 15.12.21 15:35, Tim Gardner wrote: >> From: Shyam Prasad N <sprasad@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@microsoft.com> >> Cc: stable@vger.kernel.org >> Signed-off-by: Steve French <stfrench@microsoft.com> >> Signed-off-by: Tim Gardner <tim.gardner@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. > It really wasn't picked up from a stable tree as far as I could tell, which is why I didn't put the 'backported from' line in here. I guess I considered it sufficient that we know from what upstream commit it does descend from, i.e., 'commit 7be3248f313930ff3d3436d4e9ddbe9fccc1f541 upstream'. As noted in the commit log, I received this from the Microsoft team (probably done by Steve French the CIFS maintainer). rtg ----------- Tim Gardner Canonical, Inc
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;