curl / Mailing Lists / curl-library / Single Mail
Buy commercial curl support from WolfSSL. We help you work out your issues, debug your libcurl applications, use the API, port to new platforms, add new features and more. With a team lead by the curl founder himself.

Re: core dump on curl function call

From: Ray Satiro via curl-library <curl-library_at_lists.haxx.se>
Date: Tue, 1 Mar 2022 03:30:16 -0500

On 2/28/2022 1:42 AM, treesa fairy joseph via curl-library wrote:
> Could not come back to this issue, for a while. Right now, back on this problem.
> The below shows the sample program which also generates the seg flt
>
>
>
> /***************************************************************************
> * _ _ ____ _
> * Project ___| | | | _ \| |
> * / __| | | | |_) | |
> * | (__| |_| | _ <| |___
> * \___|\___/|_| \_\_____|
> *
> * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel_at_haxx.se>, et al.
> *
> * This software is licensed as described in the file COPYING, which
> * you should have received as part of this distribution. The terms
> * are also available at https://curl.haxx.se/docs/copyright.html.
> *
> * You may opt to use, copy, modify, merge, publish, distribute and/or sell
> * copies of the Software, and permit persons to whom the Software is
> * furnished to do so, under the terms of the COPYING file.
> *
> * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
> * KIND, either express or implied.
> *
> ***************************************************************************/
> /* <DESC>
> * A multi-threaded example that uses pthreads to fetch several files at once
> * </DESC>
> */
>
> #include <stdio.h>
> #include <pthread.h>
> #include <curl/curl.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <curl/curl.h>
> #include <openssl/x509v3.h>
> #include <openssl/x509_vfy.h>
> #include <openssl/crypto.h>
> #include <openssl/lhash.h>
> #include <openssl/objects.h>
> #include <openssl/err.h>
> #include <openssl/evp.h>
> #include <openssl/x509.h>
> #include <openssl/pkcs12.h>
> #include <openssl/bio.h>
> #include <openssl/ssl.h>
> #include <openssl/ossl_typ.h>
> //#include <crypto/internal/x509_int.h>
> #include <crypto/include/internal/x509_int.h>
>
> #define NUMT 1
> typedef struct MemoryStruct
> {
> unsigned char *memory;
> size_t size;
> } memory_struct_t;
> #define ZERO_NULL 0
>
>
> typedef struct sslctxparm_st {
> unsigned char *p12file;
> const char *pst;
> PKCS12 *p12;
> EVP_PKEY *pkey;
> X509 *usercert;
> STACK_OF(X509) * ca;
> CURL *curl;
> BIO *errorbio;
> int accesstype;
> int verbose;
>
> } sslctxparm;
>
> /*
> List of URLs to fetch.
>
> If you intend to use a SSL-based protocol here you might need to setup TLS
> library mutex callbacks as described here:
>
> https://curl.haxx.se/libcurl/c/threadsafe.html
>
> */
>
> /********************************************************************************
> * Function Name : ipr_cwmp_WriteMemoryCallback
> *
> * Description :
> *
> *
> * Returns :
> *
> *******************************************************************************/
>
> size_t ipr_cwmp_WriteMemoryCallback(void *contents,
> size_t size,
> size_t nmemb,
> void *userp)
> {
> size_t realsize = size * nmemb;
> struct MemoryStruct *mem = (struct MemoryStruct *)userp;
> mem->memory = realloc(mem->memory, mem->size + realsize + 1 );
> if (mem->memory == NULL)
> {
> /* out of memory! */
> printf("Exiting the function ipr_cwmp_WriteMemoryCallback 101 \n");
> exit(1);
> }
> memcpy(&(mem->memory[mem->size]), contents, realsize);
> mem->size += realsize;
> mem->memory[mem->size] = 0;
> printf("Exiting the function ipr_cwmp_WriteMemoryCallback 100 \n");
> return realsize;
> }
>
>
> /* This is an application verification call back, it does not
> perform any addition verification but tries to find a URL
> in the presented certificate. If found, this will become
> the URL to be used in the POST.
> */
> static int ssl_app_verify_callback(X509_STORE_CTX *ctx, void *arg)
> {
> sslctxparm * p = (sslctxparm *) arg;
> int ok;
>
> if(p->verbose > 2)
> BIO_printf(p->errorbio, "entering ssl_app_verify_callback\n");
>
> ok = X509_verify_cert(ctx);
> if(ok && ctx->cert) {
> unsigned char *accessinfo;
> if(p->verbose > 1)
> X509_print_ex(p->errorbio, ctx->cert, 0, 0);
>
> // accessinfo = my_get_ext(ctx->cert, p->accesstype, NID_sinfo_access);
> // if(accessinfo) {
> // if(p->verbose)
> // BIO_printf(p->errorbio, "Setting URL from SIA to:
> %s\n", accessinfo);
> //
> // curl_easy_setopt(p->curl, CURLOPT_URL, accessinfo);
> // }
> // else if(accessinfo = my_get_ext(ctx->cert, p->accesstype,
> // NID_info_access)) {
> // if(p->verbose)
> // BIO_printf(p->errorbio, "Setting URL from AIA to:
> %s\n", accessinfo);
> //
> // curl_easy_setopt(p->curl, CURLOPT_URL, accessinfo);
> // }
> }
> if(p->verbose > 2)
> BIO_printf(p->errorbio, "leaving ssl_app_verify_callback with
> %d\n", ok);
>
> return ok;
> }
>
> /*************************************************************************************************
> * Function Name : ipr_cwmp_sslctxfun
> *
> * Description : This is an example of an curl SSL initialisation
> call back. The callback sets:
> * a private key and certificate
> * a trusted ca certificate
> * a preferred cipherlist
> * an application verification callback (the function above)
> * Returns : CURLcode
> *
> ***************************************************************************************************/
>
> static CURLcode ipr_cwmp_sslctxfun(void* sslctx, void* parm)
> {
> SSL_CTX* ctx = (SSL_CTX *) sslctx ;
> SSL_CTX_set_cert_verify_callback(ctx, ssl_app_verify_callback, parm);
> //SSL_CTX_set_cert_verify_callback(ctx,
> ipr_cwmp_ssl_app_verify_callback, parm);
> //changed this to supress the warning for ssl prototype of this function
> return CURLE_OK ;
> }
> /***************************************************************************************************/
>
>
> const char * const urls[NUMT]= {
> "https://192.168.66.116:8443/acs/AcsServlet"
> //"https://192.168.16.233:8443/acs/AcsServlet",
> //"ftp://cool.haxx.se/",
> //"https://www.cag.se/",
> //"www.haxx.se"
> };
> //curl_easy_setopt(curl, CURLOPT_SSLCERT,"client-2048.crt");
> //curl_easy_setopt(curl, CURLOPT_SSLKEY,"client-2048.key");
>
> static void *pull_one_url(void *url)
> {
> struct MemoryStruct header_chunk = {0};
> struct curl_slist *slist = NULL;
> static const char *msg = "Field=1&Field=2&Field=3";
> CURL *curl;
> struct MemoryStruct chunk = {0};
> /*SPR 17929 changes start*/
> char * str = NULL;
> char arr[512];
> memset(arr, '\0', 512);
> char * token = NULL;
> /*SPR 17929 changes end*/
>
> chunk.memory = NULL; /* will be grown as needed by the realloc above */
> chunk.size = 0;
>
> curl = curl_easy_init();
> curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
> //curl_easy_setopt(curl,CURLOPT_RESOLVE, host);
> curl_easy_setopt(curl, CURLOPT_URL, url);
> curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
> /* get verbose debug output please */
> curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
> curl_easy_setopt(curl, CURLOPT_POST, 1);
> curl_easy_setopt(curl, CURLOPT_POSTFIELDS,(char *)msg);
>
> slist = NULL;
> slist = curl_slist_append(NULL, "Content-Type: text/xml;
> UInt8set=utf-8\nSOAPAction:");
> curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookie.txt");
> curl_easy_setopt(curl, CURLOPT_COOKIE, "cookie.txt");
> if (header_chunk.size)
> {
> str = strstr((char *)header_chunk.memory, "JSESSIONID=");
> printf("Extracted JSESSIONID \n");
> }
>
> if ((header_chunk.size) && (str!= NULL))
> {
> token = strtok(str + 11, ";");
> memset(arr,0x00,512);
> sprintf(arr, "Cookie: JSESSIONID=%s",token);
> printf("Token has value %s \n",arr);
> slist = curl_slist_append(slist,arr);
> printf("Added httpHeader \n");
> }
> curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
> if(0 == header_chunk.size)
> {
> curl_easy_setopt(curl, CURLOPT_HEADERDATA,(void *)&header_chunk);
> }
>
> curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, ipr_cwmp_sslctxfun);
> //curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun);
> curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ipr_cwmp_WriteMemoryCallback);
> /* we pass our 'chunk' struct to the callback function */
> //coverity fix
> curl_easy_setopt(curl, CURLOPT_WRITEDATA,(void *)&chunk);
> curl_easy_setopt(curl, CURLOPT_SSLKEY,"./tls_files/enodeb-new.key.pem");
> curl_easy_setopt(curl, CURLOPT_SSLCERT,"./tls_files/enodeb.cert.pem");
> //curl_easy_setopt(curl, CURLOPT_SSLKEY, g_ipr_cwmp_pClientKeyFile);
> /* set the file with the certs vaildating the server */
> //curl_easy_setopt(curl, CURLOPT_SSLCERT, g_ipr_cwmp_pClientCertFile);
> /* disconnect if we can't validate server's cert */
> curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,1L);
> curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
> curl_easy_setopt(curl,CURLOPT_CAINFO,"./tls_files/ca-chain.cert.pem");
> curl_easy_setopt(curl,CURLOPT_FOLLOWLOCATION,1L);
> curl_easy_setopt(curl,CURLOPT_MAXREDIRS,5L);
> curl_easy_setopt(curl,CURLOPT_POSTREDIR,CURL_REDIR_POST_ALL);
> curl_easy_setopt(curl, CURLOPT_POST, 1);
>
> //coverity fix
> //curl_easy_setopt(curl, CURLOPT_POSTFIELDS,(char *)msg);
> //curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "cookie.txt");
> //curl_easy_setopt(curl, CURLOPT_COOKIE, "cookie.txt");
> curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC|CURLAUTH_DIGEST);
> curl_easy_setopt (curl, CURLOPT_USERNAME
> ,"BaseStationClass-002488-1114B00001");
> curl_easy_setopt (curl, CURLOPT_PASSWORD ,"abcd1234");
> // curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION,
> ipr_cwmp_sslctxfun) ;
>
>
>
> curl_easy_perform(curl); /* ignores error */
> curl_easy_cleanup(curl);
>
> return NULL;
> }
>
>
> /*
> int pthread_create(pthread_t *new_thread_ID,
> const pthread_attr_t *attr,
> void * (*start_func)(void *), void *arg);
> */
>
> int main(int argc, char **argv)
> {
> pthread_t tid[NUMT];
> int i;
>
> /* Must initialize libcurl before any threads are started */
> curl_global_init(CURL_GLOBAL_ALL);
>
> for(i = 0; i< NUMT; i++) {
> int error = pthread_create(&tid[i],
> NULL, /* default attributes please */
> pull_one_url,
> (void *)urls[i]);
> if(0 != error)
> fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
> else
> fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
> }
>
> /* now wait for all threads to terminate */
> for(i = 0; i< NUMT; i++) {
> pthread_join(tid[i], NULL);
> fprintf(stderr, "Thread %d terminated\n", i);
> }
> curl_global_cleanup();
> return 0;
> }
>
>
> On Fri, Oct 1, 2021 at 8:29 PM Daniel Stenberg <daniel_at_haxx.se> wrote:
>> On Fri, 1 Oct 2021, treesa fairy joseph wrote:
>>
>>> #0 0x00000000005377c4 in Curl_hash_clean_with_criterium (h=0xffff7c0a4d50,
>>> user=0xffff8b28d970,
>>> comp=0x4ba604 <hostcache_timestamp_remove>) at hash.c:243
>>> 243 hash.c: No such file or directory.
>>> (gdb) bt
>>> #0 0x00000000005377c4 in Curl_hash_clean_with_criterium (h=0xffff7c0a4d50,
>>> user=0xffff8b28d970,
>>> comp=0x4ba604 <hostcache_timestamp_remove>) at hash.c:243
>> This issue shows the typical signs of a threading problem. Make sure that
>> your application and threading follow the advice here:
>>
>> https://curl.se/libcurl/c/threadsafe.html
>>
>> In particular the dont-use-the-same-handle-twice rule.
>>
>> If that doesn't help, then I'd advice you to start trying to create a separate
>> stand-alone example code that reproduces the problem that you can share with
>> us.


Please don't top-post, it makes the conversation hard to follow. [1]

CURLOPT_SSL_CTX_FUNCTION callback takes three parameters but yours only
has two and that is causing memory corruption. [2]

Change it to:

static CURLcode ipr_cwmp_sslctxfun(CURL *curl, void* sslctx, void* parm)

That function sets ssl_app_verify_callback which looks to be copied from
the curlx example [3]. That example (and that function specifically)
only compiles for older OpenSSL but I guess it works for you since you
enabled deprecated features when compiling OpenSSL 1.1.1. I will see if
I can update it to work with later versions.

Since you are dereferencing parm (sslctxparm) in that function you need
to actually define it and then set it via CURLOPT_SSL_CTX_DATA [4].


[1]: https://curl.se/mail/etiquette.html#Do_Not_Top_Post
[2]: https://curl.se/libcurl/c/CURLOPT_SSL_CTX_FUNCTION.html
[3]: https://curl.se/libcurl/c/curlx.html
[4]: https://curl.se/libcurl/c/CURLOPT_SSL_CTX_DATA.html


-- 
Unsubscribe: https://lists.haxx.se/listinfo/curl-library
Etiquette:   https://curl.haxx.se/mail/etiquette.html
Received on 2022-03-01