Thread safety of reference affectation & security issue

  • Thread starter Thread starter Joannes Vermorel
  • Start date Start date
J

Joannes Vermorel

I would like to know if the here below 'MyClass' is threadsafe. In other
word, is reference affectation an "atomic operation" for the CLR ?

class MyClass
{
object obj = null;
public void Set(object obj) { this.obj = obj; }
public object Get() { return obj; }
}

If reference affectation is an atomic operation, then everything seems fine
to me. <guess>If not, that means that potentially I can retrieve an
inconsistence reference, i.e. a reference pointing some random part of
memory ? Using idea similar to the buffer overflow, the possibility of
"inconsistent" reference could be exploited as a security hole.</guess>

So I see 3 possible situations, reference affectation:
- is atomic.
- is not atomic and could be exploited as a security hole.
- is not atomic but some mecanism that I do not understand (yet) still
maintains the security.

Does someone has any idea on this problem ?
Thanks,

Joannes
 
No, the class is not guaranteeed to be threadsafe because the property
requires multiple logical steps to achieve the write/read, I am pretty
certain you should always assume your second scenario. BTW, the MSDN C#
language specification section 5.5 addresses atomicity and does say that
reference reads and writes ARE atomic, however there are obviously more
steps in both property or even field level assignment than just the
individual reference assignment.

Richard
 
Thanks for the pointer to the section 5.5, that's the answer to my question:
read/write of references are threadsafe, therefore there are no
"inconsistent" state for references.

This leads me to another question, C# and CLR aim (as far I know) to be
"machine independent". But for 64bits architectures, assuring the atomicity
of references read/write is at the same level than assuring the atomicity of
read/write for double/long/ulong.

I don't think being visionary if I say that 64bits architectures are going
one day or another to replace 32bits ones. Does anyone know why read/write
for double/long/ulong have not been defined as atomic in the C# spec ?

Joannes
 
Joannes Vermorel said:
Thanks for the pointer to the section 5.5, that's the answer to my question:
read/write of references are threadsafe, therefore there are no
"inconsistent" state for references.

This leads me to another question, C# and CLR aim (as far I know) to be
"machine independent". But for 64bits architectures, assuring the atomicity
of references read/write is at the same level than assuring the atomicity of
read/write for double/long/ulong.

I don't think being visionary if I say that 64bits architectures are going
one day or another to replace 32bits ones. Does anyone know why read/write
for double/long/ulong have not been defined as atomic in the C# spec ?

Because ensuring reference atomicity is likely to be easy on any
machine, whereas ensuring 64 bit atomicity on a 32 bit architecture
isn't. Double/long atomicity may well occur on 64 bit machines, but if
they'd *specified* that double/long reads were atomic, they'd be much
more complicated on 32 bit machines.

However, thread-safety is about much more than just atomicity. The
biggest problem, IMO, is data caching. Unless you have some sort of
memory barrier (eg a lock or volatile read/write) involved, there's
nothing to stop one thread from caching the value of a variable and
using that cached value, rather than going to main memory for the real
value - so long as the thread is consistent with itself, basically.

This is why you should always synchronize for shared data, or use
volatile variables. Personally I'm happier using a lock than
volatility, but that's just me.

Don't try doing clever stuff like the double-check lock algorithm
unless you're an expert (a real honest-to-goodness expert). The chances
are it won't buy you much performance, but you may well find that your
program isn't as well synchronized as you think it is.
 
Ah, ok, I guess I misunderstood the question (at least partially) - yes
there is no transitive or inconsistant state for reference reads/writes.
Good question on the spec but I think the answer is probably simple: My
guess is because 32 bit architecture does not support atomicity for 64 bit
length types, MS/Anders didn't want to hide the complexity and peroformance
hit of synchronizing those types automagically for you. However when the 64
bit C# is fully realized it will have atomicity for all native value types
but the decimal type and this will require modification (or branching off
more likely) of the spec.

You might want to check out this blog:
http://blogs.msdn.com/joshwil/

Not many posts but totally dedicated to the 64 bit CLR implementation.

Richard
 
Back
Top