static void locks_cleanup(JNIEnv *env) { int i; static int (*dlsym_CRYPTO_num_locks) (void); dlsym_CRYPTO_num_locks = do_dlsym(env, openssl, "CRYPTO_num_locks"); static void (*dlsym_CRYPTO_set_locking_callback) (void (*)()); dlsym_CRYPTO_set_locking_callback = do_dlsym(env, openssl, "CRYPTO_set_locking_callback"); dlsym_CRYPTO_set_locking_callback(NULL); for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) { pthread_mutex_destroy(&(lock_cs[i])); } dlsym_CRYPTO_free(lock_cs); }
static void locks_setup(JNIEnv *env) { int i; static int (*dlsym_CRYPTO_num_locks) (void); dlsym_CRYPTO_num_locks = do_dlsym(env, openssl, "CRYPTO_num_locks"); lock_cs = dlsym_CRYPTO_malloc(dlsym_CRYPTO_num_locks() * \ sizeof(pthread_mutex_t), __FILE__, __LINE__); for (i = 0; i < dlsym_CRYPTO_num_locks(); i++) { pthread_mutex_init(&(lock_cs[i]), NULL); } static void (*dlsym_CRYPTO_set_id_callback) (unsigned long (*)()); dlsym_CRYPTO_set_id_callback = do_dlsym(env, openssl, "CRYPTO_set_id_callback"); static void (*dlsym_CRYPTO_set_locking_callback) (void (*)()); dlsym_CRYPTO_set_locking_callback = do_dlsym(env, openssl, "CRYPTO_set_locking_callback"); dlsym_CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); dlsym_CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback); }
void* dlsym_impl(void* handle, const char* symbol, const char* version, void* caller_addr) { ScopedPthreadMutexLocker locker(&g_dl_mutex); g_linker_logger.ResetState(); void* result; if (!do_dlsym(handle, symbol, version, caller_addr, &result)) { __bionic_format_dlerror(linker_get_error_buffer(), nullptr); return nullptr; } return result; }
static void openssl_rand_clean(JNIEnv *env, ENGINE *eng, int clean_locks) { if (NULL != eng) { dlsym_ENGINE_finish(eng); dlsym_ENGINE_free(eng); } if (dlsym_OpenSSL_version_num() < VERSION_1_1_X) { static void (*dlsym_ENGINE_cleanup) (void); if((dlsym_ENGINE_cleanup = do_dlsym(env, openssl, "ENGINE_cleanup")) == NULL) { THROW(env, "java/lang/UnsatisfiedLinkError", "ENGINE_cleanup"); } dlsym_ENGINE_cleanup(); if (clean_locks) { locks_cleanup(env); } } }
/** * If using an Intel chipset with RDRAND, the high-performance hardware * random number generator will be used. */ static ENGINE * openssl_rand_init(JNIEnv *env) { if (dlsym_OpenSSL_version_num() < VERSION_1_1_X) { locks_setup(env); static void (*dlsym_ENGINE_load_rdrand) (void); dlsym_ENGINE_load_rdrand = do_dlsym(env, openssl, "ENGINE_load_rdrand"); dlsym_ENGINE_load_rdrand(); } ENGINE *eng = dlsym_ENGINE_by_id("rdrand"); int ret = -1; do { if (NULL == eng) { break; } int rc = dlsym_ENGINE_init(eng); if (0 == rc) { break; } rc = dlsym_ENGINE_set_default(eng, ENGINE_METHOD_RAND); if (0 == rc) { break; } ret = 0; } while(0); if (ret == -1) { openssl_rand_clean(env, eng, 0); } return eng; }
static Handle_Type *dynamic_link_module (SLFUTURE_CONST char *module) { Handle_Type *h; VOID_STAR handle; SLFUTURE_CONST char *err; char filebuf[1024]; char *save_file; char *save_err; int api_version; int *api_version_ptr; #define MAX_MODULE_NAME_SIZE 256 char module_so[MAX_MODULE_NAME_SIZE + 32]; char *module_name; char *file, *pathfile; if (strlen (module) >= MAX_MODULE_NAME_SIZE) { _pSLang_verror (SL_LimitExceeded_Error, "module name too long"); return NULL; } SLsnprintf (module_so, sizeof(module_so), "%s-module.%s", module, SO_SUFFIX); if (Module_Path != NULL) pathfile = SLpath_find_file_in_path (Module_Path, module_so); else pathfile = NULL; if ((pathfile == NULL) && (NULL != (pathfile = _pSLsecure_getenv (MODULE_PATH_ENV_NAME)))) pathfile = SLpath_find_file_in_path (pathfile, module_so); if (pathfile == NULL) pathfile = SLpath_find_file_in_path (MODULE_INSTALL_DIR, module_so); if (pathfile != NULL) file = pathfile; else file = module_so; save_err = NULL; save_file = file; while (1) { #ifndef RTLD_GLOBAL # define RTLD_GLOBAL 0 #endif #ifdef RTLD_NOW handle = (VOID_STAR) dlopen (file, RTLD_NOW | RTLD_GLOBAL); #else handle = (VOID_STAR) dlopen (file, RTLD_LAZY | RTLD_GLOBAL); #endif if (handle != NULL) { if (_pSLang_Load_File_Verbose & SLANG_LOAD_MODULE_VERBOSE) SLang_vmessage ("Importing %s", file); if (save_err != NULL) SLfree (save_err); break; } /* Purify reports that dlerror returns a pointer that generates UMR * errors. There is nothing that I can do about that.... */ if ((NULL == strchr (file, '/')) && (strlen(file) < sizeof(filebuf))) { err = (char *) dlerror (); if (err != NULL) save_err = SLmake_string (err); SLsnprintf (filebuf, sizeof (filebuf), "./%s", file); file = filebuf; continue; } if ((NULL == (err = save_err)) && (NULL == (err = (char *) dlerror ()))) err = "UNKNOWN"; _pSLang_verror (SL_Import_Error, "Error linking to %s: %s", save_file, err); if (save_err != NULL) SLfree (save_err); if (pathfile != NULL) SLfree (pathfile); return NULL; } /* Using SLpath_basename allows, e.g., import ("/path/to/module"); */ module_name = SLpath_basename (module); api_version_ptr = (int *) do_dlsym (handle, file, 0, "SLmodule_%s_api_version", module_name); if (api_version_ptr == NULL) api_version_ptr = (int *) do_dlsym (handle, file, 0, "_SLmodule_%s_api_version", module_name); if (api_version_ptr == NULL) api_version = 0; else api_version = *api_version_ptr; if ((-1 == check_api_version (file, api_version)) || (NULL == (h = allocate_handle_type (module, handle)))) { SLfree (pathfile); /* NULL ok */ dlclose (handle); return NULL; } if (NULL == (h->ns_init_fun = (int (*)(SLCONST char *)) do_dlsym (handle, file, 1, "init_%s_module_ns", module_name))) { SLfree (pathfile); free_handle_type (h); dlclose (handle); return NULL; } h->deinit_fun = (void (*)(void)) do_dlsym (handle, file, 0, "deinit_%s_module", module_name); SLfree (pathfile); /* NULL ok */ h->next = Handle_List; Handle_List = h; return h; }