Skip to content

Commit bfbc31b

Browse files
committed
smb3: allow deferred close timeout to be configurable
jira VULN-131073 cve-pre CVE-2025-38527 commit-author Steve French <stfrench@microsoft.com> commit 5efdd91 Deferred close can be a very useful feature for allowing caching data for read, and for minimizing the number of reopens needed for a file that is repeatedly opened and close but there are workloads where its default (1 second, similar to actimeo/acregmax) is much too small. Allow the user to configure the amount of time we can defer sending the final smb3 close when we have a handle lease on the file (rather than forcing it to depend on value of actimeo which is often unrelated, and less safe). Adds new mount parameter "closetimeo=" which is the maximum number of seconds we can wait before sending an SMB3 close when we have a handle lease for it. Default value also is set to slightly larger at 5 seconds (although some other clients use larger default this should still help). Suggested-by: Bharath SM <bharathsm@microsoft.com> Reviewed-by: Bharath SM <bharathsm@microsoft.com> Reviewed-by: Shyam Prasad N <sprasad@microsoft.com> Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz> Signed-off-by: Steve French <stfrench@microsoft.com> (cherry picked from commit 5efdd91) Signed-off-by: Brett Mastbergen <bmastbergen@ciq.com>
1 parent aeb1a6c commit bfbc31b

File tree

5 files changed

+22
-2
lines changed

5 files changed

+22
-2
lines changed

fs/cifs/cifsfs.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
691691
seq_printf(s, ",acdirmax=%lu", cifs_sb->ctx->acdirmax / HZ);
692692
seq_printf(s, ",acregmax=%lu", cifs_sb->ctx->acregmax / HZ);
693693
}
694+
seq_printf(s, ",closetimeo=%lu", cifs_sb->ctx->closetimeo / HZ);
694695

695696
if (tcon->ses->chan_max > 1)
696697
seq_printf(s, ",multichannel,max_channels=%zu",

fs/cifs/connect.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2649,6 +2649,8 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
26492649
return 0;
26502650
if (old->ctx->acdirmax != new->ctx->acdirmax)
26512651
return 0;
2652+
if (old->ctx->closetimeo != new->ctx->closetimeo)
2653+
return 0;
26522654

26532655
return 1;
26542656
}

fs/cifs/file.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -964,12 +964,12 @@ int cifs_close(struct inode *inode, struct file *file)
964964
* So, Increase the ref count to avoid use-after-free.
965965
*/
966966
if (!mod_delayed_work(deferredclose_wq,
967-
&cfile->deferred, cifs_sb->ctx->acregmax))
967+
&cfile->deferred, cifs_sb->ctx->closetimeo))
968968
cifsFileInfo_get(cfile);
969969
} else {
970970
/* Deferred close for files */
971971
queue_delayed_work(deferredclose_wq,
972-
&cfile->deferred, cifs_sb->ctx->acregmax);
972+
&cfile->deferred, cifs_sb->ctx->closetimeo);
973973
cfile->deferred_close_scheduled = true;
974974
spin_unlock(&cinode->deferred_lock);
975975
return 0;

fs/cifs/fs_context.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {
146146
fsparam_u32("actimeo", Opt_actimeo),
147147
fsparam_u32("acdirmax", Opt_acdirmax),
148148
fsparam_u32("acregmax", Opt_acregmax),
149+
fsparam_u32("closetimeo", Opt_closetimeo),
149150
fsparam_u32("echo_interval", Opt_echo_interval),
150151
fsparam_u32("max_credits", Opt_max_credits),
151152
fsparam_u32("handletimeout", Opt_handletimeout),
@@ -1070,6 +1071,13 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
10701071
}
10711072
ctx->acdirmax = ctx->acregmax = HZ * result.uint_32;
10721073
break;
1074+
case Opt_closetimeo:
1075+
ctx->closetimeo = HZ * result.uint_32;
1076+
if (ctx->closetimeo > SMB3_MAX_DCLOSETIMEO) {
1077+
cifs_errorf(fc, "closetimeo too large\n");
1078+
goto cifs_parse_mount_err;
1079+
}
1080+
break;
10731081
case Opt_echo_interval:
10741082
ctx->echo_interval = result.uint_32;
10751083
break;
@@ -1517,6 +1525,7 @@ int smb3_init_fs_context(struct fs_context *fc)
15171525

15181526
ctx->acregmax = CIFS_DEF_ACTIMEO;
15191527
ctx->acdirmax = CIFS_DEF_ACTIMEO;
1528+
ctx->closetimeo = SMB3_DEF_DCLOSETIMEO;
15201529

15211530
/* Most clients set timeout to 0, allows server to use its default */
15221531
ctx->handle_timeout = 0; /* See MS-SMB2 spec section 2.2.14.2.12 */

fs/cifs/fs_context.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ enum cifs_param {
124124
Opt_actimeo,
125125
Opt_acdirmax,
126126
Opt_acregmax,
127+
Opt_closetimeo,
127128
Opt_echo_interval,
128129
Opt_max_credits,
129130
Opt_snapshot,
@@ -245,6 +246,8 @@ struct smb3_fs_context {
245246
/* attribute cache timemout for files and directories in jiffies */
246247
unsigned long acregmax;
247248
unsigned long acdirmax;
249+
/* timeout for deferred close of files in jiffies */
250+
unsigned long closetimeo;
248251
struct smb_version_operations *ops;
249252
struct smb_version_values *vals;
250253
char *prepath;
@@ -277,4 +280,9 @@ static inline struct smb3_fs_context *smb3_fc2context(const struct fs_context *f
277280
extern int smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx);
278281
extern void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb);
279282

283+
/*
284+
* max deferred close timeout (jiffies) - 2^30
285+
*/
286+
#define SMB3_MAX_DCLOSETIMEO (1 << 30)
287+
#define SMB3_DEF_DCLOSETIMEO (5 * HZ) /* Can increase later, other clients use larger */
280288
#endif

0 commit comments

Comments
 (0)