Patch: add safety checks for accesses to camel folder summary
- From: José Dapena Paz <jdapena igalia com>
- To: tinymail-devel-list <tinymail-devel-list gnome org>
- Subject: Patch: add safety checks for accesses to camel folder summary
- Date: Wed, 07 Oct 2009 14:07:05 +0200
Hi,
This patch adds safety checks to camel folder summary, to avoid
crashing if the file is corrupt or is not complete.
Changelog entry:
* Added proper error checking for summary MMAP. The THROW macro
changed to provide appropriate error propagation mechanism.
--
José Dapena Paz <jdapena igalia com>
Igalia
diff --git a/libtinymail-camel/camel-lite/camel/camel-file-utils.c b/libtinymail-camel/camel-lite/camel/camel-file-utils.c
index ed183ed..8548a55 100644
--- a/libtinymail-camel/camel-lite/camel/camel-file-utils.c
+++ b/libtinymail-camel/camel-lite/camel/camel-file-utils.c
@@ -220,7 +220,7 @@ unsigned char*
camel_file_util_mmap_decode_uint32 (unsigned char *start, guint32 *dest, gboolean is_string)
{
guint32 value = 0;
- value = g_ntohl(get_unaligned_u32(start)); start += 4;
+ value = g_ntohl(get_unaligned_u32(start)); start += 4; // #0
*dest = value;
return start;
}
diff --git a/libtinymail-camel/camel-lite/camel/camel-folder-summary.c b/libtinymail-camel/camel-lite/camel/camel-folder-summary.c
index 6333ea3..b6de605 100644
--- a/libtinymail-camel/camel-lite/camel/camel-folder-summary.c
+++ b/libtinymail-camel/camel-lite/camel/camel-folder-summary.c
@@ -79,6 +79,8 @@
#include <glib.h>
#include <glib/gprintf.h>
+#define THROW g_assert (FALSE)
+
static pthread_mutex_t info_lock = PTHREAD_MUTEX_INITIALIZER;
/* this lock is ONLY for the standalone messageinfo stuff */
@@ -327,6 +329,7 @@ camel_folder_summary_unload_mmap (CamelFolderSummary *s)
if (s->file)
g_mapped_file_free (s->file);
s->file = NULL;
+ s->eof = NULL;
return;
}
@@ -695,6 +698,7 @@ perform_content_info_load(CamelFolderSummary *s)
return NULL;
ptrchr = s->filepos;
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 ((unsigned char*)ptrchr, &count, FALSE);
s->filepos = ptrchr;
@@ -755,6 +759,7 @@ camel_folder_summary_load(CamelFolderSummary *s)
}
s->filepos = (unsigned char*) g_mapped_file_get_contents (s->file);
+ s->eof = s->filepos + g_mapped_file_get_length (s->file);
if ( ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s) == -1)
goto error;
@@ -814,6 +819,7 @@ printf ("Removes %s\n", ri->uid);
if (s->saved_count <= 0) {
g_mapped_file_free (s->file);
s->file = NULL;
+ s->eof = NULL;
}
camel_operation_end (NULL);
@@ -1239,6 +1245,7 @@ camel_folder_summary_header_load(CamelFolderSummary *s)
}
s->filepos = (unsigned char*) g_mapped_file_get_contents (s->file);
+ s->eof = s->filepos + g_mapped_file_get_length (s->file);
ret = ((CamelFolderSummaryClass *)(CAMEL_OBJECT_GET_CLASS(s)))->summary_header_load(s);
@@ -1977,8 +1984,19 @@ camel_folder_summary_decode_token(CamelFolderSummary *s, char **str)
io(printf("Decode token ...\n"));
+ if (s->eof < ptrchr + sizeof(guint32)) {
+ io(printf ("Got premature EOF"));
+ *str = NULL;
+ return -1;
+ }
ptrchr = camel_file_util_mmap_decode_uint32 ((unsigned char*)ptrchr, &len, FALSE);
+ if (s->eof < ptrchr + len) {
+ io(printf ("Got premature EOF"));
+ *str = NULL;
+ return -1;
+ }
+
if (len<32) {
if (len <= 0) {
@@ -2376,9 +2394,12 @@ message_info_load(CamelFolderSummary *s, gboolean *must_add)
/* Try to find the original instance in case we are in reloading */
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
- if (len)
+ if (len) {
+ if (s->eof < ptrchr + len) THROW;
theuid = (char*)ptrchr;
+ }
ptrchr += len;
if (!s->in_reload)
@@ -2430,8 +2451,10 @@ message_info_load(CamelFolderSummary *s, gboolean *must_add)
}
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &mi->size, FALSE);
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &mi->flags, FALSE);
mi->flags &= ~CAMEL_MESSAGE_INFO_NEEDS_FREE;
@@ -2439,46 +2462,66 @@ message_info_load(CamelFolderSummary *s, gboolean *must_add)
s->set_extra_flags_func (s->folder, mi);
+ if (s->eof < ptrchr + sizeof(time_t)) THROW;
ptrchr = camel_file_util_mmap_decode_time_t (ptrchr, &mi->date_sent);
+ if (s->eof < ptrchr + sizeof(time_t)) THROW;
ptrchr = camel_file_util_mmap_decode_time_t (ptrchr, &mi->date_received);
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
- if (len)
+ if (len) {
+ if (s->eof < ptrchr + len) THROW;
mi->subject = (const char*)ptrchr;
-
+ }
ptrchr += len;
+
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
- if (len)
+ if (len) {
+ if (s->eof < ptrchr + len) THROW;
mi->from = (const char*)ptrchr;
-
+ }
ptrchr += len;
- ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
+ ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE); // #1
- if (len)
+ if (len) {
+ if (s->eof < ptrchr + len) THROW;
mi->to = (const char*)ptrchr;
+ }
ptrchr += len;
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
- if (len)
+ if (len) {
+ if (s->eof < ptrchr + len) THROW;
mi->cc = (const char*)ptrchr;
+ }
ptrchr += len;
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
-
+ if (len) {
+ if (s->eof < ptrchr + len) THROW;
+ }
ptrchr += len;
+
s->filepos = ptrchr;
+ if (s->eof < s->filepos + 4) THROW;
mi->message_id.id.part.hi = g_ntohl(get_unaligned_u32(s->filepos));
s->filepos += 4;
+ if (s->eof < s->filepos + 4) THROW;
mi->message_id.id.part.lo = g_ntohl(get_unaligned_u32(s->filepos));
s->filepos += 4;
ptrchr = (unsigned char*) s->filepos;
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &count, FALSE);
#ifdef NON_TINYMAIL_FEATURES
@@ -2490,6 +2533,7 @@ message_info_load(CamelFolderSummary *s, gboolean *must_add)
s->filepos = ptrchr;
+ if (s->eof < s->filepos + count * 8) THROW;
#ifdef NON_TINYMAIL_FEATURES
for (i=0;i<count;i++) {
mi->references->references[i].id.part.hi = g_ntohl(get_unaligned_u32(s->filepos));
@@ -2502,30 +2546,43 @@ message_info_load(CamelFolderSummary *s, gboolean *must_add)
#endif
ptrchr = s->filepos;
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &count, FALSE);
for (i=0;i<count;i++)
{
char *name = NULL;
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
- if (len)
+ if (len) {
+ if (s->eof < ptrchr + len) THROW;
name = (char*) ptrchr;
+ }
ptrchr += len;
}
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &count, FALSE);
+ /* Sergio, how ptrchr could be 0 ? */
if (!ptrchr) return NULL;
for (i=0;i<count;i++)
{
char *name = NULL, *value = NULL;
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
- if (len)
+ if (len) {
+ if (s->eof < ptrchr + len) THROW;
name = (char*)ptrchr;
+ }
ptrchr += len;
+
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 (ptrchr, &len, TRUE);
- if (len)
+ if (len) {
+ if (s->eof < ptrchr + len) THROW;
value =(char*) ptrchr;
+ }
ptrchr += len;
}
@@ -2730,6 +2787,7 @@ content_info_load(CamelFolderSummary *s)
ct = camel_content_type_new(type, subtype);
ptrchr = s->filepos;
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 ((unsigned char*)ptrchr, &count, FALSE);
s->filepos = ptrchr;
@@ -2748,6 +2806,7 @@ content_info_load(CamelFolderSummary *s)
camel_folder_summary_decode_token(s, &ci->encoding);
ptrchr = s->filepos;
+ if (s->eof < ptrchr + sizeof(guint32)) THROW;
ptrchr = camel_file_util_mmap_decode_uint32 ((unsigned char*)ptrchr, &ci->size, FALSE);
s->filepos = ptrchr;
diff --git a/libtinymail-camel/camel-lite/camel/camel-folder-summary.h b/libtinymail-camel/camel-lite/camel/camel-folder-summary.h
index e9a7f9c..500ab5b 100644
--- a/libtinymail-camel/camel-lite/camel/camel-folder-summary.h
+++ b/libtinymail-camel/camel-lite/camel/camel-folder-summary.h
@@ -216,6 +216,7 @@ struct _CamelFolderSummary {
struct _CamelFolderMetaSummary *meta_summary; /* Meta summary */
GMappedFile *file;
+ gchar *eof;
unsigned char *filepos;
GMutex *hash_lock;
GStaticRecMutex *dump_lock;
diff --git a/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-summary.c b/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-summary.c
index 49cbc7e..20c86ec 100644
--- a/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-summary.c
+++ b/libtinymail-camel/camel-lite/camel/providers/imap/camel-imap-summary.c
@@ -225,7 +225,7 @@ message_info_load (CamelFolderSummary *s, gboolean *must_add)
CamelMessageInfo *info;
CamelImapMessageInfo *iinfo;
- info = camel_imap_summary_parent->message_info_load (s, must_add);
+ info = camel_imap_summary_parent->message_info_load (s, must_add); // #3
iinfo = (CamelImapMessageInfo*)info;
if (info) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]