New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix win_write to check if fully sent #28432
Conversation
|
Please review. |
This issue/PR has been automatically marked as stale because it has not had any update (including commits, comments, labels, milestones, etc) for 30 days. It will be closed automatically if no further update occurs in 7 day. Thank you for your contributions! |
We might still want to have this fix. AJ, would you mind reviewing this since you recently worked on Windows? |
Fixes issue #28524 |
I still want this. Any way to upvote this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this, sorry it slipped through the cracks (significantly). It looks correct to me, but I'm not sure how our tests never caught it. In particular, we have an end2end test that sends a 10MB payload (//test/core/end2end:h2_full_test@invoke_large_request
). Are the windows transport buffers > 10MB by default? Best I could find, the default is O(kilobytes). If we can add a test for this, or modify one to catch it, that would be ideal.
Actually, the issue does not cause on windows environment because windows does not perform partial send (I didn’t know this at the time of writing code). It is only caused when we run grpc server on WINE. Even though, I think it’d be best to fix it because the behavior is not documented by microsoft. Therefore, we could use WINE to catch it. Do you think it is ok to add WINE tests to catch it? |
|
&bytes_sent, 0, &socket->write_info.overlapped, NULL); | ||
status = WSASend(socket->socket, buffers + async_buffers_offset, | ||
(DWORD)(tcp->write_slices->count - async_buffers_offset), | ||
NULL, 0, &socket->write_info.overlapped, NULL); | ||
if (allocated) gpr_free(allocated); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please note that the blocking behaviour of the first WSASend function on Windows hides the use-after free of the variable "allocated" (or the stack allocated version "local_buffers" that gets out of scope) of the non blocking second WSASend. In Windows this code is never reached.
This is however another issue that is out of scope of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure that's right. Per the WSASend docs:
If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture the WSABUF structures before returning from this call. This enables applications to build stack-based WSABUF arrays pointed to by the lpBuffers parameter.
Deallocating the heap (and local) variables before returning shouldn't be an issue for the subsequent overlapped WSASend call. Do I maybe misunderstand your concern here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, the copying of the buffer in wsasend is new to me. I more or less assumed it was up to the completion handler.
My comments on use after free can be ignored.
@qbx2, regarding:
Do you have a source for that information? I'm not sure it's true, if the implementations are built to WSASend's current spec:
|
@drfloob The source is Jinoh Kang from: https://bugs.winehq.org/show_bug.cgi?id=10648 . Also, he said that windows implementation sometimes does not follow the specification (documentation) |
* [EventEngine] WindowsEndpoint Initial sketch, all tests passing * Port fix from #28432 * GPR_WINDOWS guard * use MemoryAllocator::MakeReservation for allocated buffers * better logging (respect slice length) * Automated change: Fix sanity tests * improvements * Automated change: Fix sanity tests * InlinedVector<WSABUF, kMaxWSABUFCount> * initial attempt at socket util reunification * posix fixes + local run of sanitize.sh * posix socket includes * fix * Automated change: Fix sanity tests * remove unused include (breaks windows) * remove stale comment Co-authored-by: drfloob <drfloob@users.noreply.github.com>
* Fix win_write to check if fully sent * Update tcp_windows.cc * Update tcp_windows.cc
* [EventEngine] WindowsEndpoint Initial sketch, all tests passing * Port fix from #28432 * GPR_WINDOWS guard * use MemoryAllocator::MakeReservation for allocated buffers * better logging (respect slice length) * Automated change: Fix sanity tests * improvements * Automated change: Fix sanity tests * InlinedVector<WSABUF, kMaxWSABUFCount> * initial attempt at socket util reunification * posix fixes + local run of sanitize.sh * posix socket includes * fix * Automated change: Fix sanity tests * remove unused include (breaks windows) * remove stale comment Co-authored-by: drfloob <drfloob@users.noreply.github.com>
win_write
does not check if the data is completely sent in synchronous phase. When that situation happens, the connection hangs up. I added handling code for that.@donnadionne