diff options
author | william <william@25thandclement.com> | 2015-04-17 16:08:24 -0700 |
---|---|---|
committer | william <william@25thandclement.com> | 2015-04-17 16:08:24 -0700 |
commit | c6a00deb359b38ec72aeeba3b07a22fdda209dbc (patch) | |
tree | ef36b220a4c2c210702359b9989ccdf79d3c500d | |
parent | b5c0bb622f55b6e52a1ae1a5ec5a4ded0cded96b (diff) | |
download | luaossl-c6a00deb359b38ec72aeeba3b07a22fdda209dbc.tar.gz luaossl-c6a00deb359b38ec72aeeba3b07a22fdda209dbc.tar.bz2 luaossl-c6a00deb359b38ec72aeeba3b07a22fdda209dbc.zip |
pin the module in memory when installing external app data callbacks, as these can be never be uninstalled
-rw-r--r-- | src/openssl.c | 358 |
1 files changed, 234 insertions, 124 deletions
diff --git a/src/openssl.c b/src/openssl.c index 90db798..0894fcf 100644 --- a/src/openssl.c +++ b/src/openssl.c | |||
@@ -23,9 +23,6 @@ | |||
23 | * USE OR OTHER DEALINGS IN THE SOFTWARE. | 23 | * USE OR OTHER DEALINGS IN THE SOFTWARE. |
24 | * ========================================================================== | 24 | * ========================================================================== |
25 | */ | 25 | */ |
26 | #ifndef LUAOSSL_H | ||
27 | #define LUAOSSL_H | ||
28 | |||
29 | #include <limits.h> /* INT_MAX INT_MIN UCHAR_MAX */ | 26 | #include <limits.h> /* INT_MAX INT_MIN UCHAR_MAX */ |
30 | #include <stdint.h> /* uintptr_t */ | 27 | #include <stdint.h> /* uintptr_t */ |
31 | #include <string.h> /* memset(3) strerror_r(3) */ | 28 | #include <string.h> /* memset(3) strerror_r(3) */ |
@@ -33,8 +30,7 @@ | |||
33 | #include <math.h> /* INFINITY fabs(3) floor(3) frexp(3) fmod(3) round(3) isfinite(3) */ | 30 | #include <math.h> /* INFINITY fabs(3) floor(3) frexp(3) fmod(3) round(3) isfinite(3) */ |
34 | #include <time.h> /* struct tm time_t strptime(3) time(2) */ | 31 | #include <time.h> /* struct tm time_t strptime(3) time(2) */ |
35 | #include <ctype.h> /* tolower(3) */ | 32 | #include <ctype.h> /* tolower(3) */ |
36 | #include <signal.h> /* sig_atomic_t */ | 33 | #include <errno.h> /* ENOMEM ENOTSUP errno */ |
37 | #include <errno.h> /* ENOMEM errno */ | ||
38 | #include <assert.h> /* assert */ | 34 | #include <assert.h> /* assert */ |
39 | 35 | ||
40 | #include <sys/types.h> /* ssize_t pid_t */ | 36 | #include <sys/types.h> /* ssize_t pid_t */ |
@@ -80,6 +76,10 @@ | |||
80 | #include "compat52.h" | 76 | #include "compat52.h" |
81 | #endif | 77 | #endif |
82 | 78 | ||
79 | #ifndef HAVE_DLADDR | ||
80 | #define HAVE_DLADDR (!defined _AIX) /* TODO: https://root.cern.ch/drupal/content/aix-and-dladdr */ | ||
81 | #endif | ||
82 | |||
83 | #ifndef HAVE_SSL_CTX_SET_ALPN_PROTOS | 83 | #ifndef HAVE_SSL_CTX_SET_ALPN_PROTOS |
84 | #define HAVE_SSL_CTX_SET_ALPN_PROTOS (OPENSSL_VERSION_NUMBER >= 0x1000200fL) | 84 | #define HAVE_SSL_CTX_SET_ALPN_PROTOS (OPENSSL_VERSION_NUMBER >= 0x1000200fL) |
85 | #endif | 85 | #endif |
@@ -573,6 +573,83 @@ static void lib_setintegers(lua_State *L, const integer_Reg *l) { | |||
573 | } /* lib_setintegers() */ | 573 | } /* lib_setintegers() */ |
574 | 574 | ||
575 | 575 | ||
576 | /* | ||
577 | * Auxiliary Lua API routines | ||
578 | * | ||
579 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
580 | |||
581 | typedef int auxref_t; | ||
582 | typedef int auxtype_t; | ||
583 | |||
584 | static void auxL_unref(lua_State *L, auxref_t *ref) { | ||
585 | luaL_unref(L, LUA_REGISTRYINDEX, *ref); | ||
586 | *ref = LUA_NOREF; | ||
587 | } /* auxL_unref() */ | ||
588 | |||
589 | static void auxL_ref(lua_State *L, int index, auxref_t *ref) { | ||
590 | auxL_unref(L, ref); | ||
591 | lua_pushvalue(L, index); | ||
592 | *ref = luaL_ref(L, LUA_REGISTRYINDEX); | ||
593 | } /* auxL_ref() */ | ||
594 | |||
595 | static auxtype_t auxL_getref(lua_State *L, auxref_t ref) { | ||
596 | if (ref == LUA_NOREF || ref == LUA_REFNIL) { | ||
597 | lua_pushnil(L); | ||
598 | } else { | ||
599 | lua_rawgeti(L, LUA_REGISTRYINDEX, ref); | ||
600 | } | ||
601 | |||
602 | return lua_type(L, -1); | ||
603 | } /* auxL_getref() */ | ||
604 | |||
605 | |||
606 | /* | ||
607 | * dl - dynamically loaded module management | ||
608 | * | ||
609 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
610 | |||
611 | /* | ||
612 | * Prevent loader from unlinking us if we've registered a callback with | ||
613 | * OpenSSL by taking another reference to ourselves. | ||
614 | */ | ||
615 | static int dl_anchor(void) { | ||
616 | #if HAVE_DLADDR | ||
617 | extern int luaopen__openssl(lua_State *); | ||
618 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | ||
619 | static void *anchor; | ||
620 | Dl_info info; | ||
621 | int error = 0; | ||
622 | |||
623 | if ((error = pthread_mutex_lock(&mutex))) | ||
624 | return error; | ||
625 | |||
626 | if (anchor) | ||
627 | goto epilog; | ||
628 | |||
629 | if (!dladdr((void *)&luaopen__openssl, &info)) | ||
630 | goto dlerr; | ||
631 | |||
632 | if (!(anchor = dlopen(info.dli_fname, RTLD_NOW|RTLD_LOCAL))) | ||
633 | goto dlerr; | ||
634 | epilog: | ||
635 | (void)pthread_mutex_unlock(&mutex); | ||
636 | |||
637 | return error; | ||
638 | dlerr: | ||
639 | error = -2; | ||
640 | |||
641 | goto epilog; | ||
642 | #else | ||
643 | return 0;//ENOTSUP; | ||
644 | #endif | ||
645 | } /* dl_anchor() */ | ||
646 | |||
647 | |||
648 | /* | ||
649 | * compat - OpenSSL API compatibility and bug workarounds | ||
650 | * | ||
651 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
652 | |||
576 | #define COMPAT_X509_STORE_FREE_BUG 0x01 | 653 | #define COMPAT_X509_STORE_FREE_BUG 0x01 |
577 | 654 | ||
578 | static struct { | 655 | static struct { |
@@ -632,7 +709,9 @@ static void *compat_EVP_PKEY_get0(EVP_PKEY *key) { | |||
632 | } /* compat_EVP_PKEY_get0() */ | 709 | } /* compat_EVP_PKEY_get0() */ |
633 | #endif | 710 | #endif |
634 | 711 | ||
635 | /* X509_STORE_free in OpenSSL versions < 1.0.2 doesn't obey reference count */ | 712 | /* |
713 | * X509_STORE_free in OpenSSL versions < 1.0.2 doesn't obey reference count | ||
714 | */ | ||
636 | #define X509_STORE_free(store) \ | 715 | #define X509_STORE_free(store) \ |
637 | (compat.X509_STORE_free)((store)) | 716 | (compat.X509_STORE_free)((store)) |
638 | 717 | ||
@@ -672,14 +751,14 @@ static void compat_SSL_CTX_set1_cert_store(SSL_CTX *ctx, X509_STORE *store) { | |||
672 | } /* compat_SSL_CTX_set1_cert_store() */ | 751 | } /* compat_SSL_CTX_set1_cert_store() */ |
673 | #endif | 752 | #endif |
674 | 753 | ||
675 | static void compat_SSL_CTX_onfree(void *_ctx, void *data NOTUSED, CRYPTO_EX_DATA *ad NOTUSED, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) { | 754 | static void compat_init_SSL_CTX_onfree(void *_ctx, void *data NOTUSED, CRYPTO_EX_DATA *ad NOTUSED, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) { |
676 | SSL_CTX *ctx = _ctx; | 755 | SSL_CTX *ctx = _ctx; |
677 | 756 | ||
678 | if (ctx->cert_store) { | 757 | if (ctx->cert_store) { |
679 | X509_STORE_free(ctx->cert_store); | 758 | X509_STORE_free(ctx->cert_store); |
680 | ctx->cert_store = NULL; | 759 | ctx->cert_store = NULL; |
681 | } | 760 | } |
682 | } /* compat_SSL_CTX_onfree() */ | 761 | } /* compat_init_SSL_CTX_onfree() */ |
683 | 762 | ||
684 | /* helper routine to determine if X509_STORE_free obeys reference count */ | 763 | /* helper routine to determine if X509_STORE_free obeys reference count */ |
685 | static void compat_init_X509_STORE_onfree(void *store, void *data NOTUSED, CRYPTO_EX_DATA *ad NOTUSED, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) { | 764 | static void compat_init_X509_STORE_onfree(void *store, void *data NOTUSED, CRYPTO_EX_DATA *ad NOTUSED, int idx NOTUSED, long argl NOTUSED, void *argp NOTUSED) { |
@@ -693,90 +772,89 @@ static void compat_init_X509_STORE_onfree(void *store, void *data NOTUSED, CRYPT | |||
693 | 772 | ||
694 | static int compat_init(void) { | 773 | static int compat_init(void) { |
695 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | 774 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; |
696 | static volatile sig_atomic_t done; | 775 | static int store_index = -1, ssl_ctx_index = -1, done; |
697 | int error; | 776 | X509_STORE *store; |
777 | int error = 0; | ||
698 | 778 | ||
699 | if ((error = pthread_mutex_lock(&mutex))) | 779 | if ((error = pthread_mutex_lock(&mutex))) |
700 | return error; | 780 | return error; |
701 | 781 | ||
702 | if (!done) { | 782 | if (done) |
703 | /* | 783 | goto epilog; |
704 | * Test if X509_STORE_free obeys reference counts. | ||
705 | */ | ||
706 | if (-1 == CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, 0, NULL, NULL, NULL, &compat_init_X509_STORE_onfree)) | ||
707 | goto sslerr; | ||
708 | 784 | ||
709 | if (!(compat.tmp.store = X509_STORE_new())) | 785 | /* |
710 | goto sslerr; | 786 | * We need to unconditionally install at least one external |
787 | * application data callback. Because these can never be | ||
788 | * uninstalled, we can never be unloaded. | ||
789 | */ | ||
790 | if ((error = dl_anchor())) | ||
791 | goto epilog; | ||
711 | 792 | ||
712 | CRYPTO_add(&compat.tmp.store->references, 1, CRYPTO_LOCK_X509_STORE); | 793 | /* |
713 | X509_STORE_free(compat.tmp.store); | 794 | * Test if X509_STORE_free obeys reference counts by installing an |
795 | * onfree callback. | ||
796 | */ | ||
797 | if (store_index == -1 | ||
798 | && -1 == (store_index = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE, 0, NULL, NULL, NULL, &compat_init_X509_STORE_onfree))) | ||
799 | goto sslerr; | ||
714 | 800 | ||
715 | if (compat.tmp.store) { | 801 | if (!(compat.tmp.store = X509_STORE_new())) |
716 | X509_STORE_free(compat.tmp.store); | 802 | goto sslerr; |
717 | assert(compat.tmp.store == NULL); | 803 | |
718 | compat.tmp.store = NULL; | 804 | CRYPTO_add(&compat.tmp.store->references, 1, CRYPTO_LOCK_X509_STORE); |
719 | } else { | 805 | X509_STORE_free(compat.tmp.store); |
720 | /* | ||
721 | * If X509_STORE_free does NOT obey reference | ||
722 | * counts, then make sure that our fixed version is | ||
723 | * called on SSL_CTX destruction. Note that this | ||
724 | * won't fix code which doesn't properly obey the | ||
725 | * reference counts when setting the cert_store | ||
726 | * member. | ||
727 | */ | ||
728 | if (-1 == CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, 0, NULL, NULL, NULL, &compat_SSL_CTX_onfree)) | ||
729 | goto sslerr; | ||
730 | |||
731 | compat.flags |= COMPAT_X509_STORE_FREE_BUG; | ||
732 | } | ||
733 | 806 | ||
734 | done = 1; | 807 | if (compat.tmp.store) { |
808 | /* | ||
809 | * Because our onfree callback didn't execute, we assume | ||
810 | * X509_STORE_free obeys reference counts. Alternatively, | ||
811 | * our callback might not have executed for some other | ||
812 | * reason. We assert the truth of our assumption by checking | ||
813 | * again after calling X509_STORE_free once more. | ||
814 | */ | ||
815 | X509_STORE_free(compat.tmp.store); | ||
816 | assert(compat.tmp.store == NULL); | ||
817 | compat.tmp.store = NULL; /* in case assertions disabled */ | ||
818 | } else { | ||
819 | /* | ||
820 | * Because our onfree callback was invoked, X509_STORE_free | ||
821 | * appears not to obey reference counts. Ensure that our | ||
822 | * fixed version is called on SSL_CTX destruction. | ||
823 | * | ||
824 | * NB: We depend on the coincidental order of operations in | ||
825 | * SSL_CTX_free that user data destruction occurs before | ||
826 | * free'ing the cert_store member. Ruby's OpenSSL bindings | ||
827 | * also depend on this order as we both use the onfree | ||
828 | * callback to clear the member. | ||
829 | */ | ||
830 | if (ssl_ctx_index == -1 | ||
831 | && -1 == (ssl_ctx_index = CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, 0, NULL, NULL, NULL, &compat_init_SSL_CTX_onfree))) | ||
832 | goto sslerr; | ||
833 | |||
834 | compat.flags |= COMPAT_X509_STORE_FREE_BUG; | ||
735 | } | 835 | } |
836 | |||
837 | done = 1; | ||
736 | epilog: | 838 | epilog: |
737 | if (compat.tmp.store) { | 839 | if (compat.tmp.store) { |
738 | X509_STORE_free(compat.tmp.store); | 840 | X509_STORE_free(compat.tmp.store); |
739 | compat.tmp.store = NULL; | 841 | compat.tmp.store = NULL; |
740 | } | 842 | } |
741 | 843 | ||
742 | pthread_mutex_unlock(&mutex); | 844 | (void)pthread_mutex_unlock(&mutex); |
743 | 845 | ||
744 | return 0; | 846 | return error; |
745 | sslerr: | 847 | sslerr: |
746 | error = -1; | 848 | error = -1; |
747 | 849 | ||
748 | goto epilog; | 850 | goto epilog; |
749 | syserr: | ||
750 | error = errno; | ||
751 | |||
752 | goto epilog; | ||
753 | } /* compat_init() */ | 851 | } /* compat_init() */ |
754 | 852 | ||
755 | 853 | ||
756 | typedef int auxref_t; | 854 | /* |
757 | typedef int auxtype_t; | 855 | * External Application Data Hooks |
758 | 856 | * | |
759 | static void auxL_unref(lua_State *L, auxref_t *ref) { | 857 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
760 | luaL_unref(L, LUA_REGISTRYINDEX, *ref); | ||
761 | *ref = LUA_NOREF; | ||
762 | } /* auxL_unref() */ | ||
763 | |||
764 | static void auxL_ref(lua_State *L, int index, auxref_t *ref) { | ||
765 | auxL_unref(L, ref); | ||
766 | lua_pushvalue(L, index); | ||
767 | *ref = luaL_ref(L, LUA_REGISTRYINDEX); | ||
768 | } /* auxL_ref() */ | ||
769 | |||
770 | static auxtype_t auxL_getref(lua_State *L, auxref_t ref) { | ||
771 | if (ref == LUA_NOREF || ref == LUA_REFNIL) { | ||
772 | lua_pushnil(L); | ||
773 | } else { | ||
774 | lua_rawgeti(L, LUA_REGISTRYINDEX, ref); | ||
775 | } | ||
776 | |||
777 | return lua_type(L, -1); | ||
778 | } /* auxL_getref() */ | ||
779 | |||
780 | 858 | ||
781 | struct ex_state { | 859 | struct ex_state { |
782 | lua_State *L; | 860 | lua_State *L; |
@@ -835,16 +913,43 @@ static void ex_onfree(void *parent NOTUSED, void *_data, CRYPTO_EX_DATA *ad NOTU | |||
835 | free(data); | 913 | free(data); |
836 | } /* ex_onfree() */ | 914 | } /* ex_onfree() */ |
837 | 915 | ||
838 | static int ex_initonce(void) { | 916 | static int ex_init(void) { |
917 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | ||
918 | static int done; | ||
839 | struct ex_type *type; | 919 | struct ex_type *type; |
920 | int error = 0; | ||
921 | |||
922 | if ((error = pthread_mutex_lock(&mutex))) | ||
923 | return error; | ||
924 | |||
925 | if (done) | ||
926 | goto epilog; | ||
927 | |||
928 | /* | ||
929 | * Our callbacks can never be uninstalled, so ensure we're never | ||
930 | * unloaded. | ||
931 | */ | ||
932 | if ((error = dl_anchor())) | ||
933 | goto epilog; | ||
840 | 934 | ||
841 | for (type = ex_type; type < endof(ex_type); type++) { | 935 | for (type = ex_type; type < endof(ex_type); type++) { |
936 | if (type->index != -1) | ||
937 | continue; | ||
938 | |||
842 | if (-1 == (type->index = CRYPTO_get_ex_new_index(type->class_index, 0, NULL, NULL, &ex_ondup, &ex_onfree))) | 939 | if (-1 == (type->index = CRYPTO_get_ex_new_index(type->class_index, 0, NULL, NULL, &ex_ondup, &ex_onfree))) |
843 | return -1; | 940 | goto sslerr; |
844 | }; | 941 | }; |
845 | 942 | ||
846 | return 0; | 943 | done = 1; |
847 | } /* ex_initonce() */ | 944 | epilog: |
945 | (void)pthread_mutex_unlock(&mutex); | ||
946 | |||
947 | return error; | ||
948 | sslerr: | ||
949 | error = -1; | ||
950 | |||
951 | goto epilog; | ||
952 | } /* ex_init() */ | ||
848 | 953 | ||
849 | static int ex__gc(lua_State *L) { | 954 | static int ex__gc(lua_State *L) { |
850 | struct ex_state *state = lua_touserdata(L, 1); | 955 | struct ex_state *state = lua_touserdata(L, 1); |
@@ -967,6 +1072,25 @@ static void initall(lua_State *L); | |||
967 | 1072 | ||
968 | 1073 | ||
969 | /* | 1074 | /* |
1075 | * compat - Lua OpenSSL | ||
1076 | * | ||
1077 | * Bindings to our internal feature detection, compatability, and workaround | ||
1078 | * code. | ||
1079 | * | ||
1080 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | ||
1081 | |||
1082 | int luaopen__openssl_compat(lua_State *L) { | ||
1083 | initall(L); | ||
1084 | |||
1085 | lua_newtable(L); | ||
1086 | lua_pushboolean(L, !!(compat.flags & COMPAT_X509_STORE_FREE_BUG)); | ||
1087 | lua_setfield(L, -2, "X509_STORE_FREE_BUG"); | ||
1088 | |||
1089 | return 1; | ||
1090 | } /* luaopen__openssl_compat() */ | ||
1091 | |||
1092 | |||
1093 | /* | ||
970 | * OPENSSL - openssl | 1094 | * OPENSSL - openssl |
971 | * | 1095 | * |
972 | * Miscellaneous global interfaces. | 1096 | * Miscellaneous global interfaces. |
@@ -6257,18 +6381,11 @@ int luaopen__openssl_des(lua_State *L) { | |||
6257 | * | 6381 | * |
6258 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ | 6382 | * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
6259 | 6383 | ||
6260 | #ifndef HAVE_DLADDR | ||
6261 | #define HAVE_DLADDR (!defined _AIX) /* TODO: https://root.cern.ch/drupal/content/aix-and-dladdr */ | ||
6262 | #endif | ||
6263 | |||
6264 | static struct { | 6384 | static struct { |
6265 | pthread_mutex_t *lock; | 6385 | pthread_mutex_t *lock; |
6266 | int nlock; | 6386 | int nlock; |
6267 | |||
6268 | void *dlref; | ||
6269 | } mt_state; | 6387 | } mt_state; |
6270 | 6388 | ||
6271 | |||
6272 | static void mt_lock(int mode, int type, const char *file NOTUSED, int line NOTUSED) { | 6389 | static void mt_lock(int mode, int type, const char *file NOTUSED, int line NOTUSED) { |
6273 | if (mode & CRYPTO_LOCK) | 6390 | if (mode & CRYPTO_LOCK) |
6274 | pthread_mutex_lock(&mt_state.lock[type]); | 6391 | pthread_mutex_lock(&mt_state.lock[type]); |
@@ -6276,7 +6393,6 @@ static void mt_lock(int mode, int type, const char *file NOTUSED, int line NOTUS | |||
6276 | pthread_mutex_unlock(&mt_state.lock[type]); | 6393 | pthread_mutex_unlock(&mt_state.lock[type]); |
6277 | } /* mt_lock() */ | 6394 | } /* mt_lock() */ |
6278 | 6395 | ||
6279 | |||
6280 | /* | 6396 | /* |
6281 | * Sources include Google and especially the Wine Project. See get_unix_tid | 6397 | * Sources include Google and especially the Wine Project. See get_unix_tid |
6282 | * at http://source.winehq.org/git/wine.git/?a=blob;f=dlls/ntdll/server.c. | 6398 | * at http://source.winehq.org/git/wine.git/?a=blob;f=dlls/ntdll/server.c. |
@@ -6309,12 +6425,16 @@ static unsigned long mt_gettid(void) { | |||
6309 | #endif | 6425 | #endif |
6310 | } /* mt_gettid() */ | 6426 | } /* mt_gettid() */ |
6311 | 6427 | ||
6312 | |||
6313 | static int mt_init(void) { | 6428 | static int mt_init(void) { |
6314 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; | 6429 | static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; |
6315 | int bound = 0, error = 0; | 6430 | static int done, bound; |
6431 | int error = 0; | ||
6316 | 6432 | ||
6317 | pthread_mutex_lock(&mutex); | 6433 | if ((error = pthread_mutex_lock(&mutex))) |
6434 | return error; | ||
6435 | |||
6436 | if (done) | ||
6437 | goto epilog; | ||
6318 | 6438 | ||
6319 | if (!CRYPTO_get_locking_callback()) { | 6439 | if (!CRYPTO_get_locking_callback()) { |
6320 | if (!mt_state.lock) { | 6440 | if (!mt_state.lock) { |
@@ -6324,11 +6444,20 @@ static int mt_init(void) { | |||
6324 | 6444 | ||
6325 | if (!(mt_state.lock = malloc(mt_state.nlock * sizeof *mt_state.lock))) { | 6445 | if (!(mt_state.lock = malloc(mt_state.nlock * sizeof *mt_state.lock))) { |
6326 | error = errno; | 6446 | error = errno; |
6327 | goto leave; | 6447 | goto epilog; |
6328 | } | 6448 | } |
6329 | 6449 | ||
6330 | for (i = 0; i < mt_state.nlock; i++) { | 6450 | for (i = 0; i < mt_state.nlock; i++) { |
6331 | pthread_mutex_init(&mt_state.lock[i], NULL); | 6451 | if ((error = pthread_mutex_init(&mt_state.lock[i], NULL))) { |
6452 | while (i > 0) { | ||
6453 | pthread_mutex_destroy(&mt_state.lock[--i]); | ||
6454 | } | ||
6455 | |||
6456 | free(mt_state.lock); | ||
6457 | mt_state.lock = NULL; | ||
6458 | |||
6459 | goto epilog; | ||
6460 | } | ||
6332 | } | 6461 | } |
6333 | } | 6462 | } |
6334 | 6463 | ||
@@ -6341,27 +6470,11 @@ static int mt_init(void) { | |||
6341 | bound = 1; | 6470 | bound = 1; |
6342 | } | 6471 | } |
6343 | 6472 | ||
6344 | /* | 6473 | if (bound && (error = dl_anchor())) |
6345 | * Prevent loader from unlinking us if we've registered a callback | 6474 | goto epilog; |
6346 | * with OpenSSL by taking another reference to ourselves. | ||
6347 | */ | ||
6348 | #if HAVE_DLADDR | ||
6349 | if (bound && !mt_state.dlref) { | ||
6350 | Dl_info info; | ||
6351 | |||
6352 | if (!dladdr((void *)&luaopen__openssl_rand, &info)) { | ||
6353 | error = -1; | ||
6354 | goto leave; | ||
6355 | } | ||
6356 | 6475 | ||
6357 | if (!(mt_state.dlref = dlopen(info.dli_fname, RTLD_NOW|RTLD_LOCAL))) { | 6476 | done = 1; |
6358 | error = -1; | 6477 | epilog: |
6359 | goto leave; | ||
6360 | } | ||
6361 | } | ||
6362 | #endif | ||
6363 | |||
6364 | leave: | ||
6365 | pthread_mutex_unlock(&mutex); | 6478 | pthread_mutex_unlock(&mutex); |
6366 | 6479 | ||
6367 | return error; | 6480 | return error; |
@@ -6381,15 +6494,6 @@ static void initall(lua_State *L) { | |||
6381 | } | 6494 | } |
6382 | } | 6495 | } |
6383 | 6496 | ||
6384 | /* TODO: Move down to after SSL_load_error_strings */ | ||
6385 | if ((error = compat_init())) { | ||
6386 | if (error == -1) { | ||
6387 | throwssl(L, "openssl.init"); | ||
6388 | } else { | ||
6389 | luaL_error(L, "openssl.init: %s", xstrerror(error)); | ||
6390 | } | ||
6391 | } | ||
6392 | |||
6393 | pthread_mutex_lock(&mutex); | 6497 | pthread_mutex_lock(&mutex); |
6394 | 6498 | ||
6395 | if (!initssl) { | 6499 | if (!initssl) { |
@@ -6404,17 +6508,25 @@ static void initall(lua_State *L) { | |||
6404 | * already been configured. | 6508 | * already been configured. |
6405 | */ | 6509 | */ |
6406 | OPENSSL_config(NULL); | 6510 | OPENSSL_config(NULL); |
6511 | } | ||
6407 | 6512 | ||
6408 | if ((error = ex_initonce())) { | 6513 | pthread_mutex_unlock(&mutex); |
6409 | if (error == -1) { | 6514 | |
6410 | throwssl(L, "openssl.init"); | 6515 | if ((error = compat_init())) { |
6411 | } else { | 6516 | if (error == -1) { |
6412 | luaL_error(L, "openssl.init: %s", xstrerror(error)); | 6517 | throwssl(L, "openssl.init"); |
6413 | } | 6518 | } else { |
6519 | luaL_error(L, "openssl.init: %s", xstrerror(error)); | ||
6414 | } | 6520 | } |
6415 | } | 6521 | } |
6416 | 6522 | ||
6417 | pthread_mutex_unlock(&mutex); | 6523 | if ((error = ex_init())) { |
6524 | if (error == -1) { | ||
6525 | throwssl(L, "openssl.init"); | ||
6526 | } else { | ||
6527 | luaL_error(L, "openssl.init: %s", xstrerror(error)); | ||
6528 | } | ||
6529 | } | ||
6418 | 6530 | ||
6419 | ex_newstate(L); | 6531 | ex_newstate(L); |
6420 | 6532 | ||
@@ -6436,5 +6548,3 @@ static void initall(lua_State *L) { | |||
6436 | addclass(L, CIPHER_CLASS, cipher_methods, cipher_metatable); | 6548 | addclass(L, CIPHER_CLASS, cipher_methods, cipher_metatable); |
6437 | } /* initall() */ | 6549 | } /* initall() */ |
6438 | 6550 | ||
6439 | |||
6440 | #endif /* LUAOSSL_H */ | ||