Why can a program named "C:\Program" influence other programs?

Today out of the blue a file called Program appeared on root of C:\, and when logging in to the system, a popup shows a message:

File Name Warning

There is a file or folder on your computer called "C:\Program" which could cause certain applications to not function correctly. Renaming it to "C:\Program1" would solve the problem. Would you like to rename it now?

While message is self-explaining, I wonder why this file could have such a big influence? Indeed, some of the programs (maybe all, I didn't check) located in C:\Program Files... were not starting at all. I can understand how such file may be created (for example, trying to write to folder C:\Program Files\Something... but without quotes), but I hardly understand how can it impact other programs.


Solution 1:

It has such a big influence because of a long-known weakness in the Win32 API.

Programs are spawned in Win32 via the CreateProcess() system call. It can be used in several ways. People coming from Unix, Linux, or OS/2 backgrounds will usually think of it as taking two separate arguments for the program (image file) to spawn and the command tail to pass to the new process, because filenames and arguments vectors/command tails are two separate things in those operating systems' APIs. But in fact the system call can be invoked in an alternative form with program name and arguments mashed together in one big string. CreateProcess() will try to separate the program filename from the command tail.

The problem is that it does this by progressively splitting the string in twain at each successive space character, until the left-hand portion matches a file or a directory. Many Win32 programs will try to pass strings like C:\Program Files\Contoso\TakeOver.exe StackExchange.com to the system call. This will run the right program — C:\Program Files\Contoso\TakeOver.exe — with the right command tail — StackExchange.com — until the point that some obviously dangerous person comes along and creates a C:\Program file just like you did.

At that point, the system call ends up trying to run the program image file C:\Program with the command tail Files\Contoso\TakeOver.exe StackExchange.com. Heaven help you if C:\Program is in fact an executable program image.

This is a general weakness, and it applies to any program filename containing spaces in combination with any program that uses One Big String to spawn other programs. But the commonest case that is hit by this is all of the programs that live under C:\Program Files\ and a large number of Win32 programs that use the One Big String approach.

It's far too late to change the Win32 API. It was too late a decade ago. And Microsoft cannot change all of the programs written by other people that pass one big string instead of two to CreateProcess(). So Microsoft makes Windows check, at user logon, for the existence of C:\Program and display the warning that you see.

And, as you can see, there's a big "Security" warning in Microsoft's Win32 doco telling developers not to write programs using the One Big String approach, which has been there for some years now.

Further reading

  • CreateProcess() function. MSDN. Microsoft corporation.
  • Raymond Chen (2011-08-08). What does the CreateProcess function do if there is no space between the program name and the arguments?. OldNewThing.
  • Rajorshi (2009-05-13). CreateProcess vulnerabilities. Developer Docs.
  • 2005-11-15. Security Advisory: Multiple Vendor Insecure Call to CreateProcess() Vulnerability. iDEFENSE.