Mutexes are used to protect shared data structures being accessed concurrently. A certain process will own a mutex when it locks it, the owning process should be the only process to unlock or destroy the mutex. If the mutex is destroyed or unlocked while still in use then there is no more protection of critical sections and shared data.
Non-Compliant Code Example
In this example, you may imagine that there is a cleanup process trying to destroy a lock it believes to no longer be in use. If there is a heavily load on the system, then the worker process that held the lock could just be taking longer than expected and if the lock is destroyed before the worker process is done modifying the shared data, race conditions will exist.
mutex_t theLock; int data; int cleanupAndFinish() { mutex_destroy(&theLock); data++; return data; } void worker(int value) { mutex_lock(&theLock); data += value; mutex_unlock(&theLock); }
Compliant Solution
This solution requires the cleanup function to acquire the lock before destroying it. Doing it this way means that the mutex will only be destroyed by the process that owns it.
mutex_t theLock;int data; int cleanupAndFinish() { mutex_lock(&theLock); mutex_destroy(&theLock); data++; return data; } void worker(int value){ mutex_lock(&theLock); data += value; mutex_unlock(&theLock); }
Risk Assessment
The risks of ignoring mutex ownership are very similar to the risk of not using mutexes at all. If shared data structures are to be protected from race conditions, then mutex ownership must be honored.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
|
2 (medium) |
1 (unlikely) |
1 (high) |
P2 |
L3 |
References
Linux Programmers Manual entry on mutexes "man mutex"