Re: [gmime-devel] Double free crash in g_mime_header_list_register_writer()
- From: Johan van den Berg <phenom jvdb gmail com>
- To: gmime-devel-list gnome org
- Subject: Re: [gmime-devel] Double free crash in g_mime_header_list_register_writer()
- Date: Fri, 18 Jul 2014 15:54:14 +0200
Hi Jeff
Thanks a lot, I'll probably change to a source install.
If anyone has trouble with this, this hack works. Bring the struct
defines in scope:
typedef struct _ListNode {
struct _ListNode *next;
struct _ListNode *prev;
} ListNode;
typedef struct {
ListNode *head;
ListNode *tail;
ListNode *tailpred;
} List;
typedef struct _GMimeEvent GMimeEvent;
struct _GMimeHeaderList {
GMimeStream *stream;
GHashTable *writers;
GMimeEvent *changed;
GHashTable *hash;
guint32 version;
List list;
};
void g_mime_header_list_register_writer_fixed (GMimeHeaderList
*headers, const char *name, GMimeHeaderWriter writer)
{
gpointer okey, oval;
g_return_if_fail (headers != NULL);
g_return_if_fail (name != NULL);
g_hash_table_remove(headers->writers, name);
if (writer)
g_hash_table_insert (headers->writers, g_strdup (name), writer);
}
On Fri, Jul 18, 2014 at 2:51 PM, Jeffrey Stedfast <fejj gnome org> wrote:
Hi Johan,
Looks like there is indeed a double-free. I just read over the documentation
and g_hash_table_remove() free's the key for us, so there's no need to free
it (again).
The fix is to replace the whole g_hash_table_lookup if-block with:
g_hash_table_remove (headers->writers, name);
I've committed a fix to git master, but git master is 2.6.21, not 2.4.21
Hope that helps,
Jeff
On 7/18/2014 7:09 AM, Johan van den Berg wrote:
Hi
I am using gmime 2.4.21 (installed with yum on RHEL6) and glib2
2.26.1, and I am trying to disable header folding.
The crash occurs when calling g_mime_header_list_register_writer().
Is there something I am missing?
Regards
Johan
*** glibc detected *** ./gmimetest: double free or corruption
(fasttop): 0x0000000002552910 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3209475916]
/usr/lib64/libgmime-2.4.so.2(g_mime_header_list_register_writer+0x62)[0x32fee1c642]
./gmimetest[0x401c13]
./gmimetest[0x4021c7]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x320941ecdd]
./gmimetest[0x401619]
This happens when g_free(okey) is called after
g_hash_lookup_extended() is called. As far as I can tell from my
debugger, okey points to an empty string, however I don't know glib
hash tables very well so this might not be relevant.
Snippet from cgdb in /usr/src/debug/gmime-2.4.21/gmime/gmime-header.c:
924| void
925| g_mime_header_list_register_writer (GMimeHeaderList *headers,
const char *name, GMimeHeaderWriter writer)
926| {
927| gpointer okey, oval;
928|
929| g_return_if_fail (headers != NULL);
930| g_return_if_fail (name != NULL);
931|
932| if (g_hash_table_lookup (headers->writers, name)) {
933| g_hash_table_lookup_extended (headers->writers,
name, &okey, &oval);
934| g_hash_table_remove (headers->writers, name);
935+> g_free (okey);
936| }
937|
938| if (writer)
939| g_hash_table_insert (headers->writers, g_strdup
(name), writer);
940| }
My offending code snippet:
--------------------------
#include <glib.h>
#include <gmime/gmime.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
void build_multipart(void);
ssize_t nonfolding_mime_header_writer (GMimeStream *stream, const char
* name, const char * value);
char * nonfolding_mime_header_printf(const char * format, ...);
int main (int argc, char **argv)
{
g_mime_init (0);
build_multipart();
return 0;
}
void build_multipart(void)
{
GMimeMultipart * multipart;
GMimeHeaderList * headers;
multipart = g_mime_multipart_new_with_subtype("related");
headers = g_mime_object_get_header_list((GMimeObject *) multipart);
g_mime_object_set_content_type_parameter((GMimeObject *)
multipart, "type", "text/xml");
g_mime_object_set_content_type_parameter((GMimeObject *)
multipart, "start", "<xyz>");
g_mime_header_list_register_writer(headers, "Content-Type",
nonfolding_mime_header_writer);
}
ssize_t nonfolding_mime_header_writer (GMimeStream *stream, const char
* name, const char * value)
{
ssize_t nwritten;
char * val;
val = nonfolding_mime_header_printf ("%s: %s\n", name, value);
nwritten = g_mime_stream_write_string (stream, val);
g_free (val);
return nwritten;
}
char * nonfolding_mime_header_printf(const char * format, ...)
{
char * buf;
va_list ap;
va_start (ap, format);
buf = g_strdup_vprintf (format, ap);
va_end (ap);
return buf;
}
--------------------------
_______________________________________________
gmime-devel-list mailing list
gmime-devel-list gnome org
https://mail.gnome.org/mailman/listinfo/gmime-devel-list
[
Date Prev][Date Next] [
Thread Prev][Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]