[freetds] Segmentation fault retrieving non-NULL datetime fields

Robert Benjamin freetds228 at lewenberg.com
Sun Nov 6 09:56:54 EST 2005



Frediano Ziglio wrote:
> Il giorno sab, 05/11/2005 alle 11.33 -0600, Robert Benjamin ha scritto:
> 
>>I installed the development version of freetds and am still getting the 
>>same error. I re-compiled PHP with --enable-debug and this is what it 
>>tells me:
>>
>>
>>[Sat Nov  5 11:26:07 2005]  Script:  '/www-s/testfreetds.php'
>>---------------------------------------
>>/root/tmp/php-4.4.1/ext/mssql/php_mssql.c(191) : Block 0x093CA2E0 status:
>>/root/tmp/php-4.4.1/Zend/zend_variables.c(44) : Actual location 
>>(location was relayed)
>>Beginning:      OK (allocated on 
>>/root/tmp/php-4.4.1/ext/mssql/php_mssql.c:904, 19 bytes)
>>       End:      Overflown (magic=0x31383A34 instead of 0x2A8FCC84)
>>                 At least 4 bytes overflown
>>---------------------------------------
>>
> 
> 
> Are you sure you are using PHP 4.4.1 ?? I looked at
> http://chora.php.net/co.php/php-src/ext/mssql/php_mssql.c?r=1.86.2.44.2.1 (see tags) and lines seems different. Did you change php_mssql.c code?
> 
>>From overflow report
> 
> Overflown (magic=0x31383A34 instead of 0x2A8FCC84) At least 4 bytes
> overflown
> 
> so code overwrote magic which was 4 byte... 0x31383A34 is "18:4" and you
> can find starting from row 931
> 
> if (column_type == SQLDATETIM4) { 
>   DBDATETIME temp; 
>   dbconvert(NULL, SQLDATETIM4, dbdata(mssql_ptr->link,offset), -1,
> SQLDATETIME, (LPBYTE) &temp, -1);
>   dbdatecrack(mssql_ptr->link, &dateinfo, &temp); 
> }
> else
> {
>   dbdatecrack(mssql_ptr->link, &dateinfo, (DBDATETIME *)
> dbdata(mssql_ptr->link,offset));
> }
> 
> res_length = 19;
> res_buf = (unsigned char *) emalloc(res_length+1);
> sprintf(res_buf, "%d-%02d-%02d %02d:%02d:%02d" , dateinfo.year,
> dateinfo.month, dateinfo.day, dateinfo.hour, dateinfo.minute,
> dateinfo.second);
> 
> It seems that the sprintf line produce a longer string. This can happen
> if data in dateinfo is broken, like dateinfo.hour == 1234. To test this
> you can try replacing last 3 row with
> 
> res_length = 70;
> res_buf = (unsigned char *) emalloc(res_length+1);
> res_length = sprintf(res_buf, "%d-%02d-%02d %02d:%02d:%02d" ,
> dateinfo.year, dateinfo.month, dateinfo.day, dateinfo.hour,
> dateinfo.minute, dateinfo.second);
> 
> This should avoid buffer overflow (at the cost of a little waste of
> memory).
> 
> Now the question should be: why does dateinfo contain wrong data? Are
> you using SMALLDATETIME or DATETIME?
> 
> freddy77
> 


I edited the php file ext/mssql/php_mssql.c and changed the amount of 
memory that the function allocates for the SQLDATETIM4 and SQLDATETIME 
by a factor of 10 (just to be safe!). This seemed to stop the crash.

Of course, this does not solve the problem. Why are the memory amounts 
specified in php_mssql.c not correct? They have worked before.

Also, when I print out the date modified, I get a result like "Jul 19 
2005 10:50:54:813AM". The locales.conf has for the date format "date 
format = %b %d %Y %I:%M%p" (for both default and en_US). Why are seconds 
(and milliseconds) creeping in?

Still confused...


More information about the FreeTDS mailing list