Exec summary:
sfcc uses openssl in an exclusive way, preventing the use of sfcc in applications which are also using sfcc.
Problem:
ReleaseCIMCEnv calls curl_global_cleanup thereby invalidating internal hash structures of openssl. This makes other users of openssl fail.
Concrete scenario:
Use of ruby-sfcc (Ruby bindings for sfcc: https://github.com/dmacvicar/ruby-sfcc\) in Rails (http://rubyonrails.org/)
Rails does
- init of openssl
- init of CIMCEnv (via cmciConnect)
- cmciConnect inits openssl
... use of sfcc connection ...
- release of CIMCEnv -> calls curl_global_cleanup()
- next call to e.g. EVP_get_digestbyname() fails because openssl is de-initialized
See http://curl.haxx.se/mail/lib-2001-12/0001.html about the right way to call curl_global_cleanup()
Uh, there is no call to curl_global_init in sfcc, only one to curl_global_cleanup !
http://curl.haxx.se/libcurl/c/curl_global_cleanup.html says
"You should call curl_global_cleanup(3) once for each call you make to curl_global_init(3), after you are done using libcurl."
However, this somehow contradicts http://curl.haxx.se/mail/lib-2001-12/0001.html
This bug only happens if one calls cmciConnect and releases CIMCEnv without actually initiating a connection.
Because curl_easy_connect does call curl_global_init if needed.
Patch attached, this one works for me
Reworked patch - don't call curl_global_cleanup()
Calling curl_global_init(0) does not work, since SSL won't get initialized
Calling curl_global_init(CURL_GLOBAL_SSL) will conflict with other users of SSL since curl_global_cleanup() will de-initialize SSL.
There are two options now
1. add a call to curl_global_init() but call curl_global_cleanup() via atexit() only
2. drop the call to curl_global_cleanup()
I opted for the second option since any allocated memory will be released at exit() in any case.
This is a tricky one.
A problem with the proposed patch is that we will run into a resource problem if a program using SFCC doesn't exit after releasing. For example, if it makes a new CIMCEnv and releases it several times in the program, curl_global_init() will also be called several times without a corresponding cleanup.
Adding a curl_global_init() when creating the CIMCEnv seemed like a good idea, but if your most recent comment is correct, that isn't going to fly.
What if we had an option when creating to the CIMCEnv to skip curl init and cleanup calls? Then the calling program would be able to specify if the issue described in this bug is applicable to them.
Chris, I agree here.
Adding an option when creating CIMCEnv to skip the calls to curl_global_{init,cleanup} is the only sane solution here.
add option for NewCIMCEnv() to not call init/cleanup
Klaus,
Have a look at the attached patch. If it's good, I'll get it in before the release this week.
committed patch
committed to git master
Fix looks good to me. Will test next week.