Bug 3766 - Windows: crash on NULL dereference if email has invalid date
Summary: Windows: crash on NULL dereference if email has invalid date
Status: RESOLVED FIXED
Alias: None
Product: Claws Mail (Windows)
Classification: Unclassified
Component: default (show other bugs)
Version: 3.15.0
Hardware: PC Windows 10
: P3 major
Assignee: users
URL:
Depends on:
Blocks:
 
Reported: 2017-01-26 23:59 UTC by Harald van Dijk
Modified: 2017-03-27 16:25 UTC (History)
0 users

See Also:


Attachments
Handle invalid dates (1.23 KB, patch)
2017-01-27 19:36 UTC, Harald van Dijk
Details | Diff
Handle invalid dates (1.28 KB, patch)
2017-01-27 21:09 UTC, Harald van Dijk
Details | Diff

Description Harald van Dijk 2017-01-26 23:59:49 UTC
I usually use Thunderbird but decided to give Claws a try today. Not a happy experience: I found that it consistently crashed, both the 32-bit and 64-bit Windows builds of 3.14.1.

Looking into this with gdb, I found that g_date_time_to_unix was being called with a null pointer. This is coming from procheader_date_parse in src/procheader.c:

        tz = g_time_zone_new(zone);
        dt = g_date_time_new(tz, year, dmonth, day, hh, mm, ss);

        timer = g_date_time_to_unix(dt);

This assumes g_date_time_new succeeds, but it is documented on https://developer.gnome.org/glib/stable/glib-GDateTime.html#g-date-time-new as returning a null pointer if the input values are out of range. In my case, I appear to have an old spam e-mail with a "Date: Wed, 23 Apr 2014 09:95:98 GMT" header. Note the bogus minutes and seconds components there.

This should be handled sanely. The non-Win32 code path uses mktime, where out-of-range values are valid and 95 minutes simply wraps to 35 minutes on the next hour, and 98 seconds simply wraps to 38 seconds on the next minute.

The Win32 code path here can be enabled on other OSes to reproduce the crash, and I've done this on Ubuntu using the latest sources from Git.

I see that the Win32 code used to use mktime as well, but this was intentionally changed in http://git.claws-mail.org/?p=claws.git;a=commitdiff;h=b84884479e197092efb1792331dd1c2170ec912b. Should the code manually wrap out-of-range values the way mktime did?
Comment 1 Andrej Kacian 2017-01-27 00:32:14 UTC
Nice catch. However, instead of going back to mktime(), on Windows I'd prefer to normalize the date/time values using g_date_time_add_*() family of functions.
Comment 2 Harald van Dijk 2017-01-27 19:36:27 UTC
Created attachment 1717 [details]
Handle invalid dates

Sure. I also encountered another issue during testing: I have a few e-mails where the year in the header is simply given as 11. This should be changed to 2011 on all platforms. I don't see any reason why the if (year < 1000) block was moved, it doesn't make sense to exclude Windows here, so I moved it back to where it originally was. Does the attached patch look good?

Tested only on Ubuntu, with the #ifdef changed to forcibly enable this code path; I haven't set up my Windows machine to be able to compile anything.

And I think g_date_time_add_full cannot return NULL for anything that fits in an e-mail header, but I didn't want to take chances.
Comment 3 Harald van Dijk 2017-01-27 21:09:21 UTC
Created attachment 1718 [details]
Handle invalid dates

I see that my first attempt was wrong as it potentially leaked tz, and I see that it could be simplified because g_date_time_unref checks for null pointers and just returns another null pointer, avoiding problems. g_date_time_add_full does the same. So here is a second attempt at a patch, making use of that.
Comment 4 Andrej Kacian 2017-03-27 16:25:34 UTC
Oops, looks like I completely missed your patch, sorry. A similar fix has been included in recently released 3.15.0, minus the Y2K year fix-up code move.

Note You need to log in before you can comment on or make changes to this bug.