[PATCH 0/2] MR10035: kernelbase: Don't write *result on async NtWriteFile returns.
If the caller passes the same pointer to WriteFile as it passes to GetOverlappedResult in another thread, the writes to the memory location in the two files will race each other. --- Is there ever a case where piosb->Information != 0 when status != 0 (or NT_ERROR(status))? If an error status always suggests a 0 length, we can remove the check for overlapped != NULL here. DeviceIoControl is potentially affected too, but it doesn't set *returned=0 in any situation. I think ws2_32:AcceptEx might be affected by the same problem too. The other ws32_32 functions look ok. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10035
From: Stefan Dösinger <stefan@codeweavers.com> If the caller passes the same pointer to WriteFile as it passes to GetOverlappedResult in another thread, the writes to the memory location in the two files will race each other. --- Is there ever a case where piosb->Information != 0 when status != 0 (or NT_ERROR(status))? If an error status always suggests a 0 length, we can remove the check for overlapped != NULL here. DeviceIoControl is potentially affected too, but it doesn't set *returned=0 in any situation. I think ws2_32:AcceptEx might be affected by the same problem too. The other ws32_32 functions look ok. --- dlls/kernelbase/file.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index e271b03de1f..d99d63f185e 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -4013,6 +4013,8 @@ BOOL WINAPI DECLSPEC_HOTPATCH WriteFile( HANDLE file, LPCVOID buffer, DWORD coun else piosb->Information = 0; piosb->Status = STATUS_PENDING; + if (result) *result = 0; + status = NtWriteFile( file, event, NULL, cvalue, piosb, buffer, count, poffset, NULL ); if (status == STATUS_PENDING && !overlapped) @@ -4021,7 +4023,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH WriteFile( HANDLE file, LPCVOID buffer, DWORD coun status = piosb->Status; } - if (result) *result = overlapped && status ? 0 : piosb->Information; + if (result && (!overlapped || !status)) *result = piosb->Information; if (status && status != STATUS_TIMEOUT) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10035
From: Stefan Dösinger <stefan@codeweavers.com> --- The assignment of *result = 0 is already in place in this function. --- dlls/kernelbase/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index d99d63f185e..7c079260af9 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -3620,7 +3620,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH ReadFile( HANDLE file, LPVOID buffer, DWORD count, status = io_status->Status; } - if (result) *result = overlapped && status ? 0 : io_status->Information; + if (result && (!overlapped || !status)) *result = io_status->Information; if (status == STATUS_END_OF_FILE) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10035
participants (2)
-
Stefan Dösinger -
Stefan Dösinger (@stefan)