fs/smb/client/fs_context.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
From: Fredric Cover <fredric.cover.lkernel@gmail.com>
smb3_reconfigure() modifies the active volume context directly.
If smb3_fs_context_dup() fails to allocate space when copying strings
of a new context into the volume context, it clears the volume context.
Add staging logic (tmp_ctx) to ensure that either the volume context
stays the same on errors or is updated with the new state, and is
never cleared.
Signed-off-by: Fredric Cover <fredric.cover.lkernel@gmail.com>
---
fs/smb/client/fs_context.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
index b9544eb03..3a6f207a5 100644
--- a/fs/smb/client/fs_context.c
+++ b/fs/smb/client/fs_context.c
@@ -1082,6 +1082,7 @@ static void smb3_sync_ses_chan_max(struct cifs_ses *ses, unsigned int max_channe
static int smb3_reconfigure(struct fs_context *fc)
{
struct smb3_fs_context *ctx = smb3_fc2context(fc);
+ struct smb3_fs_context *tmp_ctx; /* used for copy of ctx to cifs_sb->ctx */
struct dentry *root = fc->root;
struct cifs_sb_info *cifs_sb = CIFS_SB(root->d_sb);
struct cifs_ses *ses = cifs_sb_master_tcon(cifs_sb)->ses;
@@ -1205,13 +1206,19 @@ static int smb3_reconfigure(struct fs_context *fc)
ctx->rsize = rsize ? CIFS_ALIGN_RSIZE(fc, rsize) : cifs_sb->ctx->rsize;
ctx->wsize = wsize ? CIFS_ALIGN_WSIZE(fc, wsize) : cifs_sb->ctx->wsize;
- smb3_cleanup_fs_context_contents(cifs_sb->ctx);
- rc = smb3_fs_context_dup(cifs_sb->ctx, ctx);
- smb3_update_mnt_flags(cifs_sb);
+ tmp_ctx = kzalloc_obj(*tmp_ctx, GFP_KERNEL);
+ if (!tmp_ctx)
+ return -ENOMEM;
+ rc = smb3_fs_context_dup(tmp_ctx, ctx);
+ if (!rc) {
+ smb3_cleanup_fs_context_contents(cifs_sb->ctx);
+ memcpy(cifs_sb->ctx, tmp_ctx, sizeof(*tmp_ctx));
+ smb3_update_mnt_flags(cifs_sb);
#ifdef CONFIG_CIFS_DFS_UPCALL
- if (!rc)
rc = dfs_cache_remount_fs(cifs_sb);
#endif
+ }
+ kfree(tmp_ctx);
return rc;
}
--
2.53.0
Hello Steve and list,
Please disregard this patch. I see that DaeMyung's patch series
("cifs: client: stage smb3_reconfigure() updates and restore ctx on failure")
was merged into 7.1-rc4, which addresses this exact state-corruption path.
Apologies for the noise.
Best regards,
Fredric Cover
On Mon, May 18, 2026 at 5:14 PM Fredric Cover
<fredric.cover.lkernel@gmail.com> wrote:
>
> From: Fredric Cover <fredric.cover.lkernel@gmail.com>
>
> smb3_reconfigure() modifies the active volume context directly.
> If smb3_fs_context_dup() fails to allocate space when copying strings
> of a new context into the volume context, it clears the volume context.
>
> Add staging logic (tmp_ctx) to ensure that either the volume context
> stays the same on errors or is updated with the new state, and is
> never cleared.
>
> Signed-off-by: Fredric Cover <fredric.cover.lkernel@gmail.com>
> ---
> fs/smb/client/fs_context.c | 15 +++++++++++----
> 1 file changed, 11 insertions(+), 4 deletions(-)
>
> diff --git a/fs/smb/client/fs_context.c b/fs/smb/client/fs_context.c
> index b9544eb03..3a6f207a5 100644
> --- a/fs/smb/client/fs_context.c
> +++ b/fs/smb/client/fs_context.c
> @@ -1082,6 +1082,7 @@ static void smb3_sync_ses_chan_max(struct cifs_ses *ses, unsigned int max_channe
> static int smb3_reconfigure(struct fs_context *fc)
> {
> struct smb3_fs_context *ctx = smb3_fc2context(fc);
> + struct smb3_fs_context *tmp_ctx; /* used for copy of ctx to cifs_sb->ctx */
> struct dentry *root = fc->root;
> struct cifs_sb_info *cifs_sb = CIFS_SB(root->d_sb);
> struct cifs_ses *ses = cifs_sb_master_tcon(cifs_sb)->ses;
> @@ -1205,13 +1206,19 @@ static int smb3_reconfigure(struct fs_context *fc)
> ctx->rsize = rsize ? CIFS_ALIGN_RSIZE(fc, rsize) : cifs_sb->ctx->rsize;
> ctx->wsize = wsize ? CIFS_ALIGN_WSIZE(fc, wsize) : cifs_sb->ctx->wsize;
>
> - smb3_cleanup_fs_context_contents(cifs_sb->ctx);
> - rc = smb3_fs_context_dup(cifs_sb->ctx, ctx);
> - smb3_update_mnt_flags(cifs_sb);
> + tmp_ctx = kzalloc_obj(*tmp_ctx, GFP_KERNEL);
> + if (!tmp_ctx)
> + return -ENOMEM;
> + rc = smb3_fs_context_dup(tmp_ctx, ctx);
> + if (!rc) {
> + smb3_cleanup_fs_context_contents(cifs_sb->ctx);
> + memcpy(cifs_sb->ctx, tmp_ctx, sizeof(*tmp_ctx));
> + smb3_update_mnt_flags(cifs_sb);
> #ifdef CONFIG_CIFS_DFS_UPCALL
> - if (!rc)
> rc = dfs_cache_remount_fs(cifs_sb);
> #endif
> + }
> + kfree(tmp_ctx);
>
> return rc;
> }
> --
> 2.53.0
>
© 2016 - 2026 Red Hat, Inc.