diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2014-02-19 18:32:14 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-05-06 10:55:30 -0400 |
commit | 95c1229d8dab9e43a9567c353ea19be908c14cb3 (patch) | |
tree | cb5b4091b41d86c0a0130129fcd19dd6abcd4aaa | |
parent | 84bb7edf3385b3250bd761bcf69931dbc33bc42c (diff) |
iscsi-target: Fix ERL=2 ASYNC_EVENT connection pointer bug
commit d444edc679e7713412f243b792b1f964e5cff1e1 upstream.
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>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-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 5232ac7b0745..58c479d13b57 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -2454,6 +2454,7 @@ static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn) | |||
2454 | { | 2454 | { |
2455 | struct iscsi_cmd *cmd; | 2455 | struct iscsi_cmd *cmd; |
2456 | struct iscsi_conn *conn_p; | 2456 | struct iscsi_conn *conn_p; |
2457 | bool found = false; | ||
2457 | 2458 | ||
2458 | /* | 2459 | /* |
2459 | * Only send a Asynchronous Message on connections whos network | 2460 | * Only send a Asynchronous Message on connections whos network |
@@ -2462,11 +2463,12 @@ static void iscsit_build_conn_drop_async_message(struct iscsi_conn *conn) | |||
2462 | list_for_each_entry(conn_p, &conn->sess->sess_conn_list, conn_list) { | 2463 | list_for_each_entry(conn_p, &conn->sess->sess_conn_list, conn_list) { |
2463 | if (conn_p->conn_state == TARG_CONN_STATE_LOGGED_IN) { | 2464 | if (conn_p->conn_state == TARG_CONN_STATE_LOGGED_IN) { |
2464 | iscsit_inc_conn_usage_count(conn_p); | 2465 | iscsit_inc_conn_usage_count(conn_p); |
2466 | found = true; | ||
2465 | break; | 2467 | break; |
2466 | } | 2468 | } |
2467 | } | 2469 | } |
2468 | 2470 | ||
2469 | if (!conn_p) | 2471 | if (!found) |
2470 | return; | 2472 | return; |
2471 | 2473 | ||
2472 | cmd = iscsit_allocate_cmd(conn_p, GFP_ATOMIC); | 2474 | cmd = iscsit_allocate_cmd(conn_p, GFP_ATOMIC); |