Fix tts_client_is_valid() use uid as a parameter 93/248493/5
authorSuyeon Hwang <stom.hwang@samsung.com>
Wed, 11 Nov 2020 05:35:53 +0000 (14:35 +0900)
committerSuyeon Hwang <stom.hwang@samsung.com>
Thu, 18 Mar 2021 07:58:30 +0000 (16:58 +0900)
Using the pointer as a parameter may be simple and fast implementation.
However, this program creates a sub thread that the app can not manage and this
sub thread can not know whether the pointer of client is dereferenced.

Thus, using a pointer can occur heap-use-after-free problem in this case.

To remove this kind of issue, this patch changes the parameter from pointer to
integer value uid.
But the code still direct access to pointer

Change-Id: Id657922b0c4c405a525d6cb8ce39516e59a9a744
Signed-off-by: Suyeon Hwang <stom.hwang@samsung.com>
client/tts_client.c
client/tts_client.h
client/tts_core.c

index caec6fc..8b1d16e 100644 (file)
@@ -287,13 +287,13 @@ tts_client_s* tts_client_get_by_uid(const int uid)
        return NULL;
 }
 
-bool tts_client_is_valid(tts_h tts)
+bool tts_client_is_valid(int uid)
 {
-       tts_client_s* client = tts_client_get(tts);
-       if (NULL == client) {
+       if (NULL == tts_client_get_by_uid(uid)) {
                SLOG(LOG_WARN, TAG_TTSC, "[WARNING] A handle is not valid");
                return false;
        }
+
        return true;
 }
 
@@ -387,7 +387,7 @@ GList* tts_client_get_client_list()
 
 void tts_client_set_state_changed_cb(tts_client_s* client, tts_state_changed_cb callback, void* user_data)
 {
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                return;
        }
 
@@ -402,7 +402,7 @@ void tts_client_set_state_changed_cb(tts_client_s* client, tts_state_changed_cb
 
 void tts_client_set_utterance_started_cb(tts_client_s* client, tts_utterance_started_cb callback, void* user_data)
 {
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                return;
        }
        __set_utterance_started_cb(client, callback, user_data);
@@ -410,7 +410,7 @@ void tts_client_set_utterance_started_cb(tts_client_s* client, tts_utterance_sta
 
 void tts_client_set_utterance_completed_cb(tts_client_s* client, tts_utterance_completed_cb callback, void* user_data)
 {
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                return;
        }
        __set_utterance_completed_cb(client, callback, user_data);
@@ -418,7 +418,7 @@ void tts_client_set_utterance_completed_cb(tts_client_s* client, tts_utterance_c
 
 void tts_client_set_error_cb(tts_client_s* client, tts_error_cb callback, void* user_data)
 {
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                return;
        }
 
@@ -433,7 +433,7 @@ void tts_client_set_error_cb(tts_client_s* client, tts_error_cb callback, void*
 
 void tts_client_set_default_voice_changed_cb(tts_client_s* client, tts_default_voice_changed_cb callback, void* user_data)
 {
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                return;
        }
        __set_default_voice_changed_cb(client, callback, user_data);
@@ -441,7 +441,7 @@ void tts_client_set_default_voice_changed_cb(tts_client_s* client, tts_default_v
 
 void tts_client_set_engine_changed_cb(tts_client_s* client, tts_engine_changed_cb callback, void* user_data)
 {
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                return;
        }
        __set_engine_changed_cb(client, callback, user_data);
@@ -449,7 +449,7 @@ void tts_client_set_engine_changed_cb(tts_client_s* client, tts_engine_changed_c
 
 void tts_client_set_supported_voice_cb(tts_client_s* client, tts_supported_voice_cb callback, void* user_data)
 {
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                return;
        }
        __set_supported_voice_cb(client, callback, user_data);
@@ -457,7 +457,7 @@ void tts_client_set_supported_voice_cb(tts_client_s* client, tts_supported_voice
 
 void tts_client_unset_all_cb(tts_client_s* client)
 {
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                return;
        }
 
index 4bb82ed..bd3e8e5 100644 (file)
@@ -87,7 +87,7 @@ tts_client_s* tts_client_get(tts_h tts);
 
 tts_client_s* tts_client_get_by_uid(const int uid);
 
-bool tts_client_is_valid(tts_h tts);
+bool tts_client_is_valid(int uid);
 
 int tts_client_get_size();
 
index 587d066..3f6a1e2 100644 (file)
@@ -126,9 +126,10 @@ static inline void __client_state_changed_cb(tts_client_s* client, tts_state_e b
 
 static Eina_Bool __notify_error_timer_cb(void *data)
 {
-       tts_client_s* client = (tts_client_s*)data;
+       int uid = (int)data;
+       tts_client_s* client = tts_client_get_by_uid(uid);
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
        } else {
                __client_error_cb(client, client->utt_id, client->reason);
@@ -140,9 +141,10 @@ static Eina_Bool __notify_error_timer_cb(void *data)
 
 static Eina_Bool __notify_state_timer_cb(void *data)
 {
-       tts_client_s* client = (tts_client_s*)data;
+       int uid = (int)data;
+       tts_client_s* client = tts_client_get_by_uid(uid);
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
        } else {
                __client_state_changed_cb(client, client->before_state, client->current_state);
@@ -375,7 +377,7 @@ static void __end_reprepare_thread(void* data, Ecore_Thread* thread)
 
                while (NULL != iter) {
                        tts_client_s* client = iter->data;
-                       if (NULL != client && tts_client_is_valid(client->tts)) {
+                       if (NULL != client) {
                                tts_core_prepare(client);
                        }
 
@@ -444,12 +446,12 @@ static int __send_hello_msg(tts_client_s* client)
 
 static Eina_Bool __prepare_cb(void *data)
 {
-       tts_client_s* client = (tts_client_s*)data;
+       int uid = (int)data;
+       tts_client_s* client = tts_client_get_by_uid(uid);
 
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
-               client->hello_timer = NULL;
                return EINA_FALSE;
        }
 
@@ -478,12 +480,12 @@ static Eina_Bool __prepare_cb(void *data)
 static Eina_Bool __prepare_first_cb(void *data)
 {
        /* send first hello message */
-       tts_client_s* client = (tts_client_s*)data;
+       int uid = (int)data;
+       tts_client_s* client = tts_client_get_by_uid(uid);
 
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
-               client->hello_timer = NULL;
                return EINA_FALSE;
        }
 
@@ -502,12 +504,6 @@ static Eina_Bool __prepare_first_cb(void *data)
 
 static Eina_Bool __prepare_sync_cb(tts_client_s* client)
 {
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
-               SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
-               client->hello_timer = NULL;
-               return EINA_FALSE;
-       }
-
        // TODO: make function duplicated block
        bool is_launched = __is_engine_launched(client->mode);
        SLOG(LOG_INFO, TAG_TTSC, "[INFO] tts engine is launched(%d)", is_launched);
@@ -551,12 +547,6 @@ static Eina_Bool __prepare_sync_cb(tts_client_s* client)
        }
        // TODO: make function duplicated block
 
-       /* check handle */
-       if (false == tts_client_is_valid(client->tts)) {
-               SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] A handle is not valid");
-               return EINA_FALSE;
-       }
-
        client->before_state = client->current_state;
        client->current_state = TTS_STATE_READY;
        __client_state_changed_cb(client, client->before_state, client->current_state);
@@ -625,7 +615,7 @@ int tts_core_deinitialize()
 int tts_core_notify_state_changed(tts_client_s* client, tts_state_e before_state, tts_state_e current_state)
 {
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
                return TTS_ERROR_INVALID_PARAMETER;
        }
@@ -639,7 +629,7 @@ int tts_core_notify_state_changed(tts_client_s* client, tts_state_e before_state
 int tts_core_notify_state_changed_async(tts_client_s* client, tts_state_e before_state, tts_state_e current_state)
 {
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
                return TTS_ERROR_INVALID_PARAMETER;
        }
@@ -653,7 +643,7 @@ int tts_core_notify_state_changed_async(tts_client_s* client, tts_state_e before
                if (NULL != client->notify_state_timer) {
                        ecore_timer_del(client->notify_state_timer);
                }
-               client->notify_state_timer = ecore_timer_add(0, __notify_state_timer_cb, (void*)client);
+               client->notify_state_timer = ecore_timer_add(0, __notify_state_timer_cb, (void*)client->uid);
        } else {
                SLOG(LOG_WARN, TAG_TTSC, "No registered callback(state changed)");
        }
@@ -664,7 +654,7 @@ int tts_core_notify_state_changed_async(tts_client_s* client, tts_state_e before
 int tts_core_notify_utt_started(tts_client_s* client, int utt_id)
 {
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
                return TTS_ERROR_INVALID_PARAMETER;
        }
@@ -686,7 +676,7 @@ int tts_core_notify_utt_started(tts_client_s* client, int utt_id)
 int tts_core_notify_utt_completeted(tts_client_s* client, int utt_id)
 {
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
                return TTS_ERROR_INVALID_PARAMETER;
        }
@@ -708,7 +698,7 @@ int tts_core_notify_utt_completeted(tts_client_s* client, int utt_id)
 int tts_core_notify_error(tts_client_s* client, int utt_id, tts_error_e reason)
 {
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
                return TTS_ERROR_INVALID_PARAMETER;
        }
@@ -722,7 +712,7 @@ int tts_core_notify_error(tts_client_s* client, int utt_id, tts_error_e reason)
 int tts_core_notify_error_async(tts_client_s* client, int utt_id, tts_error_e reason)
 {
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
                return TTS_ERROR_INVALID_PARAMETER;
        }
@@ -736,7 +726,7 @@ int tts_core_notify_error_async(tts_client_s* client, int utt_id, tts_error_e re
                if (NULL != client->notify_error_timer) {
                        ecore_timer_del(client->notify_error_timer);
                }
-               client->notify_error_timer = ecore_timer_add(0, __notify_error_timer_cb, (void*)client);
+               client->notify_error_timer = ecore_timer_add(0, __notify_error_timer_cb, (void*)client->uid);
        } else {
                SLOG(LOG_WARN, TAG_TTSC, "No registered callback(error)");
        }
@@ -747,7 +737,7 @@ int tts_core_notify_error_async(tts_client_s* client, int utt_id, tts_error_e re
 int tts_core_notify_default_voice_changed(tts_client_s* client, const char* before_lang, int before_voice_type, const char* language, int voice_type)
 {
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
                return TTS_ERROR_INVALID_PARAMETER;
        }
@@ -775,7 +765,7 @@ int tts_core_notify_default_voice_changed(tts_client_s* client, const char* befo
 int tts_core_notify_engine_changed(tts_client_s* client, const char* engine_id, const char* language, int voice_type, bool need_credential)
 {
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
                return TTS_ERROR_INVALID_PARAMETER;
        }
@@ -803,7 +793,7 @@ int tts_core_notify_engine_changed(tts_client_s* client, const char* engine_id,
 int tts_core_notify_supported_voice(tts_client_s* client, const char* language, int voice_type)
 {
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
                return TTS_ERROR_INVALID_PARAMETER;
        }
@@ -875,7 +865,7 @@ const char* tts_core_get_engine_name()
 int tts_core_prepare(tts_client_s* client)
 {
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
                return TTS_ERROR_INVALID_PARAMETER;
        }
@@ -885,7 +875,7 @@ int tts_core_prepare(tts_client_s* client)
                SLOG(LOG_ERROR, TAG_TTSC, "Register timer for __prepare_first_cb");
 
                ecore_thread_main_loop_begin();
-               client->hello_timer = ecore_timer_add(0.0, __prepare_first_cb, (void*)client);
+               client->hello_timer = ecore_timer_add(0.0, __prepare_first_cb, (void*)client->uid);
                ecore_thread_main_loop_end();
        } else {
                LOGD("Client is already trying to prepare");
@@ -897,7 +887,7 @@ int tts_core_prepare(tts_client_s* client)
 int tts_core_prepare_sync(tts_client_s* client)
 {
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
                return TTS_ERROR_INVALID_PARAMETER;
        }
@@ -921,7 +911,7 @@ int tts_core_prepare_sync(tts_client_s* client)
 int tts_core_unprepare(tts_client_s* client, bool is_screen_reader_on)
 {
        /* check handle */
-       if (NULL == client || false == tts_client_is_valid(client->tts)) {
+       if (NULL == client || false == tts_client_is_valid(client->uid)) {
                SLOG(LOG_ERROR, TAG_TTSC, "[ERROR] Handle is not valid.");
                return TTS_ERROR_INVALID_PARAMETER;
        }
@@ -999,7 +989,7 @@ int tts_core_reprepare()
 
                while (NULL != iter) {
                        tts_client_s* client = iter->data;
-                       if (NULL != client && tts_client_is_valid(client->tts)) {
+                       if (NULL != client && tts_client_is_valid(client->uid)) {
                                client->current_state = TTS_STATE_CREATED;
                                client->reason = TTS_ERROR_NONE;
                        }