From: min7.choi Date: Fri, 2 Oct 2015 06:03:29 +0000 (+0900) Subject: Add openssl lock and protect pthread_cancel crash X-Git-Tag: accepted/tizen/mobile/20151006.224850^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=230c9b10738ce63544d1cd2e28936761d2d94b49;p=platform%2Fframework%2Fweb%2Fdownload-provider.git Add openssl lock and protect pthread_cancel crash Change-Id: I40f642eb5a5fe9c703240d2f1c5b45b028cf662e Signed-off-by: min7.choi --- diff --git a/agent/download-agent-dl-info.c b/agent/download-agent-dl-info.c index 6e49145..bdaaf36 100644 --- a/agent/download-agent-dl-info.c +++ b/agent/download-agent-dl-info.c @@ -16,6 +16,8 @@ #include #include +#include +#include #include "download-agent-dl-info.h" #include "download-agent-http-mgr.h" @@ -23,6 +25,61 @@ static pthread_mutex_t mutex_da_info_list = PTHREAD_MUTEX_INITIALIZER; + +/* locking mechnism for safe use of openssl context */ +static void openssl_lock_callback(int mode, int type, char *file, int line) +{ + DA_LOGV("type [%d], mode [%d]", type, mode); + (void)file; + (void)line; + + if (mode & CRYPTO_LOCK) + pthread_mutex_lock(&(g_openssl_locks_list[type])); + else + pthread_mutex_unlock(&(g_openssl_locks_list[type])); +} + +static unsigned long thread_id(void) +{ + unsigned long ret = (unsigned long)pthread_self(); + return ret; +} + +da_ret_t init_openssl_locks(void) +{ + DA_LOGD(""); + int index; + int crypto_num_locks = CRYPTO_num_locks(); + DA_LOGD("crypto_num_locks [%d]", crypto_num_locks); + g_openssl_locks_list = (pthread_mutex_t *)OPENSSL_malloc(crypto_num_locks * sizeof(pthread_mutex_t)); + if (g_openssl_locks_list == DA_NULL) { + DA_LOGE("Failed to OPENSSL_malloc"); + return DA_ERR_FAIL_TO_MEMALLOC; + } + for (index = 0; index < crypto_num_locks; index++) { + pthread_mutex_init(&(g_openssl_locks_list[index]), NULL); + } + CRYPTO_set_id_callback((unsigned long (*)())thread_id); + CRYPTO_set_locking_callback((void (*)())openssl_lock_callback); + + return DA_RESULT_OK; +} +da_ret_t deinit_openssl_locks(void) +{ + DA_LOGD(""); + int index; + int crypto_num_locks = CRYPTO_num_locks(); + for (index = 0; index < crypto_num_locks; index++) { + pthread_mutex_destroy(&(g_openssl_locks_list[index])); + } + CRYPTO_set_id_callback(NULL); + CRYPTO_set_locking_callback(NULL); + OPENSSL_free(g_openssl_locks_list); + g_openssl_locks_list = NULL; + + return DA_RESULT_OK; +} + static void __init_da_info(int id) { da_info_t *da_info = DA_NULL; diff --git a/agent/download-agent-interface.c b/agent/download-agent-interface.c index 0b19813..5f54265 100755 --- a/agent/download-agent-interface.c +++ b/agent/download-agent-interface.c @@ -21,6 +21,7 @@ int da_init() { DA_LOGV(""); da_ret_t ret = DA_RESULT_OK; + ret = init_openssl_locks(); DA_LOGI("Return ret = %d", ret); return ret; } @@ -31,6 +32,7 @@ int da_deinit() DA_LOGV(""); destroy_da_info_list(); + deinit_openssl_locks(); DA_LOGI("====== da_deint EXIT ====="); return ret; } diff --git a/agent/include/download-agent-dl-info.h b/agent/include/download-agent-dl-info.h index 820135e..ad93f85 100644 --- a/agent/include/download-agent-dl-info.h +++ b/agent/include/download-agent-dl-info.h @@ -169,6 +169,7 @@ typedef struct { int update_time; } da_info_t; +pthread_mutex_t *g_openssl_locks_list; da_info_t *da_info_list[DA_MAX_ID]; #define GET_STATE_MUTEX(INFO) (INFO->mutex_state) @@ -180,6 +181,8 @@ da_info_t *da_info_list[DA_MAX_ID]; DA_MUTEX_UNLOCK (&GET_STATE_MUTEX(INFO));\ } +da_ret_t init_openssl_locks(void); +da_ret_t deinit_openssl_locks(void); da_ret_t get_available_da_id(int *available_id); da_ret_t copy_user_input_data(da_info_t *da_info, const char *url, req_data_t *ext_data, da_cb_t *da_cb_data); diff --git a/packaging/download-provider.spec b/packaging/download-provider.spec index 7e8bb7e..b429f02 100644 --- a/packaging/download-provider.spec +++ b/packaging/download-provider.spec @@ -1,7 +1,7 @@ %define _ux_define tizen2.3 Name: download-provider Summary: Download the contents in background -Version: 2.1.23 +Version: 2.1.24 Release: 0 Group: Development/Libraries License: Apache License, Version 2.0 diff --git a/provider/download-provider-notification-manager.c b/provider/download-provider-notification-manager.c index ea89c0c..c076611 100644 --- a/provider/download-provider-notification-manager.c +++ b/provider/download-provider-notification-manager.c @@ -540,13 +540,15 @@ void dp_notification_manager_kill() if (g_dp_notification_manager_tid > 0 && pthread_kill(g_dp_notification_manager_tid, 0) != ESRCH) { //send signal to notification thread - g_dp_notification_manager_tid = 0; + int status; + pthread_t tid; + tid = g_dp_notification_manager_tid; CLIENT_MUTEX_LOCK(&g_dp_notification_manager_mutex); + g_dp_notification_manager_tid = 0; pthread_cond_signal(&g_dp_notification_manager_cond); CLIENT_MUTEX_UNLOCK(&g_dp_notification_manager_mutex); - pthread_cancel(g_dp_notification_manager_tid); - int status; - pthread_join(g_dp_notification_manager_tid, (void **)&status); + pthread_cancel(tid); + pthread_join(tid, (void **)&status); } } #else diff --git a/provider/download-provider-queue-manager.c b/provider/download-provider-queue-manager.c index 41f4a36..4094b02 100644 --- a/provider/download-provider-queue-manager.c +++ b/provider/download-provider-queue-manager.c @@ -304,12 +304,14 @@ void dp_queue_manager_kill() if (g_dp_queue_manager_tid > 0 && pthread_kill(g_dp_queue_manager_tid, 0) != ESRCH) { //send signal to queue thread - g_dp_queue_manager_tid = 0; + int status; + pthread_t tid; + tid = g_dp_queue_manager_tid; CLIENT_MUTEX_LOCK(&g_dp_queue_manager_mutex); + g_dp_queue_manager_tid = 0; pthread_cond_signal(&g_dp_queue_manager_cond); CLIENT_MUTEX_UNLOCK(&g_dp_queue_manager_mutex); - pthread_cancel(g_dp_queue_manager_tid); - int status; - pthread_join(g_dp_queue_manager_tid, (void **)&status); + pthread_cancel(tid); + pthread_join(tid, (void **)&status); } }