[freetds] suspected corruption

ZIGLIO, Frediano, VF-IT Frediano.Ziglio at vodafone.com
Wed Dec 5 04:36:58 EST 2007


> 
> I removed _db_set_null_value(), combining its little 
> remaining logic with
> dbgetnull().  Everything works.  Almost.  
> 
> 30 of 33 dblib unit tests pass, all but t0011 and two new 
> ones.  It's not
> failing in a nice way, though: the code jumps into 
> dbgetnull() when it's
> *not* called.  Here's the tail of my log:
> 
> Breakpoint 2, copy_data_to_host_var (dbproc=0x804f000, srctype=47, 
>     src=0x8067404 "Short column", ' ' <repeats 188 times>..., 
> srclen=200, 
>     desttype=47, dest=0xbfbfe9e0 "Short column", ' ' <repeats 
> 188 times>, 
>     destlen=-1, bindtype=1, indicator=0x0) at
> ../../../src/dblib/dblib.c:7032
> 7032            tdsdump_log(TDS_DBG_INFO1, 
> "copy_data_to_host_var(%d [%s]
> len %d => %d [%s] len %d)\n", 
> (gdb) 
> Continuing.
> dblib.c:7032:copy_data_to_host_var(47 [SYBCHAR] len 200 => 47 
> [SYBCHAR]
> len -1)
> dblib.c:7056:copy_data_to_host_var() srctype == desttype
> 
> 	Line 7056 comes *after* any possible call to dbgetnull().  
> 	copy_data_to_host_var() doesn't (and shouldn't) call it, 
> 	because src isn't NULL and srclen > 0.  
> 
> 	But look what comes next:
> 
> dblib.c:513:dbgetnull(0x804f000, 1, -1, 0xbfbfe5e0)
> dblib.c:542:varaddr(0xbfbfe5e0) varlen -1 < 0?
> 
> Program received signal SIGSEGV, Segmentation fault.
> 0x481565a6 in memset () from /usr/lib/libc.so.12
> (gdb) bt
> #0  0x481565a6 in memset () from /usr/lib/libc.so.12
> #1  0xbfbfe5e0 in ?? ()
> #2  0x48068447 in errno () from /usr/local/lib/libsybdb.so.5
> #3  0x4806ab4b in dbnextrow (dbproc=0x804f000)
>     at ../../../src/dblib/dblib.c:1967
> #4  0x0804934b in select_rows (dbproc=0x20202020, bind_type=538976288)
>     at ../../../../src/dblib/unittests/t0011.c:119
> (gdb) kill
> 
> gdb can't see the stack frames.  We land in dbgetnull() -- we know so
> because of the log file -- without being called in any way I 
> can see.  And
> we somehow manage to skip the test for varlen < 0, arriving at a
> completely unnecessary assert.  Spooky.  I can only think the stack is
> corrupted.  

Perhaps you should compile with -O0, however I have a simple assert

08:47:27.501581 (token.c:1915):tds_get_data: type 39, varint size 2
08:47:27.502764 (token.c:1975):tds_get_data(): wire column size is -1 
08:47:27.503838 (util.c:162):Changed query state from READING to PENDING
08:47:27.505588 (dblib.c:7026):copy_data_to_host_var(56 [SYBINT4] len 4
=> 56 [SYBINT4] len 0)
08:47:27.506886 (dblib.c:7050):copy_data_to_host_var() srctype ==
desttype
08:47:27.507961 (dblib.c:7026):copy_data_to_host_var(47 [SYBCHAR] len
200 => 47 [SYBCHAR] len -1)
08:47:27.509232 (dblib.c:7050):copy_data_to_host_var() srctype ==
desttype
08:47:27.523087 (dblib.c:513):dbgetnull(0x4103728, 1, -1, 0xbe9a9894)
08:47:27.538366 (dblib.c:542):varaddr(0xbe9a9894) varlen -1 < 0?
t0011: dblib.c:544: dbgetnull: Assertion `varlen > 0' failed.
==30115== 
==30115== Process terminating with default action of signal 6 (SIGABRT)
==30115==    at 0xB51BA0: raise (in /lib/libc-2.5.so)
==30115==    by 0xB534B0: abort (in /lib/libc-2.5.so)
==30115==    by 0xB4B1DA: __assert_fail (in /lib/libc-2.5.so)
==30115==    by 0x4012565: dbgetnull (dblib.c:544)
==30115==    by 0x4010541: buffer_transfer_bound_data (buffering.h:268)
==30115==    by 0x4018F35: dbnextrow (dblib.c:1961)
==30115==    by 0x8049EFA: select_rows (t0011.c:119)
==30115==    by 0x8049769: main (t0011.c:68)
--30115-- Discarding syms at 0x4206000-0x420A000 in
/usr/lib/gconv/CP1252.so due to munmap()
--30115-- Discarding syms at 0x40F6000-0x40F9000 in
/usr/lib/gconv/ISO8859-1.so due to munmap()
--30115-- Discarding syms at 0x40EA000-0x40F5000 in
/lib/libnss_files-2.5.so due to munmap()
--30115-- Discarding syms at 0x4211000-0x421C000 in
/lib/libnss_winbind.so.2 due to munmap()
--30115-- Discarding syms at 0x421C000-0x4222000 in
/lib/libnss_dns-2.5.so due to munmap()
==30115== 
==30115== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 38 from
1)
--30115-- 

> 
> Maybe it's the unit test, but nowadays I don't expect a user 
> program to be
> able to corrupt memory in db-lib.  There are too many 
> parameter checks for
> that to happen easily.  
> 
> I did remove some null pointer checks that were guarding free(3)
> yesterday.  It's possible I goofed.  But I've checked over 
> the CVS diffs
> and if it's there, I don't see it.  My best hope is that the 
> problem has
> been lurking there all along and only just now surfaced.  
> 
> Perhaps someone with better tools or more energy can figure out what's
> going on.  I think I've done enough damage for one night.  
> 

my gdb

(gdb) bt
#0  0xb7f6c410 in __kernel_vsyscall ()
#1  0x00b51ba0 in raise () from /lib/libc.so.6
#2  0x00b534b1 in abort () from /lib/libc.so.6
#3  0x00b4b1db in __assert_fail () from /lib/libc.so.6
#4  0xb7e94566 in dbgetnull (dbproc=0x80551f0, bindtype=1, varlen=-1,
varaddr=0xbf9749e4 "Short column") at dblib.c:544
#5  0xb7e92542 in buffer_transfer_bound_data (buf=0x80551f8,
res_type=4040, compute_id=-1, dbproc=0x80551f0, idx=0) at
buffering.h:268
#6  0xb7e9af36 in dbnextrow (dbproc=0x80551f0) at dblib.c:1961
#7  0x08049efb in select_rows (dbproc=0x80551f0, bind_type=1) at
t0011.c:119
#8  0x0804976a in main (argc=1, argv=0xbf975ac4) at t0011.c:68

freddy77



More information about the FreeTDS mailing list