http://bugs.winehq.org/show_bug.cgi?id=20336
Summary: GetDriveTypeW exposes partially uninitialized out parameter iosb in NtDeviceIoControlFile ? Product: Wine Version: 1.1.31 Platform: PC OS/Version: Linux Status: NEW Keywords: download, patch Severity: normal Priority: P2 Component: ntdll AssignedTo: wine-bugs@winehq.org ReportedBy: dank@kegel.com
Building the chromium unit test suite and then running
valgrind --trace-children=all --track-origins=yes wine base_unittests.exe --gtest_filter=FileUtilTest.CreateShortcutTest
sometimes yields the error
Syscall param writev(vector[...]) points to uninitialised byte(s) at writev (writev.c:46) by wine_server_call (server.c:214) by NTDLL_wait_for_multiple_objects (sync.c:1122) by NtWaitForMultipleObjects (sync.c:1166) by NtWaitForSingleObject (sync.c:1175) by server_ioctl_file (file.c:1252) by NtDeviceIoControlFile (file.c:1318) by DeviceIoControl (file.c:2379) by get_mountmgr_drive_type (volume.c:203) by GetDriveTypeW (volume.c:1381) by IShellLinkW_fnSetPath (shelllink.c:2155) ... Address 0x7f21f248 is on thread 1's stack Uninitialised value was created by a stack allocation at DeviceIoControl (file.c:2335)
and sometimes the error
Syscall param writev(vector[...]) points to uninitialised byte(s) at writev (writev.c:46) by wine_server_call (server.c:214) by NTDLL_wait_for_multiple_objects (sync.c:1122) by wait_suspend (exception.c:85) by usr1_handler (signal_i386.c:1993) by ??? (in /lib32/libpthread-2.9.so) Address 0x7ffdae08 is on thread 1's stack Uninitialised value was created by a stack allocation at DeviceIoControl (file.c:2335)
The stack allocation in question is IO_STATUS_BLOCK iosb; in kernel32/file.c in DeviceIoControl(). Setting its fields to known values before the call to NtDeviceIoControlFile() shows that the undefined field is iosb.Information. Setting that field before the call gets rid of the valgrind error.
I can't quite follow how ioctl's work, but: the IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE ioctl seems to follow the call-once-to-get-buffer-size paradigm. Its reply is a struct mountmgr_unix_drive plus (if there is room) two nul-terminated strings. The first field of that struct is the total size needed to hold the entire reply. If you call without a big enough buffer, it fills in the size and returns STATUS_MORE_ENTRIES. It puts 0 in the Information field of the iosb in this case. GetDriveTypeW happens to not care about the two strings, so it only calls once with a small buffer.
Now, server_ioctl_file only copies the Information field of the iosb if it gets STATUS_SUCCESS. So it leaves Information undefined in the STATUS_MORE_ENTRIES case. MSDN says that Information is set to zero on failure, so if server_ioctl_file isn't going to copy that field, maybe it should set it to zero. And in fact, setting it to zero in the non-STATUS_SUCCESS case also gets rid of the valgrind error.
I have no idea what Information is used for, or what's really going on here, so I'll just attach the patch to clear Information in the non-SUCCESS case and hope somebody who knows what's going on can comment.