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>
This commit is contained in:
Henrique Carvalho 2026-01-19 14:54:44 -03:00 committed by Steve French
parent e97dcac3dc
commit c3c06e42e1

View File

@ -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 @@ parse_server_interfaces(struct network_interface_info_ioctl_rsp *buf,
+ 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,