From 302cc7c3ca14d21ccdffdebdb61c4fe028f2d5ad Mon Sep 17 00:00:00 2001 From: Sagi Grimberg Date: Tue, 2 Dec 2014 16:57:34 +0200 Subject: [PATCH] iser-target: Fix NULL dereference in SW mode DIF Fallback to software mode DIF if HCA does not support PI (without crashing obviously). It is still possible to run with backend protection and an unprotected frontend, so looking at the command prot_op is not enough. Check device PI capability on a per-IO basis (isert_prot_cmd inline static) to determine if we need to handle protection information. Trace: BUG: unable to handle kernel NULL pointer dereference at 0000000000000010 IP: [] isert_reg_sig_mr+0x351/0x3b0 [ib_isert] Call Trace: [] ? swiotlb_map_sg_attrs+0x7a/0x130 [] isert_reg_rdma+0x2fd/0x370 [ib_isert] [] ? idle_balance+0x6c/0x2c0 [] isert_put_datain+0x68/0x210 [ib_isert] [] lio_queue_data_in+0x2b/0x30 [iscsi_target_mod] [] target_complete_ok_work+0x21b/0x310 [target_core_mod] [] process_one_work+0x182/0x3b0 [] worker_thread+0x120/0x3c0 [] ? maybe_create_worker+0x190/0x190 [] kthread+0xce/0xf0 [] ? kthread_freezable_should_stop+0x70/0x70 [] ret_from_fork+0x7c/0xb0 [] ? kthread_freezable_should_stop+0x70/0x70 Reported-by: Slava Shwartsman Signed-off-by: Sagi Grimberg Cc: # v3.14+ Signed-off-by: Nicholas Bellinger --- drivers/infiniband/ulp/isert/ib_isert.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c index b0e58f1..618c815 100644 --- a/drivers/infiniband/ulp/isert/ib_isert.c +++ b/drivers/infiniband/ulp/isert/ib_isert.c @@ -61,6 +61,14 @@ static int isert_rdma_accept(struct isert_conn *isert_conn); struct rdma_cm_id *isert_setup_id(struct isert_np *isert_np); +static inline bool +isert_prot_cmd(struct isert_conn *conn, struct se_cmd *cmd) +{ + return (conn->conn_device->pi_capable && + cmd->prot_op != TARGET_PROT_NORMAL); +} + + static void isert_qp_event_callback(struct ib_event *e, void *context) { @@ -2919,8 +2927,7 @@ isert_reg_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd, if (ret) return ret; - if (wr->data.dma_nents != 1 || - se_cmd->prot_op != TARGET_PROT_NORMAL) { + if (wr->data.dma_nents != 1 || isert_prot_cmd(isert_conn, se_cmd)) { spin_lock_irqsave(&isert_conn->conn_lock, flags); fr_desc = list_first_entry(&isert_conn->conn_fr_pool, struct fast_reg_descriptor, list); @@ -2934,7 +2941,7 @@ isert_reg_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd, if (ret) goto unmap_cmd; - if (se_cmd->prot_op != TARGET_PROT_NORMAL) { + if (isert_prot_cmd(isert_conn, se_cmd)) { ret = isert_handle_prot_cmd(isert_conn, isert_cmd, wr); if (ret) goto unmap_cmd; @@ -2959,7 +2966,7 @@ isert_reg_rdma(struct iscsi_conn *conn, struct iscsi_cmd *cmd, send_wr->opcode = IB_WR_RDMA_WRITE; send_wr->wr.rdma.remote_addr = isert_cmd->read_va; send_wr->wr.rdma.rkey = isert_cmd->read_stag; - send_wr->send_flags = se_cmd->prot_op == TARGET_PROT_NORMAL ? + send_wr->send_flags = !isert_prot_cmd(isert_conn, se_cmd) ? 0 : IB_SEND_SIGNALED; } else { send_wr->opcode = IB_WR_RDMA_READ; @@ -3001,7 +3008,7 @@ isert_put_datain(struct iscsi_conn *conn, struct iscsi_cmd *cmd) return rc; } - if (se_cmd->prot_op == TARGET_PROT_NORMAL) { + if (!isert_prot_cmd(isert_conn, se_cmd)) { /* * Build isert_conn->tx_desc for iSCSI response PDU and attach */ @@ -3024,7 +3031,7 @@ isert_put_datain(struct iscsi_conn *conn, struct iscsi_cmd *cmd) atomic_sub(wr->send_wr_num, &isert_conn->post_send_buf_count); } - if (se_cmd->prot_op == TARGET_PROT_NORMAL) + if (!isert_prot_cmd(isert_conn, se_cmd)) pr_debug("Cmd: %p posted RDMA_WRITE + Response for iSER Data " "READ\n", isert_cmd); else -- 2.7.4