From: Potnuri Bharat Teja Date: Mon, 24 Apr 2017 16:51:17 +0000 (-0700) Subject: iw_cxgb4: Guard against null cm_id in dump_ep/qp X-Git-Tag: vofed-4.8-rc2^0 X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=785e7bf5d83f71fb9e51ca10d7b1a65f901034bf;p=~tnikolova%2Fcompat-rdma%2F.git iw_cxgb4: Guard against null cm_id in dump_ep/qp Endpoints that are aborting can have already dereferenced the cm_id and set ep->com.cm_id to NULL. So guard against that in dump_ep() and dump_qp(). Also create a common function for setting up ip address pointers since the same logic is needed in several places. Signed-off-by: Steve Wise Signed-off-by: Potnuri Bharat Teja --- diff --git a/linux-next-cherry-picks/0052-iw_cxgb4-Guard-against-null-cm_id-in-dump_ep.patch b/linux-next-cherry-picks/0052-iw_cxgb4-Guard-against-null-cm_id-in-dump_ep.patch new file mode 100644 index 0000000..34544c5 --- /dev/null +++ b/linux-next-cherry-picks/0052-iw_cxgb4-Guard-against-null-cm_id-in-dump_ep.patch @@ -0,0 +1,224 @@ +diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c +index 3c4b2126e0d1..bd6edb998925 100644 +--- a/drivers/infiniband/hw/cxgb4/device.c ++++ b/drivers/infiniband/hw/cxgb4/device.c +@@ -214,6 +214,52 @@ static const struct file_operations wr_log_debugfs_fops = { + .write = wr_log_clear, + }; + ++static struct sockaddr_in zero_sin = { ++ .sin_family = AF_INET, ++}; ++ ++static struct sockaddr_in6 zero_sin6 = { ++ .sin6_family = AF_INET6, ++}; ++ ++static void set_ep_sin_addrs(struct c4iw_ep *ep, ++ struct sockaddr_in **lsin, ++ struct sockaddr_in **rsin, ++ struct sockaddr_in **m_lsin, ++ struct sockaddr_in **m_rsin) ++{ ++ struct iw_cm_id *id = ep->com.cm_id; ++ ++ *lsin = (struct sockaddr_in *)&ep->com.local_addr; ++ *rsin = (struct sockaddr_in *)&ep->com.remote_addr; ++ if (id) { ++ *m_lsin = (struct sockaddr_in *)&id->m_local_addr; ++ *m_rsin = (struct sockaddr_in *)&id->m_remote_addr; ++ } else { ++ *m_lsin = &zero_sin; ++ *m_rsin = &zero_sin; ++ } ++} ++ ++static void set_ep_sin6_addrs(struct c4iw_ep *ep, ++ struct sockaddr_in6 **lsin6, ++ struct sockaddr_in6 **rsin6, ++ struct sockaddr_in6 **m_lsin6, ++ struct sockaddr_in6 **m_rsin6) ++{ ++ struct iw_cm_id *id = ep->com.cm_id; ++ ++ *lsin6 = (struct sockaddr_in6 *)&ep->com.local_addr; ++ *rsin6 = (struct sockaddr_in6 *)&ep->com.remote_addr; ++ if (id) { ++ *m_lsin6 = (struct sockaddr_in6 *)&id->m_local_addr; ++ *m_rsin6 = (struct sockaddr_in6 *)&id->m_remote_addr; ++ } else { ++ *m_lsin6 = &zero_sin6; ++ *m_rsin6 = &zero_sin6; ++ } ++} ++ + static int dump_qp(int id, void *p, void *data) + { + struct c4iw_qp *qp = p; +@@ -229,16 +275,15 @@ static int dump_qp(int id, void *p, void *data) + return 1; + + if (qp->ep) { +- if (qp->ep->com.local_addr.ss_family == AF_INET) { +- struct sockaddr_in *lsin = (struct sockaddr_in *) +- &qp->ep->com.cm_id->local_addr; +- struct sockaddr_in *rsin = (struct sockaddr_in *) +- &qp->ep->com.cm_id->remote_addr; +- struct sockaddr_in *mapped_lsin = (struct sockaddr_in *) +- &qp->ep->com.cm_id->m_local_addr; +- struct sockaddr_in *mapped_rsin = (struct sockaddr_in *) +- &qp->ep->com.cm_id->m_remote_addr; ++ struct c4iw_ep *ep = qp->ep; ++ ++ if (ep->com.local_addr.ss_family == AF_INET) { ++ struct sockaddr_in *lsin; ++ struct sockaddr_in *rsin; ++ struct sockaddr_in *m_lsin; ++ struct sockaddr_in *m_rsin; + ++ set_ep_sin_addrs(ep, &lsin, &rsin, &m_lsin, &m_rsin); + cc = snprintf(qpd->buf + qpd->pos, space, + "rc qp sq id %u rq id %u state %u " + "onchip %u ep tid %u state %u " +@@ -246,23 +291,19 @@ static int dump_qp(int id, void *p, void *data) + qp->wq.sq.qid, qp->wq.rq.qid, + (int)qp->attr.state, + qp->wq.sq.flags & T4_SQ_ONCHIP, +- qp->ep->hwtid, (int)qp->ep->com.state, ++ ep->hwtid, (int)ep->com.state, + &lsin->sin_addr, ntohs(lsin->sin_port), +- ntohs(mapped_lsin->sin_port), ++ ntohs(m_lsin->sin_port), + &rsin->sin_addr, ntohs(rsin->sin_port), +- ntohs(mapped_rsin->sin_port)); ++ ntohs(m_rsin->sin_port)); + } else { +- struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *) +- &qp->ep->com.cm_id->local_addr; +- struct sockaddr_in6 *rsin6 = (struct sockaddr_in6 *) +- &qp->ep->com.cm_id->remote_addr; +- struct sockaddr_in6 *mapped_lsin6 = +- (struct sockaddr_in6 *) +- &qp->ep->com.cm_id->m_local_addr; +- struct sockaddr_in6 *mapped_rsin6 = +- (struct sockaddr_in6 *) +- &qp->ep->com.cm_id->m_remote_addr; ++ struct sockaddr_in6 *lsin6; ++ struct sockaddr_in6 *rsin6; ++ struct sockaddr_in6 *m_lsin6; ++ struct sockaddr_in6 *m_rsin6; + ++ set_ep_sin6_addrs(ep, &lsin6, &rsin6, &m_lsin6, ++ &m_rsin6); + cc = snprintf(qpd->buf + qpd->pos, space, + "rc qp sq id %u rq id %u state %u " + "onchip %u ep tid %u state %u " +@@ -270,13 +311,13 @@ static int dump_qp(int id, void *p, void *data) + qp->wq.sq.qid, qp->wq.rq.qid, + (int)qp->attr.state, + qp->wq.sq.flags & T4_SQ_ONCHIP, +- qp->ep->hwtid, (int)qp->ep->com.state, ++ ep->hwtid, (int)ep->com.state, + &lsin6->sin6_addr, + ntohs(lsin6->sin6_port), +- ntohs(mapped_lsin6->sin6_port), ++ ntohs(m_lsin6->sin6_port), + &rsin6->sin6_addr, + ntohs(rsin6->sin6_port), +- ntohs(mapped_rsin6->sin6_port)); ++ ntohs(m_rsin6->sin6_port)); + } + } else + cc = snprintf(qpd->buf + qpd->pos, space, +@@ -533,15 +574,12 @@ static int dump_ep(int id, void *p, void *data) + return 1; + + if (ep->com.local_addr.ss_family == AF_INET) { +- struct sockaddr_in *lsin = (struct sockaddr_in *) +- &ep->com.cm_id->local_addr; +- struct sockaddr_in *rsin = (struct sockaddr_in *) +- &ep->com.cm_id->remote_addr; +- struct sockaddr_in *mapped_lsin = (struct sockaddr_in *) +- &ep->com.cm_id->m_local_addr; +- struct sockaddr_in *mapped_rsin = (struct sockaddr_in *) +- &ep->com.cm_id->m_remote_addr; ++ struct sockaddr_in *lsin; ++ struct sockaddr_in *rsin; ++ struct sockaddr_in *m_lsin; ++ struct sockaddr_in *m_rsin; + ++ set_ep_sin_addrs(ep, &lsin, &rsin, &m_lsin, &m_rsin); + cc = snprintf(epd->buf + epd->pos, space, + "ep %p cm_id %p qp %p state %d flags 0x%lx " + "history 0x%lx hwtid %d atid %d " +@@ -553,19 +591,16 @@ static int dump_ep(int id, void *p, void *data) + ep->stats.connect_neg_adv, + ep->stats.abort_neg_adv, + &lsin->sin_addr, ntohs(lsin->sin_port), +- ntohs(mapped_lsin->sin_port), ++ ntohs(m_lsin->sin_port), + &rsin->sin_addr, ntohs(rsin->sin_port), +- ntohs(mapped_rsin->sin_port)); ++ ntohs(m_rsin->sin_port)); + } else { +- struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *) +- &ep->com.cm_id->local_addr; +- struct sockaddr_in6 *rsin6 = (struct sockaddr_in6 *) +- &ep->com.cm_id->remote_addr; +- struct sockaddr_in6 *mapped_lsin6 = (struct sockaddr_in6 *) +- &ep->com.cm_id->m_local_addr; +- struct sockaddr_in6 *mapped_rsin6 = (struct sockaddr_in6 *) +- &ep->com.cm_id->m_remote_addr; ++ struct sockaddr_in6 *lsin6; ++ struct sockaddr_in6 *rsin6; ++ struct sockaddr_in6 *m_lsin6; ++ struct sockaddr_in6 *m_rsin6; + ++ set_ep_sin6_addrs(ep, &lsin6, &rsin6, &m_lsin6, &m_rsin6); + cc = snprintf(epd->buf + epd->pos, space, + "ep %p cm_id %p qp %p state %d flags 0x%lx " + "history 0x%lx hwtid %d atid %d " +@@ -577,9 +612,9 @@ static int dump_ep(int id, void *p, void *data) + ep->stats.connect_neg_adv, + ep->stats.abort_neg_adv, + &lsin6->sin6_addr, ntohs(lsin6->sin6_port), +- ntohs(mapped_lsin6->sin6_port), ++ ntohs(m_lsin6->sin6_port), + &rsin6->sin6_addr, ntohs(rsin6->sin6_port), +- ntohs(mapped_rsin6->sin6_port)); ++ ntohs(m_rsin6->sin6_port)); + } + if (cc < space) + epd->pos += cc; +@@ -600,7 +635,7 @@ static int dump_listen_ep(int id, void *p, void *data) + if (ep->com.local_addr.ss_family == AF_INET) { + struct sockaddr_in *lsin = (struct sockaddr_in *) + &ep->com.cm_id->local_addr; +- struct sockaddr_in *mapped_lsin = (struct sockaddr_in *) ++ struct sockaddr_in *m_lsin = (struct sockaddr_in *) + &ep->com.cm_id->m_local_addr; + + cc = snprintf(epd->buf + epd->pos, space, +@@ -609,11 +644,11 @@ static int dump_listen_ep(int id, void *p, void *data) + ep, ep->com.cm_id, (int)ep->com.state, + ep->com.flags, ep->stid, ep->backlog, + &lsin->sin_addr, ntohs(lsin->sin_port), +- ntohs(mapped_lsin->sin_port)); ++ ntohs(m_lsin->sin_port)); + } else { + struct sockaddr_in6 *lsin6 = (struct sockaddr_in6 *) + &ep->com.cm_id->local_addr; +- struct sockaddr_in6 *mapped_lsin6 = (struct sockaddr_in6 *) ++ struct sockaddr_in6 *m_lsin6 = (struct sockaddr_in6 *) + &ep->com.cm_id->m_local_addr; + + cc = snprintf(epd->buf + epd->pos, space, +@@ -622,7 +657,7 @@ static int dump_listen_ep(int id, void *p, void *data) + ep, ep->com.cm_id, (int)ep->com.state, + ep->com.flags, ep->stid, ep->backlog, + &lsin6->sin6_addr, ntohs(lsin6->sin6_port), +- ntohs(mapped_lsin6->sin6_port)); ++ ntohs(m_lsin6->sin6_port)); + } + if (cc < space) + epd->pos += cc;