From: Gwanglim Lee Date: Tue, 5 Jun 2018 07:30:04 +0000 (+0900) Subject: Fixed double free problem for hashes of tizen_policy and display_policy. X-Git-Tag: accepted/tizen/unified/20180619.141908~2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fapi%2Fefl-util.git;a=commitdiff_plain;h=469eb4e11dc3f685e39de14b68a6f83197ecde53 Fixed double free problem for hashes of tizen_policy and display_policy. 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 --- diff --git a/src/efl_util.c b/src/efl_util.c index f6e14db..72295c3 100644 --- a/src/efl_util.c +++ b/src/efl_util.c @@ -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 */