Fix double free issue 85/317985/3
authorpjh9216 <jh9216.park@samsung.com>
Fri, 10 Jan 2025 09:01:15 +0000 (18:01 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Fri, 10 Jan 2025 10:17:05 +0000 (19:17 +0900)
Change-Id: I9776ef666c04f4d2951d856283311d97b31c2926
Signed-off-by: pjh9216 <jh9216.park@samsung.com>
src/tizen-core/interface_source.h
src/tizen-core/source.cc
src/tizen-core/source.h
src/tizen-core/stub.cc
src/tizen-core/task.cc

index 1eaaae9a3666f6445b44c16f0c035418e6b86e65..060bf3af7e7f9d305e6a6d114b2df2b5a173e979 100644 (file)
@@ -26,11 +26,12 @@ namespace tizen_core {
 
 class Context;
 class PollFd;
+class Task;
 
 class EXPORT_API ISource {
  public:
   virtual ~ISource() = default;
-  virtual void Attach(const std::shared_ptr<Context>& context) = 0;
+  virtual void Attach(const std::shared_ptr<Context>& context, Task* task) = 0;
   virtual void AddPoll(std::shared_ptr<PollFd> poll_fd) = 0;
   virtual void RemovePoll(const std::shared_ptr<PollFd>& poll_fd) = 0;
   virtual bool IsDisposing() const = 0;
index 6414433b270a676f92fed0d74195bde44f915098..e04350fba7e9848e1a8ea4446d1cf685adae69dd 100644 (file)
@@ -22,6 +22,7 @@
 #include <utility>
 
 #include "tizen-core/log_private.h"
+#include "tizen-core/task.h"
 
 namespace tizen_core {
 namespace {
@@ -42,8 +43,7 @@ class SourceManager {
   Source* Find(GSource* gsource) {
     std::lock_guard<std::recursive_mutex> lock(mutex_);
     auto found = map_.find(gsource);
-    if (found == map_.end())
-      return nullptr;
+    if (found == map_.end()) return nullptr;
 
     return found->second;
   }
@@ -60,18 +60,16 @@ SourceManager source_manager;
 Source::Source(GSource* handle) : handle_(handle) {}
 
 Source::Source() {
-  static GSourceFuncs source_funcs = {
-    .prepare = SourcePrepareFunc,
-    .check = SourceCheckFunc,
-    .dispatch = SourceDispatchFunc,
-    .finalize = SourceFinalizeFunc,
-    .closure_callback = nullptr,
-    .closure_marshal = nullptr
-  };
+  static GSourceFuncs source_funcs = {.prepare = SourcePrepareFunc,
+                                      .check = SourceCheckFunc,
+                                      .dispatch = SourceDispatchFunc,
+                                      .finalize = SourceFinalizeFunc,
+                                      .closure_callback = nullptr,
+                                      .closure_marshal = nullptr};
 
   handle_ = g_source_new(&source_funcs, sizeof(GSource));
   if (handle_ == nullptr) {
-    _E("g_source_new() is failed");  // LCOV_EXCL_LINE
+    _E("g_source_new() is failed");                        // LCOV_EXCL_LINE
     throw std::runtime_error("g_source_new() is failed");  // LCOV_EXCL_LINE
   }
   source_manager.Insert(this);
@@ -113,18 +111,21 @@ void Source::RemovePoll(const std::shared_ptr<PollFd>& poll_fd) {
       [=](const std::shared_ptr<PollFd>& pollfd) { return pollfd == poll_fd; });
 }
 
-void Source::Attach(const std::shared_ptr<Context>& context) {
-  if (handle_ == nullptr)
-    return;
+void Source::Attach(const std::shared_ptr<Context>& context, Task* task) {
+  if (handle_ == nullptr) return;
 
-  if (attached_)
-    return;
+  if (attached_) return;
 
+  task_ = task;
   g_source_attach(handle_, context->GetHandle());
   g_source_unref(handle_);
   attached_ = true;
 }
 
+Task* Source::GetTask() {
+  return task_;
+}
+
 bool Source::IsDisposing() const { return disposing_; }
 
 void Source::Dispose() { disposing_ = true; }
@@ -140,7 +141,7 @@ void Source::SetPriority(int priority) {
 std::recursive_mutex& Source::GetMutex() const { return mutex_; }
 
 // LCOV_EXCL_START
-bool Source::OnSourcePrepare(int* timeout) {return false; }
+bool Source::OnSourcePrepare(int* timeout) { return false; }
 
 bool Source::OnSourceCheck() { return false; }
 
@@ -150,8 +151,7 @@ void Source::OnSourceFinalize() {}
 
 gboolean Source::SourcePrepareFunc(GSource* gsource, gint* timeout) {
   auto source = source_manager.Find(gsource);
-  if (source == nullptr)
-    return FALSE;
+  if (source == nullptr) return FALSE;
 
   std::lock_guard<std::recursive_mutex> lock(source->GetMutex());
   if (source->IsDisposing()) return FALSE;
@@ -160,8 +160,7 @@ gboolean Source::SourcePrepareFunc(GSource* gsource, gint* timeout) {
 
 gboolean Source::SourceCheckFunc(GSource* gsource) {
   auto source = source_manager.Find(gsource);
-  if (source == nullptr)
-    return FALSE;
+  if (source == nullptr) return FALSE;
 
   std::lock_guard<std::recursive_mutex> lock(source->GetMutex());
   if (source->IsDisposing()) return FALSE;
@@ -171,8 +170,7 @@ gboolean Source::SourceCheckFunc(GSource* gsource) {
 gboolean Source::SourceDispatchFunc(GSource* gsource, GSourceFunc callback,
                                     gpointer user_data) {
   auto source = source_manager.Find(gsource);
-  if (source == nullptr)
-    return FALSE;
+  if (source == nullptr) return FALSE;
 
   std::lock_guard<std::recursive_mutex> lock(source->GetMutex());
   if (source->IsDisposing()) return FALSE;
@@ -181,8 +179,7 @@ gboolean Source::SourceDispatchFunc(GSource* gsource, GSourceFunc callback,
 
 void Source::SourceFinalizeFunc(GSource* gsource) {
   auto source = source_manager.Find(gsource);
-  if (source == nullptr)
-    return;
+  if (source == nullptr) return;
 
   std::lock_guard<std::recursive_mutex> lock(source->GetMutex());
   source->OnSourceFinalize();
index 7871abce6c328aee46fae37174368deb7138bba7..d7dfbb54d0c5ebc370de1701b22aef1ffb754a25 100644 (file)
@@ -42,12 +42,14 @@ class EXPORT_API Source : public ISource,
 
   void AddPoll(std::shared_ptr<PollFd> poll_fd) override;
   void RemovePoll(const std::shared_ptr<PollFd>& poll_fd) override;
-  void Attach(const std::shared_ptr<Context>& context) override;
+  void Attach(const std::shared_ptr<Context>& context,
+              tizen_core::Task* task) override;
   bool IsAttached() const;
   bool IsDisposing() const override;
   void Dispose() override;
   GSource* GetHandle() const;
   void SetPriority(int priority);
+  Task* GetTask();
 
   virtual bool OnSourcePrepare(int* timeout);
   virtual bool OnSourceCheck();
@@ -68,6 +70,7 @@ class EXPORT_API Source : public ISource,
   bool attached_ = false;
   std::list<std::shared_ptr<PollFd>> poll_fds_;
   mutable std::recursive_mutex mutex_;
+  Task* task_ = nullptr;
 };
 
 }  // namespace tizen_core
index 6f05fee87c2630dd99a552721478e600b64b0911..4075fda7b3ecb621245b6744016a56591c6dfa85 100644 (file)
@@ -293,6 +293,7 @@ API int tizen_core_add_timer(tizen_core_h core, unsigned int interval,
   }
 
   *source = &timer_source;
+
   return TIZEN_CORE_ERROR_NONE;
 }
 
@@ -391,7 +392,8 @@ API int tizen_core_remove_source(tizen_core_h core,
 
   auto* task = static_cast<tizen_core::Task*>(core);
   task->RemoveSource(*isource);
-  delete isource;
+  if (!core_source->GetTask())
+    delete isource;
 
   return TIZEN_CORE_ERROR_NONE;
 }
@@ -448,7 +450,13 @@ API int tizen_core_source_destroy(tizen_core_source_h source) {
   }
 
   auto* handle = static_cast<std::shared_ptr<tizen_core::ISource>*>(source);
-  delete handle;
+  auto handle_source = std::static_pointer_cast<tizen_core::Source>(*handle);
+  auto* task = handle_source->GetTask();
+  if (task)
+    tizen_core_remove_source(task, source);
+  else
+    delete handle;
+
   return TIZEN_CORE_ERROR_NONE;
 }
 
index d6e9b51946191bbf3727c065d742f05bdbc9c9f1..b0d8743f89850ff360ba892a3c517baf4f019fef 100644 (file)
@@ -351,13 +351,13 @@ void Task::RemoveSource(std::shared_ptr<ISource> source) {
 }
 
 std::shared_ptr<ISource>& Task::AddManagedSource(std::shared_ptr<ISource> source) {
-  source->Attach(context_);
+  source->Attach(context_, this);
   managed_sources_.push_back(std::move(source));
   return managed_sources_.back();
 }
 
 void Task::AddSource(std::shared_ptr<ISource> source) {
-  source->Attach(context_);
+  source->Attach(context_, nullptr);
 }
 
 template <typename T>