serial: Fix race for IOCTL_SERIAL_WAIT_ON_MASK

Wolfgang Walter wolfgang.walter at stwm.de
Tue Apr 19 08:24:10 CDT 2011


Am Dienstag, 19. April 2011 schrieb Alexandre Julliard:
> Wolfgang Walter <wolfgang.walter at stwm.de> writes:
> > set status field of piosb to STATUS_PENDING before calling wait_on(). If
> > wait_on returns with STATUS_PENDING don't touch piosb.
> >
> > Reason: if wait_on returns with STATUS_PENDING it started a thread which
> > itself modifies the status field.
>
> In general the iosb is not modified until the operation completes.

Sorry, don't understand what you mean.

Without that patch an application of us does not work correctly (it hangs 
regularly).


This is the unpatched code:
1036 static inline NTSTATUS io_control(HANDLE hDevice,
....
1256     case IOCTL_SERIAL_WAIT_ON_MASK:
1257         if (lpOutBuffer && nOutBufferSize == sizeof(DWORD))
1258         {
1259             if (!(status = wait_on(hDevice, fd, hEvent, piosb, 
lpOutBuffer)))
1260                 sz = sizeof(DWORD);
1261         }
1262         else
1263             status = STATUS_INVALID_PARAMETER;
1264         break;
...

1272     }
1273     if (needs_close) close( fd );
1274  error:
1275     piosb->u.Status = status;
1276     piosb->Information = sz;
1277     if (hEvent && status != STATUS_PENDING) NtSetEvent(hEvent, NULL);
1278     return status;
1279 }

So this is my theorie:

* wait_on() is called.

* wait_on() calls RtlQueueWorkItem(wait_for_event, commio, 0 /* FIXME */)
  and returns with STATUS_PENDING

* wait_for_event() finishes and sets iosb before io_control() continues

* io_control sets iosb to STATUS_PENDING

=> hang

I think it is not correct to manipulate iosb once 
RtlQueueWorkItem(wait_for_event, commio, 0 /* FIXME */) has been called. 

Regards,
-- 
Wolfgang Walter
Studentenwerk München
Anstalt des öffentlichen Rechts



More information about the wine-devel mailing list