iscsi-target: Avoid early conn_logout_comp for iser connections
authorNicholas Bellinger <nab@linux-iscsi.org>
Mon, 23 Feb 2015 08:57:51 +0000 (00:57 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 26 Mar 2015 14:01:01 +0000 (15:01 +0100)
commit f068fbc82e7696d67b1bb8189306865bedf368b6 upstream.

This patch fixes a iser specific logout bug where early complete()
of conn->conn_logout_comp in iscsit_close_connection() was causing
isert_wait4logout() to complete too soon, triggering a use after
free NULL pointer dereference of iscsi_conn memory.

The complete() was originally added for traditional iscsi-target
when a ISCSI_LOGOUT_OP failed in iscsi_target_rx_opcode(), but given
iser-target does not wait in logout failure, this special case needs
to be avoided.

Reported-by: Sagi Grimberg <sagig@mellanox.com>
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: Slava Shwartsman <valyushash@gmail.com>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/target/iscsi/iscsi_target.c

index 651b5768862f38c5384438ff5013b07ac9a0cf86..9559ea749d83e7275d31a5335d23bb8f032f41ac 100644 (file)
@@ -4136,11 +4136,17 @@ int iscsit_close_connection(
        pr_debug("Closing iSCSI connection CID %hu on SID:"
                " %u\n", conn->cid, sess->sid);
        /*
-        * Always up conn_logout_comp just in case the RX Thread is sleeping
-        * and the logout response never got sent because the connection
-        * failed.
+        * Always up conn_logout_comp for the traditional TCP case just in case
+        * the RX Thread in iscsi_target_rx_opcode() is sleeping and the logout
+        * response never got sent because the connection failed.
+        *
+        * However for iser-target, isert_wait4logout() is using conn_logout_comp
+        * to signal logout response TX interrupt completion.  Go ahead and skip
+        * this for iser since isert_rx_opcode() does not wait on logout failure,
+        * and to avoid iscsi_conn pointer dereference in iser-target code.
         */
-       complete(&conn->conn_logout_comp);
+       if (conn->conn_transport->transport_type == ISCSI_TCP)
+               complete(&conn->conn_logout_comp);
 
        iscsi_release_thread_set(conn);