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
<}-: