iscsi, param: fix memory leak related issue
issue: ASAN reported that param_ut free already freed memory. Reason: spdk_iscsi_negotiate_params does some modifcation on params and may free old params and create new params. To solve this issue, we need to input **params but not *params in spdk_iscsi_negotiate_params Change-Id: I68658fd8e08f317343753620692f04e7b0b57577 Signed-off-by: Ziye Yang <optimistyzy@gmail.com> Reviewed-on: https://review.gerrithub.io/363670 Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com> Tested-by: SPDK Automated Test System <sys_sgsw@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
parent
b6a9493bb1
commit
5b89e4a18f
@ -2120,7 +2120,7 @@ spdk_iscsi_op_login_rsp_handle_t_bit(struct spdk_iscsi_conn *conn,
|
||||
*/
|
||||
static int
|
||||
spdk_iscsi_op_login_rsp_handle(struct spdk_iscsi_conn *conn,
|
||||
struct spdk_iscsi_pdu *rsp_pdu, struct iscsi_param *params,
|
||||
struct spdk_iscsi_pdu *rsp_pdu, struct iscsi_param **params,
|
||||
int alloc_len)
|
||||
{
|
||||
int rc = 0;
|
||||
@ -2145,7 +2145,7 @@ spdk_iscsi_op_login_rsp_handle(struct spdk_iscsi_conn *conn,
|
||||
SPDK_TRACEDUMP(SPDK_TRACE_DEBUG, "Negotiated Params", rsp_pdu->data, rc);
|
||||
|
||||
/* handle the CSG bit case */
|
||||
rc = spdk_iscsi_op_login_rsp_handle_csg_bit(conn, rsp_pdu, params,
|
||||
rc = spdk_iscsi_op_login_rsp_handle_csg_bit(conn, rsp_pdu, *params,
|
||||
alloc_len);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
@ -2163,6 +2163,7 @@ spdk_iscsi_op_login(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
int rc;
|
||||
struct spdk_iscsi_pdu *rsp_pdu;
|
||||
struct iscsi_param *params = NULL;
|
||||
struct iscsi_param **params_p = ¶ms;
|
||||
int alloc_len;
|
||||
int cid;
|
||||
|
||||
@ -2174,10 +2175,10 @@ spdk_iscsi_op_login(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
|
||||
|
||||
rsp_pdu = spdk_get_pdu();
|
||||
rc = spdk_iscsi_op_login_rsp_init(conn, pdu, rsp_pdu, ¶ms,
|
||||
rc = spdk_iscsi_op_login_rsp_init(conn, pdu, rsp_pdu, params_p,
|
||||
&alloc_len, &cid);
|
||||
if (rc == SPDK_ISCSI_LOGIN_ERROR_RESPONSE || rc == SPDK_ISCSI_LOGIN_ERROR_PARAMETER) {
|
||||
spdk_iscsi_op_login_response(conn, rsp_pdu, params);
|
||||
spdk_iscsi_op_login_response(conn, rsp_pdu, *params_p);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -2188,21 +2189,21 @@ spdk_iscsi_op_login(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
}
|
||||
|
||||
if (conn->state == ISCSI_CONN_STATE_INVALID) {
|
||||
rc = spdk_iscsi_op_login_phase_none(conn, rsp_pdu, params,
|
||||
rc = spdk_iscsi_op_login_phase_none(conn, rsp_pdu, *params_p,
|
||||
alloc_len, cid);
|
||||
if (rc == SPDK_ISCSI_LOGIN_ERROR_RESPONSE || rc == SPDK_ISCSI_LOGIN_ERROR_PARAMETER) {
|
||||
spdk_iscsi_op_login_response(conn, rsp_pdu, params);
|
||||
spdk_iscsi_op_login_response(conn, rsp_pdu, *params_p);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
rc = spdk_iscsi_op_login_rsp_handle(conn, rsp_pdu, params, alloc_len);
|
||||
rc = spdk_iscsi_op_login_rsp_handle(conn, rsp_pdu, params_p, alloc_len);
|
||||
if (rc == SPDK_ISCSI_LOGIN_ERROR_RESPONSE) {
|
||||
spdk_iscsi_op_login_response(conn, rsp_pdu, params);
|
||||
spdk_iscsi_op_login_response(conn, rsp_pdu, *params_p);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = spdk_iscsi_op_login_response(conn, rsp_pdu, params);
|
||||
rc = spdk_iscsi_op_login_response(conn, rsp_pdu, *params_p);
|
||||
|
||||
if (rc == 0) {
|
||||
conn->state = ISCSI_CONN_STATE_RUNNING;
|
||||
@ -2218,6 +2219,7 @@ static int
|
||||
spdk_iscsi_op_text(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
{
|
||||
struct iscsi_param *params = NULL;
|
||||
struct iscsi_param **params_p = ¶ms;
|
||||
struct spdk_iscsi_pdu *rsp_pdu;
|
||||
uint8_t *data;
|
||||
uint64_t lun;
|
||||
@ -2302,17 +2304,17 @@ spdk_iscsi_op_text(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
memset(data, 0, alloc_len);
|
||||
|
||||
/* negotiate parameters */
|
||||
data_len = spdk_iscsi_negotiate_params(conn, params,
|
||||
data_len = spdk_iscsi_negotiate_params(conn, params_p,
|
||||
data, alloc_len, data_len);
|
||||
if (data_len < 0) {
|
||||
SPDK_ERRLOG("spdk_iscsi_negotiate_params() failed\n");
|
||||
spdk_iscsi_param_free(params);
|
||||
spdk_iscsi_param_free(*params_p);
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* sendtargets is special case */
|
||||
val = spdk_iscsi_param_get_val(params, "SendTargets");
|
||||
val = spdk_iscsi_param_get_val(*params_p, "SendTargets");
|
||||
if (val != NULL) {
|
||||
if (spdk_iscsi_param_eq_val(conn->sess->params,
|
||||
"SessionType", "Discovery")) {
|
||||
@ -2393,7 +2395,7 @@ spdk_iscsi_op_text(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
rc = spdk_iscsi_copy_param2var(conn);
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("spdk_iscsi_copy_param2var() failed\n");
|
||||
spdk_iscsi_param_free(params);
|
||||
spdk_iscsi_param_free(*params_p);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2401,11 +2403,11 @@ spdk_iscsi_op_text(struct spdk_iscsi_conn *conn, struct spdk_iscsi_pdu *pdu)
|
||||
rc = spdk_iscsi_check_values(conn);
|
||||
if (rc < 0) {
|
||||
SPDK_ERRLOG("iscsi_check_values() failed\n");
|
||||
spdk_iscsi_param_free(params);
|
||||
spdk_iscsi_param_free(*params_p);
|
||||
return -1;
|
||||
}
|
||||
|
||||
spdk_iscsi_param_free(params);
|
||||
spdk_iscsi_param_free(*params_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -349,7 +349,7 @@ bool spdk_iscsi_is_deferred_free_pdu(struct spdk_iscsi_pdu *pdu);
|
||||
|
||||
void spdk_iscsi_shutdown(void);
|
||||
int spdk_iscsi_negotiate_params(struct spdk_iscsi_conn *conn,
|
||||
struct iscsi_param *params, uint8_t *data,
|
||||
struct iscsi_param **params_p, uint8_t *data,
|
||||
int alloc_len, int data_len);
|
||||
int spdk_iscsi_copy_param2var(struct spdk_iscsi_conn *conn);
|
||||
|
||||
|
@ -851,7 +851,7 @@ spdk_iscsi_negotiate_param_init(struct spdk_iscsi_conn *conn,
|
||||
|
||||
int
|
||||
spdk_iscsi_negotiate_params(struct spdk_iscsi_conn *conn,
|
||||
struct iscsi_param *params, uint8_t *data, int alloc_len,
|
||||
struct iscsi_param **params, uint8_t *data, int alloc_len,
|
||||
int data_len)
|
||||
{
|
||||
struct iscsi_param *param;
|
||||
@ -876,14 +876,14 @@ spdk_iscsi_negotiate_params(struct spdk_iscsi_conn *conn,
|
||||
return total;
|
||||
}
|
||||
|
||||
if (params == NULL) {
|
||||
if (*params == NULL) {
|
||||
/* no input */
|
||||
return total;
|
||||
}
|
||||
|
||||
/* discovery? */
|
||||
discovery = 0;
|
||||
cur_param = spdk_iscsi_param_find(params, "SessionType");
|
||||
cur_param = spdk_iscsi_param_find(*params, "SessionType");
|
||||
if (cur_param == NULL) {
|
||||
cur_param = spdk_iscsi_param_find(conn->sess->params, "SessionType");
|
||||
if (cur_param == NULL) {
|
||||
@ -924,9 +924,9 @@ spdk_iscsi_negotiate_params(struct spdk_iscsi_conn *conn,
|
||||
/* To adjust the location of FirstBurstLength location and put it to
|
||||
* the end, then we can always firstly determine the MaxBurstLength
|
||||
*/
|
||||
param = spdk_iscsi_param_find(params, "MaxBurstLength");
|
||||
param = spdk_iscsi_param_find(*params, "MaxBurstLength");
|
||||
if (param != NULL) {
|
||||
param = spdk_iscsi_param_find(params, "FirstBurstLength");
|
||||
param = spdk_iscsi_param_find(*params, "FirstBurstLength");
|
||||
|
||||
/* check the existence of FirstBurstLength */
|
||||
if (param != NULL) {
|
||||
@ -934,13 +934,13 @@ spdk_iscsi_negotiate_params(struct spdk_iscsi_conn *conn,
|
||||
if (param->next != NULL) {
|
||||
snprintf(in_val, ISCSI_TEXT_MAX_VAL_LEN + 1, "%s", param->val);
|
||||
type = param->type;
|
||||
spdk_iscsi_param_add(¶ms, "FirstBurstLength",
|
||||
spdk_iscsi_param_add(params, "FirstBurstLength",
|
||||
in_val, NULL, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (param = params; param != NULL; param = param->next) {
|
||||
for (param = *params; param != NULL; param = param->next) {
|
||||
struct iscsi_param *params_dst = conn->params;
|
||||
int add_param_value = 0;
|
||||
new_val = NULL;
|
||||
|
@ -71,12 +71,14 @@ burst_length_param_negotation(int FirstBurstLength, int MaxBurstLength,
|
||||
struct spdk_iscsi_sess sess;
|
||||
struct spdk_iscsi_conn conn;
|
||||
struct iscsi_param *params;
|
||||
struct iscsi_param **params_p;
|
||||
char data[8192];
|
||||
int rc;
|
||||
int total, len;
|
||||
|
||||
total = 0;
|
||||
params = NULL;
|
||||
params_p = ¶ms;
|
||||
|
||||
memset(&sess, 0, sizeof(sess));
|
||||
memset(&conn, 0, sizeof(conn));
|
||||
@ -131,11 +133,11 @@ burst_length_param_negotation(int FirstBurstLength, int MaxBurstLength,
|
||||
total++;
|
||||
|
||||
/* store incoming parameters */
|
||||
rc = spdk_iscsi_parse_params(¶ms, data, total, false, NULL);
|
||||
rc = spdk_iscsi_parse_params(params_p, data, total, false, NULL);
|
||||
CU_ASSERT(rc == 0);
|
||||
|
||||
/* negotiate parameters */
|
||||
rc = spdk_iscsi_negotiate_params(&conn, params,
|
||||
rc = spdk_iscsi_negotiate_params(&conn, params_p,
|
||||
data, 8192, rc);
|
||||
CU_ASSERT(rc > 0);
|
||||
|
||||
@ -148,7 +150,7 @@ burst_length_param_negotation(int FirstBurstLength, int MaxBurstLength,
|
||||
|
||||
spdk_iscsi_param_free(sess.params);
|
||||
spdk_iscsi_param_free(conn.params);
|
||||
spdk_iscsi_param_free(params);
|
||||
spdk_iscsi_param_free(*params_p);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -69,7 +69,7 @@ $valgrind test/lib/scsi/scsi_bdev/scsi_bdev_ut
|
||||
$valgrind test/lib/scsi/scsi_nvme/scsi_nvme_ut
|
||||
|
||||
# TODO: fix valgrind warnings and add $valgrind to iSCSI tests
|
||||
test/lib/iscsi/param/param_ut
|
||||
$valgrind test/lib/iscsi/param/param_ut
|
||||
$valgrind test/lib/iscsi/target_node/target_node_ut test/lib/iscsi/target_node/target_node.conf
|
||||
test/lib/iscsi/pdu/pdu
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user