From patchwork Mon Aug 22 19:28:28 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hefty, Sean" X-Patchwork-Id: 1086202 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.4) with ESMTP id p7MJSWWQ024683 for ; Mon, 22 Aug 2011 19:28:32 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753339Ab1HVT2b (ORCPT ); Mon, 22 Aug 2011 15:28:31 -0400 Received: from mga03.intel.com ([143.182.124.21]:24498 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753189Ab1HVT2b convert rfc822-to-8bit (ORCPT ); Mon, 22 Aug 2011 15:28:31 -0400 Received: from azsmga002.ch.intel.com ([10.2.17.35]) by azsmga101.ch.intel.com with ESMTP; 22 Aug 2011 12:28:30 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.68,264,1312182000"; d="scan'208";a="9863540" Received: from orsmsx604.amr.corp.intel.com ([10.22.226.87]) by AZSMGA002.ch.intel.com with ESMTP; 22 Aug 2011 12:28:30 -0700 Received: from orsmsx151.amr.corp.intel.com (10.22.226.38) by orsmsx604.amr.corp.intel.com (10.22.226.87) with Microsoft SMTP Server (TLS) id 8.2.255.0; Mon, 22 Aug 2011 12:28:28 -0700 Received: from orsmsx101.amr.corp.intel.com ([169.254.8.116]) by ORSMSX151.amr.corp.intel.com ([169.254.7.12]) with mapi id 14.01.0323.003; Mon, 22 Aug 2011 12:28:28 -0700 From: "Hefty, Sean" To: "linux-rdma (linux-rdma@vger.kernel.org)" Subject: [PATCH] rdma/cm: Fix crash in cma_req_handler Thread-Topic: [PATCH] rdma/cm: Fix crash in cma_req_handler Thread-Index: AcxhAaplY6w7faLyRtarCrQ8aUxOOw== Date: Mon, 22 Aug 2011 19:28:28 +0000 Message-ID: <1828884A29C6694DAF28B7E6B8A8237316E471B2@ORSMSX101.amr.corp.intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.22.254.138] MIME-Version: 1.0 Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Mon, 22 Aug 2011 19:28:33 +0000 (UTC) The rdma_cm uses the local qp_type to determine how to process an incoming request. This can result in an incoming REQ being treated as a SIDR REQ and vice versa. Fix this by switching off the event type instead, and for good measure verify that the listener supports the incoming connection request. This problem showed up when a user space application mismatched the qp types between a client and server app. Signed-off-by: Sean Hefty --- Please consider queuing for 3.1. drivers/infiniband/core/cma.c | 14 +++++++++++++- 1 files changed, 13 insertions(+), 1 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index b6a33b3..db58478 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1181,6 +1181,15 @@ static void cma_set_req_event_data(struct rdma_cm_event *event, event->param.conn.qp_num = req_data->remote_qpn; } +static int cma_check_req_qp_type(struct rdma_cm_id *id, struct ib_cm_event *ib_event) +{ + return (((ib_event->event == IB_CM_REQ_RECEIVED) || + (ib_event->param.req_rcvd.qp_type == id->qp_type)) || + ((ib_event->event == IB_CM_SIDR_REQ_RECEIVED) && + (id->qp_type == IB_QPT_UD)) || + (!id->qp_type)); +} + static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) { struct rdma_id_private *listen_id, *conn_id; @@ -1188,13 +1197,16 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event) int offset, ret; listen_id = cm_id->context; + if (!cma_check_req_qp_type(&listen_id->id, ib_event)) + return -EINVAL; + if (cma_disable_callback(listen_id, RDMA_CM_LISTEN)) return -ECONNABORTED; memset(&event, 0, sizeof event); offset = cma_user_data_offset(listen_id->id.ps); event.event = RDMA_CM_EVENT_CONNECT_REQUEST; - if (listen_id->id.qp_type == IB_QPT_UD) { + if (ib_event->event == IB_CM_SIDR_REQ_RECEIVED) { conn_id = cma_new_udp_id(&listen_id->id, ib_event); event.param.ud.private_data = ib_event->private_data + offset; event.param.ud.private_data_len =