[Bug 10225] New: SafeDisc 2. x triggers async device ioctl status code propagation bug in wine server

wine-bugs at winehq.org wine-bugs at winehq.org
Mon Oct 29 05:18:47 CDT 2007


http://bugs.winehq.org/show_bug.cgi?id=10225

           Summary: SafeDisc 2.x triggers async device ioctl status code
                    propagation bug in wine server
           Product: Wine
           Version: CVS/GIT
          Platform: PC
        OS/Version: Linux
            Status: UNCONFIRMED
          Severity: major
          Priority: P2
         Component: wine-kernel
        AssignedTo: wine-bugs at winehq.org
        ReportedBy: focht at gmx.net


Created an attachment (id=8843)
 --> (http://bugs.winehq.org/attachment.cgi?id=8843)
relevant trace which shows ioctl status code propagation bug

Hello,

while testing my proof-of-concept patch which makes SafeDisc v2 (yuck!) finally
work, I stumbled across a nasty ioctl status code propagation (completion) bug
in wine server.
Wasted several hours on it .. I was suspecting SD issue whole time, but its a
wine server bug :(

Attached is relevant trace (WINEDEBUG=+seh,+tid,+relay,+ntoskrnl,+server wine
./BfVietnam.exe)

Before the bug is triggered, the SafeDisc security driver makes several device
ioctl requests which return 0xC0000001 (unsuccessful) on purpose, e.g. reading
debug Drx registers with index that does not exist.
This is intended to fool reversers :-)

The next operation - checking IDT entries should succeed - but does not (as
seen from calling client).
The kernel driver completes the operation successfully and returns
irp.IoStatus.u.Status == 0 with xxxx bytes in output buffer.
I verified it several times by debugging the kernel driver.

Upon driver ioctl call return, get_next_device_request() is triggered again in
ntoskrnl event loop which sets the return data (and status code) ->
set_ioctl_result().
This queues an APC, waking up the client (alertable state).

The client process device ioctl completes with 0 (FALSE) which is wrong.
Further debugging showed that ioctl_completion APC (dlls/ntdll/file.c) returns
the errornous status code in get_ioctl_result() when woken up by server.
This error is then propagated in server_ioctl_file() to result in wrong
NtDeviceIoControlFile() return code.

What puzzled me is that "ioctl->status" is correctly set by set_ioctl_result()
(=0) but get_ioctl_result() - called within client context - yields the
previous error code (0xC0000001 of failed request).

This is either a problem of global vs. thread local error status (global_error
vs. current->error/thread) or the ioctl call data is the wrong one.

The following patch works for me, letting SD 2.x continue - though i'm not sure
if it's right:

--- snip ---

diff --git a/server/device.c b/server/device.c
index 46b2796..8fe8f7c 100644
--- a/server/device.c
+++ b/server/device.c
@@ -528,7 +528,7 @@ DECL_HANDLER(get_ioctl_result)
                 ioctl->out_data = NULL;
             }
         }
-        set_error( ioctl->status );
+
         list_remove( &ioctl->dev_entry );
         release_object( ioctl );  /* no longer on the device queue */
     }

--- snip ---

Regards


-- 
Configure bugmail: http://bugs.winehq.org/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are watching all bug changes.



More information about the wine-bugs mailing list