Using curl 7.16.1 and 7.20.0
with openssl 0.9.8l and 0.9.8o
I am getting intermittent crashes.  Apache is setup with a pkcs12 cert
and when this fails it is always early in the process ie: initialization
of the threads.  I'm guessing either curl or ssl has a missing lock but
I'm not sure which and where.  Any assistance is greatly appreciated.
 
The callstack usually looks something like the following or ends up in
the CRYPTO_malloc functions.

#0  0x00007f7ec59c4516 in pbe_cmp ()
   from /lib/libcrypto.so.0.9.8
#1  0x00007f7ec5baab15 in msort_with_tmp (p=<value optimized out>, 
    b=<value optimized out>, n=<value optimized out>) at msort.c:83
#2  0x00007f7ec5baaa08 in msort_with_tmp (p=0xae1000, b=0xae1008, 
    n=<value optimized out>) at msort.c:53
#3  0x00007f7ec5baaa08 in msort_with_tmp (p=0xae1000, b=0xae1008, 
    n=<value optimized out>) at msort.c:53
#4  0x00007f7ec5baaa08 in msort_with_tmp (p=0xae1000, b=0xae1008, 
    n=<value optimized out>) at msort.c:53
#5  0x00007f7ec5baaa08 in msort_with_tmp (p=0xae1000, b=0xae1008, 
    n=<value optimized out>) at msort.c:53
#6  0x00007f7ec5bab09c in *__GI_qsort_r (b=<value optimized out>, 
    n=<value optimized out>, s=8, cmp=0x7f7ec59c4510 <pbe_cmp>, arg=0x0)
    at msort.c:294
#7  0x00007f7ec59b70d7 in sk_sort ()
   from /lib/libcrypto.so.0.9.8
#8  0x00007f7ec59b71d1 in sk_find ()
   from /lib/libcrypto.so.0.9.8
#9  0x00007f7ec59c4461 in EVP_PBE_CipherInit ()
   from /lib/libcrypto.so.0.9.8
#10 0x00007f7ec59fdfb2 in PKCS12_pbe_crypt ()
   from /lib/libcrypto.so.0.9.8
#11 0x00007f7ec59fe123 in PKCS12_item_decrypt_d2i ()
   from /lib/libcrypto.so.0.9.8
#12 0x00007f7ec59feeb1 in PKCS12_parse ()
   from /lib/libcrypto.so.0.9.8
#13 0x00007f7ec5fd683e in cert_stuff ()
   from /lib/libcurl.so.4


This program is failing about 50% for me currently and always fails
before the thread get to the curl_easy_perform

#include <stdio.h>
#include <pthread.h>
#include <curl/curl.h>
 
#include "openssl/crypto.h"

#define NUMT 16
 
static void *pull_one_url(void *url)
{
  CURL *curl;
  int i;
  char buffer[CURL_ERROR_SIZE];
  int num_tries = 10;
  int num_successes = 0;
 
  curl = curl_easy_init();
  curl_easy_setopt(curl, CURLOPT_URL, "https://10.17.11.31";);
  curl_easy_setopt(curl, CURLOPT_VERBOSE, 0);
  curl_easy_setopt(curl, CURLOPT_SSLCERT, "mycert.pfx");
  curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "p12");
  curl_easy_setopt(curl, CURLOPT_KEYPASSWD, "exportpass");
  curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
  curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
  curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
  curl_easy_setopt(curl, CURLOPT_DNS_USE_GLOBAL_CACHE, 0L);
  curl_easy_setopt(curl, CURLOPT_NETRC, CURL_NETRC_IGNORED);
  curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, buffer);

  for( i = 0; i < num_tries; i++ )
  {
      if( curl_easy_perform(curl) == 0 )
          num_successes++;
      else
      {
          fprintf(stderr, "ERROR: %s\n", buffer);
      }
  }
  curl_easy_cleanup(curl);

  printf("DEBUG: %ud :: %i/%i\n", (unsigned long)pthread_self(),
num_successes, num_tries);
 
  return NULL;
}
 
static pthread_mutex_t **locks = NULL;
static int n_locks = 0;

static void
ssl_lock(int mode, int n, const char *file, int line)
{
    if (mode & CRYPTO_LOCK) pthread_mutex_lock(locks[n]);
    else pthread_mutex_unlock(locks[n]);
}
 
static unsigned long
ssl_thread_id(void)
{
    return (unsigned long)pthread_self();
}

int main(int argc, char **argv)
{
    pthread_t tid[NUMT];
    int i;
    int error;
  
  n_locks = CRYPTO_num_locks();
  if (n_locks) {
      locks = (pthread_mutex_t **) malloc(n_locks * sizeof(*locks));
      for (i=0; i < n_locks; i++) {
          locks[i] = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
          if( pthread_mutex_init(locks[i], NULL) )
              exit(1);
      }
        
      CRYPTO_set_locking_callback(ssl_lock);
      CRYPTO_set_id_callback(ssl_thread_id);
  }

  /* Must initialize libcurl before any threads are started */ 
  curl_global_init(CURL_GLOBAL_ALL);

  {
      int cnt = 0;
      for( cnt = 0; cnt < 1; cnt++ )
      {
          for(i=0; i< NUMT; i++) {
              error = pthread_create(&tid[i],
                                     NULL, /* default attributes please
*/ 
                                     pull_one_url,
                                     (void *)NULL);
              if(0 != error)
                  fprintf(stderr, "Couldn't run thread number %d, errno
%d\n", i, error);
              else
                  fprintf(stderr, "Thread %d, started\n", i);
          }
 
          /* now wait for all threads to terminate */ 
          for(i=0; i< NUMT; i++) {
              error = pthread_join(tid[i], NULL);
              fprintf(stderr, "Thread %d terminated\n", i);
          }
      }
  }
 
  return 0;
}




______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to