From 145e19eb5977371245d72f816443ef7704b223cf Mon Sep 17 00:00:00 2001 From: jusung son Date: Wed, 7 Mar 2018 18:19:26 +0900 Subject: [PATCH] Fix wrong resource management - callback information protection logic - socket leak Change-Id: If11518db21aefddf8de30dc2463338ccf5d86109 Signed-off-by: jusung son --- vconf-compat/vconf.c | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/vconf-compat/vconf.c b/vconf-compat/vconf.c index ef1adcb..adc7db6 100755 --- a/vconf-compat/vconf.c +++ b/vconf-compat/vconf.c @@ -58,7 +58,8 @@ struct noti { struct noti_cb { vconf_callback_fn cb; void *user_data; - int ref_cnt; + bool active; + bool in_cb; }; static bool last_result; @@ -174,8 +175,9 @@ static void free_noti(struct noti *noti) for (l = noti->noti_list, n = g_list_next(l); l; l = n, n = g_list_next(n)) { struct noti_cb *noticb = l->data; - noticb->ref_cnt--; - if (noticb->ref_cnt == 0) { + noticb->active = false; + + if (!noticb->in_cb) { noti->noti_list = g_list_delete_link(noti->noti_list, l); free(noticb); } @@ -334,7 +336,7 @@ static GList *copy_noti_list(GList *noti_list) pthread_mutex_lock(&vconf_lock); for (l = noti_list; l; l = g_list_next(l)) { struct noti_cb *noticb = l->data; - noticb->ref_cnt++; + noticb->in_cb = true; } copy = g_list_copy(noti_list); pthread_mutex_unlock(&vconf_lock); @@ -353,9 +355,9 @@ static GList *free_copy_list(GList *noti_list, GList *copy_list) for (l = noti_list, ll = g_list_next(l); l; l = ll, ll = g_list_next(ll)) { struct noti_cb *noticb = l->data; + noticb->in_cb = false; - noticb->ref_cnt--; - if (noticb->ref_cnt == 0) { + if (!noticb->active) { noti_list = g_list_delete_link(noti_list, l); free(noticb); } @@ -438,8 +440,13 @@ static int add_noti(struct noti *noti, vconf_callback_fn cb, void *user_data) noticb = find_noti_cb(noti, cb); if (noticb) { - errno = EEXIST; - return -1; + if (noticb->active) { + errno = EEXIST; + return -1; + } else { + noticb->active = true; + return 0; + } } noticb = calloc(1, sizeof(*noticb)); @@ -448,7 +455,8 @@ static int add_noti(struct noti *noti, vconf_callback_fn cb, void *user_data) noticb->cb = cb; noticb->user_data = user_data; - noticb->ref_cnt = 1; + noticb->active = true; + noticb->in_cb = false; noti->noti_list = g_list_append(noti->noti_list, noticb); @@ -596,20 +604,22 @@ EXPORT int vconf_ignore_key_changed(const char *key, vconf_callback_fn cb) noti = g_hash_table_lookup(noti_tbl, key); if (!noti) { + _close(); pthread_mutex_unlock(&vconf_lock); errno = ENOENT; return -1; } noticb = find_noti_cb(noti, cb); - if (!noticb) { + if (!noticb || !noticb->active) { + _close(); pthread_mutex_unlock(&vconf_lock); errno = ENOENT; return -1; } - noticb->ref_cnt--; - if (noticb->ref_cnt == 0) { + noticb->active = false; + if (!noticb->in_cb) { noti->noti_list = g_list_remove(noti->noti_list, noticb); free(noticb); } @@ -617,6 +627,7 @@ EXPORT int vconf_ignore_key_changed(const char *key, vconf_callback_fn cb) cnt = unregister_noti(noti); if (cnt > 0) { + _close(); pthread_mutex_unlock(&vconf_lock); return 0; } -- 2.7.4