Fix crash in raw_secure_server_socket_test.
We had a scenario where read&write events were requested after the socket was closed, leading to a use-after-free. This also fixes a scenario where we didn't delete client sockets, when accepted sockets are ignored when closing a listening socket. BUG=https://code.google.com/p/dart/issues/detail?id=18610 R=sgjesse@google.com Review URL: https://codereview.chromium.org//269003002 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@35732 260f80e4-7a28-3924-810f-c04153c831b5
This commit is contained in:
@@ -334,6 +334,7 @@ bool Handle::IssueSendTo(struct sockaddr* sa, socklen_t sa_len) {
|
||||
|
||||
void Handle::HandleIssueError() {
|
||||
DWORD error = GetLastError();
|
||||
ASSERT(event_handler_ != NULL);
|
||||
if (error == ERROR_BROKEN_PIPE) {
|
||||
event_handler_->HandleClosed(this);
|
||||
} else {
|
||||
@@ -399,6 +400,7 @@ bool DirectoryWatchHandle::IssueRead() {
|
||||
|
||||
void SocketHandle::HandleIssueError() {
|
||||
int error = WSAGetLastError();
|
||||
ASSERT(event_handler_ != NULL);
|
||||
if (error == WSAECONNRESET) {
|
||||
event_handler_->HandleClosed(this);
|
||||
} else {
|
||||
@@ -502,6 +504,17 @@ void ListenSocket::AcceptComplete(OverlappedBuffer* buffer,
|
||||
}
|
||||
|
||||
|
||||
static void DeleteIfClosed(Handle* handle) {
|
||||
if (handle->IsClosed()) {
|
||||
Dart_Port port = handle->port();
|
||||
delete handle;
|
||||
if (port != ILLEGAL_PORT) {
|
||||
DartUtils::PostInt32(port, 1 << kDestroyedEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ListenSocket::DoClose() {
|
||||
closesocket(socket());
|
||||
handle_ = INVALID_HANDLE_VALUE;
|
||||
@@ -510,6 +523,7 @@ void ListenSocket::DoClose() {
|
||||
ClientSocket *client = Accept();
|
||||
if (client != NULL) {
|
||||
client->Close();
|
||||
DeleteIfClosed(client);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -955,18 +969,8 @@ void DatagramSocket::DoClose() {
|
||||
}
|
||||
|
||||
|
||||
static void DeleteIfClosed(Handle* handle) {
|
||||
if (handle->IsClosed()) {
|
||||
Dart_Port port = handle->port();
|
||||
delete handle;
|
||||
if (port != ILLEGAL_PORT) {
|
||||
DartUtils::PostInt32(port, 1 << kDestroyedEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EventHandlerImplementation::HandleInterrupt(InterruptMessage* msg) {
|
||||
ASSERT(this != NULL);
|
||||
if (msg->id == kTimeoutId) {
|
||||
// Change of timeout request. Just set the new timeout and port as the
|
||||
// completion thread will use the new timeout value for its next wait.
|
||||
@@ -1289,6 +1293,7 @@ void EventHandlerImplementation::EventHandlerEntry(uword args) {
|
||||
&key,
|
||||
&overlapped,
|
||||
static_cast<DWORD>(millis));
|
||||
|
||||
if (!ok && overlapped == NULL) {
|
||||
if (GetLastError() == ERROR_ABANDONED_WAIT_0) {
|
||||
// The completion port should never be closed.
|
||||
|
||||
@@ -224,7 +224,6 @@ class Handle {
|
||||
|
||||
HANDLE handle() { return handle_; }
|
||||
Dart_Port port() { return port_; }
|
||||
EventHandlerImplementation* event_handler() { return event_handler_; }
|
||||
|
||||
void Lock();
|
||||
void Unlock();
|
||||
@@ -439,6 +438,7 @@ class ClientSocket : public SocketHandle {
|
||||
ASSERT(!HasPendingRead());
|
||||
ASSERT(!HasPendingWrite());
|
||||
ASSERT(next_ == NULL);
|
||||
ASSERT(closed_ == true);
|
||||
};
|
||||
|
||||
void Shutdown(int how);
|
||||
|
||||
@@ -824,6 +824,7 @@ class _NativeSocket extends NativeFieldWrapperClass1 {
|
||||
|
||||
var handler = eventHandlers[i];
|
||||
if (i == DESTROYED_EVENT) {
|
||||
assert(isClosing);
|
||||
assert(!isClosed);
|
||||
isClosed = true;
|
||||
closeCompleter.complete();
|
||||
@@ -873,7 +874,7 @@ class _NativeSocket extends NativeFieldWrapperClass1 {
|
||||
sendWriteEvents = write;
|
||||
if (read) issueReadEvent();
|
||||
if (write) issueWriteEvent();
|
||||
if (eventPort == null) {
|
||||
if (eventPort == null && !isClosing) {
|
||||
int flags = typeFlags & TYPE_TYPE_MASK;
|
||||
if (!isClosedRead) flags |= 1 << READ_EVENT;
|
||||
if (!isClosedWrite) flags |= 1 << WRITE_EVENT;
|
||||
@@ -936,6 +937,7 @@ class _NativeSocket extends NativeFieldWrapperClass1 {
|
||||
}
|
||||
|
||||
void connectToEventHandler() {
|
||||
assert(!isClosed);
|
||||
if (eventPort == null) {
|
||||
eventPort = new RawReceivePort(multiplex);
|
||||
_SocketsObservatory.add(this);
|
||||
|
||||
@@ -11,9 +11,6 @@ package/invalid_uri_test: Fail, OK # CompileTimeErrors intentionally
|
||||
|
||||
issue14236_test: Pass # Do not remove this line. It serves as a marker for Issue 14516 comment #4.
|
||||
|
||||
[ $runtime == vm && $system == windows ]
|
||||
io/raw_secure_server_socket_test: Pass, Crash # Issue 18610
|
||||
|
||||
[ $runtime == vm ]
|
||||
package/package_isolate_test: Fail # Issue 12474
|
||||
|
||||
|
||||
Reference in New Issue
Block a user