Re: [PATCH] iscsi-target: Fix iscsit_start_kthreads failure OOPs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hey Sagi,

This addresses a regression with traditional iscsi-target that I noticed
recently, but has not been tested with iser-target yet.

Would you mind taking a quick spin with iser-target to verify, and try
to intentionally fail iscsit_start_kthreads() into the two out_bitmap +
out_tx error paths..?

Thanks,

--nab

On Tue, 2015-07-07 at 08:50 +0000, Nicholas A. Bellinger wrote:
> From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>
> 
> This patch fixes a regression introduced with the following commit
> in v4.0-rc1 code:
> 
>     commit 88dcd2dab5c23b1c9cfc396246d8f476c872f0ca
>     Author: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>
>     Date:   Thu Feb 26 22:19:15 2015 -0800
> 
>         iscsi-target: Convert iscsi_thread_set usage to kthread.h
> 
> where iscsit_start_kthreads() failure would result in a NULL pointer
> dereference OOPs.
> 
> To address this bug, it adds a iscsit_kthread_err() helper to cleanup
> both zero_tsih and !zero_tsih cases, and a iscsi_target_tx_thread()
> special case to avoid iscsit_take_action_for_connection_exit() during
> the late iscsit_start_kthreads() -> kthread_run() failure case for
> iscsi_target_rx_thread().
> 
> Cc: Sagi Grimberg <sagig@xxxxxxxxxxxx>
> Cc: <stable@xxxxxxxxxxxxxxx> # v3.10+
> Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>
> ---
>  drivers/target/iscsi/iscsi_target.c       |  3 ++-
>  drivers/target/iscsi/iscsi_target_login.c | 39 +++++++++++++++++++++++++++----
>  2 files changed, 36 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
> index 4e68b62..66655b7 100644
> --- a/drivers/target/iscsi/iscsi_target.c
> +++ b/drivers/target/iscsi/iscsi_target.c
> @@ -3998,7 +3998,8 @@ get_immediate:
>  	}
>  
>  transport_err:
> -	iscsit_take_action_for_connection_exit(conn);
> +	if (conn->rx_thread_active)
> +		iscsit_take_action_for_connection_exit(conn);
>  out:
>  	return 0;
>  }
> diff --git a/drivers/target/iscsi/iscsi_target_login.c b/drivers/target/iscsi/iscsi_target_login.c
> index 3d0fe4f..76dedb6 100644
> --- a/drivers/target/iscsi/iscsi_target_login.c
> +++ b/drivers/target/iscsi/iscsi_target_login.c
> @@ -679,6 +679,7 @@ static int iscsit_start_kthreads(struct iscsi_conn *conn)
>  
>  	return 0;
>  out_tx:
> +	send_sig(SIGINT, conn->tx_thread, 1);
>  	kthread_stop(conn->tx_thread);
>  	conn->tx_thread_active = false;
>  out_bitmap:
> @@ -689,6 +690,23 @@ out_bitmap:
>  	return ret;
>  }
>  
> +static void iscsit_kthread_err(struct iscsi_session *sess,
> +			       struct iscsi_conn *conn, bool new_sess)
> +{
> +	spin_lock_bh(&sess->conn_lock);
> +	list_del(&conn->conn_list);
> +	if (atomic_dec_and_test(&sess->nconn))
> +		sess->session_state = TARG_SESS_STATE_FAILED;
> +	spin_unlock_bh(&sess->conn_lock);
> +
> +	if (!new_sess)
> +		return;
> +
> +	transport_deregister_session_configfs(sess->se_sess);
> +	transport_deregister_session(sess->se_sess);
> +	sess->se_sess = NULL;
> +}
> +
>  int iscsi_post_login_handler(
>  	struct iscsi_np *np,
>  	struct iscsi_conn *conn,
> @@ -740,8 +758,10 @@ int iscsi_post_login_handler(
>  		spin_unlock_bh(&sess->conn_lock);
>  
>  		rc = iscsit_start_kthreads(conn);
> -		if (rc)
> -			return rc;
> +		if (rc) {
> +			iscsit_kthread_err(sess, conn, false);
> +			goto out_old_sess;
> +		}
>  
>  		iscsi_post_login_start_timers(conn);
>  		/*
> @@ -751,7 +771,7 @@ int iscsi_post_login_handler(
>  		iscsit_thread_get_cpumask(conn);
>  		conn->conn_rx_reset_cpumask = 1;
>  		conn->conn_tx_reset_cpumask = 1;
> -
> +out_old_sess:
>  		iscsit_dec_conn_usage_count(conn);
>  		if (stop_timer) {
>  			spin_lock_bh(&se_tpg->session_lock);
> @@ -759,7 +779,7 @@ int iscsi_post_login_handler(
>  			spin_unlock_bh(&se_tpg->session_lock);
>  		}
>  		iscsit_dec_session_usage_count(sess);
> -		return 0;
> +		return rc;
>  	}
>  
>  	iscsi_set_session_parameters(sess->sess_ops, conn->param_list, 1);
> @@ -801,8 +821,17 @@ int iscsi_post_login_handler(
>  	spin_unlock_bh(&se_tpg->session_lock);
>  
>  	rc = iscsit_start_kthreads(conn);
> -	if (rc)
> +	if (rc) {
> +		spin_lock_bh(&se_tpg->session_lock);
> +		if (tpg->tpg_tiqn)
> +			tpg->tpg_tiqn->tiqn_nsessions--;
> +		tpg->nsessions--;
> +		spin_unlock_bh(&se_tpg->session_lock);
> +
> +		iscsit_kthread_err(sess, conn, true);
> +		iscsit_dec_conn_usage_count(conn);
>  		return rc;
> +	}
>  
>  	iscsi_post_login_start_timers(conn);
>  	/*


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux