Fixed double free problem for hashes of tizen_policy and display_policy. 79/180879/1
authorGwanglim Lee <gl77.lee@samsung.com>
Tue, 5 Jun 2018 07:30:04 +0000 (16:30 +0900)
committerGwanglim Lee <gl77.lee@samsung.com>
Tue, 5 Jun 2018 07:30:04 +0000 (16:30 +0900)
efl-util always releases all internal hashes of global resource
without checking which resource is deleting when receiving global
resource remove event. It is causing double free problem.

In order to fix this, now efl-util remembers id of global resource
and checks that when removing.

Change-Id: If592c09c575dbd0be249b6ab75f76f5b86c386f2

src/efl_util.c

index f6e14db..72295c3 100644 (file)
@@ -193,6 +193,7 @@ typedef struct _Efl_Util_Data
 
       struct
       {
+         unsigned int id;
          struct tizen_policy *proto;
          Eina_Hash *hash_noti_lv;
          Eina_Hash *hash_scr_mode;
@@ -213,6 +214,7 @@ typedef struct _Efl_Util_Data
       } devmgr;
       struct
       {
+         unsigned int id;
          struct tizen_display_policy *proto;
          Eina_Hash *hash_brightness;
       } display_policy;
@@ -237,10 +239,10 @@ static Efl_Util_Data _eflutil =
       EINA_FALSE,
       NULL, NULL, NULL,
       -1, NULL,
-      { NULL, NULL, NULL }, /* tizen_policy protocol */
+      { 0, NULL, NULL, NULL }, /* tizen_policy protocol */
       { NULL, NULL, NULL, NULL, NULL, 0 }, /* screenshooter protocol */
       { NULL, -1 }, /* tizen_input_device_manager protocol */
-      { NULL, NULL }, /* display_policy protocol */
+      { 0, NULL, NULL }, /* display_policy protocol */
       { NULL, -1, EINA_FALSE } /* tizen_gesture protocol */
    },
    {
@@ -533,7 +535,7 @@ static const struct tizen_screenshooter_listener tz_screenshooter_listener =
 static void
 _cb_wl_reg_global(void *data,
                   struct wl_registry *reg,
-                  unsigned int name,
+                  unsigned int id,
                   const char *interface,
                   unsigned int version)
 {
@@ -541,7 +543,7 @@ _cb_wl_reg_global(void *data,
      {
         struct tizen_policy *proto;
         proto = wl_registry_bind(reg,
-                                  name,
+                                  id,
                                   &tizen_policy_interface,
                                   7);
         if (!proto) return;
@@ -553,6 +555,7 @@ _cb_wl_reg_global(void *data,
         _eflutil.wl.policy.hash_noti_lv = eina_hash_pointer_new(free);
         _eflutil.wl.policy.hash_scr_mode = eina_hash_pointer_new(free);
         _eflutil.wl.policy.proto = proto;
+        _eflutil.wl.policy.id = id;
      }
    else if (strcmp(interface, "wl_output") == 0)
      {
@@ -561,17 +564,17 @@ _cb_wl_reg_global(void *data,
 
         _eflutil.wl.shot.output_list = eina_list_append(_eflutil.wl.shot.output_list, output);
 
-        output->output = wl_registry_bind(reg, name, &wl_output_interface, version);
+        output->output = wl_registry_bind(reg, id, &wl_output_interface, version);
         wl_output_add_listener(output->output, &output_listener, output);
      }
    else if (strcmp(interface, "tizen_input_device_manager") == 0)
      {
-        _eflutil.wl.devmgr.devicemgr = wl_registry_bind(reg, name, &tizen_input_device_manager_interface, version);
+        _eflutil.wl.devmgr.devicemgr = wl_registry_bind(reg, id, &tizen_input_device_manager_interface, version);
         tizen_input_device_manager_add_listener(_eflutil.wl.devmgr.devicemgr, &_wl_tz_devmgr_listener, NULL);
      }
    else if (!strcmp(interface, "tizen_display_policy"))
      {
-        _eflutil.wl.display_policy.proto = wl_registry_bind(reg, name, &tizen_display_policy_interface, version);
+        _eflutil.wl.display_policy.proto = wl_registry_bind(reg, id, &tizen_display_policy_interface, version);
         if (!_eflutil.wl.display_policy.proto) return;
 
         tizen_display_policy_add_listener(_eflutil.wl.display_policy.proto,
@@ -579,10 +582,11 @@ _cb_wl_reg_global(void *data,
                                           NULL);
 
         _eflutil.wl.display_policy.hash_brightness = eina_hash_pointer_new(free);
+        _eflutil.wl.display_policy.id = id;
      }
    else if (strcmp(interface, "tizen_gesture") == 0)
      {
-        _eflutil.wl.gesture.proto = wl_registry_bind(reg, name, &tizen_gesture_interface, version);
+        _eflutil.wl.gesture.proto = wl_registry_bind(reg, id, &tizen_gesture_interface, version);
         tizen_gesture_add_listener(_eflutil.wl.gesture.proto, &_wl_tz_gesture_listener, NULL);
      }
 }
@@ -590,14 +594,24 @@ _cb_wl_reg_global(void *data,
 static void
 _cb_wl_reg_global_remove(void *data,
                          struct wl_registry *reg,
-                         unsigned int name)
+                         unsigned int id)
 {
-   _eflutil.wl.policy.proto = NULL;
-   eina_hash_free(_eflutil.wl.policy.hash_noti_lv);
-   eina_hash_free(_eflutil.wl.policy.hash_scr_mode);
-
-   _eflutil.wl.display_policy.proto = NULL;
-   eina_hash_free(_eflutil.wl.display_policy.hash_brightness);
+   /* unset each global id number to 0 since global id is started
+    * from number 1 on server side display structure
+    */
+   if (id == _eflutil.wl.policy.id)
+     {
+        _eflutil.wl.policy.id = 0;
+        _eflutil.wl.policy.proto = NULL;
+        eina_hash_free(_eflutil.wl.policy.hash_noti_lv);
+        eina_hash_free(_eflutil.wl.policy.hash_scr_mode);
+     }
+   else if (id == _eflutil.wl.display_policy.id)
+     {
+        _eflutil.wl.display_policy.id = 0;
+        _eflutil.wl.display_policy.proto = NULL;
+        eina_hash_free(_eflutil.wl.display_policy.hash_brightness);
+     }
 }
 /* LCOV_EXCL_STOP */