@@ -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 =
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 <chu11@llnl.gov> --- ibsim/ibsim.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 51 insertions(+), 9 deletions(-)