]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
cifs: all initializations for tcon should happen in tcon_info_alloc
authorShyam Prasad N <sprasad@microsoft.com>
Mon, 30 Jun 2025 17:39:34 +0000 (23:09 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Jul 2025 16:35:18 +0000 (18:35 +0200)
[ Upstream commit 74ebd02163fde05baa23129e06dde4b8f0f2377a ]

Today, a few work structs inside tcon are initialized inside
cifs_get_tcon and not in tcon_info_alloc. As a result, if a tcon
is obtained from tcon_info_alloc, but not called as a part of
cifs_get_tcon, we may trip over.

Cc: <stable@vger.kernel.org>
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
Reviewed-by: Paulo Alcantara (Red Hat) <pc@manguebit.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/smb/client/cifsproto.h
fs/smb/client/connect.c
fs/smb/client/misc.c

index 8edb6fe89a97c69add5c458881f2d382a06f7275..5ab877e480abcbfd0a470c52025350364d88e1d1 100644 (file)
@@ -136,6 +136,7 @@ extern int SendReceiveBlockingLock(const unsigned int xid,
                        struct smb_hdr *out_buf,
                        int *bytes_returned);
 
+void smb2_query_server_interfaces(struct work_struct *work);
 void
 cifs_signal_cifsd_for_reconnect(struct TCP_Server_Info *server,
                                      bool all_channels);
index 14be8822d23a2af31dfd0ff4a4ebd3fba10bd3b5..33a292dabdb879406112e1e25333b14b14774b37 100644 (file)
@@ -113,7 +113,7 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
        return rc;
 }
 
-static void smb2_query_server_interfaces(struct work_struct *work)
+void smb2_query_server_interfaces(struct work_struct *work)
 {
        int rc;
        int xid;
@@ -2818,20 +2818,14 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
        tcon->max_cached_dirs = ctx->max_cached_dirs;
        tcon->nodelete = ctx->nodelete;
        tcon->local_lease = ctx->local_lease;
-       INIT_LIST_HEAD(&tcon->pending_opens);
        tcon->status = TID_GOOD;
 
-       INIT_DELAYED_WORK(&tcon->query_interfaces,
-                         smb2_query_server_interfaces);
        if (ses->server->dialect >= SMB30_PROT_ID &&
            (ses->server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
                /* schedule query interfaces poll */
                queue_delayed_work(cifsiod_wq, &tcon->query_interfaces,
                                   (SMB_INTERFACE_POLL_INTERVAL * HZ));
        }
-#ifdef CONFIG_CIFS_DFS_UPCALL
-       INIT_DELAYED_WORK(&tcon->dfs_cache_work, dfs_cache_refresh);
-#endif
        spin_lock(&cifs_tcp_ses_lock);
        list_add(&tcon->tcon_list, &ses->tcon_list);
        spin_unlock(&cifs_tcp_ses_lock);
index 2e9a14e28e466c3013c0e880b3b34030bf5bbf73..bbbe48447765de5113362017a967421e4fceaaeb 100644 (file)
@@ -148,6 +148,12 @@ tcon_info_alloc(bool dir_leases_enabled, enum smb3_tcon_ref_trace trace)
 #ifdef CONFIG_CIFS_DFS_UPCALL
        INIT_LIST_HEAD(&ret_buf->dfs_ses_list);
 #endif
+       INIT_LIST_HEAD(&ret_buf->pending_opens);
+       INIT_DELAYED_WORK(&ret_buf->query_interfaces,
+                         smb2_query_server_interfaces);
+#ifdef CONFIG_CIFS_DFS_UPCALL
+       INIT_DELAYED_WORK(&ret_buf->dfs_cache_work, dfs_cache_refresh);
+#endif
 
        return ret_buf;
 }