iscsi: fixed crash on invalid add_portal_group call
Fixed double free in spdk_rpc_add_portal_group() spdk_iscsi_portal_create() now takes string arguments as const char* and makes internal copies of them. This patch also fixes potential memory leak when id == NULL Change-Id: I4d0efb101471fb2368ceb8ceecb0e40614e3585d Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
This commit is contained in:
parent
abc73f6995
commit
3907139e34
@ -742,12 +742,13 @@ spdk_rpc_add_portal_group(struct spdk_jsonrpc_server_conn *conn,
|
|||||||
struct spdk_iscsi_portal *portal_list[MAX_PORTAL] = {};
|
struct spdk_iscsi_portal *portal_list[MAX_PORTAL] = {};
|
||||||
struct spdk_json_write_ctx *w;
|
struct spdk_json_write_ctx *w;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
int rc = -1;
|
||||||
|
|
||||||
if (spdk_json_decode_object(params, rpc_portal_group_decoders,
|
if (spdk_json_decode_object(params, rpc_portal_group_decoders,
|
||||||
SPDK_COUNTOF(rpc_portal_group_decoders),
|
SPDK_COUNTOF(rpc_portal_group_decoders),
|
||||||
&req)) {
|
&req)) {
|
||||||
SPDK_ERRLOG("spdk_json_decode_object failed\n");
|
SPDK_ERRLOG("spdk_json_decode_object failed\n");
|
||||||
goto invalid;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < req.portal_list.num_portals; i++) {
|
for (i = 0; i < req.portal_list.num_portals; i++) {
|
||||||
@ -755,34 +756,32 @@ spdk_rpc_add_portal_group(struct spdk_jsonrpc_server_conn *conn,
|
|||||||
req.portal_list.portals[i].port, 0);
|
req.portal_list.portals[i].port, 0);
|
||||||
if (portal_list[i] == NULL) {
|
if (portal_list[i] == NULL) {
|
||||||
SPDK_ERRLOG("portal_list allocation failed\n");
|
SPDK_ERRLOG("portal_list allocation failed\n");
|
||||||
goto invalid;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spdk_iscsi_portal_grp_create_from_portal_list(req.tag, portal_list,
|
rc = spdk_iscsi_portal_grp_create_from_portal_list(req.tag, portal_list,
|
||||||
req.portal_list.num_portals)) {
|
req.portal_list.num_portals);
|
||||||
|
|
||||||
|
if (rc < 0) {
|
||||||
SPDK_ERRLOG("create_from_portal_list failed\n");
|
SPDK_ERRLOG("create_from_portal_list failed\n");
|
||||||
goto invalid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
out:
|
||||||
* Leave the host and port strings allocated here and don't call free_rpc_portal_group(),
|
if (rc > 0) {
|
||||||
* because the pointers are inserted directly into the portal group list.
|
if (id != NULL) {
|
||||||
*/
|
w = spdk_jsonrpc_begin_result(conn, id);
|
||||||
|
spdk_json_write_bool(w, true);
|
||||||
if (id == NULL) {
|
spdk_jsonrpc_end_result(conn, w);
|
||||||
return;
|
}
|
||||||
|
} else {
|
||||||
|
spdk_jsonrpc_send_error_response(conn, id, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
|
||||||
}
|
}
|
||||||
|
|
||||||
w = spdk_jsonrpc_begin_result(conn, id);
|
|
||||||
spdk_json_write_bool(w, true);
|
|
||||||
spdk_jsonrpc_end_result(conn, w);
|
|
||||||
return;
|
|
||||||
|
|
||||||
invalid:
|
|
||||||
spdk_jsonrpc_send_error_response(conn, id, SPDK_JSONRPC_ERROR_INVALID_PARAMS, "Invalid parameters");
|
|
||||||
for (i = 0; i < req.portal_list.num_portals; i++) {
|
for (i = 0; i < req.portal_list.num_portals; i++) {
|
||||||
spdk_iscsi_portal_destroy(portal_list[i]);
|
if (portal_list[i] != NULL) {
|
||||||
|
spdk_iscsi_portal_destroy(portal_list[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
free_rpc_portal_group(&req);
|
free_rpc_portal_group(&req);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ spdk_iscsi_portal_grp_open(struct spdk_iscsi_portal_grp *pg);
|
|||||||
|
|
||||||
/* Assumes caller allocated host and port strings on the heap */
|
/* Assumes caller allocated host and port strings on the heap */
|
||||||
struct spdk_iscsi_portal *
|
struct spdk_iscsi_portal *
|
||||||
spdk_iscsi_portal_create(char *host, char *port, uint64_t cpumask)
|
spdk_iscsi_portal_create(const char *host, const char *port, uint64_t cpumask)
|
||||||
{
|
{
|
||||||
struct spdk_iscsi_portal *p = NULL;
|
struct spdk_iscsi_portal *p = NULL;
|
||||||
|
|
||||||
@ -77,8 +77,8 @@ spdk_iscsi_portal_create(char *host, char *port, uint64_t cpumask)
|
|||||||
SPDK_ERRLOG("portal malloc error (%s, %s)\n", host, port);
|
SPDK_ERRLOG("portal malloc error (%s, %s)\n", host, port);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
p->host = host;
|
p->host = strdup(host);
|
||||||
p->port = port;
|
p->port = strdup(port);
|
||||||
p->cpumask = cpumask;
|
p->cpumask = cpumask;
|
||||||
p->sock = -1;
|
p->sock = -1;
|
||||||
p->group = NULL; /* set at a later time by caller */
|
p->group = NULL; /* set at a later time by caller */
|
||||||
@ -106,7 +106,7 @@ spdk_iscsi_portal_create_from_configline(const char *portalstring,
|
|||||||
const char *cpumask_str;
|
const char *cpumask_str;
|
||||||
uint64_t cpumask = 0;
|
uint64_t cpumask = 0;
|
||||||
|
|
||||||
int n, len;
|
int n, len, rc = -1;
|
||||||
const char *p, *q;
|
const char *p, *q;
|
||||||
|
|
||||||
if (portalstring == NULL) {
|
if (portalstring == NULL) {
|
||||||
@ -240,14 +240,12 @@ spdk_iscsi_portal_create_from_configline(const char *portalstring,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
rc = 0;
|
||||||
|
|
||||||
error_out:
|
error_out:
|
||||||
if (host != NULL)
|
free(host);
|
||||||
free(host);
|
free(port);
|
||||||
if (port != NULL)
|
|
||||||
free(port);
|
return rc;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct spdk_iscsi_portal_grp *
|
struct spdk_iscsi_portal_grp *
|
||||||
@ -316,13 +314,13 @@ spdk_iscsi_portal_grp_create_from_portal_list(int tag,
|
|||||||
|
|
||||||
if (num_portals > MAX_PORTAL) {
|
if (num_portals > MAX_PORTAL) {
|
||||||
SPDK_ERRLOG("%d > MAX_PORTAL\n", num_portals);
|
SPDK_ERRLOG("%d > MAX_PORTAL\n", num_portals);
|
||||||
goto error_out;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pg = spdk_iscsi_portal_grp_create(tag);
|
pg = spdk_iscsi_portal_grp_create(tag);
|
||||||
if (!pg) {
|
if (!pg) {
|
||||||
SPDK_ERRLOG("portal group creation error (%d)\n", tag);
|
SPDK_ERRLOG("portal group creation error (%d)\n", tag);
|
||||||
goto error_out;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_portals; i++) {
|
for (i = 0; i < num_portals; i++) {
|
||||||
@ -336,28 +334,24 @@ spdk_iscsi_portal_grp_create_from_portal_list(int tag,
|
|||||||
sock = spdk_sock_listen(p->host, port);
|
sock = spdk_sock_listen(p->host, port);
|
||||||
if (sock < 0) {
|
if (sock < 0) {
|
||||||
SPDK_ERRLOG("listen error %.64s:%d\n", p->host, port);
|
SPDK_ERRLOG("listen error %.64s:%d\n", p->host, port);
|
||||||
spdk_iscsi_portal_destroy(p);
|
|
||||||
count++;
|
count++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
p->sock = sock;
|
p->sock = sock;
|
||||||
spdk_iscsi_portal_grp_add_portal(pg, p);
|
spdk_iscsi_portal_grp_add_portal(pg, p);
|
||||||
|
portal_list[i] = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if listening is failed on all the ports,
|
|
||||||
* then do not register the portal group. */
|
|
||||||
if (count == num_portals) {
|
if (count == num_portals) {
|
||||||
|
/* if listening is failed on all the ports,
|
||||||
|
* then do not register the portal group. */
|
||||||
spdk_iscsi_portal_grp_destroy(pg);
|
spdk_iscsi_portal_grp_destroy(pg);
|
||||||
goto error_out;
|
return -1;
|
||||||
|
} else {
|
||||||
|
/* Add portal group to the end of the pg list */
|
||||||
|
spdk_iscsi_portal_grp_register(pg);
|
||||||
|
return num_portals - count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add portal group to the end of the pg list */
|
|
||||||
spdk_iscsi_portal_grp_register(pg);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error_out:
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -56,7 +56,7 @@ struct spdk_iscsi_portal_grp {
|
|||||||
|
|
||||||
/* SPDK iSCSI Portal Group management API */
|
/* SPDK iSCSI Portal Group management API */
|
||||||
|
|
||||||
struct spdk_iscsi_portal *spdk_iscsi_portal_create(char *host, char *port,
|
struct spdk_iscsi_portal *spdk_iscsi_portal_create(const char *host, const char *port,
|
||||||
uint64_t cpumask);
|
uint64_t cpumask);
|
||||||
void spdk_iscsi_portal_destroy(struct spdk_iscsi_portal *p);
|
void spdk_iscsi_portal_destroy(struct spdk_iscsi_portal *p);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user