potential information leak in libpurple/cipher.c?

Julia Lawall julia at diku.dk
Tue Feb 1 08:49:14 EST 2011


In pidgin version 2.7.9, libpurple/cipher.c contains a number of functions 
like the following, which appear to have the goal of clearing a data 
structure before freeing it:

static void
md5_uninit(PurpleCipherContext *context) {
	struct MD5Context *md5_context;

	purple_cipher_context_reset(context, NULL);

	md5_context = purple_cipher_context_get_data(context);
	memset(md5_context, 0, sizeof(md5_context));

	g_free(md5_context);
	md5_context = NULL;
}

The call to memset, however, has as third argument the size of a pointer, 
and not the size of the data structure referenced by that pointer, and so 
only the first few bytes of the structure get cleared.

This problem was found using Coccinelle (http://coccinelle.lip6.fr), using 
the following semantic patch:

@@
type T;
T [] ok;
expression x,E;
@@

(
memset(ok,E,sizeof(ok))
|
memset(x, E, sizeof(
+ *
 x))
)

The rule did not find any problems in other files.

Please let me know of your assessment of this report.

A complete patch is below.

Julia Lawall

----

diff -u -p a/libpurple/cipher.c b/libpurple/cipher.c
--- a/libpurple/cipher.c 2010-06-17 06:00:31.000000000 +0200
+++ b/libpurple/cipher.c 2011-02-01 14:52:02.000000000 +0100
@@ -249,7 +249,7 @@ md5_uninit(PurpleCipherContext *context)
 	purple_cipher_context_reset(context, NULL);
 
 	md5_context = purple_cipher_context_get_data(context);
-	memset(md5_context, 0, sizeof(md5_context));
+	memset(md5_context, 0, sizeof(*md5_context));
 
 	g_free(md5_context);
 	md5_context = NULL;
@@ -705,7 +705,7 @@ md4_uninit(PurpleCipherContext *context)
 	purple_cipher_context_reset(context, NULL);
 
 	md4_context = purple_cipher_context_get_data(context);
-	memset(md4_context, 0, sizeof(md4_context));
+	memset(md4_context, 0, sizeof(*md4_context));
 
 	g_free(md4_context);
 	md4_context = NULL;
@@ -1356,7 +1356,7 @@ des_uninit(PurpleCipherContext *context)
 	struct _des_ctx *des_context;
 
 	des_context = purple_cipher_context_get_data(context);
-	memset(des_context, 0, sizeof(des_context));
+	memset(des_context, 0, sizeof(*des_context));
 
 	g_free(des_context);
 	des_context = NULL;
@@ -1706,7 +1706,7 @@ des3_uninit(PurpleCipherContext *context
 	struct _des3_ctx *des3_context;
 
 	des3_context = purple_cipher_context_get_data(context);
-	memset(des3_context, 0, sizeof(des3_context));
+	memset(des3_context, 0, sizeof(*des3_context));
 
 	g_free(des3_context);
 	des3_context = NULL;
@@ -2382,7 +2382,7 @@ rc4_uninit(PurpleCipherContext *context)
 	struct RC4Context *rc4_ctx;
 
 	rc4_ctx = purple_cipher_context_get_data(context);
-	memset(rc4_ctx, 0, sizeof(rc4_ctx));
+	memset(rc4_ctx, 0, sizeof(*rc4_ctx));
 
 	g_free(rc4_ctx);
 	rc4_ctx = NULL;
@@ -2828,7 +2828,7 @@ purple_cipher_context_destroy(PurpleCiph
 	if(cipher->ops && cipher->ops->uninit)
 		cipher->ops->uninit(context);
 
-	memset(context, 0, sizeof(context));
+	memset(context, 0, sizeof(*context));
 	g_free(context);
 	context = NULL;
 }


More information about the security mailing list