[Messaging] Prevent crash of using released structure mail_data_final 16/268816/1 accepted/tizen/6.5/unified/20220117.134841 submit/tizen_6.5/20220113.125456
authorPiotr Kosko/Tizen API (PLT) /SRPOL/Engineer/Samsung Electronics <p.kosko@samsung.com>
Fri, 24 Dec 2021 09:38:57 +0000 (10:38 +0100)
committerPiotr Kosko <p.kosko@samsung.com>
Mon, 3 Jan 2022 09:04:09 +0000 (09:04 +0000)
In line 296, there is the usage:
  mail_data_final->thread_id = mail_data_final->mail_id;

but if retries loop above reaches limit, then the structure is relased,
so using it causes crash.
To prevent it, we release data on the beginning of the next iteration of
a loop.

[Verification] TCT passrate:
messaging-email - 100%.

Change-Id: I4751e5509271f28ab803e0ef10a90ff10d61ec10

src/messaging/email_manager.cc

index 653840b..8b1c905 100644 (file)
@@ -263,6 +263,16 @@ PlatformResult EmailManager::addMessagePlatform(int account_id, std::shared_ptr<
     int retry = 0;
     const int MAX_RETRIES = 5;
     for (; retry < MAX_RETRIES; ++retry) {
+      // mail_data_final from last retry was not yet released, release it now
+      // and retry gathering data once again
+      if (mail_data_final) {
+        int free_error = email_free_mail_data(&mail_data_final, 1);
+        if (EMAIL_ERROR_NONE != free_error) {
+          LoggerW("email_free_mail_data error: %d, %s", free_error,
+                  get_error_message(free_error));
+        }
+      }
+
       err = email_get_mail_data(message->getId(), &mail_data_final);
 
       if (EMAIL_ERROR_NONE != err) {
@@ -279,11 +289,6 @@ PlatformResult EmailManager::addMessagePlatform(int account_id, std::shared_ptr<
         LoggerD("Message adding process finished after %d retries. mail_id == thread_id", retry);
         break;
       }
-
-      int free_error = email_free_mail_data(&mail_data_final, 1);
-      if (EMAIL_ERROR_NONE != free_error) {
-        LoggerW("email_free_mail_data error: %d, %s", free_error, get_error_message(free_error));
-      }
       LoggerD("Retry number %d failed", retry);
       std::this_thread::sleep_for(100ms);
     }