Unfortunately we can't kfree() the UNC and prefix paths in cifs_smb3_do_mount() because they could have come from a chased DFS referral (automount) and we rely on the new values set in cifs_sb->ctx prior to calling cifs_mount().
Instead, fix smb3_parse_devname() to not leak the UNC and prefix paths when parsing new share paths.
Cc: stable@vger.kernel.org # v5.11+ Fixes: 315db9a05b7a ("cifs: fix leak in cifs_smb3_do_mount() ctx") Signed-off-by: Paulo Alcantara (SUSE) pc@cjr.nz --- fs/cifs/cifsfs.c | 6 ------ fs/cifs/connect.c | 10 +++++++--- fs/cifs/fs_context.c | 2 ++ 3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 8a6894577697..bfe98136f9c1 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -863,12 +863,6 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, goto out; }
- /* cifs_setup_volume_info->smb3_parse_devname() redups UNC & prepath */ - kfree(cifs_sb->ctx->UNC); - cifs_sb->ctx->UNC = NULL; - kfree(cifs_sb->ctx->prepath); - cifs_sb->ctx->prepath = NULL; - rc = cifs_setup_volume_info(cifs_sb->ctx, NULL, old_ctx->UNC); if (rc) { root = ERR_PTR(rc); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index becd5f807787..ee4a92cbcb29 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3159,9 +3159,13 @@ static int do_dfs_failover(const char *path, const char *full_path, struct cifs_ int cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname) { - int rc = 0; + int rc;
- smb3_parse_devname(devname, ctx); + rc = smb3_parse_devname(devname, ctx); + if (rc) { + cifs_dbg(VFS, "%s: failed to parse %s: %d\n", __func__, devname, rc); + return rc; + }
if (mntopts) { char *ip; @@ -3189,7 +3193,7 @@ cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const c return -EINVAL; }
- return rc; + return 0; }
static int diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c index 1d6e0e15b034..b502a44e15a1 100644 --- a/fs/cifs/fs_context.c +++ b/fs/cifs/fs_context.c @@ -476,6 +476,7 @@ smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx)
/* move "pos" up to delimiter or NULL */ pos += len; + kfree(ctx->UNC); ctx->UNC = kstrndup(devname, pos - devname, GFP_KERNEL); if (!ctx->UNC) return -ENOMEM; @@ -490,6 +491,7 @@ smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx) if (!*pos) return 0;
+ kfree(ctx->prepath); ctx->prepath = kstrdup(pos, GFP_KERNEL); if (!ctx->prepath) return -ENOMEM;
FYI - Running the DFS tests now
http://smb3-test-rhel-75.southcentralus.cloudapp.azure.com/#/builders/3/buil...
On Fri, Apr 30, 2021 at 1:10 PM Paulo Alcantara pc@cjr.nz wrote:
Unfortunately we can't kfree() the UNC and prefix paths in cifs_smb3_do_mount() because they could have come from a chased DFS referral (automount) and we rely on the new values set in cifs_sb->ctx prior to calling cifs_mount().
Instead, fix smb3_parse_devname() to not leak the UNC and prefix paths when parsing new share paths.
Cc: stable@vger.kernel.org # v5.11+ Fixes: 315db9a05b7a ("cifs: fix leak in cifs_smb3_do_mount() ctx") Signed-off-by: Paulo Alcantara (SUSE) pc@cjr.nz
fs/cifs/cifsfs.c | 6 ------ fs/cifs/connect.c | 10 +++++++--- fs/cifs/fs_context.c | 2 ++ 3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 8a6894577697..bfe98136f9c1 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -863,12 +863,6 @@ cifs_smb3_do_mount(struct file_system_type *fs_type, goto out; }
/* cifs_setup_volume_info->smb3_parse_devname() redups UNC & prepath */
kfree(cifs_sb->ctx->UNC);
cifs_sb->ctx->UNC = NULL;
kfree(cifs_sb->ctx->prepath);
cifs_sb->ctx->prepath = NULL;
rc = cifs_setup_volume_info(cifs_sb->ctx, NULL, old_ctx->UNC); if (rc) { root = ERR_PTR(rc);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index becd5f807787..ee4a92cbcb29 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -3159,9 +3159,13 @@ static int do_dfs_failover(const char *path, const char *full_path, struct cifs_ int cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const char *devname) {
int rc = 0;
int rc;
smb3_parse_devname(devname, ctx);
rc = smb3_parse_devname(devname, ctx);
if (rc) {
cifs_dbg(VFS, "%s: failed to parse %s: %d\n", __func__, devname, rc);
return rc;
} if (mntopts) { char *ip;
@@ -3189,7 +3193,7 @@ cifs_setup_volume_info(struct smb3_fs_context *ctx, const char *mntopts, const c return -EINVAL; }
return rc;
return 0;
}
static int diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c index 1d6e0e15b034..b502a44e15a1 100644 --- a/fs/cifs/fs_context.c +++ b/fs/cifs/fs_context.c @@ -476,6 +476,7 @@ smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx)
/* move "pos" up to delimiter or NULL */ pos += len;
kfree(ctx->UNC); ctx->UNC = kstrndup(devname, pos - devname, GFP_KERNEL); if (!ctx->UNC) return -ENOMEM;
@@ -490,6 +491,7 @@ smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx) if (!*pos) return 0;
kfree(ctx->prepath); ctx->prepath = kstrdup(pos, GFP_KERNEL); if (!ctx->prepath) return -ENOMEM;
-- 2.31.1
Paulo Alcantara pc@cjr.nz writes:
Unfortunately we can't kfree() the UNC and prefix paths in cifs_smb3_do_mount() because they could have come from a chased DFS referral (automount) and we rely on the new values set in cifs_sb->ctx prior to calling cifs_mount().
Instead, fix smb3_parse_devname() to not leak the UNC and prefix paths when parsing new share paths.
Cc: stable@vger.kernel.org # v5.11+ Fixes: 315db9a05b7a ("cifs: fix leak in cifs_smb3_do_mount() ctx") Signed-off-by: Paulo Alcantara (SUSE) pc@cjr.nz
fs/cifs/cifsfs.c | 6 ------ fs/cifs/connect.c | 10 +++++++--- fs/cifs/fs_context.c | 2 ++ 3 files changed, 9 insertions(+), 9 deletions(-)
Please ignore this patch. The commit msg is also misleading.
I'll post another one soon.
linux-stable-mirror@lists.linaro.org