cerror-handlingbuffer-overrun

Buffer overrun and centralized error handling


I am reading Code Complete 2 and I ran across this statement in Error Handling:

Call an error-processing routine/object. Another approach is to centralize error handling in a global error-handling routine or error-handling object. The advantage of this approach is that error-processing responsibility can be centralized, which can make debugging easier. The tradeoff is that the whole program will know about this central capability and will be coupled to it. If you ever want to reuse any of the code from the system in another system, you'll have to drag the error-handling machinery along with the code you reuse.

And later it says:

This approach has an important security implication. If your code has encountered a buffer overrun, it's possible that an attacker has compromised the address of the handler routine or object. Thus, once a buffer overrun has occurred while an application is running, it is no longer safe to use this approach.

But I couldn't really understand the statement above. How can a buffer overrun cause a address compromising?


Solution

  • This is because the address of the error handling function is stored in a region of memory accessible to the application much like a 32 or 64 bit integer, depending on your platform. This will be typically somewhere on the bottom of the stack, but in case of a global error handler, it could be located in a different place, as long the thread knows how to get there.

    In the scenario of a buffer overrun, if this memory is overwritten with the address of a different function, the new function would be called rather than the expected error handling function when an error occurs in the application.

    Note that the details all depend on the framework or operation system used by your program. This tutorial has a good example for Windows:

    http://www.primalsecurity.net/0x3-exploit-tutorial-buffer-overflow-seh-bypass/

    That said, a buffer overrun may render the error handler unsafe without replacing its address. The classical example is that of a text editor that uses a global error handler to save a document to a file before when an iternal error forces the process to crash. An attacker with knowledge of the program may use a buffer overflow to replace the file stream handle with a different resource they control (like a network socket) and intercept the output.