Buffer overflow detected in a program that runs flawlessly ( apparently)

buffer, c, overflow

Solution

   int t; char r[3];
   gets(r);

Never ever use `gets` function. In this case if it receives more than `3` characters (including the terminating null character) you get a buffer overflow.

`gets` has been removed in the current Standard (C11) and was deprecated in the previous Standard (C99).

Problem

On a string containing as, bs and cs, we can perform the following operation. We can take any two adjacent different characters and replace them by the third. For example, 'ab' gets reduced to 'c' and so does 'ba' and so on. I wrote this code to perform the following operation on t strings (t<=100) and max length of strings = 100 ``` #include<stdio.h> #include<string.h> #include<stdlib.h> int redlen(char string[100][100], int x) { int g, checker; checker = 1; for(; checker; ) { checker = 0; for(int i = 0;string[x][i]!='\0'; i++) { if((string[x][i]=='a' && string[x][i+1]=='b') || (string[x][i]=='b' && string[x][i+1]=='a')) { string[x][i]='c'; checker = 1; for(g = i+1; string[x][g]!='\0'; g++) { string[x][g]=string[x][g+1]; } i = 0; } else if((string[x][i]=='b' && string[x][i+1]=='c') || (string[x][i]=='c' && string[x][i+1]=='b')) { string[x][i]='a'; checker = 1; for(g = i+1; string[x][g]!='\0'; g++) { string[x][g]=string[x][g+1]; } i = 0; } else if((string[x][i]=='a' && string[x][i+1]=='c') || (string[x][i]=='c' && string[x][i+1]=='a')) { string[x][i]='b'; checker = 1; for(g = i+1; string[x][g]!='\0'; g++) { string[x][g]=string[x][g+1]; } i = 0; } } } return strlen(string[x]); } void main() { int t; char r[3]; gets(r); t = atoi(r); char string[100][100]; int i; for(i = 0; i<t; i++) { gets(string[i]); } int printval; for(i = 0; i<t; i++) { printval = redlen(string, i); printf("%d",printval); printf(" \n"); } } ``` It worked fine on the sample case of the problem and also on the cases I developed on my own. But when I submitted it online, it passed only one of the ten cases, and in the rest, this message popped up. ``` *** buffer overflow detected ***: /run-DkQcMiKXhWz9LjirrRnu/solution terminated ======= Backtrace: ========= /lib/i386-linux-gnu/tls/i686/nosegneg/libc.so.6(__fortify_fail+0x45)[0xb76df045] /lib/i386-linux-gnu/tls/i686/nosegneg/libc.so.6(+0x102e1a)[0xb76dde1a] /lib/i386-linux-gnu/tls/i686/nosegneg/libc.so.6(__gets_chk+0x165)[0xb76ddd85] /run-DkQcMiKXhWz9LjirrRnu/solution[0x8048436] /lib/i386-linux-gnu/tls/i686/nosegneg/libc.so.6(__libc_start_main+0xf3)[0xb75f44d3] /run-DkQcMiKXhWz9LjirrRnu/solution[0x80484e9] ======= Memory map: ======== 08048000-08049000 r-xp 00000000 ca:02 15613970 /run-DkQcMiKXhWz9LjirrRnu/solution 08049000-0804a000 r--p 00000000 ca:02 15613970 /run-DkQcMiKXhWz9LjirrRnu/solution 0804a000-0804b000 rw-p 00001000 ca:02 15613970 /run-DkQcMiKXhWz9LjirrRnu/solution 084e2000-08503000 rw-p 00000000 00:00 0 [heap] b75ba000-b75d6000 r-xp 00000000 ca:01 394527 /lib/i386-linux-gnu/libgcc_s.so.1 b75d6000-b75d7000 r--p 0001b000 ca:01 394527 /lib/i386-linux-gnu/libgcc_s.so.1 b75d7000-b75d8000 rw-p 0001c000 ca:01 394527 /lib/i386-linux-gnu/libgcc_s.so.1 b75d8000-b75db000 rw-p 00000000 00:00 0 b75db000-b777e000 r-xp 00000000 ca:01 394522 /lib/i386-linux- gnu/tls/i686/nosegneg/libc-2.15.so b777e000-b777f000 ---p 001a3000 ca:01 394522 /lib/i386-linux-gnu/tls/i686/nosegneg/libc-2.15.so b777f000-b7781000 r--p 001a3000 ca:01 394522 /lib/i386-linux-gnu/tls/i686/nosegneg/libc-2.15.so b7781000-b7782000 rw-p 001a5000 ca:01 394522 /lib/i386-linux-gnu/tls/i686/nosegneg/libc-2.15.so b7782000-b7789000 rw-p 00000000 00:00 0 b7789000-b778a000 r-xp 00000000 00:00 0 [vdso] b778a000-b77aa000 r-xp 00000000 ca:01 400153 /lib/i386-linux-gnu/ld-2.15.so b77aa000-b77ab000 r--p 0001f000 ca:01 400153 /lib/i386-linux-gnu/ld-2.15.so b77ab000-b77ac000 rw-p 00020000 ca:01 400153 /lib/i386-linux-gnu/ld-2.15.so bfe6e000-bfe8f000 rw-p 00000000 00:00 0 [stack] Aborted (core dumped) ``` It wasn't exactly same in all the cases, but pretty much the same. Please help.

Original source