gnutls/gnutls-global-deinit.patch
2014-04-28 15:39:07 +02:00

100 lines
2.6 KiB
Diff

diff --git a/lib/gnutls_global.c b/lib/gnutls_global.c
index 9b7047a..8cd9fd3 100644
--- a/lib/gnutls_global.c
+++ b/lib/gnutls_global.c
@@ -53,8 +53,8 @@ extern const ASN1_ARRAY_TYPE pkix_asn1_tab[];
void *_gnutls_file_mutex;
void *_gnutls_pkcs11_mutex;
-ASN1_TYPE _gnutls_pkix1_asn;
-ASN1_TYPE _gnutls_gnutls_asn;
+ASN1_TYPE _gnutls_pkix1_asn = ASN1_TYPE_EMPTY;
+ASN1_TYPE _gnutls_gnutls_asn = ASN1_TYPE_EMPTY;
gnutls_log_func _gnutls_log_func = NULL;
gnutls_audit_log_func _gnutls_audit_log_func = NULL;
@@ -166,6 +166,9 @@ gnutls_global_set_mem_functions(gnutls_alloc_function alloc_func,
GNUTLS_STATIC_MUTEX(global_init_mutex);
static int _gnutls_init = 0;
+/* cache the return code */
+static int _gnutls_init_ret = 0;
+
/**
* gnutls_global_init:
*
@@ -186,6 +189,9 @@ static int _gnutls_init = 0;
* do not support library constructors and static linking. This
* function also became thread safe.
*
+ * A subsequent call of this function if the initial has failed will
+ * return the same error code.
+ *
* Returns: On success, %GNUTLS_E_SUCCESS (0) is returned,
* otherwise a negative error code is returned.
**/
@@ -199,7 +205,7 @@ int gnutls_global_init(void)
_gnutls_init++;
if (_gnutls_init > 1) {
- ret = 0;
+ ret = _gnutls_init_ret;
goto out;
}
@@ -235,14 +241,17 @@ int gnutls_global_init(void)
goto out;
}
+ _gnutls_pkix1_asn = ASN1_TYPE_EMPTY;
res = asn1_array2tree(pkix_asn1_tab, &_gnutls_pkix1_asn, NULL);
if (res != ASN1_SUCCESS) {
+ gnutls_assert();
ret = _gnutls_asn2err(res);
goto out;
}
res = asn1_array2tree(gnutls_asn1_tab, &_gnutls_gnutls_asn, NULL);
if (res != ASN1_SUCCESS) {
+ gnutls_assert();
ret = _gnutls_asn2err(res);
goto out;
}
@@ -306,6 +315,7 @@ int gnutls_global_init(void)
ret = 0;
out:
+ _gnutls_init_ret = ret;
GNUTLS_STATIC_MUTEX_UNLOCK(global_init_mutex);
return ret;
}
@@ -316,11 +326,19 @@ static void _gnutls_global_deinit(unsigned destructor)
if (_gnutls_init == 1) {
_gnutls_init = 0;
+ if (_gnutls_init_ret < 0) {
+ /* only deinitialize if gnutls_global_init() has
+ * succeeded */
+ gnutls_assert();
+ goto fail;
+ }
+
gnutls_crypto_deinit();
_gnutls_rnd_deinit();
_gnutls_ext_deinit();
asn1_delete_structure(&_gnutls_gnutls_asn);
asn1_delete_structure(&_gnutls_pkix1_asn);
+
_gnutls_crypto_deregister();
gnutls_system_global_deinit();
_gnutls_cryptodev_deinit();
@@ -341,6 +359,8 @@ static void _gnutls_global_deinit(unsigned destructor)
if (_gnutls_init > 0)
_gnutls_init--;
}
+
+ fail:
GNUTLS_STATIC_MUTEX_UNLOCK(global_init_mutex);
}