It rather involved being on the other side of this airtight hatchway: Denial of service by high CPU usage


We received the following security vulnerability report:

Windows is vulnerable to a denial of service attack that consumes 100% CPU.

  1. Use the following procedure to create a file that is enchanted by magic pixie dust: [...]

  2. Rename the file to TEST.EXE.
  3. Execute as many copies of the program as you have CPU cores.

Observe that CPU usage climbs to 100% and never goes down. This a clear demonstration that Windows is vulnerable to a denial of service attack from magic pixie dust.

The magic pixie dust is a red herring. This vulnerability report is basically saying "If you are allowed to run arbitrary programs, then it is possible to run a program that consumes all the available CPU."

Well, duh.

This is another case of if I can run an arbitrary program, then I can do arbitrary things, also known as MS07-052: Code execution results in code execution. (Or in the lingo of Internet memes, "High CPU is high.")

Now, of course, if the magic pixie dust somehow allows a user to do things like access resources they do not have access to, or to circumvent resource usage quotas, then there would be a serious problem here, and if if the high CPU usage could be triggered remotely, then there is a potential for a denial-of-service attack. But there was nothing of the sort. Here's a much less complicated version of magic pixie dust:

int __cdecl main(int, char **) { for (;;) { } /*NOTREACHED*/ }
Comments (40)
  1. Joshua says:

    The vulnerability is real, but that snippet doesn't exploit it. The real vulnerability is the ability to create sufficient realtime threads to hog all CPU as an unprivileged user. This crashes the machine on the spot as even the write behind disk cache never flushes. Realtime threads should be limited to admin sessions and console sessions (not RDP sessions).

  2. Joshua: They don't even have to be real time threads to do that; I've had AV products swallow so much CPU time just running at normal priority that you end up buttoning the system and rebooting.

    I think Windows has the ability to impose a processor usage quota, although it's per-session so there's still a vector to screw people over.  But then you can't really stop that entirely short of saying "you can't run anything", at which point the system become kind of pointless.

  3. 12BitSlab says:

    Recently, we ran into a situation where some commercial backup software (I won't mention the name), used 100% of the CPU for around 40 minutes each night when it started up.  It was so bad, the NIC dropped packets and there was ZERO disk activity during that time.  Once we tracked it down, we de-installed that software and alerted the vendor.  They didn't seem to care too much.  It turns out they are still using DDE to communicate between their background service and their foreground GUI.

    That problem is NOT a Windows problem — it is 100% a case of really bad application software.

  4. That's a "our codebase is old and we don't want to rewrite the code that's probably been there for nearly 30 years" problem.

    I'm now just going to sit and reminisce about NetDDE and Wonderware InTouch (sometimes I miss doing industrial automation).

  5. Anon says:

    @12BitSlab

    But everything is a Microsoft problem… the "100% Backwards Compatibility" push for the worst development practices imaginable from third-parties means that Microsoft has taken responsibility for maintaining all of the bad software on Windows.

  6. @Joshua: But there's no point protecting realtime priority because it doesn't win anything: you can easily cripple windows by:

    > creating windows in a tight loop till you exhaust all the window handles on the system (note: at this point you can't open any tools to recover the system if they create windows);

    > creating processes in a tight loop till the system collapses under the weight;

    > allocating huge amounts of memory and constantly writing to random locations within it to cause a paging storm.

    But also, there's no security vulnerability here in any real sense.

  7. Hildar says:

    Allowing a user with the right to execute code results in code execution. What a security risk!

    What next, a user who can log in can log in? A local administrator can delete system32? (Actually bypassing the restrictions windows places on things in %windir% is left as an exercise for the reader. Don't try this at home^W on production kids)

  8. Joshua says:

    @carbon twelve: Actually creating windows is something I've recovered from. Ctrl+Alt+Del to spawn a new session. Each session has its own window count and handle space. On my production servers I leave windowless logins enabled and if the system can create new processes at all I can get back in and kill the offender.

    I've been able to use my windowless login during a paging storm so bad the console wasn't responding.

  9. JM says:

    All kidding aside, it is of course possible to design the operating system in such a way that no process can cross particular boundaries of resource usage imposed on it. But then you're not really talking about a general desktop OS like Windows, where even measuring resource usage is an imprecise science at best, and which has to host a zoo of independent processes not explicitly designed to play nice.

  10. Mc says:

    Programs can also allocate all the memory on the system fill the page file and cause system failure in that way.   If they are allowed to write files (temp directory?) they can exhaust all the disk space on that drive too.

  11. Matt says:

    The problem isn't that a single program can consume all CPU cycles, its that the scheduler allows it to do that at the expense of every other process and cripple the system.

    (And its an even bigger problem when Microsoft release a process critical to security – Microsoft Update – that causes that exact problem)

  12. Joshua says:

    @Mc:

    Memory Quota.

    Disk Quota.

    CPU Quota would also work for runaway CPU jobs if they weren't using realtime threads.

  13. kantos says:

    I recall a professor of mine once prototyped an attack against servers on the Intel Netburst platform. The attack depended on the hyperthreading feature being enabled, the idea was that the malicious code would cause pipeline stall after pipeline stall completely bringing the machine to a halt. Although in my experience this didn't require a special attack, it just required running code… but that was an architecture problem, not an OS issue.

  14. max630 says:

    this is hardly a security poblem, but it really easy for application to make system's element unresponible. Even such microsoft software as visual studio, while starting, freezes the task panel for some seconds, and it is very annoying

  15. Joker_vD says:

    @Joshua: What default CPU usage quota would look like? People running numerical crunchers (aka "video games") would be quite unhappy to learn they have to manually fiddle with settings to allow them to use 99% of CPU.

  16. Nico says:

    >  if I can run an arbitrary program, then I can do arbitrary things

    Yet this didn't stop Microsoft from killing the Windows Gadget website and removing gadgets from Windows 8, just because "they can run code".  I understand the design was to replace gadgets with Metro apps in Windows 8, but that was no excuse for nuking the entire platform and ecosystem on Windows 7.

    The advisory (technet.microsoft.com/…/2719662) could be entirely replaced with "Malicious program is malicious". :(

  17. alegr1 says:

    Well, the least Windows could do is detect runaway threads and demote their priority. Unfortunately, Microsoft would rather implement another (possibly patented) kludge instead of fixing such problems.

    Window handle space exhaustion can be alleviated by using process-local handles for non-topmost windows.

    [Procses-local handles would mean that EnumChildWindows would return handles that you couldn't use. Also, the limited resource is not handles; it is desktop heap. Restricting handles is just a way to restrict heap usage. -Raymond]
  18. Michael says:

    @aleqr1

    From my experience Windows already automatically demotes process cpu priority of 100% cpu usage processes. But I am not sure if this applies when they have realtime priority.

  19. Anonymous Coward says:

    The problem isn't that a process can consume 100% CPU but that when this happens, Windows starts to handle ctrl-alt-del so badly. Out of the box, the process priorities aren't optimal, for example it would have been better if the taskbar would be running in a different process than the desktop and folder windows and if that process ran at high priority. It would also have been better if a process launched as the task manager got some special magic that normal processes don't have access to that gives the process extra high priority, higher than anything else.

    There is a valid problem being reported here, but you need to be able to read between the lines. Yes, it is nonsensical if you take it as literally as you possibly can and then stop thinking. But if you try to look at this from the user's perspective, you understand that 100% CPU consumption is a very bad thing. And it happens. Programs have bugs that make them hang and do this. The user may not have enough technical knowledge to suggest the right cause or solution, but the problem is very valid.

    [While there may be other issues here, it was reported as a security vulnerability in how Windows treats magic pixie dust. (I also shudder at the thought that some third party taskbar extension is now running at super-high priority. Not that having super-high priority really helps you any, because it will eventually block on something that isn't super-high priority.) -Raymond]
  20. alegr1 says:

    [Procses-local handles would mean that EnumChildWindows would return handles that you couldn't use]

    No. For an out of process caller, that needs to return only global handles.

    [Okay, so you have the other problem, which is that you can't find all the windows. This breaks a lot of apps, including UI automation. Plus, as I noted, the issue is not handle exhaustion anyway. The issue is heap exhaustion. Whether or not you hide child window handles, they still occupy heap. -Raymond]
  21. alegr1 says:

    Task manager runs on High priority, but I think it sets the priority itself. If the box is overloaded by high priority runaway threads, it may not have an opportunity to start.

  22. alegr1 says:

    [Okay, so you have the other problem, which is that you can't find all the windows. This breaks a lot of apps, including UI automation. Plus, as I noted, the issue is not handle exhaustion anyway. -Raymond]

    Most programs don't care about UI automation. For those special cases, the required programs could be run under some new appcompat flags.

    For process-local windows, the desktop heap would not need to be used.

    [But you have to decide ahead of time which heap to put the data in. If you put it in a per-process heap, and then somebody runs an automation app, well, now all your data are in the wrong place. -Raymond]
  23. Joshua says:

    [ The high priority thread must use lock-free everything to avoid blocking on low-priority threads, and you can't do that and present UI at the same time. -Raymond]

    It's called calling CreateDC on another process's window and it's about as bad of an idea as it sounds. I've only ever done it with the desktop window (which does NOT have clipchildren) as a joke. Not for production code if you value your sanity.

  24. Euro Micelli says:

    > @Alegr1: Most programs don't care about UI automation.

    The moment the user needs Assistive Technology (Narrator, JAWS, etc.) every program has to care about UI Automation or it becomes unusable.

  25. cheong00 says:

    Argh… the Gadget toolbar…

    I always want the ability to dock Modern Apps to Gadget toolbar. In that way you can effectively use the screen estate to host the kind of notification you want without using the whole screen.

    I used to hold the CPU gadget at the upper right corner in Vista, then have memopad like application at the remaining of lower-right part of screen, and have the application I'm using tiled to the remaining area on screen.

    Btw, if you're using Win2008 or above with terminal server role and WSRM installed ( blogs.msdn.com/…/using-wsrm-to-control-rds-dynamic-fair-share-scheduling.aspx ), you can prevent non-admin process from eating up CPU resource and therefore preventing Administrator to login.

  26. immibis says:

    It's also a vulnerability if there is some security policy in place that normally prevents people running arbitrary programs, and the magic pixie dust circumvents it.

  27. Anonymous Coward says:

    @The finder didn't seem concerned that apps can consume 100% CPU. They were concerned that pixie dust can consume 100% CPU.

    We don't have access to your ‘finder’, so you can make him say all kinds of crazy stuff I suppose, but so far it sounds like you simply didn't understand him. Pixie dust caused 100% CPU consumption, bad things happened. If it had been something else that caused the 100% CPU consumption you'd be saying that the finder was only concerned with that. Whatever.

    @Since third party taskbar extensions run inside the taskbar, if you try to isolate them into another process, you now have cross-process input queue attachment, which is its own crazy world of hurt.

    Then isolate them in a way that doesn't cause input queue attachment. Stop thinking in terms of problems, but in terms of solutions. Furthermore, people don't tend to run taskbar extensions. A taskbar is just a bunch of buttons and icons, it isn't that hard.

    @Anything with UI cannot be shielded from other UI threads, because there is only one window manager. Also, there's that blah blah blah the same time.

    Nonsense. You say it cannot be done over and over, but it is certainly possible, it just has to be implemented. Microsoft just chose not to, for whatever reason.

  28. Anonymous Coward says:

    @While there may be other issues here, it was reported as a security vulnerability in how Windows treats magic pixie dust.

    I don't doubt that for a second. But if you want to interpret these reports you have to learn to read between the lines. And to stop interpreting things literally when the literal interpretation makes no sense. The people talking to you don't have the same knowledge you do, and you should be aware of that.

    @I also shudder at the thought that some third party taskbar extension is now running at super-high priority.

    That's why I suggested a) to run the taskbar in a different process than where most of the horrible extensions live and b) to give the task manager higher priority than everything else, including the task bar. You could even improve on point a) through sandboxing, but I feel I shouldn't even have to say that.

    @Not that having super-high priority really helps you any, because it will eventually block on something that isn't super-high priority.

    In practice, things that run at a higher priority are shielded quite well from ***-ups in things that run at a lower priority, so your statement that it doesn't help is simply false, as you well know.

    [The finder didn't seem concerned that apps can consume 100% CPU. They were concerned that pixie dust can consume 100% CPU. Since third party taskbar extensions run inside the taskbar, if you try to isolate them into another process, you now have cross-process input queue attachment, which is its own crazy world of hurt. Anything with UI cannot be shielded from other UI threads, because there is only one window manager. Also, there's that cross-process input queue attachment. The high priority thread must use lock-free everything to avoid blocking on low-priority threads, and you can't do that and present UI at the same time. -Raymond]
  29. Brian says:

    Wow!  My security bulletin name made an actual blog entry.  Thanks Raymond!  (Also, MS07… long time reader.)

  30. Scarlet Manuka says:

    @Anonymous Coward:

    After pointing out that we have less access to the original problem submitter than Raymond, why do you claim to be in a better position to interpret the problem submitter's meaning?

    "Isolate them in a way that doesn't cause input queue attachment." Well, if they're not in the same process, you're going to have to have a shared input queue one way or another, or the extensions won't get input at all. So I assume you're calling for them to be in the same process but somehow running at a lower priority. So what are we talking about here, implementing priority on a sub-process level so the extensions can run at a different priority to the host process? How is the end user going to pick out which thread needs to have its priority lowered, never mind the OS re-architecting that would be required? I find it a bit laughable that you exhort Raymond to "stop thinking in terms of problems, but in terms of solutions", and yet you're not proposing solutions, only complaining about problems.

    "People don't tend to run taskbar extensions" – well, clearly they *do*, otherwise it wouldn't be an issue. Furthermore, if there's one thing I've learned from reading this blog, it's that any exposed interface (and a good proportion of things that aren't even exposed) will be abused in horrifying ways by legions of incompetent application developers, and then will become a backwards compatibility constraint for eternity. So if taskbar extensions are possible at all (which they obviously are) it's a dead cert that people are using them, and I'd give decent odds that somewhere there's a company whose core in-house business application would break if the taskbar extension functionality was downgraded in any way.

    Your last two paragraphs are even more incoherent. To me it comes across as if you're saying "LA LA LA I CAN'T HEAR YOU I DON'T CARE IF IT'S PHYSICALLY IMPOSSIBLE YOU SHOULD MAKE IT HAPPEN ANYWAY." (Eliding Raymond's points with "blah blah blah" just makes it appear that you have no good answer for them, so you're hoping that by ignoring them people won't notice.) Or else you're saying that the issue of 100% CPU usage is so vital that the OS should be completely re-architected to make it possible to run taskbar extensions at a lower priority than the taskbar. Either way you don't appear to be in touch with reality.

    [The finder concluded with the recommendation, "Microsoft should make Windows refuse to execute programs that have been enchanted with magic pixie dust." They were totally fixated on the pixie dust. If they were concerned about applications in general being able to consume 100% CPU, then the recommendation would have been "Microsoft should make Windows more resilient to programs that consume 100% CPU." -Raymond]
  31. John Doe says:

    You can support UI automation/assistive tools without global handles, or on the other hand, with windowless controls.  It's not as readily available, but e.g. IE does it, and I suppose Java applications do so too.  In essence, the only handles that have to be "global" are those of top-level windows.

    In this aspect, Mac OS X has a leaky implementation, where although you can't handle windows at such a low-level as in Win32 (at least, it's not documented), you need to enable access for assistive devices system-wide, giving the impression that under the hood, windows are actually global objects.  The situation improved quite a bit in 10.9: support.apple.com/…/HT6026  Now, you tell which applications you allow to control the computer.

    But OMG, the main thread GUI thing…  It's not just the limit on a single thread, it's that the first thread is the only one guaranteed to be able to run a GUI and load certain libraries…

  32. Anonymous Coward says:

    @Scarlet Manuka:

    ‘why do you claim to be in a better position to interpret the problem submitter's meaning?’ Because Raymond's interpretation is obviously false. I don't get the feeling I'm hearing a real person here. Whereas if you assume that the ‘finder’ is technically incompetent and Raymond can't read between the lines, it all makes sense. The fact that the ‘finder’ was fixated on the pixie dust only corroborates that, since it aligns well with my experiences with customers.

    ‘you're not proposing solutions, only complaining about problems’ You cannot be serious. I have proposed many solutions already, some of which would actually help a lot and need no API or kernel changes. Others might, but then again Microsoft can do that.

    ‘…taskbar extensions…’ Suppose some people do. Why would it make sense to not add reliability for everyone who doesn't because some do? And why would it make sense to not shield the taskbar from all shell extensions and software in other processes, because it purportedly cannot be shielded from taskbar extensions, whiach are of limited use anyway?

    ‘I don't care if it's physically impossible’ It is not physically impossible, and claiming that it is, is dishonest. If I right click a taskbar button I want a menu to pop up with a working close button, immediately. There is nothing about computers that makes this impossible. And given that Microsoft can change Windows, they can make this work.

    ‘Eliding Raymond's points with "blah blah blah" just makes it appear’ If you read the bit I elided, you'll see that the bits I cut away were irrelevant objections that wouldn't actually stand in the way of improving the situation.

    ‘you don't appear to be in touch with reality.’ Right. I'm getting the same opinion of you to be frank. I'm sorry if I sound crass, but I feel like I'm talking to a wall. I've made many helpful suggestions and good points and none of them have been addressed in any way, and instead I've been showered with irrelevancies that don't matter.

    And what I understand even less is why you people have to be so unreasonable about it.

  33. Anon says:

    @John Doe

    You *CAN*. You *CAN* also build your own operating system from scratch. These are both GODAWFUL ideas.

    We work with an application that is 30 years old, which is a void when examined with UIAutomation, because the original developers who worked on the project thought "Hey, we CAN just roll our own controls, this 'windows' thing will never last!", and instead rolled their own.

    Every single control in the application is custom – from scrollbars to menu strips. This means that every single common interface has to be implemented – from scratch – in the application, because the alternative is burning it to the ground.

  34. smf says:

    I have wondered whether it would be a good idea to automatically kill processes that are running so hot that they prevent the machine from being usable. Software would soon get fixed so that it behaved better. But I rarely run old software, so for the ancient Enterprise LOB apps you would need a compatibility flag that would did allow software to destabilise your machine.

  35. smf says:

    @Anonymous Coward

    "‘I don't care if it's physically impossible’ It is not physically impossible, and claiming that it is, is dishonest. If I right click a taskbar button I want a menu to pop up with a working close button, immediately. There is nothing about computers that makes this impossible. And given that Microsoft can change Windows, they can make this work."

    If you've read this blog for more than a month then you should be aware that Microsoft can't just change Windows however they want. They might be able to improve it for your case, but due to making compromises that might open up other issues. There is a finite number of people working at Microsoft, they probably have better things to do.

  36. Crescens2k says:

    @Anonymous Coward:

    "Then isolate them in a way that doesn't cause input queue attachment. Stop thinking in terms of problems, but in terms of solutions."

    Is there actually a simple way to do this that exists in Windows already? Input queue attachment is more abstract that AttachThreadInput, with the extension being dependent on the input from the taskbar, it is implicitly attached.

    If you want to get rid of that, what choices do you have? Well, you could poll the input devices or somehow get Windows to forward all input messages to some unrelated hidden window. Polling is of course inefficient since it would have to be done constantly, so it would eat up CPU, and iirc, there is no Win32 function exposed to poll the mouse state. This polling would also have to run at high priority otherwise it would end up missing input if the CPU is under load.

    So then, forwarding messages to a hidden message only window for the extensions to use. So what could go wrong with this? Well, the cross thread attachment also acts as a synchronisation barrier, so now the taskbar is waiting on some synchronisation object for the extension to finish doing its work, instead of the call acting as this barrier.

    Is there any real way to change this? I don't think so, even with exposing new API functions or reusing legacy ones like DirectInput.

    So, unless there is a method that exists that everyone in the world isn't getting, the only two options for the extension to act on user input are for the taskbar to forward events, i.e. input queue attachment, or independently get the input. Both of these have their own problems, especially with the extensions being isolated in some way from the taskbar, and the answers are not easy.

    So while you may write "Stop thinking in terms of problems, but in terms of solutions.", isn't it important to know what problem you are trying to solve before you design a solution for it?

    [If you detach the input queues, then you create a whole bunch of new problems. Also, many shell extensions "know" that they are in the main Explorer process and run around doing crazy things (like subclassing other windows). -Raymond]
  37. ariel says:

    @Crescens2k

    If you really wanted a reliably fast taskbar, you could certainly do it Qubes-style – the taskbar and extension communicate (asynchronously) via a pipe (+ maybe shared memory for fast image transfer). Qubes even does it in an X11-compatible way (I'm from the Linux world so I don't know if you can do it Win32-compatibly).

  38. Crescens2k says:

    [If you detach the input queues, then you create a whole bunch of new problems. Also, many shell extensions "know" that they are in the main Explorer process and run around doing crazy things (like subclassing other windows). -Raymond]

    Yeah, I was glossing over that a bit to try and explain that the attachment doesn't have to be as concrete as calling a function. But I probably failed.

  39. SuperSpy says:

    On the topic of Task Manager when the system is heavily loaded, it seems like Task Manager gets launched at normal priority, then after initializing sets itself to high.  But if the system is heavily loaded or the offending task is running above normal, starting off at normal gets Task Manager stuck to the point where it can't ever get far enough to promote it's priority.

    It would be nice if the 'Task Manager' option from winlogon (which is already running at high priority) would just launch Taskmgr.exe at high priority directly.

  40. Killer{R} says:

    About priority – AFAIK its possible to restrict non-admin users from setting too high priority to their processes and threads. Once upon a time SeIncreaseBasePriorityPrivilege was invented for that.

Comments are closed.

Skip to main content