Nan Xue
Nan Xue

Reputation: 35

Turning off stack protection

I was just wondering, cause I have this C code:

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

int fillBuffer(int argc, char *argv[]) {
  char bufferA[4] = "aaa";
  char bufferB[4] = "bbb";

  if(argc > 1)
    strcpy(bufferB, argv[1]);

  printf("bufferA: %s\n", bufferA);
  printf("bufferB: %s\n", bufferB);

  return 0;
}

int main(int argc, char *argv[]) {
  fillBuffer(argc, argv);
  return 0;
}

and I tried turning off the stack protection by using the: -fno-stack-protector

and when I try to run it by doing: ./program (escape key) 5f, the program outputs to:

bufferA: f

bufferB: fffff

I'm just not sure how bufferA becomes f also. Can anyone explain this to me?

Upvotes: 0

Views: 102

Answers (2)

ScottK
ScottK

Reputation: 1556

Your strcpy call is unsafe, and will corrupt your stack if argv[1] contains more than 3 characters (plus one for the null termination character). Do not hit escape, just space and the 5f and you get the proper output:

scott> a.out 5f
bufferA: aaa
bufferB: 5f

When you hit escape, the shell can add additional characters to the string parameter, and because your strcpy is unsafe (does not check length) it will go beyond the end of your buffer and corrupt your stack. Your buffer is only 4 characters long, so your program will corrupt the stack if a parameter longer than 3 characters is entered.

To fix it, increase your buffer size from 4 to something more reasonable like 60, and use strncpy to ensure that you do not exceed the buffer if the parameter is too long:

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

#define MAX_PARM_LEN  60

int fillBuffer(int argc, char *argv[]) {
  char bufferA[MAX_PARM_LEN] = "aaa";
  char bufferB[MAX_PARM_LEN] = "bbb";

  if(argc > 1)
    strncpy(bufferB, argv[1], MAX_PARM_LEN);

  printf("bufferA: %s\n", bufferA);
  printf("bufferB: %s\n", bufferB);

  return 0;
}

int main(int argc, char *argv[]) {
  fillBuffer(argc, argv);
  return 0;
}

One last point: don't turn off stack protection.

Upvotes: 0

NoirDelire
NoirDelire

Reputation: 59

The local buffer A and B are stored reverse order on your stack. So, on in memory you have 8 bytes starting buffer B then buffer A.

When you strcpy your 5 "f" to buffer B, the first 4 go into buffer B, and the last one with the end string '\0' to buffer A.

Then when you printf your buffers, buffer A contain 1 "f" and the string terminator. That's where it comes from.

Upvotes: 1

Related Questions