SChannel and MS14-066

So, Microsoft rolls out a critical patch to fix a vulnerability in SChannel that could allow remote code execution. That patch also includes four new cipher suites (GCM) for TLS v1.2.

Three days later, the KB article is updated stating that some problems may exist on scenarios where TLS v1.2 is used. What?! Also, some other issues are being reported. The patch could just fix the vulnerability; instead it includes some new stuff that apparently is causing problems and the fix is disabling that new stuff. Way to go!

Edit 1: Disabling the new cipher suites does solve the TLS v1.2 problem for now…

Edit 2: Meanwhile, Microsoft rolled out a secondary package that removes the troublesome cipher suites and can be installed along with the previous update.

Numbers Everyone Should Know

A quick comparison of different data-access times on a distributed system:

  • L1 cache reference – 0.5 ns
  • Branch mispredict – 5 ns
  • L2 cache reference – 7 ns
  • Mutex lock/unlock – 100 ns
  • Main memory reference – 100 ns
  • Compress 1K bytes with Zippy – 10,000 ns
  • Send 2K bytes over 1 Gbps network – 20,000 ns
  • Read 1 MB sequentially from memory – 250,000 ns
  • Round trip within same datacenter – 500,000 ns
  • Disk seek – 10,000,000 ns
  • Read 1 MB sequentially from network – 10,000,000 ns
  • Read 1 MB sequentially from disk – 30,000,000 ns
  • Send packet CA->Netherlands->CA – 150,000,000 ns

Seen on this talk from Jeff Dean (Google).

Task.Run and Task.Factory.StartNew

The Task.Run method was introduced in .NET 4.5 (back in 2012 I think) to simplify the cases where one needs to offload some work to the thread pool. Previously we used TaskFactory.StartNew method which has much more flexibility – and the inherent complexity. If not used correctly, the different parameter combinations could allow strange/bogus behaviors, such as accidentally starting a task on the UI thread.

Even though Task.Run simplifies the general case, from time to time I find myself wondering which is happening under the hood. Using some decompiler we can what Task.Run(Action action) is doing:

public static Task Run(Action action)
{
StackCrawlMark stackCrawlMark = StackCrawlMark.LookForMyCaller;
return Task.InternalStartNew(null, action, null,
default(CancellationToken),
     TaskScheduler.Default,
     TaskCreationOptions.DenyChildAttach,
InternalTaskOptions.None, ref stackCrawlMark);
}

So, it’s using:

  • TaskScheduler.Default – This ensures we’re offloading to the thread pool. One of the problems of not specifying the scheduler when using Task.Factory.StartNew is that it uses TaskScheduler.Current, which might be other than the default. In .NET 4.5 there’s also the TaskCreationOptions.HideScheduler flag, which results in TaskScheduler.Current being TaskScheduler.Default within the created task, even if it runs on a different scheduler
  • TaskCreationOptions.DenyChildAttach – This ensures that tasks created within the current task that specify TaskCreationOptions.AttachToParent won’t actually attach to anything because they won’t “see” the current task.

It’s worth pointing that the Task.Run call above is equivalent to:

Task.Factory.StartNew(action, CancellationToken.None, TaskCreationOptions.DenyChildAttach, TaskScheduler.Default);

Both these arguments make sense as defaults and they are specially important when invoking external code. .NET folks actually admit they would make it the default if they could redo .NET 4.

You can find this and other useful information on the pfxteam blog; I really recommend reading it!