[minicoredumper] [PATCH 07/14] minicoredumper: Fix Coverity and SVACE warnings

Mateusz Moscicki m.moscicki2 at partner.samsung.com
Tue May 21 14:52:43 CEST 2019


Change-Id: Ib9164189283e72c6b3a37b7855f86990e3d686ee
---
 src/common/elf_dumplist.c         |  16 ++-
 src/minicoredumper/corestripper.c | 212 ++++++++++++++++++++++++--------------
 src/minicoredumper/prog_config.c  |  24 +++--
 3 files changed, 155 insertions(+), 97 deletions(-)

diff --git a/src/common/elf_dumplist.c b/src/common/elf_dumplist.c
index e293e62..f76ba8c 100644
--- a/src/common/elf_dumplist.c
+++ b/src/common/elf_dumplist.c
@@ -309,7 +309,7 @@ static int alloc_dump_note(struct core_data *dump_list, int elfclass,
 	n->n_type = NT_DUMPLIST;
 	n->n_namesz = name_size;
 	n->n_descsz = desc_size;
-	sprintf(NOTE_NAME_PTR(n), NT_OWNER);
+	snprintf(NOTE_NAME_PTR(n), name_size, NT_OWNER);
 
 	desc = NOTE_DESC_PTR(n, name_size);
 	for (cur = dump_list; cur; cur = cur->next) {
@@ -356,7 +356,7 @@ static void _prune_dump_list(int elfclass, void *desc, int count,
 	}
 }
 
-static int prune_dump_list(int elfclass, Elf_Data *data,
+static void prune_dump_list(int elfclass, Elf_Data *data,
 			   struct core_data *dump_list)
 {
 	char *name;
@@ -385,8 +385,6 @@ static int prune_dump_list(int elfclass, Elf_Data *data,
 
 		n = ((void *)n) + nsize;
 	}
-
-	return 0;
 }
 
 int add_dump_list(int core_fd, size_t *core_size,
@@ -466,7 +464,7 @@ int add_dump_list(int core_fd, size_t *core_size,
 			 * directly after the elf header) */
 
 			if (offset == ehdr.e_phoff)
-				offset += ehdr.e_phentsize * ehdr.e_phnum;
+				offset += (GElf_Off)(ehdr.e_phentsize * ehdr.e_phnum);
 
 			if (add_debug_section(e, strtab_scn, offset,
 					      last_offset - offset) != 0) {
@@ -499,10 +497,8 @@ int add_dump_list(int core_fd, size_t *core_size,
 
 			/* disable dump list items that are already
 			 * covered by the existing data */
-			if (prune_dump_list(gelf_getclass(e), data,
-					    dump_list) != 0) {
-				goto out;
-			}
+			prune_dump_list(gelf_getclass(e), data,
+					    dump_list);
 		}
 	} else {
 		/* create new section */
@@ -562,7 +558,7 @@ int add_dump_list(int core_fd, size_t *core_size,
 	if (gelf_getehdr(e, &ehdr) == NULL)
 		goto out;
 
-	*core_size = last_offset + (ehdr.e_shentsize * ehdr.e_shnum);
+	*core_size = last_offset + (GElf_Off)(ehdr.e_shentsize * ehdr.e_shnum);
 
 	err = 0;
 out:
diff --git a/src/minicoredumper/corestripper.c b/src/minicoredumper/corestripper.c
index 65df340..27fe8c0 100644
--- a/src/minicoredumper/corestripper.c
+++ b/src/minicoredumper/corestripper.c
@@ -114,8 +114,7 @@ static ssize_t read_file_fd(int fd, char *dst, int len)
 	do {
 		r = read(fd, dst + size, len);
 		if (r == -1) {
-			info("Couldn't read file fd=%d; error %s", fd,
-			     strerror(errno));
+			info("Couldn't read file fd=%d; error %m", fd);
 			return r;
 		}
 
@@ -136,8 +135,7 @@ static ssize_t write_file_fd(int fd, char *src, int len)
 	do {
 		r = write(fd, src + size, len);
 		if (r == -1) {
-			info("Couldn't write file fd=%d error %s", fd,
-			     strerror (errno));
+			info("Couldn't write file fd=%d error %m", fd);
 			return r;
 		}
 		if (r > 0) {
@@ -337,16 +335,20 @@ static int copy_file(const char *dest, const char *src)
 	FILE *f_src;
 	int i;
 
-	if (stat(src, &sb) != 0)
+	f_src = fopen(src, "r");
+	if (!f_src)
 		return -1;
 
-	/* non-regular files ignored */
-	if ((sb.st_mode & S_IFMT) != S_IFREG)
+	if (fstat(fileno(f_src), &sb) != 0) {
+		fclose(f_src);
 		return -1;
+	}
 
-	f_src = fopen(src, "r");
-	if (!f_src)
+	/* non-regular files ignored */
+	if ((sb.st_mode & S_IFMT) != S_IFREG) {
+		fclose(f_src);
 		return -1;
+	}
 
 	f_dest = fopen(dest, "w");
 	if (!f_dest) {
@@ -531,8 +533,7 @@ static char *alloc_dst_dir(time_t timestamp, const char *base_dir,
 	}
 
 	if (mkdir(tmp_path, 0700) == -1) {
-		info("unable to create directory \'%s\': %s", tmp_path,
-		     strerror(errno));
+		info("unable to create directory \'%s\': %m", tmp_path);
 		free(tmp_path);
 		return NULL;
 	}
@@ -607,8 +608,7 @@ static int init_di(struct dump_info *di)
 		di->elf_fd = shm_open(tmp_path, O_CREAT|O_EXCL|O_RDWR,
 				      S_IRUSR|S_IWUSR);
 		if (di->elf_fd < 0) {
-			info("unable to create shared object \'%s\': %s", tmp_path,
-			     strerror(errno));
+			info("unable to create shared object \'%s\': %m", tmp_path);
 			free(tmp_path);
 			return 1;
 		}
@@ -621,8 +621,7 @@ static int init_di(struct dump_info *di)
 
 		di->core_fd = open(di->core_path, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
 		if (di->core_fd < 0) {
-			info("unable to create core \'%s\': %s", di->core_path,
-			     strerror(errno));
+			info("unable to create core \'%s\': %m", di->core_path);
 			return 1;
 		}
 	} else {
@@ -642,8 +641,7 @@ static int init_di(struct dump_info *di)
 		di->fatcore_fd = open(tmp_path, O_CREAT|O_RDWR,
 				      S_IRUSR|S_IWUSR);
 		if (di->fatcore_fd < 0) {
-			info("unable to create fatcore \'%s\': %s", tmp_path,
-			     strerror(errno));
+			info("unable to create fatcore \'%s\': %m", tmp_path);
 			free(tmp_path);
 			return 1;
 		}
@@ -656,8 +654,7 @@ static int init_di(struct dump_info *di)
 
 	di->mem_fd = open(tmp_path, O_RDONLY);
 	if (di->mem_fd < 0) {
-		info("unable to open mem \'%s\': %s", tmp_path,
-		     strerror(errno));
+		info("unable to open mem \'%s\': %m", tmp_path);
 		free(tmp_path);
 		return 1;
 	}
@@ -679,7 +676,7 @@ static int init_log(struct dump_info *di)
 
 	di->info_file = fopen(tmp_path, "w+");
 	if (di->info_file == NULL) {
-		info("unable to create \'%s\': %s", tmp_path, strerror(errno));
+		info("unable to create \'%s\': %m", tmp_path);
 		free(tmp_path);
 		return 1;
 	}
@@ -709,7 +706,7 @@ static int do_elf_ph_parse(struct dump_info *di, GElf_Phdr *type,
 
 	/* start from beginning of core */
 	if (lseek64(di->elf_fd, 0, SEEK_SET) == -1) {
-		info("lseek failed: %s", strerror(errno));
+		info("lseek failed: %m");
 		goto out;
 	}
 
@@ -1094,6 +1091,7 @@ static int open_compressor(struct dump_info *di, const char *core_suffix,
 
 	if (pipe(pipefd) != 0) {
 		free(tmp_path);
+		close(fd);
 		return -1;
 	}
 
@@ -1102,6 +1100,7 @@ static int open_compressor(struct dump_info *di, const char *core_suffix,
 		close(pipefd[0]);
 		close(pipefd[1]);
 		free(tmp_path);
+		close(fd);
 		return -1;
 	}
 
@@ -2108,14 +2107,14 @@ bool get_notes_end_offset(int fd, size_t start, size_t *off_to_note_end) {
 	bool result = true;
 
 	if (!buff) {
-		info("allocation of %d bytes error:  %s", sizeof(ElfW(Ehdr)), strerror(errno));
+		info("allocation of %d bytes error:  %m", sizeof(ElfW(Ehdr)));
 		result = false;
 		goto out;
 	}
 
 	size_t tmp_ret = pread64(fd, buff, sizeof(ElfW(Ehdr)), start);
 	if (tmp_ret != sizeof(ElfW(Ehdr))) {
-		info("pread64 (len: %d addr: 0x%lx) error: %s", sizeof(ElfW(Ehdr)), start, strerror(errno));
+		info("pread64 (len: %d addr: 0x%lx) error: %m", sizeof(ElfW(Ehdr)), start);
 		result = false;
 		goto out;
 	}
@@ -2132,7 +2131,7 @@ bool get_notes_end_offset(int fd, size_t start, size_t *off_to_note_end) {
 
 		tmp_ret = pread64(fd, header_buff, phdr_item_size*phdr_item_count, start+ehdr->e_phoff);
 		if (tmp_ret != phdr_item_size*phdr_item_count) {
-			info("pread64 (len: %d addr: 0x%lx) error: %s", phdr_item_size*phdr_item_count, start+ehdr->e_phoff, strerror(errno));
+			info("pread64 (len: %d addr: 0x%lx) error: %m", phdr_item_size*phdr_item_count, start+ehdr->e_phoff);
 			result = false;
 			goto out;
 		}
@@ -2209,7 +2208,11 @@ static int dump_maps(struct dump_info *di, int get_only)
 
 	while (fgets(buf, MAPS_LINE_MAXSIZE, f)) {
 		/* read memory range */
-		if (sscanf(buf, "%lx-%lx ", &start, &end) != 2)
+		start = strtoul(buf, &p, 16);
+		if (p == buf || p >= (buf + strlen(buf)))
+			continue;
+		end = strtoul(p+1, &p, 16);
+		if (p == buf)
 			continue;
 
 		/* find 2nd item: man proc(5) */
@@ -2268,23 +2271,22 @@ static int dump_maps(struct dump_info *di, int get_only)
 out_err:
 	if (f)
 		fclose(f);
-	if (buf)
-		free(buf);
+	free(buf);
 
 	return err;
 #undef MAPS_LINE_MAXSIZE
 }
 
 static int read_remote(struct dump_info *di, unsigned long addr, void *dst,
-		       ssize_t len)
+		       size_t len)
 {
 	int ret;
 
 	ret = pread64(di->mem_fd, dst, len, addr);
 	if (ret != len) {
-		info("read_remote failed: len=%d, addr=0x%lx, "
-		     "dest=0x%x, errno=\"%s\"",
-		     len, addr, dst, strerror(errno));
+		info("read_remote failed: len=%zu, addr=0x%lx, "
+		     "dest=0x%x, errno=\"%m\"",
+		     len, addr, dst);
 		return -1;
 	}
 
@@ -2314,8 +2316,7 @@ static int alloc_remote_string(struct dump_info *di, unsigned long addr,
 		ret = pread64(di->mem_fd, ptr, i, addr);
 		if (ret != i) {
 			ret = errno;
-			info("read_remote failed: addr %#lx: %s", addr,
-			     strerror(errno));
+			info("read_remote failed: addr %#lx: %m", addr);
 			free(ptr);
 			if (ret == 0)
 				ret = -1;
@@ -2424,6 +2425,9 @@ static int alloc_remote_data_content(struct dump_info *di, unsigned long addr,
 		return 0;
 	}
 
+	if (dd->es_n > SIZE_MAX / sizeof(*es))
+		return EFAULT;
+
 	es = calloc(sizeof(*es), dd->es_n);
 	if (!es) {
 		/* clear fields so there is no free() attempt */
@@ -2455,7 +2459,7 @@ static int dump_data_to_core(struct dump_info *di, struct dump_data_elem *es,
 	if ((es->flags & MCD_DATA_PTR_INDIRECT)) {
 		addr_ind = (unsigned long)es->data_ptr;
 		ret = read_remote(di, (unsigned long)es->data_ptr,
-				  &addr, sizeof(es->data_ptr));
+				  &addr, sizeof(addr));
 		if (ret != 0)
 			return ret;
 	} else {
@@ -2466,7 +2470,7 @@ static int dump_data_to_core(struct dump_info *di, struct dump_data_elem *es,
 	/* resolve length pointer */
 	if ((es->flags & MCD_LENGTH_INDIRECT)) {
 		ret = read_remote(di, (unsigned long)es->u.length_ptr,
-				  &length, sizeof(es->u.length_ptr));
+				  &length, sizeof(length));
 		if (ret != 0)
 			return ret;
 	} else {
@@ -2554,7 +2558,7 @@ static int dump_data_file_bin(struct dump_info *di, struct mcd_dump_data *dd,
 	if ((es->flags & MCD_DATA_PTR_INDIRECT)) {
 		addr_ind = (unsigned long)es->data_ptr;
 		ret = read_remote(di, (unsigned long)es->data_ptr,
-				  &addr, sizeof(es->data_ptr));
+				  &addr, sizeof(addr));
 		if (ret != 0)
 			return ret;
 	} else {
@@ -2565,7 +2569,7 @@ static int dump_data_file_bin(struct dump_info *di, struct mcd_dump_data *dd,
 	/* resolve length pointer */
 	if ((es->flags & MCD_LENGTH_INDIRECT)) {
 		ret = read_remote(di, (unsigned long)es->u.length_ptr,
-				  &length, sizeof(es->u.length_ptr));
+				  &length, sizeof(length));
 		if (ret != 0)
 			return ret;
 	} else {
@@ -2615,6 +2619,15 @@ out:
 	return ret;
 }
 
+static bool make_dir(const char *path) {
+	if (mkdir(path, 0700) == 0 || errno == EEXIST) {
+		return true;
+	} else {
+		info("mkdir %s failed: %m\n", path);
+		return false;
+	}
+}
+
 static int dump_data_content_file(struct dump_info *di,
 				  struct mcd_dump_data *dd)
 {
@@ -2632,11 +2645,13 @@ static int dump_data_content_file(struct dump_info *di,
 
 	/* create "dumps" directory */
 	snprintf(tmp_path, len, "%s/dumps", di->dst_dir);
-	mkdir(tmp_path, 0700);
+	if (!make_dir(tmp_path))
+		goto out;
 
 	/* create dumps pid sub-directory */
 	snprintf(tmp_path, len, "%s/dumps/%i", di->dst_dir, di->cmd_params->pid);
-	mkdir(tmp_path, 0700);
+	if (!make_dir(tmp_path))
+		goto out;
 
 	/* open text file for output */
 	snprintf(tmp_path, len, "%s/dumps/%i/%s", di->dst_dir, di->cmd_params->pid,
@@ -2663,9 +2678,14 @@ static int dump_data_content_file(struct dump_info *di,
 	fclose(file);
 
 	/* delete file if it is empty */
-	if (stat(tmp_path, &sb) == 0) {
-		if (sb.st_size == 0)
+	int tmp_fd = open(tmp_path, 0);
+
+	if (tmp_fd == -1)
+		info("Cannot open file %s: %m\n", tmp_path);
+	else {
+		if (fstat(tmp_fd, &sb) == 0 && sb.st_size == 0)
 			unlink(tmp_path);
+		close(tmp_fd);
 	}
 out:
 	free(tmp_path);
@@ -2777,13 +2797,21 @@ static void dump_fat_core(struct dump_info *di)
 	for (tmp = di->vma; tmp; tmp = tmp->next) {
 		len = tmp->file_end - tmp->start;
 
-		lseek64(di->mem_fd, tmp->start, SEEK_SET);
-		lseek64(di->fatcore_fd, tmp->file_off, SEEK_SET);
+		if (lseek64(di->mem_fd, tmp->start, SEEK_SET) == -1) {
+			info("lseek64 error: %m");
+			goto out;
+		}
+		if (lseek64(di->fatcore_fd, tmp->file_off, SEEK_SET) == -1) {
+			info("lseek64 error: %m");
+			goto out;
+		}
 
 		if (copy_data(di->mem_fd, di->fatcore_fd, -1, len, buf) < 0)
 			break;
 	}
 
+out:
+
 	free(buf);
 }
 
@@ -2855,9 +2883,11 @@ static void copy_proc_files(struct dump_info *di, int tasks, const char *name,
 		do_fds = 1;
 
 	snprintf(path, size, "%s/proc", di->dst_dir);
-	mkdir(path, 0700);
+	if (!make_dir(path))
+		goto out;
 	snprintf(path, size, "%s/proc/%d", di->dst_dir, di->cmd_params->pid);
-	mkdir(path, 0700);
+	if (!make_dir(path))
+		goto out;
 
 	/* handle non-task file */
 	if (!tasks) {
@@ -2867,17 +2897,18 @@ static void copy_proc_files(struct dump_info *di, int tasks, const char *name,
 			copy_link(path, path + base_len);
 		else
 			copy_file(path, path + base_len);
-		free(path);
-		return;
+		goto out;
 	}
 
 	snprintf(path, size, "%s/proc/%d/task", di->dst_dir, di->cmd_params->pid);
-	mkdir(path, 0700);
+	if (!make_dir(path))
+		goto out;
 
 	for (i = 0 ; i < di->ntsks; i++) {
 		snprintf(path, size, "%s/proc/%d/task/%d", di->dst_dir,
 			 di->cmd_params->pid, di->tsks[i].pr_pid);
-		mkdir(path, 0700);
+		if (!make_dir(path))
+			continue;
 
 		/* handle the normal task case */
 		if (!do_fds) {
@@ -2894,7 +2925,8 @@ static void copy_proc_files(struct dump_info *di, int tasks, const char *name,
 		/* special case: copy the symlinks in the fd directory */
 		snprintf(path, size, "%s/proc/%d/task/%d/fd", di->dst_dir,
 			 di->cmd_params->pid, di->tsks[i].pr_pid);
-		mkdir(path, 0700);
+		if (!make_dir(path))
+			continue;
 
 		d = opendir(path + base_len);
 		if (!d)
@@ -2918,7 +2950,7 @@ static void copy_proc_files(struct dump_info *di, int tasks, const char *name,
 
 		closedir(d);
 	}
-
+out:
 	free(path);
 }
 
@@ -3252,6 +3284,7 @@ static int get_so_list(struct dump_info *di)
 	void *buf;
 	int ret;
 	int fd;
+	int result = 0;
 
 	if (asprintf(&filename, "/proc/%d/auxv", di->cmd_params->pid) == -1)
 		return -1;
@@ -3271,18 +3304,22 @@ static int get_so_list(struct dump_info *di)
 
 	close(fd);
 
-	if (ret < 0)
-		return -1;
+	if (ret < 0) {
+		info("/proc/%d/auxv read error: %m", di->cmd_params->pid);
+		result = -1;
+		goto out;
+	}
 
 	/* get value from DT_DEBUG element from /proc/PID/auxv
 	 * (this is the r_debug structure) */
-	if (init_from_auxv(di, buf, &ptr) != 0)
-		return -1;
-
-	free(buf);
+	if ((ret = init_from_auxv(di, buf, &ptr)) != 0) {
+		info("init_from_auxv error: %d", ret);
+		result = -1;
+		goto out;
+	}
 
 	if (!ptr)
-		return 0;
+		goto out;
 
 	/* dump r_debug structure */
 	if (di->cfg->prog_config.dump_auxv_so_list)
@@ -3332,7 +3369,10 @@ static int get_so_list(struct dump_info *di)
 			    &ptr, sizeof(ptr));
 	}
 
-	return 0;
+out:
+	free(buf);
+
+	return result;
 }
 
 static void get_interesting_buffers(struct dump_info *di)
@@ -3343,7 +3383,7 @@ static void get_interesting_buffers(struct dump_info *di)
 	unsigned long addr;
 	int ret;
 
-	memset(&dd, 0, sizeof(es));
+	memset(&dd, 0, sizeof(dd));
 	dd.es_n = 1;
 	dd.es = &es;
 	dd.type = MCD_BIN;
@@ -3445,7 +3485,8 @@ static void do_dump(struct dump_info *di)
 
 	/* Get shared object list. This is necessary for sym_address() to work.
 	 * This function will also dump the auxv data (if configured). */
-	get_so_list(di);
+	if (get_so_list(di) < 0)
+		fatal("get_so_list failed");
 
 	/* dump all stacks (if configured) */
 	if (di->cfg->prog_config.stack.dump_stacks)
@@ -3621,16 +3662,19 @@ static struct cmd_parameters* copy_cmd_params(struct cmd_parameters* cmd_params)
 
 static int do_all_dumps(struct dump_info *di)
 {
-	struct config *cfg = NULL;
-	const char *recept;
+	struct config* cfg = NULL;
+	const char *recept = NULL;
+	int result = 1;
 	bool live_dumper;
-	char *comm_base;
-	char *comm;
-	char *exe;
+	char *comm_base = NULL;
+	char *comm = NULL;
+	char *exe = NULL;
 	char *p;
 
 	struct cmd_parameters *orig_params, *ext_params;
 
+	di->dst_dir = NULL;
+
 	ext_params = copy_cmd_params(di->cmd_params);
 	if (ext_params == NULL)
 		fatal("malloc for ext_params error: %m");
@@ -3647,7 +3691,7 @@ static int do_all_dumps(struct dump_info *di)
 
 	comm = alloc_comm(di->cmd_params->exe_name, di->cmd_params->pid);
 	if (!comm)
-		return 1;
+		goto out;
 
 	if (di->cmd_params->pid == 0)
 		exe = strdup("");
@@ -3655,7 +3699,7 @@ static int do_all_dumps(struct dump_info *di)
 		exe = alloc_exe(di->cmd_params->pid);
 
 	if (!exe)
-		return 1;
+		goto out;
 
 	comm_base = comm;
 	while (1) {
@@ -3673,20 +3717,17 @@ static int do_all_dumps(struct dump_info *di)
 	}
 
 	if (!di->dst_dir)
-		return 1;
+		goto out;
 
 	recept = get_prog_recept(cfg, comm, exe);
 	if (!recept)
-		return 1;
+		goto out;
 
 	if (init_prog_config(cfg, recept) != 0)
-		return 1;
+		goto out;
 
 	live_dumper = cfg->prog_config.live_dumper;
 
-	free_config(cfg);
-	free(comm);
-	free(exe);
 
 	if (live_dumper) {
 		char pidstr[16];
@@ -3740,16 +3781,23 @@ static int do_all_dumps(struct dump_info *di)
 			free(pids);
 	}
 
-	free(ext_params);
 
 	if (di->cmd_params->pid != 0) {
 		/* dump crashed task */
 		do_dump(di);
 	}
 
+	result = 0;
+out:
+
+	free_config(cfg);
+	free(comm);
+	free(exe);
+
+	free(ext_params);
 	free(di->dst_dir);
 
-	return 0;
+	return result;
 }
 
 typedef enum {
@@ -3837,15 +3885,18 @@ struct cmd_parameters* parse_args(char *argv[], int argc)
 	return cmd_params;
 }
 
+#define BUFF_LEN 1024
+
 void print_argv(int argc, char *argv[])
 {
-	char buff[1024];
+	char buff[BUFF_LEN];
 	int offset = 0;
 	for (int i = 0; i < argc; i++) {
-		int ret = snprintf(&buff[offset], 1024-offset, " %s", argv[i]);
+		int ret = snprintf(&buff[offset], BUFF_LEN-offset, " %s", argv[i]);
 		if (ret < 0)
 			fatal("print command line arguments error");
-		offset += ret;
+		else
+			offset += ret;
 	}
 	info("argv:%s", buff);
 }
@@ -3869,7 +3920,8 @@ int main(int argc, char *argv[])
 	openlog("minicoredumper", LOG_NDELAY, LOG_SYSLOG);
 
 	/* prevent memory paging to swap */
-	mlockall(MCL_CURRENT | MCL_FUTURE);
+	if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0)
+		info("mlockall failed: %m");
 
 	print_argv(argc, argv);
 
diff --git a/src/minicoredumper/prog_config.c b/src/minicoredumper/prog_config.c
index 0cd195b..a9b8b09 100644
--- a/src/minicoredumper/prog_config.c
+++ b/src/minicoredumper/prog_config.c
@@ -214,21 +214,25 @@ static int read_buffer_item(struct json_object *root, struct prog_config *cfg)
 			goto out_err;
 
 		if (strcmp(n, "symname") == 0) {
+			if (tmp->symname)
+				free(tmp->symname);
 			tmp->symname = alloc_json_string(v);
 			if (!tmp->symname)
 				goto out_err;
 
 		} else if (strcmp(n, "follow_ptr") == 0) {
 			if (get_json_boolean(v, &tmp->follow_ptr) != 0)
-				return -1;
+				goto out_err;
 
 		} else if (strcmp(n, "data_len") == 0) {
 			int i;
 			if (get_json_int(v, &i, true) != 0)
-				return -1;
+				goto out_err;
 			tmp->data_len = i;
 
 		} else if (strcmp(n, "ident") == 0) {
+			if (tmp->ident)
+				free(tmp->ident);
 			tmp->ident = alloc_json_string(v);
 			if (!tmp->ident)
 				goto out_err;
@@ -515,11 +519,15 @@ static int read_watch_elem(struct json_object *root, struct config *cfg)
 			goto out_err;
 
 		if (strcmp(n, "exe") == 0) {
+			if (tmp->exe)
+				free(tmp->exe);
 			tmp->exe = alloc_json_string(v);
 			if (!tmp->exe)
 				goto out_err;
 
 		} else if (strcmp(n, "comm") == 0) {
+			if (tmp->comm)
+				free(tmp->comm);
 			tmp->comm = alloc_json_string(v);
 			if (!tmp->comm)
 				goto out_err;
@@ -532,6 +540,8 @@ static int read_watch_elem(struct json_object *root, struct config *cfg)
 				goto out_err;
 
 			if (s[0] == '/') {
+				if (tmp->recept)
+					free(tmp->recept);
 				/* absolute path */
 				tmp->recept = s;
 			} else {
@@ -628,6 +638,8 @@ static int read_base_config(struct json_object *root, struct config *cfg)
 			}
 
 		} else if (strcmp(n, "base_dir") == 0) {
+			if (cfg->base_dir)
+				free(cfg->base_dir);
 			cfg->base_dir = alloc_json_string(v);
 			if (!cfg->base_dir)
 				return -1;
@@ -650,15 +662,14 @@ struct config *init_config(const char *cfg_file)
 		return NULL;
 	o = json_object_from_file(cfg_file);
 	if (!o) {
-		fatal("unable to parse config file: %s", strerror(errno));
 		free(cfg);
-		return NULL;
+		fatal("unable to parse config file: %s", strerror(errno));
 	}
 
 	if (read_base_config(o, cfg) < 0) {
-		fatal("unable to read base config");
-		free(cfg);
+		free_config(cfg);
 		cfg = NULL;
+		fatal("unable to read base config");
 	}
 
 	json_object_put(o);
@@ -710,7 +721,6 @@ int init_prog_config(struct config *cfg, const char *cfg_file)
 	o = json_object_from_file(cfg_file);
 	if (!o) {
 		fatal("unable to parse recept file: %s", strerror(errno));
-		return -1;
 	}
 
 	ret = read_prog_config(o, &cfg->prog_config);
-- 
2.7.4




More information about the minicoredumper mailing list