Fix ASAN issue: heap-use-after-free
[platform/core/multimedia/libmm-camcorder.git] / src / mm_camcorder_util.c
index 42afe2d..3614ffe 100644 (file)
@@ -166,37 +166,44 @@ static void __gdbus_stream_eos_cb(GDBusConnection *connection,
 {
        int played_idx = 0;
        gboolean stopped_by_user = FALSE;
-       _MMCamcorderGDbusCbInfo *gdbus_info = NULL;
-       mmf_camcorder_t *hcamcorder = NULL;
-
-       MMCAM_LOG_WARNING("entered");
+       gboolean do_free = FALSE;
+       _MMCamcorderGDbusCbInfo *info = NULL;
 
        if (!param || !user_data) {
                MMCAM_LOG_ERROR("invalid parameter %p %p", param, user_data);
                return;
        }
 
-       gdbus_info = (_MMCamcorderGDbusCbInfo *)user_data;
-       hcamcorder = (mmf_camcorder_t *)gdbus_info->mm_handle;
+       info = (_MMCamcorderGDbusCbInfo *)user_data;
+
+       MMCAM_LOG_WARNING("entered[gdbus_info:%p]", info);
 
        g_variant_get(param, "(ib)", &played_idx, &stopped_by_user);
 
-       g_mutex_lock(&gdbus_info->sync_mutex);
+       g_mutex_lock(&info->sync_mutex);
 
-       MMCAM_LOG_WARNING("gdbus_info->param %d, played_idx %d, stopped_by_user %d, handle %p",
-               gdbus_info->param, played_idx, stopped_by_user, hcamcorder);
+       MMCAM_LOG_WARNING("gdbus_info->param %d, played_idx %d, stopped_by_user %d",
+               info->param, played_idx, stopped_by_user);
 
-       if (gdbus_info->param == played_idx) {
-               g_dbus_connection_signal_unsubscribe(connection, gdbus_info->subscribe_id);
+       if (info->param == played_idx) {
+               g_dbus_connection_signal_unsubscribe(connection, info->subscribe_id);
 
-               gdbus_info->is_playing = FALSE;
-               gdbus_info->subscribe_id = 0;
-               gdbus_info->param = 0;
+               info->is_playing = FALSE;
+               info->subscribe_id = 0;
+               info->param = 0;
 
-               g_cond_signal(&gdbus_info->sync_cond);
+               g_cond_signal(&info->sync_cond);
        }
 
-       g_mutex_unlock(&gdbus_info->sync_mutex);
+       if (info->free_in_cb)
+               do_free = TRUE;
+
+       g_mutex_unlock(&info->sync_mutex);
+
+       if (do_free) {
+               MMCAM_LOG_WARNING("free gdbus_info[%p]", info);
+               _mmcamcorder_gdbus_info_free(info);
+       }
 
        MMCAM_LOG_WARNING("done");
 
@@ -943,6 +950,60 @@ int _mmcamcorder_get_device_led_brightness(GDBusConnection *conn, int *brightnes
 }
 
 
+_MMCamcorderGDbusCbInfo *_mmcamcorder_gdbus_info_new(void)
+{
+       _MMCamcorderGDbusCbInfo *new_info = g_new0(_MMCamcorderGDbusCbInfo, 1);
+
+       g_mutex_init(&new_info->sync_mutex);
+       g_cond_init(&new_info->sync_cond);
+
+       MMCAM_LOG_INFO("new gdbus_info[%p]", new_info);
+
+       return new_info;
+}
+
+
+void _mmcamcorder_gdbus_info_free(_MMCamcorderGDbusCbInfo *info)
+{
+       if (!info) {
+               MMCAM_LOG_WARNING("NULL info");
+               return;
+       }
+
+       MMCAM_LOG_INFO("free gdbus_info[%p]", info);
+
+       g_mutex_clear(&info->sync_mutex);
+       g_cond_clear(&info->sync_cond);
+
+       g_free(info);
+}
+
+
+void _mmcamcorder_gdbus_info_check_free(_MMCamcorderGDbusCbInfo *info)
+{
+       gboolean do_free = FALSE;
+
+       if (!info) {
+               MMCAM_LOG_WARNING("NULL info");
+               return;
+       }
+
+       g_mutex_lock(&info->sync_mutex);
+
+       if (info->subscribe_id > 0) {
+               MMCAM_LOG_WARNING("gdbus_info[%p] will be freed in sound EOS cb", info);
+               info->free_in_cb = TRUE;
+       } else {
+               do_free = TRUE;
+       }
+
+       g_mutex_unlock(&info->sync_mutex);
+
+       if (do_free)
+               _mmcamcorder_gdbus_info_free(info);
+}
+
+
 int _mmcamcorder_send_sound_play_message(GDBusConnection *conn, _MMCamcorderGDbusCbInfo *gdbus_info,
        const char *sample_name, const char *stream_role, const char *volume_gain, int sync_play)
 {