cifs: fix potential use-after-free bugs in TCP_Server_Info::hostname
[sfrench/cifs-2.6.git] / fs / cifs / connect.c
index 7bfef741f758dd073321d107b5fd3b67b34c9add..c71505a29482c885e12af1cc54ab5191c0e3bd97 100644 (file)
@@ -403,8 +403,10 @@ static int __reconnect_target_unlocked(struct TCP_Server_Info *server, const cha
                if (server->hostname != target) {
                        hostname = extract_hostname(target);
                        if (!IS_ERR(hostname)) {
+                               spin_lock(&server->srv_lock);
                                kfree(server->hostname);
                                server->hostname = hostname;
+                               spin_unlock(&server->srv_lock);
                        } else {
                                cifs_dbg(FYI, "%s: couldn't extract hostname or address from dfs target: %ld\n",
                                         __func__, PTR_ERR(hostname));
@@ -561,9 +563,7 @@ cifs_echo_request(struct work_struct *work)
                goto requeue_echo;
 
        rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS;
-       if (rc)
-               cifs_dbg(FYI, "Unable to send echo request to server: %s\n",
-                        server->hostname);
+       cifs_server_dbg(FYI, "send echo request: rc = %d\n", rc);
 
        /* Check witness registrations */
        cifs_swn_check();
@@ -1404,6 +1404,8 @@ static int match_server(struct TCP_Server_Info *server, struct smb3_fs_context *
 {
        struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr;
 
+       lockdep_assert_held(&server->srv_lock);
+
        if (ctx->nosharesock)
                return 0;
 
@@ -1810,7 +1812,9 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)
        if (tcon == NULL)
                return -ENOMEM;
 
+       spin_lock(&server->srv_lock);
        scnprintf(unc, sizeof(unc), "\\\\%s\\IPC$", server->hostname);
+       spin_unlock(&server->srv_lock);
 
        xid = get_xid();
        tcon->ses = ses;