Shared Object Lock¶
What does this mean ?¶
A lock must be shared by the operations protecting the same resource. The problem is exposing that lock to unrelated code, for example by locking this, a public Type object, or an interned string. Another caller may acquire the same monitor for a different purpose. See Microsoft's lock guidance.
What can happen ?¶
Unexpected lock contention can stall work; inconsistent acquisition order can produce a deadlock. These are concurrency and availability risks, not proof that an attacker can exploit every affected method.
Recommendation¶
Use a dedicated private lock object, consistently covering both reads and writes of protected state. Use a static gate for static shared state. Keep critical sections short and avoid callbacks into unknown code while locked. For C# 13/.NET 9+, a dedicated System.Threading.Lock is also available. await cannot appear inside a lock body; asynchronous coordination needs an appropriate separate design.
Sample Code¶
Publicly accessible monitor:
public class Counter
{
private int value;
public void Increment() { lock (this) { value++; } }
public int Value { get { lock (this) { return value; } } }
}
Private monitor for the same state:
public class Counter
{
private readonly object gate = new object();
private int value;
public void Increment() { lock (gate) { value++; } }
public int Value { get { lock (gate) { return value; } } }
}
Regression test: run concurrent increments and assert the exact final count. Hold lock(counter) in an independent task and verify the replacement still makes progress. Include timeout-based failure detection so a concurrency regression cannot hang the test suite.
References¶
- C# lock statement
- Related: thread suspension.