Base · Medium

CWE-413: Improper Resource Locking

The product does not lock or does not correctly lock a resource when the product must have exclusive access to the resource.

CWE-413 · Base Level ·1 CVEs ·2 Mitigations

Description

The product does not lock or does not correctly lock a resource when the product must have exclusive access to the resource.

When a resource is not properly locked, an attacker could modify the resource while it is being operated on by the product. This might violate the product's assumption that the resource will not change, potentially leading to unexpected behaviors.

Potential Impact

Integrity, Availability

Modify Application Data, DoS: Instability, DoS: Crash, Exit, or Restart

Demonstrative Examples

The following function attempts to acquire a lock in order to perform operations on a shared resource.
Bad
void f(pthread_mutex_t *mutex) {
                        pthread_mutex_lock(mutex);
                           
                           /* access shared resource */
                           
                           
                           pthread_mutex_unlock(mutex);
                     }
However, the code does not check the value returned by pthread_mutex_lock() for errors. If pthread_mutex_lock() cannot acquire the mutex for any reason, the function may introduce a race condition into the program and result in undefined behavior.
In order to avoid data races, correctly written programs must check the result of thread synchronization functions and appropriately handle all errors, either by attempting to recover from them or reporting them to higher levels.
Good
int f(pthread_mutex_t *mutex) {
                        int result;
                           result = pthread_mutex_lock(mutex);if (0 != result)return result;
                           
                           
                           /* access shared resource */
                           
                           
                           return pthread_mutex_unlock(mutex);
                     }
This Java example shows a simple BankAccount class with deposit and withdraw methods.
Bad
public class BankAccount {
                        
                           
                           // variable for bank account balance
                           private double accountBalance;
                           
                           // constructor for BankAccount
                           public BankAccount() {accountBalance = 0;}
                           
                           // method to deposit amount into BankAccount
                           public void deposit(double depositAmount) {
                              
                                 double newBalance = accountBalance + depositAmount;accountBalance = newBalance;
                           }
                           
                           // method to withdraw amount from BankAccount
                           public void withdraw(double withdrawAmount) {
                              
                                 double newBalance = accountBalance - withdrawAmount;accountBalance = newBalance;
                           }
                           
                           // other methods for accessing the BankAccount object
                           ...
                     }
However, the deposit and withdraw methods have shared access to the account balance private class variable. This can result in a race condition if multiple threads attempt to call the deposit and withdraw methods simultaneously where the account balance is modified by one thread before another thread has completed modifying the account balance. For example, if a thread attempts to withdraw funds using the withdraw method before another thread that is depositing funds using the deposit method completes the deposit then there may not be sufficient funds for the withdraw transaction.
To prevent multiple threads from having simultaneous access to the account balance variable the deposit and withdraw methods should be synchronized using the synchronized modifier.
Good
public class BankAccount {
                        ...
                           // synchronized method to deposit amount into BankAccount
                           public synchronized void deposit(double depositAmount) {...}
                           
                           // synchronized method to withdraw amount from BankAccount
                           public synchronized void withdraw(double withdrawAmount) {...}
                           ...
                     }
An alternative solution is to use a lock object to ensure exclusive access to the bank account balance variable. As shown below, the deposit and withdraw methods use the lock object to set a lock to block access to the BankAccount object from other threads until the method has completed updating the bank account balance variable.
Good
public class BankAccount {
                        ...
                           // lock object for thread access to methods
                           private ReentrantLock balanceChangeLock;
                           
                           // condition object to temporarily release lock to other threads
                           private Condition sufficientFundsCondition;
                           
                           // method to deposit amount into BankAccount
                           public void deposit(double amount) {
                              
                                 
                                 // set lock to block access to BankAccount from other threads
                                 balanceChangeLock.lock();try {
                                    double newBalance = balance + amount;balance = newBalance;
                                       
                                       // inform other threads that funds are available
                                       sufficientFundsCondition.signalAll();
                                    
                                 } catch (Exception e) {...}finally {// unlock lock objectbalanceChangeLock.unlock();}
                           }
                           
                           // method to withdraw amount from bank account
                           public void withdraw(double amount) {
                              
                                 
                                 // set lock to block access to BankAccount from other threads
                                 balanceChangeLock.lock();try {
                                    while (balance < amount) {
                                          
                                             
                                             // temporarily unblock access
                                             
                                             
                                             // until sufficient funds are available
                                             sufficientFundsCondition.await();
                                       }double newBalance = balance - amount;balance = newBalance;
                                    
                                 } catch (Exception e) {...}finally {// unlock lock objectbalanceChangeLock.unlock();}
                           }...
                     }

Mitigations & Prevention

Architecture and Design

Use a non-conflicting privilege scheme.

Architecture and DesignImplementation

Use synchronization when locking a resource.

Detection Methods

  • Automated Static Analysis High — Automated static analysis, commonly referred to as Static Application Security Testing (SAST), can find some instances of this weakness by analyzing source code (or binary/compiled code) without having to execute it. Typically, this is done by building a model of data flow and control flow, then sea

Real-World CVE Examples

CVE IDDescription
CVE-2022-20141Chain: an operating system kernel has insufficent resource locking (CWE-413) leading to a use after free (CWE-416).

Taxonomy Mappings

  • PLOVER: — Insufficient Resource Locking
  • The CERT Oracle Secure Coding Standard for Java (2011): VNA00-J — Ensure visibility when accessing shared primitive variables
  • The CERT Oracle Secure Coding Standard for Java (2011): VNA02-J — Ensure that compound operations on shared variables are atomic
  • The CERT Oracle Secure Coding Standard for Java (2011): LCK00-J — Use private final lock objects to synchronize classes that may interact with untrusted code
  • Software Fault Patterns: SFP19 — Missing Lock

Frequently Asked Questions

What is CWE-413?

CWE-413 (Improper Resource Locking) is a software weakness identified by MITRE's Common Weakness Enumeration. It is classified as a Base-level weakness. The product does not lock or does not correctly lock a resource when the product must have exclusive access to the resource.

How can CWE-413 be exploited?

Attackers can exploit CWE-413 (Improper Resource Locking) to modify application data, dos: instability, dos: crash, exit, or restart. This weakness is typically introduced during the Architecture and Design, Implementation phase of software development.

How do I prevent CWE-413?

Key mitigations include: Use a non-conflicting privilege scheme.

What is the severity of CWE-413?

CWE-413 is classified as a Base-level weakness (Medium abstraction). It has been observed in 1 real-world CVEs.