]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
cifs: make sure server interfaces are requested only for SMB3+
authorShyam Prasad N <sprasad@microsoft.com>
Wed, 13 Mar 2024 10:40:41 +0000 (10:40 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Apr 2024 13:11:27 +0000 (15:11 +0200)
[ Upstream commit 13c0a74747cb7fdadf58c5d3a7d52cfca2d51736 ]

Some code paths for querying server interfaces make a false
assumption that it will only get called for SMB3+. Since this
function now can get called from a generic code paths, the correct
thing to do is to have specific handler for this functionality
per SMB dialect, and call this handler.

This change adds such a handler and implements this handler only
for SMB 3.0 and 3.1.1.

Cc: stable@vger.kernel.org
Cc: Jan Čermák <sairon@sairon.cz>
Reported-by: Paulo Alcantara <pc@manguebit.com>
Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/smb/client/cifsglob.h
fs/smb/client/connect.c
fs/smb/client/smb2ops.c
fs/smb/client/smb2pdu.c

index 91a4061233f1adeb59007332a86ee30665d77070..35a12413bbee6f8ad3aab62dfab8091fe1cecf49 100644 (file)
@@ -339,6 +339,9 @@ struct smb_version_operations {
        /* informational QFS call */
        void (*qfs_tcon)(const unsigned int, struct cifs_tcon *,
                         struct cifs_sb_info *);
+       /* query for server interfaces */
+       int (*query_server_interfaces)(const unsigned int, struct cifs_tcon *,
+                                      bool);
        /* check if a path is accessible or not */
        int (*is_path_accessible)(const unsigned int, struct cifs_tcon *,
                                  struct cifs_sb_info *, const char *);
index c3d805ecb7f11ebcbcfde1559f52d57b3420d9ab..bc8d09bab18bbb0b8d5fe4d7f69f399cac421318 100644 (file)
@@ -123,12 +123,16 @@ static void smb2_query_server_interfaces(struct work_struct *work)
        struct cifs_tcon *tcon = container_of(work,
                                        struct cifs_tcon,
                                        query_interfaces.work);
+       struct TCP_Server_Info *server = tcon->ses->server;
 
        /*
         * query server network interfaces, in case they change
         */
+       if (!server->ops->query_server_interfaces)
+               return;
+
        xid = get_xid();
-       rc = SMB3_request_interfaces(xid, tcon, false);
+       rc = server->ops->query_server_interfaces(xid, tcon, false);
        free_xid(xid);
 
        if (rc) {
index ba734395b0360909da5c476dd95ffb62a0ddd7c6..4852afe3929be8e8534ecd3773644423ba7a1de8 100644 (file)
@@ -5429,6 +5429,7 @@ struct smb_version_operations smb30_operations = {
        .tree_connect = SMB2_tcon,
        .tree_disconnect = SMB2_tdis,
        .qfs_tcon = smb3_qfs_tcon,
+       .query_server_interfaces = SMB3_request_interfaces,
        .is_path_accessible = smb2_is_path_accessible,
        .can_echo = smb2_can_echo,
        .echo = SMB2_echo,
@@ -5543,6 +5544,7 @@ struct smb_version_operations smb311_operations = {
        .tree_connect = SMB2_tcon,
        .tree_disconnect = SMB2_tdis,
        .qfs_tcon = smb3_qfs_tcon,
+       .query_server_interfaces = SMB3_request_interfaces,
        .is_path_accessible = smb2_is_path_accessible,
        .can_echo = smb2_can_echo,
        .echo = SMB2_echo,
index fca55702b51adacc71b5e4c468a45e705cf08c4e..4d7d0bdf7a472b29b1dc70b916bd19957e48e624 100644 (file)
@@ -409,14 +409,15 @@ skip_sess_setup:
        spin_unlock(&ses->ses_lock);
 
        if (!rc &&
-           (server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL)) {
+           (server->capabilities & SMB2_GLOBAL_CAP_MULTI_CHANNEL) &&
+           server->ops->query_server_interfaces) {
                mutex_unlock(&ses->session_mutex);
 
                /*
                 * query server network interfaces, in case they change
                 */
                xid = get_xid();
-               rc = SMB3_request_interfaces(xid, tcon, false);
+               rc = server->ops->query_server_interfaces(xid, tcon, false);
                free_xid(xid);
 
                if (rc == -EOPNOTSUPP && ses->chan_count > 1) {