Skip to main content
Engineering LibreTexts

15.1: Understanding a Stack Buffer Overflow

  • Page ID
    19953
  • \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \) \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)\(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\) \(\newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\) \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\) \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\) \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\) \( \newcommand{\Span}{\mathrm{span}}\)\(\newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    When a program calls a function, the standard calling convention provides the guidance for how the parameters are passed, how the return address is saved, how and which registers must be preserved, and how stack-based local variables are to be allocated.

    For example, consider the function call;

           expFunc(arg1, arg2, arg3);
    

    In addition, we will assume that the function, expFunc(), reads in a line of text from the user and stores it in a locally declared array. The local variables include the array of 48 bytes and one quadword local variable (8 bytes). This can be accomplished easily in a high-level language or as is done in Chapter 13, System Services, Console Input.

    The resulting call frame would be as follows:

    截屏2021-07-31 下午9.42.16.png

    When the function completes, all elements of the call frame are removed. The preserved registers are restored to their original contents, the local variables are removed, and the return address is copied off the stack and placed in the rip register which effects a jump back to the original calling routine. As noted in Chapter 12, Functions, this layout supports multiple levels of function calls including recursion.

    The example in Chapter 13 that reads characters from the user and entered them into an array explicitly checked the character count to ensure that the count does not exceed the buffer size. It would be easy to forget to perform this important check. Indeed, some C functions such as strcpy() do not perform verification of sizes and are thus considered unsafe(For more information, refer to: http://en.Wikipedia.org/wiki/C_stand...ulnerabilities) or described as an unsafe function.

    In this example, over-writing the 48 character buffer will destroy the contents of the stack that contains the original values for the rbp register and possibly the rip register. If the stack content of the original value of the rip register is altered or corrupted in any way, the function will not be able to return to the calling routine and would attempt to jump to some random location. If the random location is outside the program scope, which is likely, the program will generate a segment fault (i.e., “seg fault” or program crash).

    Debugging this type of error can be a significant challenge. The error appears at the very end of the function (on the return). The problem is actually in the body of the function and in fact may be due to code that is not included (as opposed to wrong code that is there).

    Testing if a program has this vulnerability would involve typing significantly more characters than expected when prompted. For example, if name is prompted for and 200 characters are entered (possibly by holding down a key), the program crashing would be a sign that such a vulnerability exists. An error message would indicate such a vulnerability does not exist. While straightforward, this type of testing is often not checked thoroughly or even omitted entirely.


    This page titled 15.1: Understanding a Stack Buffer Overflow is shared under a CC BY-NC-SA license and was authored, remixed, and/or curated by Ed Jorgensen.

    • Was this article helpful?