[Note: I have temporarily subscribed to the wine-devel mailing list to
send this message, but I don't know how long I'll stay subscribed, so
please COPY me explicitly on replies. Thanks!]
I'm trying to use wine-20000716 to run Quicken Deluxe 98. For the most
part, it DOES seem to work fairly well, at least for basic functionality.
However, when I try to run it with libsafe protection, the libsafe library
kills it (because of a detected buffer overflow) before it even finishes
initializing Quicken... (It might be useful for Wine developers to start
using libsafe in general, since it can catch buffer overflows that may be
going unnoticed but causing random crashes...)
Libsafe can be found at:
http://www.bell-labs.com/org/11356/libsafe.html
Anyway, here is the error in /var/log/secure:
Aug 2 14:03:21 onyx libsafe.so[5748]: version 1.3
Aug 2 14:03:21 onyx libsafe.so[5748]: detected an attempt to write across stack
boundary.
Aug 2 14:03:21 onyx libsafe.so[5748]: terminating /usr/local/bin/wine
Aug 2 14:03:21 onyx libsafe.so[5748]: overflow caused by strcat()
When I try running under gdb, I can set a breakpoing on main(), start
the program, then set a breakpoint on _libsafe_die and continue. When
it hits the breakpoint, here is the (corrupted) stack trace:
Breakpoint 2, 0x40017040 in _libsafe_die () from /lib/libsafe.so.1.3
(gdb) bt
#0 0x40017040 in _libsafe_die () from /lib/libsafe.so.1.3
#1 0x400174a4 in strcat () from /lib/libsafe.so.1.3
#2 0x400f7450 in lstrcatA (dst=0x40b06268 "C:\\quickenw\\LF",
src=0x42d4b5ac "MSP") at string.c:67
#3 0x42d438ce in ?? ()
#4 0x6e30376c in ?? ()
Cannot access memory at address 0x6900464c
(gdb)
I tried to have gdb break on the strcat() function. It ends up binding
to the one in libc by preference over libsafe. With some
trial-and-error, I found that the following strcat() call occurs very
shortly before the error is caught:
Breakpoint 3, strcat (dest=0x404c3224 "C:\\quickenw\\lib",
src=0x40b0627c "LFIMG70N.DLL") at ../sysdeps/generic/strcat.c:30
30 in ../sysdeps/generic/strcat.c
(gdb) bt
#0 strcat (dest=0x404c3224 "C:\\quickenw\\lib", src=0x40b0627c "LFIMG70N.DLL")
at ../sysdeps/generic/strcat.c:30
#1 0x40017467 in strcat () from /lib/libsafe.so.1.3
#2 0x400d3213 in ELF_LoadLibraryExA (
libname=0x40b06270 "C:\\quickenw\\LFIMG70N.DLL", flags=0) at elf.c:128
#3 0x400d6e87 in MODULE_LoadLibraryExA (
libname=0x40b06270 "C:\\quickenw\\LFIMG70N.DLL", hfile=0, flags=0)
at module.c:1210
#4 0x400d6bed in LoadLibraryExA (
libname=0x40b06270 "C:\\quickenw\\LFIMG70N.DLL", hfile=0, flags=0)
at module.c:1142
#5 0x400d7006 in LoadLibraryA (
libname=0x40b06270 "C:\\quickenw\\LFIMG70N.DLL") at module.c:1254
#6 0x42d430d2 in ?? ()
#7 0x400d9906 in PE_InitDLL (wm=0x404c2c50, type=1, lpReserved=0x0)
at pe_image.c:1012
#8 0x400d4cca in MODULE_InitDLL (wm=0x404c2c50, type=1, lpReserved=0x0)
at module.c:89
#9 0x400d4e34 in MODULE_DllProcessAttach (wm=0x404c2c50, lpReserved=0x0)
at module.c:166
#10 0x400d6c01 in LoadLibraryExA (libname=0x40925011 "LTFIL70N.DLL", hfile=0,
flags=0) at module.c:1145
#11 0x400d7006 in LoadLibraryA (libname=0x40925011 "LTFIL70N.DLL")
at module.c:1254
#12 0x40909802 in ?? ()
#13 0x408e0f35 in ?? ()
#14 0x408e1011 in ?? ()
#15 0x408ef2ae in ?? ()
#16 0x408ccf47 in ?? ()
#17 0x421e80 in ?? ()
#18 0x4594bf in ?? ()
#19 0x66ae9a in ?? ()
#20 0x5f4099aa in ?? ()
#21 0x77ea57 in ?? ()
#22 0x4014b815 in start_process () at process.c:387
#23 0x4014ec70 in SYSDEPS_DoCallOnStack (func=0x4014b504 <start_process>,
arg=0x0) at sysdeps.c:236
#24 0x4014ed1b in SYSDEPS_CallOnStack () at sysdeps.c:246
#25 0x4014ede9 in SYSDEPS_SwitchToThreadStack (func=0x4014b504 <start_process>)
at sysdeps.c:306
#26 0x4014b90f in PROCESS_Start (main_module=4194304,
filename=0x8049ca0 "/etc/localtime") at process.c:426
#27 0x4014bb16 in PROCESS_InitWine (argc=3, argv=0xbffff9e4) at process.c:487
#28 0x80488b1 in Letext () at main.c:65
#29 0x403449cb in __libc_start_main (main=0x8048874 <main>, argc=3,
argv=0xbffff9e4, init=0x804859c <_init>, fini=0x80488fc <_fini>,
rtld_fini=0x4000ae60 <_dl_fini>, stack_end=0xbffff9dc)
at ../sysdeps/generic/libc-start.c:92
(gdb)
When I try to finish these stack frames one at a time, finally
single-stepping in LoadLibraryExA(), here's the last few steps before
_libsafe_die() is called:
(gdb) bt
#0 MODULE_LoadLibraryExA (libname=0x40b06270 "C:\\quickenw\\LFIMG70N.DLL",
hfile=0, flags=0) at module.c:1245
#1 0x400d6bed in LoadLibraryExA (
libname=0x40b06270 "C:\\quickenw\\LFIMG70N.DLL", hfile=0, flags=0)
at module.c:1142
#2 0x400d7006 in LoadLibraryA (
libname=0x40b06270 "C:\\quickenw\\LFIMG70N.DLL") at module.c:1254
#3 0x42d430d2 in ?? ()
#4 0x400d9906 in PE_InitDLL (wm=0x404c2c50, type=1, lpReserved=0x0)
at pe_image.c:1012
#5 0x400d4cca in MODULE_InitDLL (wm=0x404c2c50, type=1, lpReserved=0x0)
at module.c:89
#6 0x400d4e34 in MODULE_DllProcessAttach (wm=0x404c2c50, lpReserved=0x0)
at module.c:166
#7 0x400d6c01 in LoadLibraryExA (libname=0x40925011 "LTFIL70N.DLL", hfile=0,
flags=0) at module.c:1145
#8 0x400d7006 in LoadLibraryA (libname=0x40925011 "LTFIL70N.DLL")
at module.c:1254
#9 0x40909802 in ?? ()
#10 0x408e0f35 in ?? ()
#11 0x408e1011 in ?? ()
#12 0x408ef2ae in ?? ()
#13 0x408ccf47 in ?? ()
#14 0x421e80 in ?? ()
#15 0x4594bf in ?? ()
#16 0x66ae9a in ?? ()
#17 0x5f4099aa in ?? ()
#18 0x77ea57 in ?? ()
#19 0x4014b815 in start_process () at process.c:387
#20 0x4014ec70 in SYSDEPS_DoCallOnStack (func=0x4014b504 <start_process>,
arg=0x0) at sysdeps.c:236
#21 0x4014ed1b in SYSDEPS_CallOnStack () at sysdeps.c:246
#22 0x4014ede9 in SYSDEPS_SwitchToThreadStack (func=0x4014b504 <start_process>)
at sysdeps.c:306
#23 0x4014b90f in PROCESS_Start (main_module=4194304,
filename=0x8049ca0 "/etc/localtime") at process.c:426
#24 0x4014bb16 in PROCESS_InitWine (argc=3, argv=0xbffff9e4) at process.c:487
#25 0x80488b1 in Letext () at main.c:65
#26 0x403449cb in __libc_start_main (main=0x8048874 <main>, argc=3,
argv=0xbffff9e4, init=0x804859c <_init>, fini=0x80488fc <_fini>,
rtld_fini=0x4000ae60 <_dl_fini>, stack_end=0xbffff9dc)
at ../sysdeps/generic/libc-start.c:92
(gdb) n
1246 LeaveCriticalSection(&PROCESS_Current()->crit_section);
(gdb) n
1247 return NULL;
(gdb) n
LoadLibraryExA (libname=0x40b06270 "C:\\quickenw\\LFIMG70N.DLL", hfile=0,
flags=0) at module.c:1143
1143 if ( wm )
(gdb) n
1154 LeaveCriticalSection(&PROCESS_Current()->crit_section);
(gdb) n
1156 return wm ? wm->module : 0;
(gdb) n
Breakpoint 2, 0x40017040 in _libsafe_die () from /lib/libsafe.so.1.3
(gdb) bt
#0 0x40017040 in _libsafe_die () from /lib/libsafe.so.1.3
#1 0x400174a4 in strcat () from /lib/libsafe.so.1.3
#2 0x400f7450 in lstrcatA (dst=0x40b06268 "C:\\quickenw\\LF",
src=0x42d4b5ac "MSP") at string.c:67
#3 0x42d438ce in ?? ()
#4 0x6e30376c in ?? ()
Cannot access memory at address 0x6900464c
(gdb)
If I run "wine -debugmsg +relay -managed qw" to see the relay trace
messages, here's the tail end of the output before libsafe kills it:
[...]
Call kernel32.348: GetModuleFileNameA(42d40000,40b061cc,00000200) ret=42d43763 fs=008f
Ret kernel32.348: GetModuleFileNameA() retval=00000018 ret=42d43763 fs=008f
Call kernel32.773: lstrcpyA(40b061d8,42d4d0d0 "LF") ret=42d437b3 fs=008f
Ret kernel32.773: lstrcpyA() retval=40b061d8 ret=42d437b3 fs=008f
Call kernel32.764: lstrcatA(40b061cc "C:\\quickenw\\LF",42d4b4c8 "PSD") ret=42d437c7
fs=008f
Ret kernel32.764: lstrcatA() retval=40b061cc ret=42d437c7 fs=008f
Call kernel32.764: lstrcatA(40b061cc "C:\\quickenw\\LFPSD",42d4d0c8 "70N.DLL")
ret=42d437d6 fs=008f
Ret kernel32.764: lstrcatA() retval=40b061cc ret=42d437d6 fs=008f
Call kernel32.538: OpenFile(40b061cc "C:\\quickenw\\LFPSD70N.DLL",40b06144,00004000)
ret=42d437ee fs=008f
Ret kernel32.538: OpenFile() retval=ffffffff ret=42d437ee fs=008f
Call kernel32.773: lstrcpyA(42d4b514,42d4d108 "MAC") ret=42d435fb fs=008f
Ret kernel32.773: lstrcpyA() retval=42d4b514 ret=42d435fb fs=008f
Call kernel32.348: GetModuleFileNameA(42d40000,40b061cc,00000200) ret=42d43051 fs=008f
Ret kernel32.348: GetModuleFileNameA() retval=00000018 ret=42d43051 fs=008f
Call kernel32.773: lstrcpyA(40b061d8,42d4d0d0 "LF") ret=42d4309b fs=008f
Ret kernel32.773: lstrcpyA() retval=40b061d8 ret=42d4309b fs=008f
Call kernel32.764: lstrcatA(40b061cc "C:\\quickenw\\LF",42d4b514 "MAC") ret=42d430ac
fs=008f
Ret kernel32.764: lstrcatA() retval=40b061cc ret=42d430ac fs=008f
Call kernel32.764: lstrcatA(40b061cc "C:\\quickenw\\LFMAC",42d4d0c8 "70N.DLL")
ret=42d430b8 fs=008f
Ret kernel32.764: lstrcatA() retval=40b061cc ret=42d430b8 fs=008f
Call kernel32.643: SetErrorMode(00008001) ret=42d430c5 fs=008f
Ret kernel32.643: SetErrorMode() retval=00008000 ret=42d430c5 fs=008f
Call kernel32.495: LoadLibraryA(40b061cc "C:\\quickenw\\LFMAC70N.DLL") ret=42d430d2
fs=008f
Ret kernel32.495: LoadLibraryA() retval=00000000 ret=42d430d2 fs=008f
Call kernel32.643: SetErrorMode(00008000) ret=42d430d7 fs=008f
Ret kernel32.643: SetErrorMode() retval=00008001 ret=42d430d7 fs=008f
Call kernel32.773: lstrcpyA(42d4b560,42d4d104 "IMG") ret=42d43623 fs=008f
Ret kernel32.773: lstrcpyA() retval=42d4b560 ret=42d43623 fs=008f
Call kernel32.348: GetModuleFileNameA(42d40000,40b061cc,00000200) ret=42d43051 fs=008f
Ret kernel32.348: GetModuleFileNameA() retval=00000018 ret=42d43051 fs=008f
Call kernel32.773: lstrcpyA(40b061d8,42d4d0d0 "LF") ret=42d4309b fs=008f
Ret kernel32.773: lstrcpyA() retval=40b061d8 ret=42d4309b fs=008f
Call kernel32.764: lstrcatA(40b061cc "C:\\quickenw\\LF",42d4b560 "IMG") ret=42d430ac
fs=008f
Ret kernel32.764: lstrcatA() retval=40b061cc ret=42d430ac fs=008f
Call kernel32.764: lstrcatA(40b061cc "C:\\quickenw\\LFIMG",42d4d0c8 "70N.DLL")
ret=42d430b8 fs=008f
Ret kernel32.764: lstrcatA() retval=40b061cc ret=42d430b8 fs=008f
Call kernel32.643: SetErrorMode(00008001) ret=42d430c5 fs=008f
Ret kernel32.643: SetErrorMode() retval=00008000 ret=42d430c5 fs=008f
Call kernel32.495: LoadLibraryA(40b061cc "C:\\quickenw\\LFIMG70N.DLL") ret=42d430d2
fs=008f
Ret kernel32.495: LoadLibraryA() retval=00000000 ret=42d430d2 fs=008f
Call kernel32.643: SetErrorMode(00008000) ret=42d430d7 fs=008f
Ret kernel32.643: SetErrorMode() retval=00008001 ret=42d430d7 fs=008f
Call kernel32.773: lstrcpyA(42d4b5ac,42d4d100 "MSP") ret=42d43840 fs=008f
Ret kernel32.773: lstrcpyA() retval=42d4b5ac ret=42d43840 fs=008f
Call kernel32.348: GetModuleFileNameA(42d40000,40b061c4,00000200) ret=42d43871 fs=008f
Ret kernel32.348: GetModuleFileNameA() retval=00000018 ret=42d43871 fs=008f
Call kernel32.773: lstrcpyA(40b061d0,42d4d0d0 "LF") ret=42d438bd fs=008f
Ret kernel32.773: lstrcpyA() retval=40b061d0 ret=42d438bd fs=008f
Call kernel32.764: lstrcatA(40b061c4 "C:\\quickenw\\LF",42d4b5ac "MSP") ret=42d438ce
fs=008f
Detected an attempt to write across stack boundary.
Terminating /usr/local/bin/wine.
Of course, if I try to get as much debug information as possible with
"wine -debugmsg +all -managed qw", I get an assertion failure much
earlier:
[...]
trace:profile:PROFILE_GetWineIniString ('wine','path','c:\windows;c:\windows\system'):
returning
'C:\windows\system;C:\windows;C:\windows\sysbckup;C:\windows\system\viewers;C:\windows\command;C:\windows\system\wbem;C:\windows\Msagent;C:\windows\Application
Data\Microsoft\Installer\{00160409-78E1-11D2-B60F-006097C998E7};C:\windows\system\oobe;C:\windows\command\ebd;C:\windows\system\macromed\director;C:\windows\options\cabs;C:\windows\help;C:\windows\Temporary
Internet
Files\Content.IE5\mlctc5cd;C:\windows\system\macromed\shock7;C:\windows\system\macromed\Shockwave;C:\windows\inf;C:\windows\Msagent\Intl;C:\windows\MsApps\Grphflt;C:\windows\Application
Data\Microsoft\welcome;C:\windows\Temporary Internet
Files\Content.IE5\g6je94ot;C:\windows\system\shellext'
err:heap:HEAP_ValidateInUseArena Heap 40430000: in-use arena 40430588 next block has
PREV_FREE flag
Heap: 40430000
Next: 00000000 Sub-heaps: 40430000
Free lists:
Block Stat Size Id
40430024 free 00000001 0000 prev=40430e94 next=404300dc
40430038 free 00000001 0000 prev=404300dc next=4043004c
4043004c free 00000001 0000 prev=40430038 next=40430060
40430060 free 00000001 0000 prev=4043004c next=40430268
Sub-heap 40430000: size=00110000 committed=00010000
Block Stat Size Id
40430094 used 00000018 0000 EIP=0x400b343b
404300b8 used 00000018 0000 EIP=0x400b48bf
404300dc free 00000014 0000 prev=40430024 next=40430038
40430100 Used 00000018 0000 back=404300dc EIP=0x400b343b
40430124 used 00000018 0000 EIP=0x400b345d
40430148 used 00000018 0000 EIP=0x400b3483
4043016c used 00000018 0000 EIP=0x400b343b
40430190 used 00000018 0000 EIP=0x400b345d
404301b4 used 00000018 0000 EIP=0x400b3483
404301d8 used 00000018 0000 EIP=0x400b343b
404301fc used 00000018 0000 EIP=0x400b345d
40430220 used 00000018 0000 EIP=0x400b3483
40430244 used 00000018 0000 EIP=0x400b48e2
40430268 free 00000310 0000 prev=40430060 next=40430e94
40430588 Used 000003f0 0000 back=40430268 EIP=0x40101201
40430984 free 775c3a40 6e69 prev=65747379 next=735c7377
Total: Size=00110000 Committed=00010000 Free=775c3d64 Used=00000510 Arenas=00000160
(0%)
wine: heap.c:226: HEAP_GetPtr: Assertion `0' failed.
trace:heap:HeapAlloc (65430000,08000000,00000018): returning 654a2978
08240580: *killed* exit_code=0
Command terminated by signal 6
So, I try "wine -debugmsg +all,-heap -managed qw" to avoid that one, and
get an outright crash (SEGV):
trace:reg:RegCreateKeyExA (0x10,"registry",0,(null),1,f003f,(nil),0xbfffef44,(nil))
trace:profile:PROFILE_RegistryLoad New section: 'registry'
trace:reg:RegSetValueExA (0x18,"AltCurrentUserFile",0,1,0xbfffef5b,1)
trace:profile:PROFILE_RegistryLoad New key: name='AltCurrentUserFile', value=''
trace:reg:RegSetValueExA (0x18,"AltUserFile",0,1,0xbfffef54,1)
trace:profile:PROFILE_RegistryLoad New key: name='AltUserFile', value=''
trace:reg:RegSetValueExA (0x18,"AltLocalMachineFile",0,1,0xbfffef5c,1)
trace:profile:PROFILE_RegistryLoad New key: name='AltLocalMachineFile',
value=''trace:reg:RegSetValueExA (0x18,"LoadGlobalRegistryFiles",0,1,0xbfffef60,2)
trace:profile:PROFILE_RegistryLoad New key: name='LoadGlobalRegistryFiles', value='Y'
trace:reg:RegSetValueExA (0x18,"LoadHomeRegistryFiles",0,1,0xbfffef5e,2)
trace:profile:PROFILE_RegistryLoad New key: name='LoadHomeRegistryFiles', value='Y'
trace:reg:RegSetValueExA (0x18,"LoadAltRegistryFiles",0,1,0xbfffef5d,2)
trace:profile:PROFILE_RegistryLoad New key: name='LoadAltRegistryFiles', value='Y'
trace:reg:RegSetValueExA (0x18,"LoadWindowsRegistryFiles",0,1,0xbfffef61,2)
trace:profile:PROFILE_RegistryLoad New key: name='LoadWindowsRegistryFiles', value='Y'
trace:reg:RegSetValueExA (0x18,"WritetoHomeRegistryFiles",0,1,0xbfffef61,2)
trace:profile:PROFILE_RegistryLoad New key: name='WritetoHomeRegistryFiles', value='Y'
trace:reg:RegSetValueExA (0x18,"WritetoAltRegistryFiles",0,1,0xbfffef60,2)
trace:profile:PROFILE_RegistryLoad New key: name='WritetoAltRegistryFiles', value='Y'
trace:reg:RegSetValueExA (0x18,"UseNewFormat",0,1,0xbfffef55,2)
trace:profile:PROFILE_RegistryLoad New key: name='UseNewFormat', value='N'
trace:reg:RegCloseKey (0x18)
trace:reg:RegCreateKeyExA (0x10,"Tweak.Layout",0,(null),1,f003f,(nil),0xbfffef44,(nil))
trace:profile:PROFILE_RegistryLoad New section: 'Tweak.Layout'
trace:reg:RegCloseKey (0x18)
trace:reg:RegCreateKeyExA (0x10,"programs",0,(null),1,f003f,(nil),0xbfffef44,(nil))
trace:profile:PROFILE_RegistryLoad New section: 'programs'
trace:reg:RegSetValueExA (0x18,"Default",0,1,0xbfffef50,1)
trace:profile:PROFILE_RegistryLoad New key: name='Default', value=''
trace:reg:RegSetValueExA (0x18,"Startup",0,1,0xbfffef50,1)
trace:profile:PROFILE_RegistryLoad New key: name='Startup', value=''
trace:reg:RegCloseKey (0x18)
trace:reg:RegCreateKeyExA (0x10,"Console",0,(null),1,f003f,(nil),0xbfffef44,(nil))
trace:profile:PROFILE_RegistryLoad New section: 'Console'
trace:reg:RegCloseKey (0x18)
trace:reg:RegCreateKeyExA (0x10,"Clipboard",0,(null),1,f003f,(nil),0xbfffef44,(nil))
trace:profile:PROFILE_RegistryLoad New section: 'Clipboard'
trace:reg:RegSetValueExA (0x18,"ClearAllSelections",0,1,0xbfffef5b,2)
trace:profile:PROFILE_RegistryLoad New key: name='ClearAllSelections',
value='0'trace:reg:RegSetValueExA (0x18,"PersistentSelection",0,1,0xbfffef5c,2)
trace:profile:PROFILE_RegistryLoad New key: name='PersistentSelection', value='1'
trace:reg:RegCloseKey (0x18)
trace:reg:RegOpenKeyExA (0x10,"Drive A",0,f003f,0xbfffee64)
trace:profile:PROFILE_GetWineIniString ('Drive A','Path',''): returning ''
warn:dosfs:DRIVE_Init Drive A: not defined
trace:reg:RegOpenKeyExA (0x10,"Drive B",0,f003f,0xbfffee64)
trace:profile:PROFILE_GetWineIniString ('Drive B','Path',''): returning ''
warn:dosfs:DRIVE_Init Drive B: not defined
trace:reg:RegOpenKeyExA (0x10,"Drive C",0,f003f,0xbfffee64)
trace:reg:RegQueryValueExA (0x18,"Path",(nil),0xbfffee5c,0xbfffee68,0xbfffee60=1024)
trace:reg:RegCloseKey (0x18)
trace:profile:PROFILE_GetWineIniString ('Drive C','Path',''): returning '/dos'
Segmentation fault (core dumped)
Here's the backtrace from that crash:
#0 0x400ee9f6 in HeapAlloc (heap=1078132736, flags=2, size=24) at heap.c:1111
#1 0x400ef6e1 in HEAP_strdupA (heap=1078132736, flags=0,
str=0xbffff398 "/dos") at heap.c:1645
#2 0x400b343b in DRIVE_Init () at drive.c:176
#3 0x400d4b06 in MAIN_MainInit () at main.c:38
#4 0x4014b417 in process_init (argv=0xbffff9d4) at process.c:238
#5 0x4014b944 in PROCESS_InitWine (argc=5, argv=0xbffff9d4) at process.c:443
#6 0x80488b1 in Letext () at main.c:65
#7 0x403449cb in __libc_start_main (main=0x8048874 <main>, argc=5,
argv=0xbffff9d4, init=0x804859c <_init>, fini=0x80488fc <_fini>,
rtld_fini=0x4000ae60 <_dl_fini>, stack_end=0xbffff9cc)
at ../sysdeps/generic/libc-start.c:92
Does anyone have any idea what's going on here? I'm not at all familiar
with the wine code, and I've grown weary of single-stepping through
unfamiliar (and idiomatic) code...
Deven