C#-CWE-362

Race condition: unsynchronized access to shared resources can lead to incorrect behavior or security issues

Required inputs: CSharpAST

This rule detects **race conditions (CWE-362)** where concurrent access or modification of shared resources can lead to incorrect behavior, lost updates, or security issues. Common categories detected by this rule: - **Non-atomic updates**: read-modify-write operations (e.g., `x = x + 1`) on shared fields without synchronization. - **TOCTOU (Time-of-Check/Time-of-Use)**: checking a resource (like a file) and then acting on it later without atomicity. - **Concurrent collection misuse**: iterating a non-concurrent collection while it may be modified by another thread. - **Unsafe double-checked locking**: lazy initialization without proper memory barriers. - **Check-then-act**: checking shared state and acting later without synchronization. ### Vulnerable examples and fixes **1) Non-atomic increment (vulnerable)**

public class Counter
{
    public int Value = 0;

    public void Increment()
    {
        // Vulnerable: read-modify-write is not atomic
        Value = Value + 1;
    }
}
**Fix — use Interlocked (recommended):**

using System.Threading;

public class Counter
{
    private int _value;

    public void Increment()
    {
        Interlocked.Increment(ref _value); // atomic
    }
}
--- **2) TOCTOU on filesystem (vulnerable)**

string path = @"C:\data\report.txt";
if (!File.Exists(path))
{
    // Another thread/process could create the file here
    File.Create(path).Dispose();
}
**Fix — use atomic API or try-create:**

try
{
    using (var fs = new FileStream(path, FileMode.CreateNew, FileAccess.Write))
    {
        // created atomically or throws if exists
    }
}
catch (IOException)
{
    // handle existing file
}
--- **3) Enumerating and modifying a List concurrently (vulnerable)**

List items = new List();

void AddItem(int x) { items.Add(x); } // from multiple threads

void PrintAll()
{
    foreach (var v in items) // may throw or see inconsistent state
        Console.WriteLine(v);
}
**Fix — use concurrent collection or snapshot:**

using System.Collections.Concurrent;

ConcurrentBag items = new ConcurrentBag();

void AddItem(int x) { items.Add(x); }

void PrintAll()
{
    foreach (var v in items) Console.WriteLine(v);
}
or

int[] snapshot;
lock (_sync) // same lock used by producers
{
    snapshot = items.ToArray();
}
foreach (var v in snapshot) Console.WriteLine(v);
--- **4) Unsafe double-checked locking (vulnerable)**

public class Singleton
{
    private static Singleton _instance;

    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
            {
                lock (typeof(Singleton))
                {
                    if (_instance == null)
                        _instance = new Singleton(); // may be visible partially constructed
                }
            }
            return _instance;
        }
    }
}
**Fix — use `Lazy` (recommended):**

private static readonly Lazy _instance = new Lazy(() => new Singleton());
public static Singleton Instance => _instance.Value;
--- ### Guidance for developers - Prefer atomic primitives (`Interlocked`) and concurrent collections (`ConcurrentDictionary`, `ConcurrentQueue`, `ConcurrentBag`) for common concurrent patterns. - Use `lock` for grouping multiple operations that must be atomic together. - Use atomic file APIs (e.g., `FileMode.CreateNew`) instead of check-then-act on the filesystem. - When designing APIs, prefer operations that perform checks and the action atomically (server-side), or document and protect the shared state. This rule is intentionally conservative: it flags likely dangerous patterns for manual review rather than attempting to prove every race condition automatically.

Possible Messages

Key

Text

Severity

Disabled

race_check_then_act

Check-then-act on shared state without synchronization detected: perform the check and action atomically.

None

False

race_double_checked_locking

Unsafe double-checked locking detected: use Lazy<T> or ensure proper volatile semantics and locking.

None

False

race_enum_modify_collection

Concurrent modification while enumerating a non-concurrent collection detected: use a concurrent collection, snapshot, or synchronization.

None

False

race_non_atomic_increment

Non-atomic update of shared numeric field detected: use Interlocked or lock.

None

False

race_toctou_filesystem

Time-of-check/time-of-use (TOCTOU) on filesystem detected: use atomic file APIs or perform operations under synchronization.

None

False

Options