[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