2

I am trying to demonstrate buffer overflow in strcmp funcion in C. I have strcpyV.c file:

#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{

    char a[8];
    char b[8];

    // function causes buffer overflow
    strcpy(b, "01234567");

    // buffer overflow again
    strcpy(a, "89abcdef");

    printf("\nb = %s\n", b);

    return 0;
}

I compile this program using gcc compiler.

gcc -o strcpyV strcpyV.c

When I do this in raspberry py B+ (Raspbian wheezy) and run:

./strcpyV

I get expected result:

b = 0123456789abcdef

But when I do this whole process in Ubuntu 16.04 result is:

b = 01234567

Is there any way how to compile code without this memory protection?

tprieboj
  • 1,680
  • 6
  • 31
  • 54

2 Answers2

3

You can disable safety check:

From the manual:

-fstack-protector
      Emit extra code to check for buffer overflows, such as stack smashing attacks.  >This is done by adding a guard variable to functions with
      vulnerable objects.  This includes functions that call alloca, and functions with >buffers larger than 8 bytes.  The guards are initialized when
      a function is entered and then checked when the function exits.  If a guard check >fails, an error message is printed and the program exits.

-fstack-protector-all
      Like -fstack-protector except that all functions are protected.

If you would like to disable this just put no no- to the option name

-fno-stack-protector -fno-stack-protector-all

Buffer overflow example:

int main(){
    int valid = 0;
    char str1 = ["START"];
    char str2 = [8];

    gets(str2);
    if(strncmp(str1, str2, 8) == 0){
        valid = 1;
        cout << "buffer: " << str1 << ", " << str2 << ", " << valid << endl;
    }

}
JoakimE
  • 1,820
  • 1
  • 21
  • 30
2

You could pack the arrays in a struct. Then the rules for struct packing would apply. The struct packing rules are not defined by the standard, but if we use gcc the char arrays will be contiguous in this case (note that b is now placed before a):

#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
    struct ab {
        char b[8];   
        char a[8];
    } s;

    // function causes buffer overflow
    strcpy(s.b, "01234567");

    // I removed this buffer overflow by making the string fit.
    // A second overflow doesn't add anything - quite the opposite.
    // The first overflow is sufficient to get the
    // behaviour you want.
    strcpy(s.a, "89abcde");

    printf("\nb = %s\n", s.b);

    return 0;
}
Klas Lindbäck
  • 33,105
  • 5
  • 57
  • 82
  • 1
    What does that change? It still is undefined behaviour -> anything can happen. And the standard does not guarantee **no** padding is added between the members. – too honest for this site Nov 24 '16 at 17:41
  • @Olaf You are right that the second overflow detracts from the value of the example, so I removed it in my answer. I did point out that I rely on the padding rules used by gcc, but I have clarified that further. – Klas Lindbäck Nov 25 '16 at 08:18
  • Padding rules are not defined by the compiler but tylically the ABI. gcc like any other compiler for a platform has to conformto it. A platform with e.g. 16 byte cache-lines might use 16 byte alignment for members, as that will store them optimally in the cache. Anyway, accessing an array beyond its borders is UB. The compiler can assume you don't and generate appropriate code. For example a 64 bit arch can pass the whole array in a single register; what now, if you access beyond that array?. There is simply no use speculating what can happen or if it works. – too honest for this site Nov 25 '16 at 12:31
  • @Olaf Knowing and recognizing common results of UB is immensely valuble for diagnosing and fixing bugs. If the behaviour changes then the OP will need to rewrite his code to demonstrate (to his students, I presume) a common result of buffer overflow. – Klas Lindbäck Nov 25 '16 at 13:36
  • Sorry, but that is wrong. It is fine to see what happened if you encounter UB. But trying to generate code which shows a **defined** behaviour for **undefined** behaviour is useless. - Unless you want t write malware which is not supported by SO. – too honest for this site Nov 25 '16 at 14:03