summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLee Duncan <leeman.duncan@gmail.com>2021-01-05 14:21:02 -0800
committerGitHub <noreply@github.com>2021-01-05 14:21:02 -0800
commitb83e9a3ec2315e1766ed513eaeaf8aca19e3b596 (patch)
tree49aa3f547c394f60ad98ed9e3eacebdfbbf923f3
parent1303fa6ffa2ad02eb9179f34d723cf5efbcc2b9c (diff)
parentb24f8ff48e2285e42d151f73e464531c49a9509e (diff)
downloadopen-iscsi-b83e9a3ec2315e1766ed513eaeaf8aca19e3b596.tar.gz
Merge pull request #239 from wenchao-hao/master
Fix 4 memory leak in source code
-rw-r--r--libopeniscsiusr/context.c6
-rw-r--r--libopeniscsiusr/node.c9
-rw-r--r--libopeniscsiusr/session.c2
-rw-r--r--usr/idbm.c30
-rw-r--r--usr/iscsiadm.c27
5 files changed, 55 insertions, 19 deletions
diff --git a/libopeniscsiusr/context.c b/libopeniscsiusr/context.c
index fe92155..c5e869f 100644
--- a/libopeniscsiusr/context.c
+++ b/libopeniscsiusr/context.c
@@ -55,8 +55,12 @@ struct iscsi_context *iscsi_context_new(void)
void iscsi_context_free(struct iscsi_context *ctx)
{
- if (ctx != NULL)
+ if (ctx == NULL)
+ return;
+
+ if (ctx->db)
_idbm_free(ctx->db);
+
free(ctx);
}
diff --git a/libopeniscsiusr/node.c b/libopeniscsiusr/node.c
index 6bec201..0bf357b 100644
--- a/libopeniscsiusr/node.c
+++ b/libopeniscsiusr/node.c
@@ -109,6 +109,15 @@ int iscsi_nodes_get(struct iscsi_context *ctx, struct iscsi_node ***nodes,
_good(_scandir(ctx, NODE_CONFIG_DIR, &namelist, &n), rc, out);
_debug(ctx, "Got %d target from %s nodes folder", n, NODE_CONFIG_DIR);
+ /*
+ * If continue with n == 0, calloc() might return a memory which failed
+ * to be freed in iscsi_nodes_free()
+ *
+ * So here just goto out to exit if n == 0
+ */
+ if (n == 0)
+ goto out;
+
*node_count = n & UINT32_MAX;
*nodes = (struct iscsi_node **) calloc(*node_count,
sizeof(struct iscsi_node *));
diff --git a/libopeniscsiusr/session.c b/libopeniscsiusr/session.c
index 98601dc..7ace4d6 100644
--- a/libopeniscsiusr/session.c
+++ b/libopeniscsiusr/session.c
@@ -256,6 +256,8 @@ int iscsi_sessions_get(struct iscsi_context *ctx,
*session_count = 0;
_good(_iscsi_sids_get(ctx, &sids, session_count), rc ,out);
+ if (!*session_count)
+ goto out;
*sessions = calloc (*session_count, sizeof(struct iscsi_session *));
_alloc_null_check(ctx, *sessions, rc, out);
diff --git a/usr/idbm.c b/usr/idbm.c
index f8b50f1..10eb8e2 100644
--- a/usr/idbm.c
+++ b/usr/idbm.c
@@ -1014,8 +1014,8 @@ int idbm_rec_update_param(recinfo_t *info, char *name, char *value,
int i;
int passwd_done = 0;
char passwd_len[8];
- char *tmp_value, *token;
- bool *found;
+ char *tmp_value, *token, *tmp;
+ bool *found = NULL;
int *tmp_data;
setup_passwd_len:
@@ -1079,12 +1079,25 @@ setup_passwd_len:
if (!info[i].data)
continue;
tbl = (void *)info[i].opts[0];
- /* strsep is destructive, make a copy to work with */
+ /*
+ * strsep is destructive, make a copy to work with
+ * tmp_value would be modified in strsep() too, so
+ * here make a copy of tmp_value to tmp
+ */
tmp_value = strdup(value);
+ if (!tmp_value)
+ return ISCSI_ERR_NOMEM;
+ tmp = tmp_value;
+
k = 0;
tmp_data = malloc(info[i].data_len);
+ if (!tmp_data)
+ goto free_tmp;
memset(tmp_data, ~0, info[i].data_len);
+
found = calloc(info[i].numopts, sizeof(bool));
+ if (!found)
+ goto free_tmp_data;
next_token: while ((token = strsep(&tmp_value, ", \n"))) {
if (!strlen(token))
@@ -1113,7 +1126,7 @@ next_token: while ((token = strsep(&tmp_value, ", \n"))) {
" for '%s'", token, info[i].name);
}
memcpy(info[i].data, tmp_data, info[i].data_len);
- free(tmp_value);
+ free(tmp);
free(tmp_data);
tmp_value = NULL;
tmp_data = NULL;
@@ -1135,8 +1148,17 @@ next_token: while ((token = strsep(&tmp_value, ", \n"))) {
return ISCSI_ERR_INVAL;
+free_tmp_data:
+ free(tmp_data);
+
+free_tmp:
+ free(tmp);
+ return ISCSI_ERR_NOMEM;
+
updated:
strlcpy((char*)info[i].value, value, VALUE_MAXVAL);
+ if (found)
+ free(found);
#define check_password_param(_param) \
if (!passwd_done && !strcmp(#_param, name)) { \
diff --git a/usr/iscsiadm.c b/usr/iscsiadm.c
index ea1643b..3987168 100644
--- a/usr/iscsiadm.c
+++ b/usr/iscsiadm.c
@@ -3627,7 +3627,7 @@ main(int argc, char **argv)
"Priority must be greater than or "
"equal to zero.", killiscsid);
rc = ISCSI_ERR_INVAL;
- goto free_ifaces;
+ goto out;
}
break;
case 't':
@@ -3639,7 +3639,7 @@ main(int argc, char **argv)
log_error("can not recognize operation: '%s'",
optarg);
rc = ISCSI_ERR_INVAL;
- goto free_ifaces;
+ goto out;
}
break;
case 'n':
@@ -3651,7 +3651,7 @@ main(int argc, char **argv)
case 'H':
host_no = parse_host_info(optarg, &rc);
if (rc)
- goto free_ifaces;
+ goto out;
break;
case 'r':
sid = iscsi_sysfs_get_sid_from_path(optarg);
@@ -3659,7 +3659,7 @@ main(int argc, char **argv)
log_error("invalid sid '%s'",
optarg);
rc = ISCSI_ERR_INVAL;
- goto free_ifaces;
+ goto out;
}
break;
case 'R':
@@ -3710,7 +3710,7 @@ main(int argc, char **argv)
mode = str_to_mode(optarg);
rc = verify_mode_params(argc, argv, mode);
if (ISCSI_SUCCESS != rc)
- goto free_ifaces;
+ goto out;
break;
case 'C':
sub_mode = str_to_submode(optarg);
@@ -3739,11 +3739,11 @@ main(int argc, char **argv)
printf("Invalid iface name %s. Must be from "
"1 to %d characters.\n",
optarg, ISCSI_MAX_IFACE_LEN - 1);
- goto free_ifaces;
+ goto out;
} else if (!iface || rc) {
printf("Could not add iface %s.", optarg);
rc = ISCSI_ERR_INVAL;
- goto free_ifaces;
+ goto out;
}
list_add_tail(&iface->list, &ifaces);
@@ -3760,7 +3760,7 @@ main(int argc, char **argv)
log_error("Invalid index %s. %s.",
optarg, strerror(errno));
rc = ISCSI_ERR_INVAL;
- goto free_ifaces;
+ goto out;
}
break;
case 'A':
@@ -3778,7 +3778,7 @@ main(int argc, char **argv)
if (!param) {
log_error("Cannot allocate memory for params.");
rc = ISCSI_ERR_NOMEM;
- goto free_ifaces;
+ goto out;
}
list_add_tail(&param->list, &params);
name = NULL;
@@ -3789,12 +3789,12 @@ main(int argc, char **argv)
if (optopt) {
log_error("unrecognized character '%c'", optopt);
rc = ISCSI_ERR_INVAL;
- goto free_ifaces;
+ goto out;
}
if (killiscsid >= 0) {
kill_iscsid(killiscsid, timeout);
- goto free_ifaces;
+ goto out;
}
if (mode < 0)
@@ -3802,14 +3802,14 @@ main(int argc, char **argv)
if (mode == MODE_FW) {
rc = exec_fw_op(NULL, NULL, info_level, do_login, op);
- goto free_ifaces;
+ goto out;
}
increase_max_files();
if (idbm_init(get_config_file)) {
log_warning("exiting due to idbm configuration error");
rc = ISCSI_ERR_IDBM;
- goto free_ifaces;
+ goto out;
}
switch (mode) {
@@ -4070,7 +4070,6 @@ out:
free(rec);
iscsi_sessions_free(ses, se_count);
idbm_terminate();
-free_ifaces:
list_for_each_entry_safe(iface, tmp, &ifaces, list) {
list_del(&iface->list);
free(iface);