From patchwork Wed Jun 19 21:42:33 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Al Chu X-Patchwork-Id: 2752271 X-Patchwork-Delegate: hal@mellanox.com Return-Path: X-Original-To: patchwork-linux-rdma@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 933DB9F8E1 for ; Wed, 19 Jun 2013 21:42:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id CE30320421 for ; Wed, 19 Jun 2013 21:42:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C14582041F for ; Wed, 19 Jun 2013 21:42:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935096Ab3FSVmd (ORCPT ); Wed, 19 Jun 2013 17:42:33 -0400 Received: from prdiron-3.llnl.gov ([128.15.143.173]:37140 "EHLO prdiron-3.llnl.gov" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935023Ab3FSVmd (ORCPT ); Wed, 19 Jun 2013 17:42:33 -0400 X-Attachments: Received: from auk59.llnl.gov (HELO [134.9.93.24]) ([134.9.93.24]) by prdiron-3.llnl.gov with ESMTP; 19 Jun 2013 14:42:32 -0700 Subject: [PATCH] ibsim: Fix seg-fault on unconnected client From: Albert Chu To: linux-rdma@vger.kernel.org Date: Wed, 19 Jun 2013 14:42:33 -0700 Message-Id: <1371678153.19017.102.camel@auk59.llnl.gov> Mime-Version: 1.0 X-Mailer: Evolution 2.12.3 (2.12.3-19.el5) Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Spam-Status: No, score=-8.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP A segfault would regularly occur if ibsim was restarted but previously connected clients had not disconnected. The previously connected clients would assume their previous connection was still valid. Signed-off-by: Albert L. Chu --- ibsim/ibsim.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 51 insertions(+), 9 deletions(-) diff --git a/ibsim/ibsim.c b/ibsim/ibsim.c index 5f86fef..819a66d 100644 --- a/ibsim/ibsim.c +++ b/ibsim/ibsim.c @@ -280,10 +280,23 @@ static int sim_ctl_disconnect_client(Client * cl, struct sim_ctl * ctl) return 0; } +static int sim_ctl_validate_client(Client * cl, struct sim_ctl * ctl) +{ + if (!cl->pid) { + ctl->type = SIM_CTL_ERROR; + return -1; + } + return 0; +} + static int sim_ctl_get_port(Client * cl, struct sim_ctl * ctl) { - struct sim_port *p = (void *)ctl->data; + struct sim_port *p; + + if (sim_ctl_validate_client(cl, ctl) < 0) + return -1; + p = (void *)ctl->data; p->lid = cl->port->lid; p->state = cl->port->state; return 0; @@ -291,8 +304,12 @@ static int sim_ctl_get_port(Client * cl, struct sim_ctl * ctl) static int sim_ctl_get_gid(Client * cl, struct sim_ctl * ctl) { - char *gid = (void *)ctl->data; + char *gid; + if (sim_ctl_validate_client(cl, ctl) < 0) + return -1; + + gid = (void *)ctl->data; mad_get_array(cl->port->portinfo, 0, IB_PORT_GID_PREFIX_F, gid); memcpy(gid + 8, &cl->port->node->nodeguid, 8); return 0; @@ -300,14 +317,21 @@ static int sim_ctl_get_gid(Client * cl, struct sim_ctl * ctl) static int sim_ctl_get_guid(Client * cl, struct sim_ctl * ctl) { - char *guid = (void *)ctl->data; + char *guid; + + if (sim_ctl_validate_client(cl, ctl) < 0) + return -1; + guid = (void *)ctl->data; memcpy(guid, &cl->port->node->nodeguid, 8); return 0; } static int sim_ctl_get_nodeinfo(Client * cl, struct sim_ctl * ctl) { + if (sim_ctl_validate_client(cl, ctl) < 0) + return -1; + memcpy(ctl->data, cl->port->node->nodeinfo, sizeof(ctl->data)); return 0; } @@ -315,7 +339,12 @@ static int sim_ctl_get_nodeinfo(Client * cl, struct sim_ctl * ctl) static int sim_ctl_get_portinfo(Client * cl, struct sim_ctl * ctl) { Port *p; - uint8_t port_num = ctl->data[0]; + uint8_t port_num; + + if (sim_ctl_validate_client(cl, ctl) < 0) + return -1; + + port_num = ctl->data[0]; if (port_num == 0 || port_num > cl->port->node->numports) p = cl->port; else if (cl->port->node->type == SWITCH_NODE) @@ -345,8 +374,12 @@ static void set_issm(Port *port, unsigned issm) static int sim_ctl_set_issm(Client * cl, struct sim_ctl * ctl) { - int issm = *(int *)ctl->data; + int issm; + + if (sim_ctl_validate_client(cl, ctl) < 0) + return -1; + issm = *(int *)ctl->data; VERB("set issm %d port %" PRIx64, issm, cl->port->portguid); cl->issm = issm; set_issm(cl->port, issm); @@ -356,12 +389,17 @@ static int sim_ctl_set_issm(Client * cl, struct sim_ctl * ctl) static int sim_ctl_get_pkeys(Client * cl, struct sim_ctl * ctl) { - Port *port = cl->port; - unsigned size = (port->node->sw && port->portnum) ? + Port *port; + unsigned size; + + if (sim_ctl_validate_client(cl, ctl) < 0) + return -1; + + port = cl->port; + size = (port->node->sw && port->portnum) ? mad_get_field(port->node->sw->switchinfo, 0, IB_SW_PARTITION_ENFORCE_CAP_F) : mad_get_field(port->node->nodeinfo, 0, IB_NODE_PARTITION_CAP_F); - size *= sizeof(port->pkey_tbl[0]); if (size > sizeof(ctl->data)) size = sizeof(ctl->data); @@ -373,8 +411,12 @@ static int sim_ctl_get_pkeys(Client * cl, struct sim_ctl * ctl) static int sim_ctl_get_vendor(Client * cl, struct sim_ctl * ctl) { - struct sim_vendor *v = (void *)ctl->data; + struct sim_vendor *v; + + if (sim_ctl_validate_client(cl, ctl) < 0) + return -1; + v = (void *)ctl->data; v->vendor_id = mad_get_field(cl->port->node->nodeinfo, 0, IB_NODE_VENDORID_F); v->vendor_part_id =