summaryrefslogtreecommitdiff
path: root/src/stats.c
diff options
context:
space:
mode:
authorGrant Erickson <marathon96@gmail.com>2011-03-03 10:44:46 -0800
committerSamuel Ortiz <sameo@linux.intel.com>2011-03-04 11:35:31 +0100
commited896f9789f7c808fb86b4534cbd4eccfa401e82 (patch)
treef0a1aac87da4bbfb458645b8d0afbaa650f3cdb3 /src/stats.c
parent81afa6cbc63a929cfbe52798086e61e4796dab66 (diff)
downloadconnman-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.c18
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,