summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenrique Carvalho <henrique.carvalho@suse.com>2026-01-19 20:54:44 +0300
committerSteve French <stfrench@microsoft.com>2026-02-09 02:07:43 +0300
commitc3c06e42e1527716c54f3ad2ced6a034b5f3a489 (patch)
tree9d4a7d6a9a50a12e0f97e7d0b9b1cacd70cfda95
parente97dcac3dc0bd37e4b56aaa6874b572a3a461102 (diff)
downloadlinux-c3c06e42e1527716c54f3ad2ced6a034b5f3a489.tar.xz
smb: client: prevent races in ->query_interfaces()
It was possible for two query interface works to be concurrently trying to update the interfaces. Prevent this by checking and updating iface_last_update under iface_lock. Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com> Signed-off-by: Steve French <stfrench@microsoft.com>
-rw-r--r--fs/smb/client/smb2ops.c19
1 files changed, 8 insertions, 11 deletions
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 653e2f29384d..262df6d2c2c8 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -637,13 +637,6 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
p = buf;
spin_lock(&ses->iface_lock);
- /* do not query too frequently, this time with lock held */
- if (ses->iface_last_update &&
- time_before(jiffies, ses->iface_last_update +
- (SMB_INTERFACE_POLL_INTERVAL * HZ))) {
- spin_unlock(&ses->iface_lock);
- return 0;
- }
/*
* Go through iface_list and mark them as inactive
@@ -666,7 +659,6 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
"Empty network interface list returned by server %s\n",
ses->server->hostname);
rc = -EOPNOTSUPP;
- ses->iface_last_update = jiffies;
goto out;
}
@@ -795,8 +787,6 @@ next_iface:
+ sizeof(p->Next) && p->Next))
cifs_dbg(VFS, "%s: incomplete interface info\n", __func__);
- ses->iface_last_update = jiffies;
-
out:
/*
* Go through the list again and put the inactive entries
@@ -825,10 +815,17 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon, bool in_
struct TCP_Server_Info *pserver;
/* do not query too frequently */
+ spin_lock(&ses->iface_lock);
if (ses->iface_last_update &&
time_before(jiffies, ses->iface_last_update +
- (SMB_INTERFACE_POLL_INTERVAL * HZ)))
+ (SMB_INTERFACE_POLL_INTERVAL * HZ))) {
+ spin_unlock(&ses->iface_lock);
return 0;
+ }
+
+ ses->iface_last_update = jiffies;
+
+ spin_unlock(&ses->iface_lock);
rc = SMB2_ioctl(xid, tcon, NO_FILE_ID, NO_FILE_ID,
FSCTL_QUERY_NETWORK_INTERFACE_INFO,