From c0c872653431a6ae3c7958495d937f0fbb5d4b11 Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Wed, 10 Jan 2007 21:05:03 -0500 Subject: [PATCH] Added libXML memory handlers: xmlfree(), xmlmalloc(), xmlrealloc() and xmlstrdup(). xmlfree() and xmlrealloc() will clear the contents of memory before free()'ing. --- TODO | 3 +- src/commands.c | 26 ++++++------- src/common.h | 7 ++++ src/pwmd.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index e04a6361..b65d36c7 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,4 @@ -More secure memory allocation in libxml, libgcrypt and everywhere else. Both -of these API's have the ability to specify custom memory allocators. +More secure memory allocation in libgcrypt and everywhere else. Let the LIST command take an element path as an argument. diff --git a/src/commands.c b/src/commands.c index 8f48c02f..cff393df 100644 --- a/src/commands.c +++ b/src/commands.c @@ -246,24 +246,22 @@ gboolean open_command(struct client_s *client, gchar **req) strerror(errno)); return FALSE; } - else { new_doc: - if ((client->xml = new_document()) == NULL) { - send_to_client(client, "ERR %03i malloc(): %s\n", EPWMD_ERROR, - strerror(errno)); - return FALSE; - } - - client->len = strlen(client->xml); + if ((client->xml = new_document()) == NULL) { + send_to_client(client, "ERR %03i malloc(): %s\n", EPWMD_ERROR, + strerror(errno)); + return FALSE; + } - if (cache_add_file(client->md5file, NULL) == FALSE) { - send_error(client, EPWMD_MAX_SLOTS); - return FALSE; - } + client->len = strlen(client->xml); - client->filename = g_strdup(filename); - return parse_xml(client); + if (cache_add_file(client->md5file, NULL) == FALSE) { + send_error(client, EPWMD_MAX_SLOTS); + return FALSE; } + + client->filename = g_strdup(filename); + return parse_xml(client); } if (cache_get_key(client->md5file, shakey) == TRUE) diff --git a/src/common.h b/src/common.h index 0cea103b..7440e757 100644 --- a/src/common.h +++ b/src/common.h @@ -20,6 +20,13 @@ #define COMMON_H typedef struct { + void *data; + size_t size; +} mem_t; + +GSList *memlist; + +typedef struct { guchar filename[16]; // MD5 guchar key[32]; // SHA256 gboolean used; diff --git a/src/pwmd.c b/src/pwmd.c index c7c415e1..27f3011c 100644 --- a/src/pwmd.c +++ b/src/pwmd.c @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include @@ -414,6 +415,9 @@ quit: if (cl->filename) g_free(cl->filename); + if (memlist) + g_slist_free(memlist); + g_main_loop_unref(gloop); g_main_loop_quit(gloop); return FALSE; @@ -426,6 +430,117 @@ quit: return TRUE; } +static void xmlfree(void *ptr) +{ + gpointer p; + int n; + mem_t *data; + + if (!ptr) + return; + + for (n = 0; ; n++) { + if ((p = g_slist_nth_data(memlist, n)) == NULL) + break; + + data = p; + + if (data->data == ptr) { + memset(data->data, 0, data->size); + free(data->data); + memlist = g_slist_remove(memlist, p); + return; + } + } + +#ifdef DEBUG + warnx("xmlfree(): %p not found", ptr); + assert(0); +#endif +} + +static void *xmlmalloc(size_t size) +{ + void *p; + mem_t *new; + + if (size <= 0) + return NULL; + + if ((new = malloc(sizeof(mem_t))) == NULL) + return NULL; + + if ((p = malloc(size)) == NULL) { + free(new); + return NULL; + } + + new->data = p; + new->size = size; + memlist = g_slist_append(memlist, new); + return new->data; +} + +static void *xmlrealloc(void *ptr, size_t size) +{ + void *p, *new; + int n; + mem_t *data; + + if (!ptr) + return xmlmalloc(size); + + if (size <= 0) + return ptr; + + for (n = 0; ; n++) { + if ((p = g_slist_nth_data(memlist, n)) == NULL) + break; + + data = p; + + if (data->data == ptr) { + if ((new = malloc(size)) == NULL) + return NULL; + + memcpy(new, data->data, (size < data->size) ? size : data->size); + memset(data->data, 0, data->size); + free(data->data); + data->data = new; + data->size = size; + return data->data; + } + } + +#ifdef DEBUG + warnx("xmlrealloc(): %p not found", ptr); + assert(0); +#endif + return NULL; +} + +static char *xmlstrdup(const char *str) +{ + char *new; + size_t len; + const char *p; + char *np; + + if (!str) + return NULL; + + len = strlen(str) + 1; + + if ((new = xmlmalloc(len * sizeof(char))) == NULL) + return NULL; + + for (p = str, np = new; *p; p++) + *np++ = *p; + + *np = 0; + return new; +} + /* * Called every time a connection is made. */ @@ -465,6 +580,8 @@ static void doit(int fd) // FIXME 100% CPU if removed (poll()). send_to_client(cl, "OK \n"); + xmlMemSetup(xmlfree, xmlmalloc, xmlrealloc, xmlstrdup); + xmlInitMemory(); g_main_loop_run(gloop); g_io_channel_unref(cl->ioc); g_free(cl); -- 2.11.4.GIT