STATUS_BUFFER_OVERFLOW really should be named STATUS_BUFFER_OVERFLOW_PREVENTED


One category of dubious security vulnerability that comes into the security response team is people who recently discovered the STATUS_BUFFER_OVERFLOW status code.

Title: Buffer overflow occurs in scenario X

Description: Run a file monitoring tool and perform scenario X. In the log, you will see entries that have the error STATUS_BUFFER_OVERFLOW. This is an easily reproducible buffer overflow bug.

If only the system were so smart that it could detect buffer overflows in this way. But what you’re seeing is not actual a buffer overflow. The status code STATUS_BUFFER_OVERFLOW does not mean that a buffer overflow has occurred; rather, it means that the buffer passed by the application was too small to hold all the requested data. Its name should really be STATUS_BUFFER_OVERFLOW_PREVENTED or STATUS_INSUFFICIENT_BUFFER. Indeed, the corresponding Win32 error code has the less misleading name ERROR_INSUFFICIENT_BUFFER.

Every wannabe security investigator sees this error code in a monitoring tool and says “Jackpot!” And then they send a report to the security response team and brag about it to their friends. “Dude, I found two dozen buffer overflows in just a few minutes. I am so 31337!”

Comments (21)
  1. acd says:

    Its name should really be (…) STATUS_INSUFFICIENT_BUFFER

    Maybe Mark (http://technet.microsoft.com/en-us/sysinternals/bb963890.aspx) can initiate that change?

    Or STATUS_BUFFER_TOO_SMALL, a little shorter (still one character longer as the original).

    There are potential backward compatibility issues, but the people who wrote their own log processors can also modify them?

  2. Blah says:

    "Indeed, the corresponding Win32 error code has the less misleading name ERROR_INSUFFICIENT_BUFFER."

    If this one’s not a Win32 code, what is it? No mention in your entire post.

  3. x says:

    There is a STATUS_BUFFER_TOO_SMALL which has a different meaning

    //

    // MessageId: STATUS_BUFFER_TOO_SMALL

    //

    // MessageText:

    //

    // {Buffer Too Small}

    // The buffer is too small to contain the entry. No information has been written to the buffer.

    //

    #define STATUS_BUFFER_TOO_SMALL          ((NTSTATUS)0xC0000023L)

    //

    // MessageId: STATUS_BUFFER_OVERFLOW

    //

    // MessageText:

    //

    // {Buffer Overflow}

    // The data was too large to fit into the specified buffer.

    //

    #define STATUS_BUFFER_OVERFLOW           ((NTSTATUS)0x80000005L)

    Note that one of these is an error status and the other is a warning.

  4. Ulric says:

    it’s true, if the system could detect buffer overflow, they wouldn’t be a problem :P

  5. John says:

    So what’s the difference between ERROR_INSUFFICIENT_BUFFER ("The data area passed to a system call is too small.") and ERROR_MORE_DATA_AVAILABLE ("More data is available.")?

  6. James says:

    Blah: This is an NTSTATUS code, returned by the NT Native API, which is what a normal file access monitoring application will actually be monitoring. The Win32 functions you’re calling, like OpenFile, are just wrappers around NT kernel functions like NtCreateFile.

    It’s possible to call the native functions directly, but not possible to call the Win32 function without that turning into a call to the corresponding Native function, so the Native function is the one to watch.

  7. Pax says:

    Ah, the power of words…

    Reminds me of the time we wrote an application which output "Error 0" to the log files when things worked.

    We had one customer who raised a bug report on all the errors appearing in the logs.

    This, despite the fact that everything was working fine and we made it clear the log file was for our purposes in post-mortem debugging, not for them to browse for their amusement.

    Our solution: we changed the word "Error" to "Status" in the next release – the customer was satisfied (probably because the were using "grep -i error" to test it).

    Cheers,

    Pax.

  8. Pax says:

    quoth the raven:

    =====

    So what’s the difference between ERROR_INSUFFICIENT_BUFFER ("The data area passed to a system call is too small.") and ERROR_MORE_DATA_AVAILABLE ("More data is available.")?

    =====

    Sounds like #1 leaves your buffer alone, #2 gives you a bit (to fill your buffer) and says there’s more.

    #2 I’ve seen similar in the C I/O calls which deliver a byte stream – #1 is probably used where you’ve asked for a structure to be filled out.

    Cheers,

    Pax.

  9. Adrian Oney says:

    Minor correction of above – "warning" status values are 0x8xxxxxxx, not 0x4xxxxxxx

  10. LarryOsterman says:

    John, ERROR_INSUFFICIENT_BUFFER vs ERROR_MORE_DATA_AVAILABLE is an artifact of the Lan Manager APIs (and applies to some Win32 APIs as well).

    The Lan Manager APIs filled in buffers that contained an array of 1 or more fixed size structures.  Within those fixed size structures, were pointers to variable length strings.  The strings were packed at the buffer at the end of the fixed size structures.  If the buffer supplied wasn’t big enough to fill in the fixed size structures, ERROR_INSUFFICIENT_BUFFER was returned, if there wasn’t enough data for the variable length strings, ERROR_MORE_DATA was returned.

    In many circumstances, it wasn’t necessary to get the variable length strings, so the two cases were different.

    ERROR_MORE_DATA is also used for message mode named pipes (to let the caller know that there is more data available in the message than was read).

  11. AdamT says:

    I remember the first time runninng filemon and seeing lots of buffer overflow messages.

    Although the aim was to find security issues, the sheer number of these overflows was a big enough clue that it didn’t mean what I first thought it might, and that I should read up a little bit more on it before getting too excited.

  12. Adrian Oney says:

    The Windows Kernel’s I/O Manager has two broad techniques to get data back to user mode:

    1. "Direct" I/O, wherein hardware writes directly into the user mode buffer specified by the app

    2. "Buffered" I/O, wherein hardware writes to a kernel mode buffer, and the I/O manager later copies it back to the user mode buffer

    For small buffers, #2 is more efficient.

    A driver returns an "error" status (0xCxxxxxxx) to tell the kernel to copy nothing to user mode.

    A driver returns either a success (0xxxxxxxx) or a "warning" status (0x4xxxxxxx) to indicate there *is* data to copy back.

    Imagine a request that returns in the buffer:

    1. Number of elements (32bit value)

    2. The elements themselves (varying size)

    If you called the driver with a buffer of size zero, the NumberOfElements field couldn’t even be written out. In this case, a driver would return an error (STATUS_BUFFER_TOO_SMALL)

    If you called with just enough room (32bits) to contain the NumberOfElements field, the driver might write a 0 into it and return a warning (STATUS_BUFFER_OVERFLOW)

    In this regard, ERROR_MORE_DATA most closely matches the intended meaning of STATUS_BUFFER_OVERFLOW.

  13. Neil says:

    I remember the behaviour that at the time I found odd when calling one of the WNet APIs using a server from a particular network vendor.

    Calling the API (unfortunately I forget which) with a zero buffer would cause the API to fail indicating that it needed a buffer of at least the size of the fixed structure. Of course this wasn’t enough, and the API had to be called again to determine the buffer size including all of the variable strings.

  14. SRS says:

    Reporting spurious bugs to Microsoft is the only way some of us get respect from our peers.

    Can’t you just humour us? Perhaps send us a slogan T-Shirt: "I am a Microsoft Bug Slayer, First Class. No Really."

  15. Beth says:

    Off topic, but taking a shot in the dark –

    I have a meeting in bldg 10 tomorrow. I can find it on the maps I’ve found and know I can get close by way of the transit center, but HOW to get from there to bldg 10 without doing in my arthritic knee is drivin me crazy.

    Any help would be MOST appreciated :)

  16. Damit says:

    Beth – you may be able to take a shuttle from teh transit center to that building. It’s pretty close :)

  17. Beth says:

    So, would that be the shuttles avail thru MS that I’ve heard about? I had heard that there’s an area at the TC that all you do is tell them what bldg and they drive you to the door

  18. Damit says:

    Yes, that’s it. This is sort of getting off-topic though, so I don’t know if Raymond will ask us to stop.

  19. Beth says:

    Thanks so much..and my apologies to Ray! :)

  20. anonymous says:

    This is a non-issue in so far that STATUS_BUFFER_OVERFLOW is well documented. Heck, for accessing the registry this is actually the preferred way to read data of unkwown size: One call with a NULL buffer and zero length to get STATUS_BUFFER_OVERFLOW and the required size returned, then allocating the buffer and calling it again to get the buffer filled. In the first case, you only expect STATUS_SUCCESS for zero-length data or STATUS_BUFFER_OVERFLOW for non-zero-length, and in the second case only STATUS_SUCCESS – anything else is an error.

  21. Morten says:

    Raymond, for once you are wrong. :-) That message used exactly the right word. It’s a perfect decoy. It can even be ignored auto-magically with a proper autoresponse. Imagine the damage a nincompoop like that could do if he started looking for *real* problems… ;-)

Comments are closed.