Wait for download thread before destroying da_info 66/240966/5 accepted/tizen/unified/20200818.130009 submit/tizen/20200814.045951
authorSeonah Moon <seonah1.moon@samsung.com>
Thu, 13 Aug 2020 08:37:48 +0000 (17:37 +0900)
committerSeonah Moon <seonah1.moon@samsung.com>
Thu, 13 Aug 2020 09:09:17 +0000 (18:09 +0900)
A cancel request doesn't take effect immediately. (__http_gotheaders_cb)
So, below scenario can occur.

1. client-request thread requests cancel a download for a number of reasons. (ex. zombie client)
2. client-request thread is terminated.
3. queue-manager deallocates da_info_list for terminating.
4. download is canceled and then a http thread accesses to da_info for notifying download terminated.
5. heap-use-after-free occurs.

Change-Id: I47a7ef4c4d7ddda5f4594ee30885e3af230c6116

agent/download-agent-dl-info.c
agent/include/download-agent-dl-info.h
packaging/download-provider.spec

index e866836..b65003a 100644 (file)
@@ -17,6 +17,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <curl/curl.h>
+#include <pthread.h>
 
 #ifdef USE_SSL_THREAD_LOCKING
 #include <openssl/crypto.h>
@@ -126,7 +127,7 @@ static void __init_da_info(int id)
        }
 
        da_info->da_id = DA_INVALID_ID;
-       da_info->tid = DA_INVALID_ID;
+       da_info->thread_id = 0;
        memset(&(da_info->cb_info), 0x00, sizeof(da_cb_t));
        da_info->is_cb_update = DA_FALSE;
        da_info->http_info = http_info;
@@ -499,6 +500,12 @@ void destroy_da_info_list()
        DA_MUTEX_LOCK(&mutex_da_info_list);
        for (i = 0; i < DA_MAX_ID; i++) {
                if (DA_NULL != da_info_list[i]) {
+                       if (da_info_list[i]->thread_id) {
+                               DA_LOGI("%lu is running. wait for the download thread.",
+                                               da_info_list[i]->thread_id);
+                               pthread_join(da_info_list[i]->thread_id, NULL);
+                       }
+
                        if (da_info_list[i]->req_info) {
                                __destroy_req_info(da_info_list[i]->req_info);
                                da_info_list[i]->req_info = DA_NULL;
@@ -537,7 +544,7 @@ void destroy_da_info(int id)
                        da_info->file_info = DA_NULL;
                }
                da_info->da_id = DA_INVALID_ID;
-               da_info->tid = DA_INVALID_ID;
+               da_info->thread_id = 0;
                memset(&(da_info->cb_info), 0x00, sizeof(da_cb_t));
                free(da_info);
                da_info_list[id] = DA_NULL;
index 10d2f87..445a025 100644 (file)
@@ -167,7 +167,6 @@ typedef struct {
 
 typedef struct {
        int da_id;
-       int tid;
        pthread_t thread_id;
        http_info_t *http_info;
        file_info_t *file_info;
index 816c53e..6bae5f4 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       download-provider
 Summary:    Download the contents in background
-Version:    2.2.0
+Version:    2.2.1
 Release:    0
 Group:      Development/Libraries
 License:    Apache-2.0