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:
ajohnsen@google.com
2014-05-05 09:17:26 +00:00
parent e432a80e08
commit 82d1382faa
4 changed files with 20 additions and 16 deletions
+16 -11
View File
@@ -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.
+1 -1
View File
@@ -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);
+3 -1
View File
@@ -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);
-3
View File
@@ -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