segfault on exit...? (Sorry, lots of code...)

Warren, Tony tonyw@prairiesys.com
Thu, 5 Jun 2003 10:04:12 -0500


I apologize for the size of this post - I didn't know if I should
include everything for people to look at, or send it on request...  so I
opted for the quicker solution.  Please let me know if that is improper
protocol...

Well!  I'm SOOO close to finishing this "simple" project, but it has 2
major problems:

1. when the encryption test application calls the library, it
consistently terminates
   with a segmentation fault - WHEN it's exiting...  apparently there's
some double
   referencing of memory between the functions...,  
I've done backtracing with gdb (trying to self-teach) and it seems the
argv value wacks out when returning from the encryption function...

>Breakpoint 3, main (argc=1, argv=0xbffffa24) at pkc1.c:55
>55        rcode = pkEncrypt_buffer (destFN, encryptMe, pKeyFN);
>(gdb) bt
>#0  main (argc=1, argv=0xbffffa24) at pkc1.c:55
>#1  0x4009cb65 in __libc_start_main (main=0x8048a70 <main>, argc=1,
ubp_av=0xbffffa24, 
>    init=0x8048770 <_init>, fini=0x804945c <_fini>,
rtld_fini=0x4000df24 <_dl_fini>, 
>    stack_end=0xbffffa1c) at ../sysdeps/generic/libc-start.c:111
>(gdb) c
>Continuing.
>
>Breakpoint 5, main (argc=538976288, argv=0x20202020) at pkc1.c:56
>56        printf ("\n\npkEncrypt function result:  %d\n\n", rcode);
>(gdb) bt
>#0  main (argc=538976288, argv=0x20202020) at pkc1.c:56
>#1  0x20202020 in ?? ()
>Cannot access memory at address 0x20202020
:
:
>Breakpoint 7, main (argc=538976288, argv=0x20202020) at pkc1.c:66
>66      }       // end main
>(gdb) c
>Continuing.
>
>Program received signal SIGSEGV, Segmentation fault.
>0x20202020 in ?? ()


2. the decryption test app overruns the exit and aborts... 

gdb says the return is also weird, but differently...

>0x8048ad8       52      } // end main
>(gdb) bt
>#0  0x8048ad8 in main (argc=2, argv=0xbffffa14) at pkc2.c:52
>#1  0x4009cb65 in __libc_start_main (main=0x8048a40 <main>, argc=2,
ubp_av=0xbffffa14, 
>    init=0x8048748 <_init>, fini=0x804932c <_fini>,
rtld_fini=0x4000df24 <_dl_fini>, 
>    stack_end=0xbffffa0c) at ../sysdeps/generic/libc-start.c:111
>(gdb) nexti
>0x8048ad9 in main (argc=134515264, argv=0x2) at pkc2.c:52
>52      } // end main
>(gdb) bt
>#0  0x8048ad9 in main (argc=134515264, argv=0x2) at pkc2.c:52
>(gdb) nexti
>0x4009cb65 in __libc_start_main (main=0x8048a40 <main>, argc=2,
ubp_av=0xbffffa14, 
>    init=0x8048748 <_init>, fini=0x804932c <_fini>,
rtld_fini=0x4000df24 <_dl_fini>, 
>    stack_end=0xbffffa0c) at ../sysdeps/generic/libc-start.c:111
>111     ../sysdeps/generic/libc-start.c: No such file or directory.
>(gdb) bt
>#0  0x4009cb65 in __libc_start_main (main=0x8048a40 <main>, argc=2,
ubp_av=0xbffffa14, 
>    init=0x8048748 <_init>, fini=0x804932c <_fini>,
rtld_fini=0x4000df24 <_dl_fini>, 
>    stack_end=0xbffffa0c) at ../sysdeps/generic/libc-start.c:111
>(gdb) nexti
>0x4009cb68      111     in ../sysdeps/generic/libc-start.c
>(gdb) bt
>#0  0x4009cb68 in __libc_start_main (main=0x8048a40 <main>, argc=2,
ubp_av=0xbffffa14, 
>    init=0x8048748 <_init>, fini=0x804932c <_fini>,
rtld_fini=0x4000df24 <_dl_fini>, 
>    stack_end=0xbffffa0c) at ../sysdeps/generic/libc-start.c:111
>(gdb) nexti
>0x4009cb69      111     in ../sysdeps/generic/libc-start.c
>(gdb) bt
>#0  0x4009cb69 in __libc_start_main (main=0x8048a40 <main>, argc=2,
ubp_av=0xbffffa14, 
>    init=0x8048748 <_init>, fini=0x804932c <_fini>,
rtld_fini=0x4000df24 <_dl_fini>, 
>    stack_end=0xbffffa0c) at ../sysdeps/generic/libc-start.c:111
>(gdb) nexti
>
>Program received signal SIGABRT, Aborted.
>0x400ad4e1 in __kill () from /lib/libc.so.6
>(gdb) bt
>#0  0x400ad4e1 in __kill () from /lib/libc.so.6
>#1  0x400ad2ba in raise (sig=6) at ../sysdeps/posix/raise.c:27
>#2  0x400aea82 in abort () at ../sysdeps/generic/abort.c:88
>#3  0x401aa9a5 in __deregister_frame_info_bases () at unwind-pe.h:211
>#4  0x80489b6 in __do_global_dtors_aux ()
>#5  0x8049345 in _fini ()
>#6  0x400aff56 in exit (status=0) at exit.c:57
>#7  0x4009cb6e in __libc_start_main (main=0x8048a40 <main>, argc=2,
ubp_av=0xbffffa14, 
>    init=0x8048748 <_init>, fini=0x804932c <_fini>,
rtld_fini=0x4000df24 <_dl_fini>, 
>    stack_end=0xbffffa0c) at ../sysdeps/generic/libc-start.c:111

I've appreciated all the help you have given so far... It's really made
a big difference.  Thank you in advance for any insight you can lend to
these issues as well.


I'm running libgcrypt 1.1.12
Red Hat Linux release 7.0 (Guinness)
Kernel 2.2.16-22 on an i686

encryption app code follows:
************************************************************************
**
#include <stdio.h>
#include "pkcrypt.h"

int main (int argc, char *argv[]){
  char encryptMe[] = "fedcba9876543210";
  char *destFN;
  char path[256];
  char *FN = "encrData";
  char *pKeyFN = "/usr2/ps/data/xdev/F/0/publicKey";
  int rcode;
  memset (path, '\0', sizeof(path));

  if (argc>2) strcpy(FN, argv[2]);
  if (argc>3) strcpy(path, argv[3]);
  else strcpy(path, "/usr2/ps/data/cds1/F/0/");

  destFN = strcat(path, FN);

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

  printf ("This is a test app for the pkcrypt.h library.\n\n");
  printf ("Data to be encrypted: '%s'\n\n", encryptMe);

  rcode = pkEncrypt_buffer (destFN, encryptMe, pKeyFN);
  printf ("\n\npkEncrypt function result:  %d\n\n", rcode);
  if (rcode)
  {
    printf ("\n\npkEncrypt failed.  Aborting program...\n\n");
    return rcode;
  }
  printf ("\n\nThanks for encrypting with us...\n");
  printf ("Your encrypted file was saved at:%s\n", destFN);
  return rcode;

}       // end main

decryption app code follows:
************************************************************************
**
#include <stdio.h>
#include "pkcrypt.h"
int main (int argc, char *argv[]) {
  char *decrypted;
  char *sKeyFN = "/usr2/ps/data/xdev/F/0/privateKey";
  int rcode;
  char *destFN = "/usr2/ps/data/cds1/F/0/encrData";

  printf ("This is a test app for the pkcrypt.h library.\n\n");
  printf ("Location of data to be decrypted: '%s'\n\n", destFN);

  rcode = pkDecrypt_file (destFN, decrypted, sKeyFN);
  printf ("\n\npkDecrypt function result:  %d\n\n", rcode);
  if (rcode)  {
    printf ("\n\npkDecrypt failed.  Aborting program...\n\n");
    return rcode;
  }

  printf ("\n\nThe final decrypted value = \'%s\'\n", decrypted);
  return rcode;

} // end main


library code follows:
(I commented out releases, trying to find segfault - no luck)
************************************************************************
**
#include <stdio.h>
#include "/usr/local/include/gcrypt.h"
#include "pkcrypt.h"

int packData (GcrySexp *data, char *encryptVal) {
  GCRY_MPI mData;


  size_t n = 1024;
  int rcode;
  char keyPhrase[] = "value";

  /* padding to avoid 'out of core' error */
  char *encryptMe = "
";
  encryptMe = strcat(encryptVal, encryptMe);

  /*  converts the string 'encryptMe' into an mpi - required initial
step */
  rcode = gcry_mpi_scan (&mData, GCRYMPI_FMT_USG, encryptMe, NULL);
  if (rcode) { // failure
    printf ("\n\nmpi_scan failed. Exiting...\n\n");
    return rcode;
  }

  /*  rolls the mpi 'mData' into Sexp *data */
  rcode = gcry_sexp_build (data, NULL, "(data(flags raw)(value %m))",
mData);
//  gcry_mpi_release (mData);
  if (rcode) { // failure
    printf ("\n\nsexp_build failed. Exiting...\n\n");
    return rcode;
  }
  return rcode;
}

int makeKeyPair (GcrySexp *pKey, GcrySexp *sKey) {
  char secKey[] = "private-key";
  char pubkey[] = "public-key";
  GcrySexp Key, PARMS;
  char saveBuff[1024];
  int rcode, errVal, idx = 0, nbits = 1024;
  const char *pkFileName = "/usr2/ps/data/xdev/F/0/publicKey";
  const char *skFileName = "/usr2/ps/data/xdev/F/0/privateKey";
  FILE *pkFile;
  GcryMPI parmMPI[6];
  size_t keySize, retSize;

  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);


  /* Build parameter Sexp 'PARMS' to describe the type of public key
desired (RSA) */
  rcode = gcry_sexp_build (&PARMS, NULL, "(genkey(rsa(nbits %d)))",
nbits);

  /* Build a public key pair as defined in PARMS */
  rcode = gcry_pk_genkey (&Key, PARMS);
  if (rcode) { // failure
    printf ("genkey failed - exiting...\n\n");
  }

  /* return the portion of the key pair that is only the public key */
  *pKey = gcry_sexp_find_token (Key, pubkey, strlen (pubkey));
  if (*pKey) {

    /******** sprint encrypted sexp back to dataBuff for fwrite..
*********/
    memset(saveBuff, '\0', sizeof(saveBuff));
    retSize = gcry_sexp_sprint(*pKey, GCRYSEXP_FMT_CANON, saveBuff,
sizeof(saveBuff));


    pkFile = fopen(pkFileName, "w");

    if (pkFile == NULL) {
       printf ("ERROR: opening key file [%s]\n", pkFileName);
    } else {
       fwrite (saveBuff, 1, retSize, pkFile);
       fclose (pkFile);
    }
  retSize = gcry_sexp_canon_len((const unsigned char *)saveBuff,
sizeof(saveBuff),
                                &errVal, &rcode);
  rcode = gcry_sexp_sscan(pKey, &errVal, saveBuff, retSize);
  } else return -9;

  /* return the portion of the key pair that is only the secret key */
  *sKey = gcry_sexp_find_token (Key, secKey, strlen (secKey));
  if (!*sKey) return -8;

  /******** sprint encrypted sexp back to dataBuff for fwrite..
*********/
  memset(saveBuff, '\0', sizeof(saveBuff));
  retSize = gcry_sexp_sprint(*sKey, GCRYSEXP_FMT_CANON, saveBuff,
sizeof(saveBuff));

  pkFile = fopen(skFileName, "w");

  if (pkFile == NULL) {
    printf ("ERROR: opening key file [%s]\n", skFileName);
  } else {
    fwrite (saveBuff, 1, retSize, pkFile);
    }
    fclose(pkFile);


//  gcry_sexp_release (PARMS);
//  gcry_sexp_release (Key);
//  gcry_control (GCRYCTL_TERM_SECMEM, 0);

  return rcode;
}

int pkEncrypt (GcrySexp *result, char *encryptMe, GcrySexp pKey) {
  GcrySexp data;
  int rcode;
  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);

  rcode = packData (&data, encryptMe);
  if (rcode) { // packData Failed!!
//    gcry_sexp_release (data);
    return rcode;
  }
  else {
    rcode = gcry_pk_encrypt (result, data, pKey);
    if (rcode) {  // Encryption Failed!!
//      gcry_sexp_release (pKey);
//      gcry_sexp_release (data);
//      gcry_control (GCRYCTL_TERM_SECMEM, 0);
      return rcode;
    }
//  printf("\nEncrypted block as an S-Expression:\n");
//  gcry_sexp_dump(*result);
  }

//  gcry_sexp_release (pKey);
//  gcry_control (GCRYCTL_TERM_SECMEM, 0);
  return rcode;
}

int pkDecrypt (char *decrypted, GcrySexp result, GcrySexp sKey) {
  GcrySexp data2;
  size_t n;
  int rcode;
  const char *tmpString;
  char keyPhrase[] = "value";

  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);

  rcode = gcry_pk_decrypt (&data2, result, sKey);
  if (rcode) { // failure
    printf("decryption with sKey failed!\n");
//    gcry_sexp_release (data2);
    gcry_control (GCRYCTL_TERM_SECMEM, 0);
    return rcode;
  }

  /*  successful decryption!! */
  tmpString = gcry_sexp_nth_data(data2, 0, &n);
  decrypted = strncpy(decrypted, tmpString, 16);
  decrypted[16] = '\0';
//  if (data2) gcry_sexp_release (data2);
//  if (result) gcry_sexp_release (result);
//  if (sKey) gcry_sexp_release (sKey);
//  gcry_control (GCRYCTL_TERM_SECMEM, 0);
  return rcode;
}

int pkEncrypt_buffer (char *destFN, char *dataBuff, char *pKeyFN) {
  GcrySexp pKey, result;
  int rcode;
  char saveBuff[1024];
  size_t retSize, errVal, KEYSIZE = 1024;
  FILE *fp;

  /* pull pKey from *pKeyFN */
  if (!pKeyFN) pKeyFN = "/usr2/ps/data/xdev/F/0/publicKey";
  fp=fopen(pKeyFN,"r");
  memset(saveBuff, '\0', sizeof(saveBuff));
  retSize = fread(saveBuff, 1, KEYSIZE, fp);
  fclose(fp);

  rcode = gcry_sexp_sscan(&pKey, &errVal, saveBuff, retSize);
  rcode = pkEncrypt (&result, dataBuff, pKey);
  if (rcode)
  {
    printf ("\n\npkEncrypt failed.  Aborting program...\n\n");
    return rcode;
  }

  /******** sprint encrypted sexp back to dataBuff for fwrite..
*********/
  memset(saveBuff, '\0', sizeof(saveBuff));
  retSize = gcry_sexp_sprint(result, GCRYSEXP_FMT_CANON, saveBuff,
sizeof(saveBuff));

  fp = fopen(destFN, "w");
  if (fp == NULL) printf ("ERROR: opening save file [%s]\n", destFN);
  else fwrite (saveBuff, 1, retSize, fp);

  fclose(fp);



 
/***********************************************************************
*
  *  Cleaning House - memory-wise...
 
************************************************************************
/
//  if (result) gcry_sexp_release (result);
//  if (pKey) gcry_sexp_release (pKey);
  return rcode;
}

int pkDecrypt_file (char *decryptFN, char *dataBuff, char *sKeyFN) {
  GcrySexp sKey, sourceBlock;
  int rcode;
  char readBuff[1024];
  size_t retSize, errVal, KEYSIZE = 1024;
  FILE *fp;

  /* pull sKey from *sKeyFN */
  if (!sKeyFN) sKeyFN = "/usr2/ps/data/xdev/F/0/privateKey";
  memset(readBuff, '\0', sizeof(readBuff));
  fp=fopen(sKeyFN,"r");
  retSize = fread(readBuff, 1, sizeof(readBuff), fp);
  fclose(fp);

  rcode = gcry_sexp_sscan(&sKey, &errVal, readBuff, retSize);

  /* pull encrypted text from *decryptFN */
  memset(readBuff, '\0', KEYSIZE);
  fp=fopen(decryptFN,"r");
  retSize = fread(readBuff, 1, sizeof(readBuff), fp);
  fclose(fp);

  rcode = gcry_sexp_sscan(&sourceBlock, &errVal, readBuff, retSize);
  rcode = pkDecrypt (dataBuff, sourceBlock, sKey);
  if (rcode) {
    printf ("\n\npkDecrypt failed.  Aborting program...\n\n");
    return rcode;
  }

 
/***********************************************************************
*
  *  Cleaning House - memory-wise...
 
************************************************************************
/
//  if (sourceBlock) gcry_sexp_release (sourceBlock);
//  if (sKey) gcry_sexp_release (sKey);
  return rcode;
}
-- 
Tony 
<}-: