OSDN Git Service

smb3: Handle error case during offload read path
authorRohith Surabattula <rohiths@microsoft.com>
Thu, 29 Oct 2020 06:07:56 +0000 (06:07 +0000)
committerSteve French <stfrench@microsoft.com>
Mon, 16 Nov 2020 05:05:33 +0000 (23:05 -0600)
Mid callback needs to be called only when valid data is
read into pages.

These patches address a problem found during decryption offload:
      CIFS: VFS: trying to dequeue a deleted mid
that could cause a refcount use after free:
      Workqueue: smb3decryptd smb2_decrypt_offload [cifs]

Signed-off-by: Rohith Surabattula <rohiths@microsoft.com>
Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com>
CC: Stable <stable@vger.kernel.org> #5.4+
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/smb2ops.c

index b3b2abb..dab94f6 100644 (file)
@@ -4559,7 +4559,25 @@ static void smb2_decrypt_offload(struct work_struct *work)
                                      dw->server->vals->read_rsp_size,
                                      dw->ppages, dw->npages, dw->len,
                                      true);
-               mid->callback(mid);
+               if (rc >= 0) {
+#ifdef CONFIG_CIFS_STATS2
+                       mid->when_received = jiffies;
+#endif
+                       mid->callback(mid);
+               } else {
+                       spin_lock(&GlobalMid_Lock);
+                       if (dw->server->tcpStatus == CifsNeedReconnect) {
+                               mid->mid_state = MID_RETRY_NEEDED;
+                               spin_unlock(&GlobalMid_Lock);
+                               mid->callback(mid);
+                       } else {
+                               mid->mid_state = MID_REQUEST_SUBMITTED;
+                               mid->mid_flags &= ~(MID_DELETED);
+                               list_add_tail(&mid->qhead,
+                                       &dw->server->pending_mid_q);
+                               spin_unlock(&GlobalMid_Lock);
+                       }
+               }
                cifs_mid_q_entry_release(mid);
        }