Fix potential race introduced in Icd7f5f03

Digit wrote:

"You probably don't want to close the socket here without updating
c->socket as well. Otherwise, another thread holding a handle to the
client after the c->decRef() could end up sending a message to a
different socket, if the file descriptor index is reused by another
client in the meantime."

Change-Id: Icdefb5ffc0c7607325d7db761e1f04e5d868bfb7
This commit is contained in:
Brad Fitzpatrick 2011-03-17 17:14:46 -07:00
parent 13aa8ad445
commit 3549b0dc28
3 changed files with 23 additions and 17 deletions

View File

@ -44,7 +44,7 @@ public:
// SocketListener creates a SocketClient (at refcount 1) and calls
// decRef() when it's done with the client.
void incRef();
void decRef();
bool decRef(); // returns true at 0 (but note: SocketClient already deleted)
};
typedef android::List<SocketClient *> SocketClientCollection;

View File

@ -104,20 +104,23 @@ int SocketClient::sendData(const void* data, int len) {
}
void SocketClient::incRef() {
pthread_mutex_lock(&mRefCountMutex);
mRefCount++;
pthread_mutex_unlock(&mRefCountMutex);
pthread_mutex_lock(&mRefCountMutex);
mRefCount++;
pthread_mutex_unlock(&mRefCountMutex);
}
void SocketClient::decRef() {
bool deleteSelf = false;
pthread_mutex_lock(&mRefCountMutex);
mRefCount--;
if (mRefCount == 0) {
deleteSelf = true;
}
pthread_mutex_unlock(&mRefCountMutex);
if (deleteSelf) {
delete this;
}
bool SocketClient::decRef() {
bool deleteSelf = false;
pthread_mutex_lock(&mRefCountMutex);
mRefCount--;
if (mRefCount == 0) {
deleteSelf = true;
} else if (mRefCount < 0) {
SLOGE("SocketClient refcount went negative!");
}
pthread_mutex_unlock(&mRefCountMutex);
if (deleteSelf) {
delete this;
}
return deleteSelf;
}

View File

@ -225,8 +225,11 @@ void SocketListener::runListener() {
}
pthread_mutex_unlock(&mClientsLock);
/* Destroy the client */
close(c->getSocket());
c->decRef();
int socket = c->getSocket();
if (c->decRef()) {
// Note: 'c' is deleted memory at this point.
close(socket);
}
}
}
}