Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

libCurl SSL error after fork()

I'm developing a FUSE driver and when I run it as a daemon (without the -f or -d flags) all https request made through libcurl fail. I was able to reproduce the error by making an https request, forking and returning the parent process, and then making a second request from the new process. If I remove the fork call or make an http request there are no errors.

I'm making an official bug report right now, but does anyone know how I can make it work?

Here's my code and the (logfile) output:

Note: if you run my program, pipe to /dev/null because libcurl sends the received buffer to stdout by default.

#include <curl/curl.h>
#include <string>
#include <unistd.h>
#include <iostream>

using namespace std;

void log(string str)
{   //TODO: remove
    static const char logfile[] = "/home/austin/megalog";
    FILE *f = fopen(logfile, "a");
    fwrite(str.data(), str.size(), 1, f);
    fclose(f);
    cout << str;
}

int main(int argc, char *argv[])
{
    string url = "https://www.google.com/";
    char errBuf[1024];
    CURLcode err;

    curl_global_init(CURL_GLOBAL_DEFAULT);
    CURL *handle = curl_easy_init();
    curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
    curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, errBuf);

    if ((err = curl_easy_perform(handle)))
    {
        log("first request failed\n");
        return 1;
    }
    curl_easy_cleanup(handle);

    if(fork())
        return 0;

    handle = curl_easy_init();
    curl_easy_setopt(handle, CURLOPT_URL, url.c_str());
    curl_easy_setopt(handle, CURLOPT_ERRORBUFFER, errBuf);

    if ((err = curl_easy_perform(handle)))
    {
        log(string("curl error while sending: (") + to_string(err) + ") " + curl_easy_strerror(err) + "\n");
        log(errBuf);
    }
    else
        log("no error\n");

    return 0;
}

...and the output:

$ g++ -std=c++11 main.cpp -lcurl
$ rm -f log
$ ./a.out > /dev/null
$ cat log
curl error while sending: (35) SSL connect error
A PKCS #11 module returned CKR_DEVICE_ERROR, indicating that a problem has occurred with the token or slot.

I'm using (the latest) libcurl version 7.29.0, (the latest) openssl version 1.0.1e, and I'm running Fedora 18 with kernel version 3.7.4.

like image 933
br1ckd Avatar asked Oct 04 '22 16:10

br1ckd


1 Answers

To make this work, you need to call curl_global_cleanup before fork and curl_global_init again after fork. Someone in the libcurl mailing list mentioned that this is a common problem when calling fork after initializing libraries that need to be initialized.

like image 199
br1ckd Avatar answered Oct 18 '22 12:10

br1ckd