* Fix a potential race condition when deleting a semaphore set: previously only

the ipc hash table lock along with the semaphore set hash table lock were
  hold, thinking (wrongly) that the semaphore set lock itself was not needed.
  What could happen was that another process on semop could have gained the lock
  of the set itself, and then release the semaphore set hash table lock.
  This would make it think that the set was still valid, while it could have
  actually been deleted right after it release the semaphore set hash table lock.
  Same would have happened for any other processes waiting on the semaphore set
  mutex queue. By calling the lock on the mutex when deleting the set, it
  *should be* safe to assume that there is no one else waiting on its queue,
  since the list of waiters is handled in a FIFO way.

As far as I can see from the mutex_destroy code, it looks safe to hold the lock
when calling this function. Please confirm.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27268 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Salvatore Benedetto 2008-09-01 16:16:03 +00:00
parent 52b877461d
commit dc0cdfb2f0

View File

@ -846,7 +846,11 @@ _user_xsi_semctl(int semaphoreID, int semaphoreNumber, int command,
setLocker.SetTo(&semaphoreSet->Lock(), false);
setHashLocker.Unlock();
ipcHashLocker.Unlock();
}
} else
// We are about to delete the set along with its mutex, so
// we can't use the MutexLocker class, as the mutex itself
// won't exist on function exit
mutex_lock(&semaphoreSet->Lock());
int result = 0;
XsiSemaphore *semaphore = semaphoreSet->Semaphore(semaphoreNumber);
@ -1005,8 +1009,9 @@ _user_xsi_semctl(int semaphoreID, int semaphoreNumber, int command,
case IPC_RMID: {
// If this was the command, we are still holding
// the semaphore set hash table lock along with the
// ipc hash table lock, but not the semaphore set
// itself lock as it would be useless in this case
// ipc hash table lock and the semaphore set lock
// itself, this way we are sure there is not
// one waiting in the queue of the mutex.
if (!semaphoreSet->HasPermission()) {
TRACE_ERROR(("xsi_semctl: calling process has not "
"permission on semaphore %d, key %d\n",