diff options
| -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 */ | ||
