Showing posts with label .net internals. Show all posts
Showing posts with label .net internals. Show all posts

22/10/2015

TransactionScope and multi-threading

Home

It's my third post about TransactionScope. This time I'll write about using it with multi-threading. Let's start with the following code:
using (var t = new TransactionScope())
{
   var t1 = Task.Factory.StartNew(UpdateDatabase);
   var t2 = Task.Factory.StartNew(UpdateDatabase);
   Task.WaitAll(t1, t2);
   t.Complete();
}

private static void UpdateDatabase()
{
   using (var c = new SqlConnection(connectionString))
   {
      c.Open();

      WriteDebugInfo();

      new SqlCommand(updateCommand, c).ExecuteNonQuery();
   }
}

private static void WriteDebugInfo()
{
   Console.WriteLine("Thread= {0}, LocalIdentifier = {1}, DistributedIdentifier = {2}",
      Thread.CurrentThread.ManagedThreadId,
      Transaction.Current?.TransactionInformation.LocalIdentifier,
      Transaction.Current?.TransactionInformation.DistributedIdentifier);
}
It seems simple but it doesn't work. The problem is that a connection that is created in UpdateDatabase method will not participate in any transaction. We can also observe that WriteDebugInfo will write empty transaction identifiers to the console. It happens because in order to read an ambient transaction (the transaction the code is executed in) TransactionScope uses Transaction.Current property which is thread static (i.e. specific for a thread).

To overcome this issue we have two possibilities. The first one is to use DependentTransacion. However, I'll not show how to do it because since .NET 4.5.1 there is a better way - TransactionScopeAsyncFlowOption enum. Let's try.
using (var t = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
   ...
}
Unfortunately, there is a big chance that this time we will get TransactionException with the message The operation is not valid for the state of the transaction. in the line with ExecuteNonQuery. The simplified stack trace is:

at System.Transactions.TransactionStatePSPEOperation.get_Status(InternalTransaction tx)
at System.Transactions.TransactionInformation.get_Status()
...
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
at Sandbox.Program.UpdateDatabase(Object o)

I read a lot about this but nobody was able to explain why it happens. I also looked into the source code of TransactionStatePSPEOperation class. It was instructive because I learned what is PSPE - Promotable Single Phase Enlistment. However, it also didn't give me an exact answer.

So, I played a little bit with the code and I noticed that the problem occurs when:
  • One thread tries to run ExecuteNonQuery.
  • Another thread waits for the opening of the connection.
However, when both connections were already opened then the exception wasn't thrown.

At this point it is worth reminding one thing - when there are 2 or more connections opened in a transaction scope at the same time then a transaction is promoted to a distributed one. I'm not 100% sure but I think that the problem occurs because it is not allowed to use a connection which participates in a transaction which is in the middle of promotion to the distributed one. So, the solution is to assure that a transaction will be distributed from the beginning. Here is a fixed code with a magic line (I found it here):

using (var t = new TransactionScope())
{
   //The magic line that makes a transaction distributed
   TransactionInterop.GetTransmitterPropagationToken(Transaction.Current);

   var t1 = Task.Factory.StartNew(UpdateDatabase);
   var t2 = Task.Factory.StartNew(UpdateDatabase);
   Task.WaitAll(t1, t2);
   t.Complete();
}
Nonetheless, the more I think about this the more convinced I'm that using TransactionScope with multi-threading is asking for problems.

14/04/2015

What I've learned about .NET from security recommendations for C/C++ applications

Home

Some time ago I had an occasion to read about security tips and tricks for C/C++. I don't use C/C++ in my day to day work however it was interesting. I also started looking for information if these recommendations apply to .NET and thanks to that I learned a few new things.

ASLR

ASLR (Address Space Layout Randomization) is a security feature introduced in Windows Vista (it is also common in other operating systems) that causes that locations of executables/libraries/stack/heap in the memory are selected randomly. For example it minimizes a chance to perform a successful buffer-overflow attack.

ASLR is not turned on for all programs but only for these that are ASLR-compatible. It is controlled by a linker option /DYNAMICBASE besides it can be enabled/disabled by editbin tool. By default this flag is set to ON in Visual Studio.

The good information is that ASLR has been supported by ngen since .NET 3.5 SP1.

VirtualAlloc vs HeapAlloc

Another recommendation says that in order to allocate memory VirtualAlloc method should be used instead of HeapAlloc because the later can bypass ASLR (for details see also this article).

I asked a question on Stack Overflow how it is implemented in .NET and the answer is that .NET uses VirtualAlloc. However, my understanding is that we shouldn't be worried because CLR effectively provides its own ASLR.

DEP

DEP (Data Execution Prevention) is another security feature that doesn't allow one to execute areas of memory that are marked as not-executable. i.e. they contain data and not code. Similarly to ASLR there is a linker flag /NXCOMPACT that enable/disable this feature and it has been used in .NET framework since .NET 2.0 SP1.

It is also worth mentioning that in practise NXCOMPACT affects only 32 bit processes. 64bit process always use DEP and it is not possible to disable it (see also this article or this article). As to 32bit processes, I heard the recommendation to explicitly call SetProcessDEPPolicy function at the beginning of 32bit program (also in .NET) to assure that DEP will be used.

EncodePointer and Decode Pointer

Everybody knows what are events and delegates in .NET and we use them everyday. The equivalent of delegates in C/C++ are function pointers. I was really surprised when I read that it is not recommended to use them directly, for example as callbacks.

Instead, they should obfuscated and de-obfuscated when needed by using EncodePointer/DecodePointer functions. It is a concept somehow similar to ASRL. The goal of this technique is to make it difficult to predict a pointer value and override it so that it will point some malicious code.

I couldn't find information if .NET uses these functions internally so I asked a question on Stack Overflow. The answer is that probably .NET doesn't use them..

Safe Structured Exception Handling

Simplifying, structured exceptions are exceptions on the operating system level. Every structured exception has a handler that is executed when the exception occurs. It is important that it is potentially possible to override an address of this handler and perform an attack.

Safe SEH is a security mechanism that doesn't allow one to do so by providing a table of possible handlers. It is controlled via /SAFESEH linker flag but again it does matter only for 32 bit processes.

It seems to me that .NET doesn't use this flag because I found this flag disabled in the make file of Core CLR. However, one of guys who answered my question on Stack Overflow says that .NET uses a table lookup for exception handlers, not pointers on the stack, what gives the same result as SAFESEH.