Quantcast
Channel: wxWidgets: Ticket Query
Viewing all articles
Browse latest Browse all 66

#12455: wxDateTime::Format(): buffer overflow (time zone %Z access on broken uninitialized stack-based struct tm)

$
0
0

Hello,

Issue persists on current SVN.

wx 2.8.10 Valgrind 3.5.0 traces (plus some program log output):

after COPTime_HumanReadable2wxDateTime: <0x1dc61460> time "0084-08-07 00:00:00 <C8>S<C6>]?aE<B4>HwE<9E>^F^W<C8>^S<C6>^]3?a^ET<C6>]\inE"

==14317== Conditional jump or move depends on uninitialised value(s ) ==14317== at 0x5D70CAC: strftime_l (in /lib/libc-2.5.so) ==14317== by 0x5D6F81E: strftime (in /lib/libc-2.5.so) ==14317== by 0x62CC511: CallStrftime(char const*, tm const*) (datetime.cpp:456) ==14317== by 0x62D1DEF: wxDateTime::Format(char const*, wxDateTime::TimeZone const&) const (datetime.cpp:2660) ==14317== by 0x561396C: COPTime_DumpTime(wxDateTime const&, char const*) (cop_time.cpp:344) ==14317== by 0x5613F32: COPTime_HumanReadable2wxDateTime(wxDateTime&, int, int, int, int, int, int, int) (cop_time.cpp:520)

==14317== Use of uninitialised value of size 4 ==14317== at 0x5D70CB8: strftime_l (in /lib/libc-2.5.so) ==14317== by 0x5D6F81E: strftime (in /lib/libc-2.5.so) ==14317== by 0x62CC511: CallStrftime(char const*, tm const*) (datetime.cpp:456) ==14317== by 0x62D1DEF: wxDateTime::Format(char const*, wxDateTime::TimeZone const&) const (datetime.cpp:2660) ==14317== by 0x561396C: COPTime_DumpTime(wxDateTime const&, char const*) (cop_time.cpp:344) ==14317== by 0x5613F32: COPTime_HumanReadable2wxDateTime(wxDateTime&, int, int, int, int, int, int, int) (cop_time.cpp:520)

Happens due to src/common/datetime.cpp/wxDateTime::Format() doing:

// used for calls to strftime() when we only deal with time struct tm tmTimeOnly; tmTimeOnly.tm_hour = tm.hour; tmTimeOnly.tm_min = tm.min; tmTimeOnly.tm_sec = tm.sec; tmTimeOnly.tm_wday = 0; tmTimeOnly.tm_yday = 0; tmTimeOnly.tm_mday = 1; // any date will do tmTimeOnly.tm_mon = 0; tmTimeOnly.tm_year = 76; tmTimeOnly.tm_isdst = 0; // no DST, we adjust for tz ourselves

and _NOT_ doing any memset() (bad, BAAD) on the stack-local, UNINITIALIZED struct (memset() should _always_ be done regardless of whether we "know" that we properly assigned all members of struct tm, since we _cannot_ know this in wx code since struct tm is very system-specific) and then not initializing the tm_zone member (const char *) to any useful value either, before calling

#ifdef HAVE_STRFTIME

res += CallStrftime(_T("%Z"), &tmTimeOnly);

#endif

Result is a nice _very_ long garbage string (log output above), dangerously close to risking an application-side buffer overflow in case the wxDateTime::Format() caller is daring enough to copy the result to a fixed-size-calculated (say 10 time + 10 date + 10 time zone chars == 30 chars) char buffer.

Once the tmTimeOnly has been fixed to have a memset(), there's still the issue of a non-working %Z zone string processing: there's still a NULL string instead of useful zone name input.

Thanks!


Viewing all articles
Browse latest Browse all 66

Trending Articles