[Libwebsockets] openssl init (was v2.0 crashes)

Andy Green andy at warmcat.com
Sat May 14 00:31:33 CEST 2016



On 05/13/2016 11:46 PM, Andrejs Hanins wrote:
>
>
> BR, /Andrey/
> On 13 May 2016, at 17:05, Andy Green <andy at warmcat.com
> <mailto:andy at warmcat.com>> wrote:
>
>>
>>
>> On May 13, 2016 9:39:41 PM GMT+08:00, Roger Light <roger at atchoo.org
>> <mailto:roger at atchoo.org>> wrote:
>>> On Fri, May 13, 2016 at 1:11 PM, Andy Green <andy at warmcat.com
>>> <mailto:andy at warmcat.com>> wrote:
>>>>
>>>>
>>>> On May 13, 2016 7:25:43 PM GMT+08:00, Andrejs Hanins
>>> <andrejs.hanins at ubnt.com <mailto:andrejs.hanins at ubnt.com>> wrote:
>>>
>>>>> Still, each creation of ctx calls SSL_library_init. In my code I need
>>>>> to recreate the ctx when network configuration
>>>>> changes, so SSL_library_init still might be called several times for
>>>>> one process. Do you think this is a problem from SSL library design
>>>>> point of view?
>>>>
>>>> I see the point, actually I dunno, because openssl and valgrind don't
>>> play well
>>>> together.  Those openssl calls just seem to set statics in the
>>> process context,
>>>> they seem to allocate but don't take any args.
>>>
>>> Calling the openssl initialisation functions more than once doesn't
>>> matter, apart from it not being pretty.
>>>
>>> There's no way for you to be able to predict if another library has
>>
>> Yes, good point.
>>
>>> called the init functions, so there's no way you can guard against
>>> multiple calls externally to lws - and this implies that there's no
>>> point worrying about it internally either.
>>
>> It's true there's no symptom we're trying to fix.
> Exactly. I just wanted to make sure this "double init" stuff is not
> harmful.

It's really an openssl issue not a lws one.

I was also curious what this magic openssl init actually does, it's here 
on 1.0.1 in use by Fedora

https://github.com/openssl/openssl/blob/OpenSSL_1_0_1-stable/ssl/ssl_algs.c#L64

Basically he only calls EVP_add[cipher|digest|digest_alias], basically 
listing what assets the library was configured with.

Those all come down to the business end at OBJ_NAME_add(), and he 
devolves to storing name:value pairs using lh_OBJ_NAME_insert() which

# define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst)

is an alias for LHM_lh_insert(), which devolves to lh_insert() that 
actually does the job.

OBJ_NAME there is a static pointer to a hash table defined in 
crypto/objects/o_names.c with some typing magic

DECLARE_LHASH_OF(OBJ_NAME);
static LHASH_OF(OBJ_NAME) *names_lh = NULL;

The apis in o_names.c check names_lh for NULL (by calling 
OBJ_NAME_init()) and if so do a onetime init ultimately at lh_new(), 
which mallocs the hashtable.

lh_insert() maintains the allocated hashtable, but before creating 
elements, it checks if they already exist: getrn() computes the hash and 
returns the HASH_NODE with the content already, or NULL if not in the table.

void *lh_insert(_LHASH *lh, void *data)
{
     unsigned long hash;
     LHASH_NODE *nn, **rn;
     void *ret;

     lh->error = 0;
     if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes))
         expand(lh);

     rn = getrn(lh, data, &hash);

     if (*rn == NULL) {
         if ((nn = (LHASH_NODE *)OPENSSL_malloc(sizeof(LHASH_NODE))) == 
NULL) {
...



Since SSL_library_init() is exclusively a pile of these hashtable entry 
insertions, there is zero problem calling it multiple times, it will 
malloc the hashtable the first insertion, fill it up the first time and 
when it goes through the motions subsequently, it's a NOP at lh_insert().

The other init like error strings, we already call the APIs to take them 
down in context destroy.

So there is nothing to fix or manage here, it's already OK.

-Andy

>> Openssl changed this api in 1.1.0 anyway.
>>
>> -Andy
>>
>>> Cheers,
>>>
>>> Roger
>>



More information about the Libwebsockets mailing list