diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-02-19 18:32:14 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-04-07 04:48:52 -0400 |
commit | d444edc679e7713412f243b792b1f964e5cff1e1 (patch) | |
tree | 741d5b8acb70e1c986df5f2e7d2edc7984ce74d7 /drivers/target/iscsi | |
parent | f225225848a70006d039b4caa2a089b660756cd5 (diff) |
iscsi-target: Fix ERL=2 ASYNC_EVENT connection pointer bug
This patch fixes a long-standing bug in iscsit_build_conn_drop_async_message()
where during ERL=2 connection recovery, a bogus conn_p pointer could
end up being used to send the ISCSI_OP_ASYNC_EVENT + DROPPING_CONNECTION
notifying the initiator that cmd->logout_cid has failed.
The bug was manifesting itself as an OOPs in iscsit_allocate_cmd() with
a bogus conn_p pointer in iscsit_build_conn_drop_async_message().
Reported-by: Arshad Hussain <arshad.hussain@calsoftinc.com>
Reported-by: santosh kulkarni <santosh.kulkarni@calsoftinc.com>
Cc: <stable@vger.kernel.org> #3.1+
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/iscsi')
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 27f37c92dff3..96aee439c9fd 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -2491,6 +2491,7 @@ static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn) | |||
2491 | { | 2491 | { |
2492 | struct iscsi_cmd *cmd; | 2492 | struct iscsi_cmd *cmd; |
2493 | struct iscsi_conn *conn_p; | 2493 | struct iscsi_conn *conn_p; |
2494 | bool found = false; | ||
2494 | 2495 | ||
2495 | /* | 2496 | /* |
2496 | * Only send a Asynchronous Message on connections whos network | 2497 | * Only send a Asynchronous Message on connections whos network |
@@ -2499,11 +2500,12 @@ static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn) | |||
2499 | list_for_each_entry(conn_p, &conn->sess->sess_conn_list, conn_list) { | 2500 | list_for_each_entry(conn_p, &conn->sess->sess_conn_list, conn_list) { |
2500 | if (conn_p->conn_state == TARG_CONN_STATE_LOGGED_IN) { | 2501 | if (conn_p->conn_state == TARG_CONN_STATE_LOGGED_IN) { |
2501 | iscsit_inc_conn_usage_count(conn_p); | 2502 | iscsit_inc_conn_usage_count(conn_p); |
2503 | found = true; | ||
2502 | break; | 2504 | break; |
2503 | } | 2505 | } |
2504 | } | 2506 | } |
2505 | 2507 | ||
2506 | if (!conn_p) | 2508 | if (!found) |
2507 | return; | 2509 | return; |
2508 | 2510 | ||
2509 | cmd = iscsit_allocate_cmd(conn_p, TASK_RUNNING); | 2511 | cmd = iscsit_allocate_cmd(conn_p, TASK_RUNNING); |