COMMAND
kernel
SYSTEMS AFFECTED
Win NT, 2000
PROBLEM
Daniel Siffredi found following. This is a new bug found in W2K
in all flavors, works with all levels of users. Here is the
proof of concept:
- Open a Cmd Window
- Ping to any host (for example ping 127.0.0.1 or preferred a
host in your LAN), no switch needed. Just ping
- Now press F7 and Enter (try a couple of times quickly...less
than ten , and you can see what a meaning)
- The machine reboots, from nothing a warm reboot.
This is not network related. You can make it happen with a
"dir *.ini /s". Type this in press Enter and immediately press
F7 and Enter several times quickly then press Cntl-C, the dir
will stop due to the break combo, display another 2 "dir *.ini
/s" on the console then freeze for a moment and reboot.
On a Terminal Services enabled server it will crash the system
through a RDP or ICA connection. This can be a real problem with
people running large Terminal Server environments.
Windows XP (Whistler) Professional build 2462 (beta 2) does NOT
have this problem. Terminal Services on Adv. Server + Citrix
Metaframe is also affected.
Funny, a large multiuser system can be brought to its knees from
userland.
Bronek Kozicki used kernel debugger running on serial port to get
more details from both. Apparently there's unhandled exception
in csrss.exe process space (it's Win32 SubSystem - wise book says
that a lot of Win32 job is actually done by Executive). You may
find more details in attached Windbg log files: csrss_halt-1.txt
was recorded when smaller system crashed (one with 128MB RAM)
csrss_halt-2.txt was recorded when bigger system crashed (one
with 512MB RAM). In this file Bronek allowed system to continue
running after exception was handled by system dubugger (command
tcb), so at the end of file you will find BSOD itself. It looks
like:
*** Fatal System Error: 0xc000021a
(0xE2682B68,0xC0000005,0x5FFB4484,0x00B5FA38)
STOP: c000021a {Fatal System Error}
The Windows SubSystem system process terminated unexpectedly
with a status of 0xc0000005 (0x5ffb4484 0x00b5fa38).
The system has been shut down.
The reason of the system rebooting or halting is because
csrss.exe (the process implementing the win32 subsystem) produces
and unhandled exception and dies. The OS is unable to continue
its normal operation without this fundamental process and it
KeBugChecks and dies.
In csrss.exe, CSRSRV.DLL!CsrUnhandledExceptionFilter gets called.
This function calls NTDLL!NtRaiseHardError with an error code of
0xC000021A (STATUS_SYSTEM_PROCESS_TERMINATED, that is, csrss.exe
is death), and all ends up in KeBugCheckEx when the system
reboots/halts.
Who implements the history window that it shows when you press
F7? Well, it isn't implemented by cmd.exe itself, it is
implemented inside csrss.exe, specifically, in winsrv.dll. Here
lays the implementation for all the F-X functions (F1,F2,F3, etc)
that cmd.exe provides to the user. The window itself is drawn by
code inside winsrv.dll, what makes us think that any console
application can make use of this functionality, but we couldn't
find the win32 api to do it.
Because of this, this might not be a cmd.exe bug alone, but
something that could affect other applications as well.
SOLUTION
Hernan Ochoa developed a temporary patch to solve the problem.
The patch directly eliminates the functionality of all F-Keys
inside cmd.exe (and all applications that use the history window
functionality, etc.). So, you can continue to use cmd.exe, but
pressing F7 inside it will have no effect at all, pressing F2
will have no effect at all either, it's possible to easily make
a patch that only eliminates F7, but, oh well...
At WINSRV.DLL!5FFBD881 there's a function that contains inside a
big switch() statement and implements the functionality of the
F-Keys. Near the beggining of the function you have the following
code:
.text:5FFBD891 cmp di, 76h
.text:5FFBD895 mov [ebp+var_4], esi
.text:5FFBD898 mov [ebp+var_8], esi
.text:5FFBD89B jz loc_5FFCFEDF
Here the code is making some comparison against a parameter that
gets passed to it (the value 76h). You can change the
.text:5FFBD89B jz loc_5FFCFEDF
for a
jmp 5FFBDC42
that actually jumps to the end of the function, and returns
without performing any action.
This is the function that actually decides which window to
display (history window, copy window, etc) based on the F-Key you
pressed, so following the code a little, very little more, will
allow to make a patch that only prevents the use of F7, instead
of eliminating the functionality of all the F-keys.
Another solution is to add the following registry key to every
user (go to HKEY_USERS and add it for every SID):
Software\Policies\Microsoft\Windows\System
there, create a DWORD value named DisableCMD, and set the value
to 1. This will prevent your users to execute cmd.exe.
The correct patch would be the winsrv.dll patch described above.
Remember this is a quick hack while waiting for the proper patch
by Microsoft.