diff options
| author | Henrique Carvalho <henrique.carvalho@suse.com> | 2026-01-19 20:54:44 +0300 |
|---|---|---|
| committer | Steve French <stfrench@microsoft.com> | 2026-02-09 02:07:43 +0300 |
| commit | c3c06e42e1527716c54f3ad2ced6a034b5f3a489 (patch) | |
| tree | 9d4a7d6a9a50a12e0f97e7d0b9b1cacd70cfda95 | |
| parent | e97dcac3dc0bd37e4b56aaa6874b572a3a461102 (diff) | |
| download | linux-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.c | 19 |
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, |
