Fix use after free issue 47/319847/1
authorHwankyu Jhun <h.jhun@samsung.com>
Mon, 4 Nov 2024 11:35:00 +0000 (20:35 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Mon, 4 Nov 2024 11:35:00 +0000 (20:35 +0900)
When the task instance is deleted before returning the ThreadLoop method,
it causes the use-after-free issue. This patch adds the local variable
not to remove the task instance before returning the ThreadLoop method.

Change-Id: I31f98586965f483f2258ff72f933a06589d2d3ac
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
src/tizen-core/stub.cc
src/tizen-core/task.cc

index b5940b2b0bbf63ef37aa5e6414eced018ecb14e4..9fe6c83fdef293978ea630bb17b02c06cf11e079 100644 (file)
@@ -189,6 +189,7 @@ API int tizen_core_task_destroy(tizen_core_task_h task) {
 
   auto* handle = static_cast<tizen_core::Task*>(task);
   if (handle->GetRefCount() == 1) handle->Dispose();
+  if (handle->IsRunning()) handle->Quit();
   handle->UnrefSelf();
   return TIZEN_CORE_ERROR_NONE;
 }
index 8c9656c4748c751f05f88b276ca5af68e08be5ed..b6fa04a589caf160347fe9aa3d2176278430bc00 100644 (file)
@@ -203,21 +203,16 @@ Task::Task(std::string name, bool use_thread)
   context_ = ContextManager::GetInst().Create(name_, use_thread_);
   if (context_ == nullptr)
     throw std::invalid_argument("failed to create context");
-
-  loop_ = g_main_loop_new(context_->GetHandle(), FALSE);
 }
 
 Task::~Task() {
   _W("~Task: %s", name_.c_str());
-  Quit();
   if (use_thread_ && thread_.joinable()) {
     if (pthread_self() == thread_.native_handle())
       thread_.detach();
     else
       thread_.join();
   }
-
-  g_main_loop_unref(loop_);
 }
 
 std::shared_ptr<Task> Task::Create(std::string name, bool use_thread) {
@@ -240,11 +235,12 @@ std::shared_ptr<Context> Task::GetContext() const {
 }
 
 void Task::Quit() {
-  if (g_main_loop_is_running(loop_))
+  if (loop_ && g_main_loop_is_running(loop_))
     g_main_loop_quit(loop_);
 }
 
 void Task::Run() {
+  loop_ = g_main_loop_new(context_->GetHandle(), FALSE);
   if (use_thread_) {
     std::unique_lock<std::mutex> lock(loop_mutex_);
     idle_entered_ = false;
@@ -258,6 +254,8 @@ void Task::Run() {
   } else {
     tid_ = getpid();
     g_main_loop_run(loop_);
+    g_main_loop_unref(loop_);
+    loop_ = nullptr;
 
     while (g_main_context_pending(context_->GetHandle()))
       g_main_context_dispatch(context_->GetHandle());
@@ -267,6 +265,7 @@ void Task::Run() {
 }
 
 bool Task::IsRunning() const {
+  if (loop_ == nullptr) return false;
   return g_main_loop_is_running(loop_);
 }
 
@@ -389,6 +388,7 @@ bool Task::ClearCpuBoosting() {
 
 void Task::ThreadLoop() {
   _D("[%s] BEGIN", name_.c_str());
+  auto self = shared_from_this();
   {
     std::unique_lock<std::mutex> lock(loop_mutex_);
     GSource* source = g_idle_source_new();
@@ -411,6 +411,8 @@ void Task::ThreadLoop() {
 
   pthread_setname_np(pthread_self(), name_.c_str());
   g_main_loop_run(loop_);
+  g_main_loop_unref(loop_);
+  loop_ = nullptr;
 
   while (g_main_context_pending(context_->GetHandle()))
     g_main_context_dispatch(context_->GetHandle());