CWE-833 describes multiple threads or executable segments waiting for each other to release a lock they need. None can move. MITRE marks it as not language specific and not technology specific, so it can appear in applications, libraries, operating systems and hardware.
How it happens
Thread one holds lock A and wants lock B. Thread two holds lock B and wants lock A. Both wait forever.
# Vulnerable: opposite lock order in two functions
def transfer_ab():
with lock_a:
with lock_b:
move()
def transfer_ba():
with lock_b:
with lock_a:
move()
MITRE's record includes deadlocks in operating systems and libraries, such as CVE-2009-2857 (OS deadlock), CVE-2009-1961 (OS deadlock involving three separate functions) and CVE-2009-2699 (deadlock in a library). It also lists CVE-1999-1476, a bug in some Intel Pentium processors where an invalid instruction caused a hang.
What an attacker gains
Availability only. MITRE says each thread hangs and prevents tasks from completing, and in some cases CPU use rises when a lock check runs in a tight loop. An attacker who can trigger the right interleaving can freeze a service with a few requests.
How to find it
MITRE lists automated static analysis. Add lock order review: record which locks each code path takes and in what order. Stress tests with many concurrent requests, plus thread dumps taken from a hung process, show which threads wait on which locks.
How to fix it
The record gives no formal mitigations. Proven practices:
- Always acquire locks in one global order.
- Hold as few locks as possible, for as short a time as possible.
- Use timeouts or try-lock calls and back off on failure.
- Avoid calling unknown code, such as callbacks, while holding a lock.
# Fixed: one agreed order
def transfer_ba():
with lock_a:
with lock_b:
move()
Quick check
Is deadlock a security issue or just a bug?
Both. If an outsider can trigger it, it is a denial of service.