Buffer Overflows

No, I’m not talking about the kind of buffer overflows that viruses can take advantage of to inject malicious code onto other systems, I’m talking about the kind that, if you use Filemon or Regmon, you’ve probably seen in their traces. If you’ve never noticed one, fire up one of those two tools and after collecting a log of system-wide activity, find an example by searching for “buffer overflow”. Here’s an example of file system buffer overflow errors:

Do these errors indicate a problem? No, they are a standard way for the system to indicate that there’s more information available than can fit into a requester’s output buffer. In other words, the system is telling the caller that if it was to copy all the data requested, it would overflow the buffer. Thus, the error really means that a buffer overflow was avoided, not that one occurred.

Given that a buffer overflow means that a requester didn’t receive all the data that they asked for you’d expect programmers to avoid them, or when they can’t, to follow with another request specifying a buffer large enough for the data. However, in the Filemon trace neither case applies. Instead, there are two different requests in a row, each resulting in buffer overflow errors. In the first request the Csrss.exe process, which is the Windows environment subsystem process, queries information about a file system volume and in the second request it queries information about a particular file. It doesn’t follow up with successful requests, but continues with other activity.

The answer to why Csrss.exe doesn’t care that its requests result in errors lies in the type of requests it’s making. A program that queries volume information using Windows APIs is underneath using the NtQueryVolumeInformationFile API that’s exported by Ntdll.dll, the Native API export DLL (you can read more about the Native API here). There are several different classes of information that a program can query. The one that Csrss is asking for in the trace is FileFsVolumeInformation. The Windows Installable File System (IFS) Kit documents that for that class a caller should expect output data to be formatted as a FILE_FS_VOLUME_INFORMATION structure, which looks like this:

typedef struct _FILE_FS_VOLUME_INFORMATION {
LARGE_INTEGER VolumeCreationTime;
ULONG VolumeSerialNumber;
ULONG VolumeLabelLength;
BOOLEAN SupportsObjects;
WCHAR VolumeLabel[1];
} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;

Notice that the first four fields in the structure have a fixed length while the last field, VolumeLabel, has a size that depends on the length of the volume’s label string.

When a file system driver gets this type of query it fills in as much information as fits in the caller’s buffer and, if the buffer is too small to hold the entire structure, returns a buffer overflow error and the size of the buffer required to hold all the data. I suspect that Csrss is really only interested in the volume creation time and therefore passing in a buffer only large enough to hold the first part of the structure. The file system driver fills that part in, and because the volume label won’t fit in Csrss’s buffer, returns an error. However, Csrss has gotten the information it wanted and ignores the error.

The second buffer overflow has a similar explaination. Csrss is querying information about a file using the FileAllInformation class of NtQueryInformationFile. The IFS Kit documents the output structure as:

typedef struct _FILE_ALL_INFORMATION {
FILE_BASIC_INFORMATION BasicInformation;
FILE_STANDARD_INFORMATION StandardInformation;
FILE_INTERNAL_INFORMATION InternalInformation;
FILE_EA_INFORMATION EaInformation;
FILE_ACCESS_INFORMATION AccessInformation;
FILE_POSITION_INFORMATION PositionInformation;
FILE_MODE_INFORMATION ModeInformation;
FILE_ALIGNMENT_INFORMATION AlignmentInformation;
FILE_NAME_INFORMATION NameInformation;
} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION;

Again, the only variable length field is the last one, which stores the name of the file being queried. If Csrss doesn’t care about the name, only the information preceding it in the structure, it can pass a buffer only large enough to hold those fields and ignore the buffer overflow error.

Incidentally, a stack trace of the second buffer overflow reveals this:

What is the "sxs" module? A look at the sxs DLL in Process Explorer’s DLL View of the Csrss process shows this:

SxS is the “Fusion” DLL, which a little research will show manages the Side-by-Side Assembly storage that allows multiple versions of the same DLLs to exist in harmony on a system. SxS is calling GetFileInformationByHandle, which is a Windows API documented in the Platform SDK. The API takes a file handle as input and returns a buffer formatted as a BY_HANDLE_FILE_INFORMATION structure:

typedef struct _BY_HANDLE_FILE_INFORMATION {
DWORD dwFileAttributes;
FILETIME ftCreationTime;
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
DWORD dwVolumeSerialNumber;
DWORD nFileSizeHigh;
DWORD nFileSizeLow;
DWORD nNumberOfLinks;
DWORD nFileIndexHigh;
DWORD nFileIndexLow;
} BY_HANDLE_FILE_INFORMATION;

All of the information returned in this structure, except for the volume serial number, is also returned in the FILE_ALL_INFORMATION structure. You can therefore probably guess where the call to NtQueryVolumeInformationFile that occurs immediately prior to the NtQueryInformationFile call originates: GetFileInformationByHandle first queries the volume in order to get its serial number.

Our investigation shows that the buffer overflow errors seen in the Filemon trace are errors expected by the GetFileInformationByHandle API, which is simply avoiding the need to allocate buffers large enough to hold information it’s not interested in. The bottom line is that buffer overflow errors in a Filemon trace are not an indication that there's a security problem and are usually not due to bad programming.

Next time I’ll explore buffer overflows in Regmon traces.

Originally by Mark Russinovich on 5/17/2005 5:18:00 PM
Migrated from original Sysinternals.com/Blog


# re: Buffer Overflows

Many people claim Microsoft applications gain an unfair advantage because they use undocumented (in their opinion, secret) functions of Windows. I know using undocumented functions is bad (in general). If you have time, I'd love to see a treatment affirming or refuting the common belief that Microsoft takes advantage of their OS in ways nobody else can, or point me toward any other treatments others have done on this topic.

Thanks for your time!

5/17/2005 7:32:00 PM by John


# re: Buffer Overflows

So, If I've got this straight... The buffer overflow you've just spoken off is that the system is returning too much data to the requesting application. And this is the opposite to the type of buffer overflow that is a security risk were the application sends too much data to the system and the data is somehow given over to another handler. Is that about it?

5/17/2005 9:50:00 PM by rivet


# re: Buffer Overflows

It's different because in this case the application is giving the OS the correct size of the buffer, so it will not write too much data.

In a real security risk overrun, the application will usually assume a buffer size that is large enough, which means if it gets sent back too much data, that data will overflow the buffer and overwrite another part of the application.

This allows somebody to (for example) overwrite the stack to modify the return address of the current operation, and execute some malicious code.

5/18/2005 2:28:00 AM by Wells


# re: Buffer Overflows

Er, the term "buffer overflow" used in this context is utterly wrong. The error is actually "buffer too small", represented by the constant ERROR_MORE_DATA.

5/18/2005 8:09:00 AM by Jacques Troux


# re: Buffer Overflows

John,

Sxs.dll is a system component, much like ntdll/kernel32. There is no conspiracy of Microsoft applications using undocumented APIs.

Plus, as Mark said, GetFileInformationByHandle *is* documented.

5/18/2005 2:05:00 PM by Junfeng


# re: Buffer Overflows

I tried the CPUMon v3.0, but it crashed my CPU and immediate restart my PC. Don't know why?(I used the HP-PC(HP PC DX6120 CPU:P4-3.0GB 256MB RAM 80GB HDD WIN XP PRO 3-1-1 WARRANTY FDD LAN 16X DVD). Thank you!

5/25/2005 7:40:00 PM by Doulos B. Warn


# re: Buffer Overflows

In response to;
Doulos B. Warn said...
7:40 PM, May 25, 2005

CPUmon page here;
https://www.sysinternals.com/ntw2k/freeware/cpumon.shtml

States (in red): "Note that CPUMon does not work on Pentium 4 CPUs."

5/26/2005 11:00:00 PM by rivet


# re: Buffer Overflows

>States (in red): "Note that CPUMon does not work on Pentium 4 CPUs."

Gotta love HyperThreading, eh?

6/3/2005 9:05:00 AM by Revenant