Thread: stack smashing? Studying file processing in C

  1. #1
    Registered User
    Join Date
    Jan 2013
    Posts
    68

    stack smashing? Studying file processing in C

    This code does what it is supposed to do, but at the end of the file, I get an error that I have never encountered before. What exactly is stack smashing? I suspect that the files and the permissions might be the issue. Any help will be appreciated.

    Code:
    /*Write a a program for file matching
    */
    #include<stdio.h>
    #include<stdlib.h>
    
    
    int main(void)
    {
    	int masterAccount; //account from old master file
    	int transactionAccount; //account from transactions file
    	double masterBalance; //balance from old master file
    	double transactionBalance; //balance from transactions file
    	char masterName[30]; //name from master file
    	FILE *ofPtr; //old master file pointer
    	FILE *tfPtr; //transactioin file pointer
    	FILE *nfPtr; //new master file pointer
    
    
    	//terminate application if respective files cannot be opened
    	if((ofPtr = fopen("oldmast.dat", "r")) == NULL)
    	{
    		printf("Unable to open oldmast.dat\n");
    		exit(1);
    	}//end if
    
    
            if((tfPtr = fopen("trans.dat", "r")) == NULL)
            { 
                    printf("Unable to open trans.dat\n");
                    exit(1);
            }//end if
    
    
            if((nfPtr = fopen("newmast.dat", "w")) == NULL)
            { 
                    printf("Unable to open newmast.dat\n");
                    exit(1);
            }//end if
    
    
    	//display account currently being processed
    	printf("Processing....\n");
    	fscanf(tfPtr, "%d%lf", &transactionAccount, &transactionBalance);
    
    
    	//while not end of transactions file
    	while(!feof(tfPtr))
    	{
    		//read next record from old master file
    		fscanf(ofPtr, "%d%[^0-9-]%lf", &masterAccount, masterName, &masterBalance);
    
    
    		//display accounts from master file until number of new account is reached
    		while(masterAccount < transactionAccount && !feof(ofPtr))
    		{
    			fprintf(nfPtr, "%d %s %lf\n", masterAccount, masterName, masterBalance);
    			printf("%d %s %lf\n", masterAccount, masterName, masterBalance);
    
    
    			//read next record from old master file
    			fscanf(ofPtr, "%d%[^0-9-]%lf\n", &masterAccount, masterName, &masterBalance);
    		}//end while
    
    
    		//if matching account found, update balance and output account information
    		if ( masterAccount == transactionAccount ) 
    		{
    		  masterBalance += transactionBalance;
    		  fprintf( nfPtr, "%d %s %lf\n", masterAccount, masterName, masterBalance );
    		  printf( "%d %s %lf\n", masterAccount, masterName, masterBalance );  
    		} /* end if */
    	
    		//tell user if account from transactions file does not match account from master file
    		else if (masterAccount > transactionAccount)
    		{
    			printf("Unmatched transaction record for account %d\n", transactionAccount);
    			fprintf(nfPtr, "%d %s %lf\n", masterAccount, masterName, masterBalance);
    			printf("%d %s %lf\n", masterAccount, masterName, masterBalance);
    		}//end else if 
    		else
    		{
    			printf("Unmatched transaction record for account %d\n", transactionAccount);
    		}//end else
    
    
    		//get next account and balance from transactions file
    		fscanf(tfPtr, "%d%lf", &transactionAccount, &transactionBalance);
    	}//end while
    
    
    	//loop through file and display account information
    	while(!feof(ofPtr))
    	{
    		fscanf(ofPtr, "%d%[^0-9-]%lf", &masterAccount, masterName, &masterBalance);
    		fprintf(nfPtr, "%d %s %lf", masterAccount, masterName, masterBalance);
    		printf("%d %s %lf", masterAccount, masterName, masterBalance);
    	}//end while
    
    
    	//close all file pointers
    	fclose(ofPtr);
    	fclose(tfPtr);
    	fclose(nfPtr);
    
    
    	return 0;
    }//end main
    output
    Code:
    Processing....100   Hank Hill   369.120000
    300   Dale Gribble   185.560000
    Unmatched transaction record for account 400
    500   Bill Dauterive   234.560000
    700   Jefferey D. Boomhauer   567.890000
    900   Beauregard "Buck" Strickland   -1152.390000
    Unmatched transaction record for account 1000
    *** stack smashing detected ***: ./filematching terminated
    ======= Backtrace: =========
    /lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0xb76680e5]
    /lib/i386-linux-gnu/libc.so.6(+0x10409a)[0xb766809a]
    ./filematching[0x804897c]
    /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb757d4d3]
    ./filematching[0x8048521]
    ======= Memory map: ========
    08048000-08049000 r-xp 00000000 08:01 29886554   /home/amenomurakumo/C/CTraining/filematching
    08049000-0804a000 r--p 00000000 08:01 29886554   /home/amenomurakumo/C/CTraining/filematching
    0804a000-0804b000 rw-p 00001000 08:01 29886554   /home/amenomurakumo/C/CTraining/filematching
    08110000-08131000 rw-p 00000000 00:00 0          [heap]
    b752d000-b7549000 r-xp 00000000 08:01 3407916    /lib/i386-linux-gnu/libgcc_s.so.1
    b7549000-b754a000 r--p 0001b000 08:01 3407916    /lib/i386-linux-gnu/libgcc_s.so.1
    b754a000-b754b000 rw-p 0001c000 08:01 3407916    /lib/i386-linux-gnu/libgcc_s.so.1
    b7563000-b7564000 rw-p 00000000 00:00 0 
    b7564000-b7707000 r-xp 00000000 08:01 3411530    /lib/i386-linux-gnu/libc-2.15.so
    b7707000-b7709000 r--p 001a3000 08:01 3411530    /lib/i386-linux-gnu/libc-2.15.so
    b7709000-b770a000 rw-p 001a5000 08:01 3411530    /lib/i386-linux-gnu/libc-2.15.so
    b770a000-b770d000 rw-p 00000000 00:00 0 
    b7723000-b7727000 rw-p 00000000 00:00 0 
    b7727000-b7728000 r-xp 00000000 00:00 0          [vdso]
    b7728000-b7748000 r-xp 00000000 08:01 3411542    /lib/i386-linux-gnu/ld-2.15.so
    b7748000-b7749000 r--p 0001f000 08:01 3411542    /lib/i386-linux-gnu/ld-2.15.so
    b7749000-b774a000 rw-p 00020000 08:01 3411542    /lib/i386-linux-gnu/ld-2.15.so
    bfc3b000-bfc5c000 rw-p 00000000 00:00 0          [stack]
    Aborted (core dumped)

  2. #2
    Registered User HelpfulPerson's Avatar
    Join Date
    Jun 2013
    Location
    Over the rainbow
    Posts
    288
    Quote Originally Posted by jwall View Post
    This code does what it is supposed to do, but at the end of the file, I get an error that I have never encountered before. What exactly is stack smashing? I suspect that the files and the permissions might be the issue. Any help will be appreciated.

    Code:
    /*Write a a program for file matching
    */
    #include<stdio.h>
    #include<stdlib.h>
    
    
    int main(void)
    {
        int masterAccount; //account from old master file
        int transactionAccount; //account from transactions file
        double masterBalance; //balance from old master file
        double transactionBalance; //balance from transactions file
        char masterName[30]; //name from master file
        FILE *ofPtr; //old master file pointer
        FILE *tfPtr; //transactioin file pointer
        FILE *nfPtr; //new master file pointer
    
    
        //terminate application if respective files cannot be opened
        if((ofPtr = fopen("oldmast.dat", "r")) == NULL)
        {
            printf("Unable to open oldmast.dat\n");
            exit(1);
        }//end if
    
    
            if((tfPtr = fopen("trans.dat", "r")) == NULL)
            { 
                    printf("Unable to open trans.dat\n");
                    exit(1);
            }//end if
    
    
            if((nfPtr = fopen("newmast.dat", "w")) == NULL)
            { 
                    printf("Unable to open newmast.dat\n");
                    exit(1);
            }//end if
    
    
        //display account currently being processed
        printf("Processing....\n");
        fscanf(tfPtr, "%d%lf", &transactionAccount, &transactionBalance);
    
    
        //while not end of transactions file
        while(!feof(tfPtr))
        {
            //read next record from old master file
            fscanf(ofPtr, "%d%[^0-9-]%lf", &masterAccount, masterName, &masterBalance);
    
    
            //display accounts from master file until number of new account is reached
            while(masterAccount < transactionAccount && !feof(ofPtr))
            {
                fprintf(nfPtr, "%d %s %lf\n", masterAccount, masterName, masterBalance);
                printf("%d %s %lf\n", masterAccount, masterName, masterBalance);
    
    
                //read next record from old master file
                fscanf(ofPtr, "%d%[^0-9-]%lf\n", &masterAccount, masterName, &masterBalance);
            }//end while
    
    
            //if matching account found, update balance and output account information
            if ( masterAccount == transactionAccount ) 
            {
              masterBalance += transactionBalance;
              fprintf( nfPtr, "%d %s %lf\n", masterAccount, masterName, masterBalance );
              printf( "%d %s %lf\n", masterAccount, masterName, masterBalance );  
            } /* end if */
        
            //tell user if account from transactions file does not match account from master file
            else if (masterAccount > transactionAccount)
            {
                printf("Unmatched transaction record for account %d\n", transactionAccount);
                fprintf(nfPtr, "%d %s %lf\n", masterAccount, masterName, masterBalance);
                printf("%d %s %lf\n", masterAccount, masterName, masterBalance);
            }//end else if 
            else
            {
                printf("Unmatched transaction record for account %d\n", transactionAccount);
            }//end else
    
    
            //get next account and balance from transactions file
            fscanf(tfPtr, "%d%lf", &transactionAccount, &transactionBalance);
        }//end while
    
    
        //loop through file and display account information
        while(!feof(ofPtr))
        {
            fscanf(ofPtr, "%d%[^0-9-]%lf", &masterAccount, masterName, &masterBalance);
            fprintf(nfPtr, "%d %s %lf", masterAccount, masterName, masterBalance);
            printf("%d %s %lf", masterAccount, masterName, masterBalance);
        }//end while
    
    
        //close all file pointers
        fclose(ofPtr);
        fclose(tfPtr);
        fclose(nfPtr);
    
    
        return 0;
    }//end main
    output
    Code:
    Processing....100   Hank Hill   369.120000
    300   Dale Gribble   185.560000
    Unmatched transaction record for account 400
    500   Bill Dauterive   234.560000
    700   Jefferey D. Boomhauer   567.890000
    900   Beauregard "Buck" Strickland   -1152.390000
    Unmatched transaction record for account 1000
    *** stack smashing detected ***: ./filematching terminated
    ======= Backtrace: =========
    /lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x45)[0xb76680e5]
    /lib/i386-linux-gnu/libc.so.6(+0x10409a)[0xb766809a]
    ./filematching[0x804897c]
    /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb757d4d3]
    ./filematching[0x8048521]
    ======= Memory map: ========
    08048000-08049000 r-xp 00000000 08:01 29886554   /home/amenomurakumo/C/CTraining/filematching
    08049000-0804a000 r--p 00000000 08:01 29886554   /home/amenomurakumo/C/CTraining/filematching
    0804a000-0804b000 rw-p 00001000 08:01 29886554   /home/amenomurakumo/C/CTraining/filematching
    08110000-08131000 rw-p 00000000 00:00 0          [heap]
    b752d000-b7549000 r-xp 00000000 08:01 3407916    /lib/i386-linux-gnu/libgcc_s.so.1
    b7549000-b754a000 r--p 0001b000 08:01 3407916    /lib/i386-linux-gnu/libgcc_s.so.1
    b754a000-b754b000 rw-p 0001c000 08:01 3407916    /lib/i386-linux-gnu/libgcc_s.so.1
    b7563000-b7564000 rw-p 00000000 00:00 0 
    b7564000-b7707000 r-xp 00000000 08:01 3411530    /lib/i386-linux-gnu/libc-2.15.so
    b7707000-b7709000 r--p 001a3000 08:01 3411530    /lib/i386-linux-gnu/libc-2.15.so
    b7709000-b770a000 rw-p 001a5000 08:01 3411530    /lib/i386-linux-gnu/libc-2.15.so
    b770a000-b770d000 rw-p 00000000 00:00 0 
    b7723000-b7727000 rw-p 00000000 00:00 0 
    b7727000-b7728000 r-xp 00000000 00:00 0          [vdso]
    b7728000-b7748000 r-xp 00000000 08:01 3411542    /lib/i386-linux-gnu/ld-2.15.so
    b7748000-b7749000 r--p 0001f000 08:01 3411542    /lib/i386-linux-gnu/ld-2.15.so
    b7749000-b774a000 rw-p 00020000 08:01 3411542    /lib/i386-linux-gnu/ld-2.15.so
    bfc3b000-bfc5c000 rw-p 00000000 00:00 0          [stack]
    Aborted (core dumped)
    Personally I've never had that error. I do know that it is usually not suggested you use feof() to loop through a file though. You should use the function's return value to determine that insetad.

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    HelpfulPerson, was it really necessary to quote the entire OP for a three sentence reply???

    OP, don't use feof. FAQ > Why it's bad to use feof() to control a loop - Cprogramming.com

  4. #4
    Registered User HelpfulPerson's Avatar
    Join Date
    Jun 2013
    Location
    Over the rainbow
    Posts
    288
    Quote Originally Posted by rags_to_riches View Post
    HelpfulPerson, was it really necessary to quote the entire OP for a three sentence reply???

    OP, don't use feof. FAQ > Why it's bad to use feof() to control a loop - Cprogramming.com
    It wasn't, it's just a habit.

  5. #5
    Registered User
    Join Date
    Jan 2013
    Posts
    68
    Quote Originally Posted by HelpfulPerson View Post
    It wasn't, it's just a habit.
    Thanks for the help, but how would I implement

    Code:
    fgets(buf, sizeof(buf), fp) != NULL
    in this situation, will it stop the stack smashing error?

    BTW I'm on linux

  6. #6
    Registered User
    Join Date
    Jan 2013
    Posts
    68
    Stack Smashing is actually a protection mechanism used by gcc to detect buffer overflow attacks.
    I got the error because some the input was too big for the array. I should have gotten a segmentation fault.

  7. #7
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Any chance that mastername array is getting overflowed when reading the file (perhaps end of file issue)?

  8. #8
    Registered User
    Join Date
    Jan 2013
    Posts
    68
    rcgldr: That was exactly it--I believe I said that in my previous post . But I would still like to know how to loop through a file without using feof in this program?

  9. #9
    Registered User HelpfulPerson's Avatar
    Join Date
    Jun 2013
    Location
    Over the rainbow
    Posts
    288
    Quote Originally Posted by jwall View Post
    rcgldr: That was exactly it--I believe I said that in my previous post . But I would still like to know how to loop through a file without using feof in this program?
    I use this function when getting a file line in my programs.


    Code:
    char * get_next_file_line( FILE * file )
    {
        char * line = malloc(sizeof(char) * BUFSIZ );
        char * new_line;
    
    
        if ( line == NULL )
        {
            perror("Malloc");
            exit(1);
        }
    
    
        if ( fgets(line, BUFSIZ, file) == NULL )
        {
            free(line);
            return NULL;
        } else
        {
            if ((new_line = strchr(line, '\n')) != NULL ) /* Removes the '\n' and replaces it with a '\0' if it is found */
                *new_line = '\0';
    
    
            return line;
        }
    }
    Then for looping through, I do this

    Code:
    for (; (file_line = get_next_file_line(txt_file)) != NULL; )
    You don't have to use my code, but I learn by example, so I thought this might've been better. Most functions will return something similar to NULL or EOF, but you should probably look at the documentation for each one to be sure.

    Short code summary :

    get_next_file_line() : I dynamically allocated memory to the size of BUFSIZ to prevent bugs caused from invalid memory in pointers and to make sure there should be a decent amount of space for each file line. I test the allocation and then exit if there's a problem. If at EOF or an error has occured, I free the memory I allocated and return to the calling function, if that is not true I replace the newline character ( if any ) with a null terminating character. Then I return the char * line,

    loop : This should be self-explanatory.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Stack Smashing
    By dtow1 in forum Linux Programming
    Replies: 7
    Last Post: 11-18-2012, 08:54 PM
  2. *** stack smashing detected ***
    By Martin_HS in forum C Programming
    Replies: 9
    Last Post: 05-29-2009, 04:01 AM
  3. Smashing The Stack
    By 0624167 in forum Linux Programming
    Replies: 1
    Last Post: 03-03-2009, 02:09 PM
  4. smashing the stack
    By rohit in forum C Programming
    Replies: 3
    Last Post: 10-07-2002, 07:06 AM
  5. smashing the stack
    By rohit in forum Linux Programming
    Replies: 1
    Last Post: 10-07-2002, 02:47 AM