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 <[email protected]> --- 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 = -- 1.7.1 -- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
