One of the obscure gems garnered from my current reading of the book Concurrent Programming on Windows (by Joe Duffy) is an insight into the INVALID_HANDLE_VALUE constant.
Background
In Win32 programming, functions that return a HANDLE (such as CreateFile) may return INVALID_HANDLE_VALUE to indicate failure (sometimes). You can check for this return value and call GetLastError to find out why the operation failed.
In .NET functions typically indicate unexpected failure by throwing an exception. The endless dance of “Do something; Did it succeed? If not, why did it fail. Do something else; Did it succeed? …” is replaced by structured exception handling and constructs such as try-catch, which let you defer thinking about error scenarios until you want to, rather than thinking… about errors… at every… step… of… the… way.
So if .NET methods such as File.Open() will throw exceptions rather than returning INVALID_HANDLE_VALUE we have no need to expose INVALID_HANDLE_VALUE in the .NET BCL, right? Not quite.
INVALID_HANDLE_VALUE as an input parameter
In addition to being used as a magic return value indicating failure, INVALID_HANDLE_VALUE also has some magic powers with methods that accept a HANDLE as a parameter. Now, you won’t get any useful behaviour from passing INVALID_HANDLE_VALUE to CloseHandle, however there is a group of functions that let you provide an event handle, do some asynchronous work, and then signal your event to let you know the work has been completed.
Functions such as UnregisterWaitEx and DeleteTimerQueueTimer will cancel any pending registered wait operation or a timer-queue timer, however if a callback has already been triggered this will still run to completion. If you need to clean up any resources used by your callback, to avoid pulling the rug out from under its feet, you must first ensure that your callback is not still executing. To avoid having to manually introduce control synchronisation in your callback, UnregisterWaitEx and DeleteTimerQueueTimer let you provide an event handle which will be signalled when any executing callbacks have returned.
If you don’t want the overhead of allocating another event and then registering a wait on it (in order to perform the clean-up asynchronously, when the event is signalled) you can tell the function to block and wait for any executing collback functions to complete before returning by providing INVALID_HANDLE_VALUE for the wait handle.
The MSDN documentation makes no suggestion that this behaviour is even possible (not even in the previewdocumentation for .NET 4). I’m not sure if this is an oversight or an intentionally unsupported behaviour.
To work around this we can do a little poking around the BCL with Reflector:
WaitHandle, the base class for all events in .NET, has a static readonly IntPtr field called InvalidHandle which is populated with the value of INVALID_HANDLE_VALUE; but
Alas, WaitHandle.InvalidHandle is protected, rather than public! (Why, oh why?)
Conveniently, the internal handle value is initialised by the default constructor of WaitHandle to InvalidHandle; but
Alas, WaitHandle is marked abstract, so we can't instantiate it directly.
Conclusion
So the only way to get at INVALID_HANDLE_VALUE in .NET is to subclass WaitHandle. We don't actually need to do anything in our subclass, mind you:
public class InvalidWaitHandle : WaitHandle { }
So there you have it, pretty convoluted but works like a charm!
Here’s the full version, with documentation and a cached instance:
using System.Threading;
/// <summary>
/// An inert wait handle that can be used to avoid allocating a real event in
/// some situations.
/// </summary>
/// <remarks>
/// <para>
/// An <see cref="InvalidWaitHandle"/> can be provided to methods such as
/// <see cref="RegisteredWaitHandle.Unregister(WaitHandle)"/> and
/// <see cref="Timer.Dispose(WaitHandle)"/>. In this case, the function waits
/// for all callback functions to complete before returning, rather than
/// returning immediately and signalling the provided wait handle
/// asynchronously.
/// </para>
/// <para>
/// Internally, this results in the use of INVALID_HANDLE_VALUE when calling
/// the underlying Win32 functions.
/// </para>
/// <para>
/// For further information, see "Concurrent Programming on Windows" (First
/// Edition, 2009) by Joe Duffy, p. 374, 377.
/// </para>
/// </remarks>
public class InvalidWaitHandle : WaitHandle
{
static InvalidWaitHandle()
{
Instance = new InvalidWaitHandle();
}
/// <summary>
/// Gets a shared instance of <see cref="InvalidWaitHandle"/> which may
/// be re-used.
/// </summary>
/// <remarks>
/// Using this field allows a single <see cref="InvalidWaitHandle"/> to
/// be re-used as opposed to creating a <c>new</c> instance at every call
/// site.
/// </remarks>
/// <value>A shared instance of <see cref="InvalidWaitHandle"/> which may
/// be re-used.</value>
public static InvalidWaitHandle Instance { get; private set; }
}
Eric Lippert takes a short break from his usual barrage of mind-melting in-depth technical articles to provide a short article on genealogy, wherein he explains the simple system for naming cousin-hood and removed-ness in English.
This was all fairly straightforward, until he linked to a mind-melting video of a country singer asserting that he is his own grandfather, complete with an accompanying family tree diagram that updates as the song progresses to help you keep track of the facts:
So I guess the moral of the story is that directed graphs should ideally be kept acyclic if at all possible?
Before we continue the exploration into security vulnerabilities of drive-through restaurants... Eric Lippert has returned from his holiday of pre-recorded posts on mind-bendingC# trivia, and come out with a rather amusing analysis of airport check-in queue strategies, based on analytic queueing theory.
Last time, I set the scene of a restaurant drive-through, with the hopes of illustrating how innocent optimisations can introduce security vulnerabilities if we’re not careful.
We forgot to do our threat modelling! Nobody stopped to ask the question “what are we changing? what does this affect? how could this compromise our security?”
The “null-order”
Let’s consider the “null-order”: An in-store customer reaches the head of the queue, walks up to the counter, and realises that she doesn’t have any money. The order transaction is safely aborted and the customer leaves. There is no need for the restaurant employee to enter the “null-order” in their computer because there is no order to be made, duh! (Note that the customer realised the lack of wallet before placing the order.)
Now lets consider a “null-order” for the drive-through interface: A customer joins the back of the queue and is (often, but not always) in a single-lane one-way traffic system, where the only way out is to drive through the whole system: past the order point, the pay window, and the delivery window. If the drive-through is busy, there will be other cars occupying this space so the driver is stuck — they cannot escape the pipeline.
When they realise they have no money (again, before placing the order) they will place a “null-order”. The employee will not enter the “null-order” into the computer because there is no order being made. Duh! The customer wants to leave the queue at this point but she is stuck, so has to drive to the payment window. She must then execute a “null-payment” and explain to the cashier that no payment is necessary because no order was placed. Duh! No problem. Then the customer drives to the third window, staffed by an employee whose job is to deliver food to the cars as fast as possible, preferably with a smile.
The exploit
So what does all this have to do with security vulnerabilities of concurrent pipeline processing?
Well, one fun example of a non-software exploit is the fast-food drive-through free food scam:
Go to the drive-through of a fast-food restaurant and make sure there is someone behind you in the queue.
Don’t order anything (say you forgot to bring money).
Go to the pay window and say you didn’t order anything.
Proceed to the order pick-up window and collect the food that the car behind you is currently paying for.
Continuing with my previous analogy: Since the order-point employee didn’t enter the “null-order” into the system (duh!) it didn’t get pushed onto the internal order queue. At that point the internal order queue was no longer synchronised with the physical queue of cars. Therefore, the cashier didn’t know she was expecting a “null-payment” from this customer, but this could be explained away by the customer. If the customer doesn’t also explain this at the order-delivery window they will be handed the order placed by the car behind (which is currently being paid for right behind them!)
By introducing this pipeline optimisation, we’ve suddenly introduced the need for the in-sore systems to be able to process a “null-order”, which sounded like a ludicrous idea for the in-store scenario, but is actually essential for keeping the drive-through queue synchronised with the internal order queue.
As I said before, security is a burden that you must carry through any refactoring, optimisations, or other changes; even those that seem unrelated.
The fast-food restaurant’s basic feature is the ability to go in, order some food, pay for it, and receive the order (preferably within a short period of time).
The fast food drive-through
At some point this wasn’t enough. Cars got popular, people were in a rush, and a new interface was dreamt up which could allow this workflow to be executed without having to park your car and enter the restaurant — the drive-through was born.
Presumably the naïve drive-through interface would mimic the user experience of the in-store interface: There are several windows with individual queues, you pick one and join the queue with your car, drive up to the window, place your order, pay, and receive food all at the same window, then leave.
This presents some problems because cars are not as small and agile as humans, so trying to mimic the same layout for cars as humans isn’t going to work very well. (You’d need a massive amount of room to let the car from each window drive off independently.)
Given the amount of room available at a typical restaurant, the drive-through would need to only have a single queue. You would join the back of the queue, eventually reach the window, place and order, pay, and receive food all at the same window.
Optimising throughput at the drive-through
This design is still as secure as the in-store experience, but because there is only one window and one queue it is a lot slower than the in-store experience, where there are multiple restaurant employees serving multiple customer queues concurrently.
So how do we make a multi-stage process at the lone drive-through window more efficient? We introduce parallelism through pipelining (as seen in most processor architectures these days). We split the multi-function order/payment/deliver window up into three separate windows (or a microphone and two windows) and specialise each window to a single task. (Fast-food restaurants are already good at efficiency through task specialisation.)
Now the order window (or microphone) can be ready to take the next order as soon as it is done taking the current one. The payment window can be taking payment for the first order whilst the second order is being dictated. Then the third window can be delivering the order whilst the second window is taking payment for the next order, and the order window (or microphone) is taking yet a third order.
Genius! We’ve improved the efficiency by allowing three customers to be served at once, whilst keeping to the space constraint of only having a single queue of cars at the drive-through.
Can you spot the security hole we’ve opened up with this optimisation?
If it looks like a duck, and quacks like a duck, then it must be a duck!
“In computer programming, duck typing is a style of dynamic typing in which an object's current set of methods and properties determines the valid semantics, rather than its inheritance from a particular class or implementation of a specific interface.” — Wikipedia
With duck-typing an interface implementation is implicit once you have implemented the relevant members. .NET does not currently have any broad support for this, however, with the emergent dynamic language features, I wouldn't be surprised if this were supported natively by the runtime in the near future.
In the mean time, you can synthesise duck-typing via reflection, with a library such as this, which would allow you to do a duck-typed cast like this:
IDoo myDoo = DuckTyping.Cast<IDoo>(myFoo)
Duck Typing Trivia
Interestingly, there is one small place where duck-typing is in use in C# today — the foreach operator. Krzysztof Cwalina states that in order to be enumerable by the foreach operator, a class must:
Provide a public method GetEnumerator that takes no parameters and returns a type that has two members: a) a method MoveMext that takes no parameters and return a Boolean, and b) a property Current with a getter that returns an Object.
Notice that he makes no mention of IEnumerable nor IEnumerator. Although it is common to implement these interfaces when creating an enumerable class, if you were to drop the interfaces but leave the implementation, your class would still be enumerable by foreach. Voila! Duck-typing!
Example Code
But don’t take my word for it. Here’s some demo code to prove it:
public class Program
{
public static void Main()
{
foreach (int i in new DuckEnumerable())
Console.WriteLine(i);
Console.ReadKey();
}
}
public class DuckEnumerable // Not IEnumerable
{
public Duck GetEnumerator()
{
return new Duck();
}
}
public class Duck // Not IEnumerator
{
private int n = 0;
public int Current
{
get { return this.n; }
}
public bool MoveNext()
{
return (this.n++ < 10);
}
}