Kernel Resource Leak BIO_do_connect

210 views Asked by At

I need to help with the following; I've tried looking for an answer and I have been left with asking.

Inspector XE has given the following result: Kernel Resource Leak on the line

he=BIO_gethostbyname(str);

This line is apart of the OpenSSL sourcecode and I can't imagine anything being wrong here.

This function is called inside:

BIO_do_connect();

My code is.

bio = BIO_new_connect(...);
if (BIO_do_connect(bio) != 1) { ... }
...
if (BIO_free(bio) != 0) { ... }

The connection is successful, the only errors which occur happen when I call this function 1,000 times concurrently with threads.

Could this program really causing a Kernel Resource Leak?

1

There are 1 answers

2
seldon On BEST ANSWER

BIO_gethostbyname is not (cannot be) threadsafe, since it returns a pointer to a static buffer. Indeed, there is mention of this in openssl's bio.h, reading

struct hostent *BIO_gethostbyname(const char *name);
/* We might want a thread-safe interface too:
 * struct hostent *BIO_gethostbyname_r(const char *name,
 *     struct hostent *result, void *buffer, size_t buflen);
 * or something similar (caller allocates a struct hostent,
 * pointed to by "result", and additional buffer space for the various
 * substructures; if the buffer does not suffice, NULL is returned
 * and an appropriate error code is set).
 */

...however, no BIO_gethostbyname_r function has materialised thus far, and in any case it wouldn't help you if it had and BIO_do_connect didn't use it.

But despair not! There is locking code around this function call, so it can (probably) be made to work. Funny thing, though -- the locking code doesn't always do anything. I'll assume that you didn't compile OpenSSL with OPENSSL_NO_LOCKING because it isn't default and I can't imagine anyone putting it in if they wanted to develop multi-threaded applications, so my guess is that you forgot to call

CRYPTO_thread_setup();

before spawning threads that use OpenSSL. The reason this is important is that CRYPTO_thread_setup does, among other things, set a function pointer to a platform-dependent function that handles the actual locking. If CRYPTO_thread_setup is not called, this pointer remains NULL, and CRYPTO_lock (the relevant function at the bottom of the macros used around the BIO_gethostbyname call) will silently do nothing. There is not, as far as I know, any documentation from which you could have known this.

It could be argued that your optimism about the quality of the OpenSSL codebase is misplaced.