Search code examples
cgccgdbmemory-alignmentmemory-corruption

Variable data corruption with C GCC on Fedora 17 64 bit


I am creating a temporary buffer and copying a string to the buffer using sprintf. I then call the function analyzeRecordForPGDBOperation passing the buffer as parameter. I Parse the string with strtok using | as delimiter. I see a strange problem the value of codesite is corrupted later on even though its printed correctly in switch case 2. The value of codesite is incorrect when i print in case 3 and case 4.

I tried to see the reson for it in gdb using a watch on the codesite variable, I get the following output but I am not sure why I get this issue.

[root@pe1800xs64 trunk]# uname -r 3.9.10-100.fc17.x86_64

"Output from GDB:"

Old value = "71663138", '\000' New value = "\000\061\066\066\063\061\063\070", '\000'

0x00000038f30939ee in __strcpy_sse2_unaligned () from /lib64/libc.so.6

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

int main() 
{
    char tmp[256];
    sprintf(tmp, "%s", "99|71663138|316DEA40C62D6BA40B3C0AA2FE06C457|1442319758");
    analyzeRecordForPGDBOperation(tmp);
    return 0;
}

void analyzeRecordForPGDBOperation(char *data)
{
    char tempBuff[256] = {'\0',};
    char park[16] = {'\0',};
    char codesite[16] = {'\0',};
    char key[24] = {'\0',};
    char timestamp[16] = {'\0',};
    int caseVal = 0;
    sprintf(tempBuff, "%s", data);
    char *p = strtok(tempBuff,"|");

    for (; p != NULL; p = strtok(NULL, "|"))
    {
        caseVal++;
        switch(caseVal)
        {
            case 1:
                sprintf(park, "%s", p);
                break;
            case 2:
                sprintf(codesite, "%s", p);
                //Value of codesite is printed correctly here
                printf("\nCodesite: %s\n", codesite);
                break;
            case 3:
                sprintf(key, "%s", p);
                //Value of codesite is corrupted
                printf("\nCodesite Case 3: %s\n", codesite);
                break;
            case 4:
                sprintf(timestamp, "%s", p);
                //Value of codesite is corrupted
                printf("\nCodesite case 4: %s\n", codesite);
                break;
            default:
                break;
       }
    }
}

Output:

[root@pe1800xs64 trunk]# ./a.out

analyzeRecordForPGDBOperation

Codesite: 71663138

Codesite Case 3:

Codesite case 4:


Solution

  • If this "316DEA40C62D6BA40B3C0AA2FE06C457" is the value which you need to copy on your case 3, then the destination buffer key is not large enough.

    This triggers undefined behavior and this is why you see strange result in codesite afterwards even though you didn't directly modify that.