* 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:
parent
52b877461d
commit
dc0cdfb2f0
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user