diff options
author | Grant Erickson <marathon96@gmail.com> | 2011-03-03 10:44:46 -0800 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2011-03-04 11:35:31 +0100 |
commit | ed896f9789f7c808fb86b4534cbd4eccfa401e82 (patch) | |
tree | f0a1aac87da4bbfb458645b8d0afbaa650f3cdb3 /src/stats.c | |
parent | 81afa6cbc63a929cfbe52798086e61e4796dab66 (diff) | |
download | connman-ed896f9789f7c808fb86b4534cbd4eccfa401e82.tar.gz connman-ed896f9789f7c808fb86b4534cbd4eccfa401e82.tar.bz2 connman-ed896f9789f7c808fb86b4534cbd4eccfa401e82.zip |
stats: Avoid double-frees on a failed mapping
Added debugging statements and ensure, following calls to g_free, that
the statistics file name field is set to NULL to ensure that a failed
file mapping and a subsequent call to stats_free doesn't fault when
trying to double-free it.
Diffstat (limited to 'src/stats.c')
-rw-r--r-- | src/stats.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/src/stats.c b/src/stats.c index 679a372e..30c0169d 100644 --- a/src/stats.c +++ b/src/stats.c @@ -214,6 +214,9 @@ static void stats_free(gpointer user_data) { struct stats_file *file = user_data; + if (file == NULL) + return; + msync(file->addr, file->len, MS_SYNC); munmap(file->addr, file->len); @@ -232,8 +235,7 @@ static void stats_free(gpointer user_data) file->name = NULL; } - if (file != NULL) - g_free(file); + g_free(file); } static void update_first(struct stats_file *file) @@ -275,6 +277,9 @@ static int stats_file_remap(struct stats_file *file, size_t size) void *addr; int err; + DBG("file %p size %u addr %p len %u", file, size, file->addr, + file->len); + page_size = sysconf(_SC_PAGESIZE); new_size = (size + page_size - 1) & ~(page_size - 1); @@ -315,6 +320,8 @@ static int stats_file_remap(struct stats_file *file, size_t size) static int stats_open(struct stats_file *file, const char *name) { + DBG("file %p name %s", file, name); + file->name = g_strdup(name); file->fd = TFR(open(file->name, O_RDWR | O_CREAT, 0644)); @@ -322,6 +329,7 @@ static int stats_open(struct stats_file *file, connman_error("open error %s for %s", strerror(errno), file->name); g_free(file->name); + file->name = NULL; return -errno; } @@ -337,6 +345,7 @@ static int stats_open_temp(struct stats_file *file) connman_error("create tempory file error %s for %s", strerror(errno), file->name); g_free(file->name); + file->name = NULL; return -errno; } @@ -350,6 +359,8 @@ static int stats_file_setup(struct stats_file *file) size_t size = 0; int err; + DBG("file %p fd %d name %s", file, file->fd, file->name); + err = fstat(file->fd, &st); if (err < 0) { connman_error("fstat error %s for %s\n", @@ -357,6 +368,7 @@ static int stats_file_setup(struct stats_file *file) TFR(close(file->fd)); g_free(file->name); + file->name = NULL; return -errno; } @@ -371,6 +383,7 @@ static int stats_file_setup(struct stats_file *file) if (err < 0) { TFR(close(file->fd)); g_free(file->name); + file->name = NULL; return err; } @@ -586,6 +599,7 @@ static void stats_file_cleanup(struct stats_file *file) { file->fd = -1; g_free(file->name); + file->name = NULL; } static int stats_file_close_swap(struct stats_file *history_file, |