Fix memory leak
[platform/core/appfw/pkgmgr-server.git] / src / pkgmgr-server.c
index 197ad3d..846a330 100644 (file)
@@ -44,7 +44,6 @@
 #include <pkgmgr-info.h>
 #include <pkgmgr/pkgmgr_parser_db.h>
 #include <tzplatform_config.h>
-#include <dd-display.h>
 
 #include "pkgmgr_installer.h"
 #include "pkgmgr-server.h"
@@ -94,6 +93,7 @@ static GIOChannel *sio;
 static guint swid;
 static GHashTable *backend_info_table;
 static GMainLoop *mainloop;
+static GDBusConnection *system_conn;
 
 static int (*_drm_tizen_register_license)
                (const char *pRespBuf, unsigned int respBufLen);
@@ -130,22 +130,105 @@ static void __set_backend_free(int position)
        backend_busy = backend_busy & ~(1 << position);
 }
 
+static GDBusConnection *_get_system_conn(void)
+{
+       GError *err = NULL;
+
+       if (system_conn)
+               return system_conn;
+
+       system_conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
+       if (system_conn == NULL) {
+               ERR("Failed to get system bus: %s", err->message);
+               g_error_free(err);
+               return NULL;
+       }
+
+       return system_conn;
+}
+
+#define DEVICED_DBUS_PATH "org.tizen.system.deviced"
+#define DEVICED_DBUS_OBJECT_PATH "/Org/Tizen/System/DeviceD/Display"
+#define DEVICED_DBUS_INTERFACE_NAME "org.tizen.system.deviced.display"
+
 static void __set_power_lock(void)
 {
+       GDBusConnection *conn;
+       GDBusMessage *msg;
+       GError *err = NULL;
+       int ret = 0;
+
        if (is_lock_set)
                return;
 
-       if (display_lock_state(LCD_OFF, STAY_CUR_STATE, 0) == 0)
+       conn = _get_system_conn();
+       if (conn == NULL)
+               return;
+
+       msg = g_dbus_message_new_method_call(DEVICED_DBUS_PATH,
+                       DEVICED_DBUS_OBJECT_PATH,
+                       DEVICED_DBUS_INTERFACE_NAME,
+                       "lockstate");
+       if (msg == NULL) {
+               ERR("g_dbus_message_new_method_call() has failed");
+               return;
+       }
+
+       g_dbus_message_set_body(msg, g_variant_new("(sssi)", "lcdoff",
+                       "staycurstate", "NULL", 0));
+       if (!g_dbus_connection_send_message(conn, msg,
+                               G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err)) {
+               ERR("Unable to send dbus message for acquring lock as  %s",
+                               err->message);
+               ret = -1;
+       }
+
+       if (ret == 0)
                is_lock_set = true;
+       g_object_unref(msg);
+       g_dbus_connection_flush_sync(conn, NULL, NULL);
+       g_clear_error(&err);
 }
 
 static void __release_power_lock(void)
 {
+       GError *err = NULL;
+       GDBusConnection *conn;
+       GDBusMessage *msg;
+       int ret = 0;
+
        if (!is_lock_set)
                return;
 
-       if (display_unlock_state(LCD_OFF, PM_SLEEP_MARGIN) == 0)
+       conn = _get_system_conn();
+       if (conn == NULL)
+               return;
+
+       msg = g_dbus_message_new_method_call(DEVICED_DBUS_PATH,
+                       DEVICED_DBUS_OBJECT_PATH,
+                       DEVICED_DBUS_INTERFACE_NAME,
+                       "unlockstate");
+       if (msg == NULL) {
+               ERR("g_dbus_message_new_method_call() is failed");
+               return;
+       }
+
+       g_dbus_message_set_body(msg, g_variant_new("(ss)", "lcdoff",
+                       "sleepmargin"));
+       if (!g_dbus_connection_send_message(conn, msg,
+                               G_DBUS_SEND_MESSAGE_FLAGS_NONE, NULL, &err)) {
+               ERR("Unable to send dbus message for releasing lock as  %s",
+                       err->message);
+               ret = -1;
+       }
+
+       if (ret == 0)
                is_lock_set = false;
+       g_object_unref(msg);
+       g_dbus_connection_flush_sync(conn, NULL, NULL);
+       g_clear_error(&err);
+
+       return;
 }
 
 static gboolean getsize_io_handler(GIOChannel *io, GIOCondition cond,
@@ -154,7 +237,7 @@ static gboolean getsize_io_handler(GIOChannel *io, GIOCondition cond,
        GError *err = NULL;
        GIOStatus s;
        gsize len;
-       char buf[MAX_LONGLONG_LENGTH];
+       char buf[MAX_LONGLONG_LENGTH] = {0};
        long long result = 0;
        struct backend_job *job = (struct backend_job *)data;
        struct getsize_sync_extra_info *extra_getsize_info =
@@ -354,7 +437,7 @@ static int __check_csr(const char *path)
 {
        int ret;
        void *context;
-       void *malware;
+       void *malware = NULL;
        void *lib_handle;
        int (*_csr_cs_context_create)(void **handle);
        int (*_csr_cs_scan_file)(void *handle, const char *file_path, void **malware);
@@ -373,41 +456,34 @@ static int __check_csr(const char *path)
        if (!_csr_cs_context_create || !_csr_cs_scan_file ||
                        !_csr_cs_context_destroy) {
                ERR("Failed to load CSR symbols");
-               ret = -1;
-               goto catch;
+               dlclose(lib_handle);
+               return -1;
        }
 
        ret = _csr_cs_context_create(&context);
        if (ret != 0) {
                ERR("Failed to create context");
-               ret = -1;
-               goto catch;
+               dlclose(lib_handle);
+               return -1;
        }
 
        ret = _csr_cs_scan_file(context, path, &malware);
-       if (ret != 0) {
+       /* the csr engine may not exist */
+       if (ret != 0)
                DBG("CSR result[%d]", ret);
-               ret = 0;
-               goto catch;
-       }
 
        ret = _csr_cs_context_destroy(context);
-       if (ret != 0) {
+       if (ret != 0)
                ERR("Failed to destroy context");
-               ret = -1;
-               goto catch;
-       }
+
+       dlclose(lib_handle);
 
        if (malware != NULL) {
-               ERR("CSR denied[%d] installation", path);
-               ret = -1;
+               ERR("CSR detected malware from [%s]", path);
+               return -1;
+       } else {
+               return 0;
        }
-
-catch:
-       if (lib_handle)
-               dlclose(lib_handle);
-
-       return ret;
 }
 
 static int __kill_app(char *appid, uid_t uid)
@@ -427,7 +503,7 @@ static int __kill_app(char *appid, uid_t uid)
 
        ret = aul_terminate_pid_for_uid(pid, uid);
        if (ret != AUL_R_OK) {
-               ERR("failed to terminate app(%d)", appid);
+               ERR("failed to terminate app(%s)", appid);
                return -1;
        }
 
@@ -653,6 +729,7 @@ static char **__generate_argv(const char *args)
        if (FALSE == ret_parse) {
                ERR("Failed to split args: %s", args);
                ERR("messsage: %s", gerr->message);
+               g_error_free(gerr);
                exit(1);
        }
 
@@ -758,9 +835,13 @@ static int __process_install(struct backend_job *job)
                return -1;
 
        req_id = g_shell_quote(job->req_id);
+       if (!req_id)
+               return -1;
        pkgid = g_shell_quote(job->pkgid);
-       if (!req_id || !pkgid)
+       if (!pkgid) {
+               g_free(req_id);
                return -1;
+       }
 
        snprintf(args, sizeof(args), "%s -k %s -i %s -u %d %s", backend_cmd,
                        req_id, pkgid, (int)job->target_uid, job->args);
@@ -789,10 +870,13 @@ static int __process_mount_install(struct backend_job *job)
                return -1;
 
        req_id = g_shell_quote(job->req_id);
+       if (!req_id)
+               return -1;
        pkgid = g_shell_quote(job->pkgid);
-       if (!req_id || !pkgid)
+       if (!pkgid) {
+               g_free(req_id);
                return -1;
-
+       }
        snprintf(args, sizeof(args), "%s -k %s -w %s -u %d %s", backend_cmd,
                        req_id, pkgid, (int)job->target_uid, job->args);
 
@@ -820,9 +904,13 @@ static int __process_reinstall(struct backend_job *job)
                return -1;
 
        req_id = g_shell_quote(job->req_id);
+       if (!req_id)
+               return -1;
        pkgid = g_shell_quote(job->pkgid);
-       if (!req_id || !pkgid)
+       if (!pkgid) {
+               g_free(req_id);
                return -1;
+       }
 
        snprintf(args, sizeof(args), "%s -k %s -r %s -u %d", backend_cmd,
                        req_id, pkgid, (int)job->target_uid);
@@ -1271,6 +1359,7 @@ static int __process_getsize_sync(struct backend_job *job)
                goto error;
        }
 
+       job->extra_data = extra_getsize_info;
        extra_getsize_info->getsize_fifo = strdup(fifo_path);
        if (!extra_getsize_info->getsize_fifo) {
                ERR("out of memory");
@@ -1281,7 +1370,6 @@ static int __process_getsize_sync(struct backend_job *job)
                ERR("failed to mkfifo");
                goto error;
        }
-       job->extra_data = extra_getsize_info;
 
        snprintf(args, sizeof(args), "%s %s %s %d -k %s -u %d --sync",
                        backend_cmd, job->pkgid, job->args, job->caller_uid,
@@ -1678,6 +1766,42 @@ static int __process_set_app_label(struct backend_job *job)
        return ret;
 }
 
+static int __process_set_app_icon(struct backend_job *job)
+{
+       int ret;
+       pkgmgrinfo_appinfo_h handle = NULL;
+       char *app_root_path = NULL;
+
+       ret = pkgmgrinfo_appinfo_get_usr_appinfo(job->pkgid, job->target_uid, &handle);
+       if (ret != PMINFO_R_OK) {
+               _return_value_to_caller(job->req_id, g_variant_new("(i)", ret));
+               return PKGMGR_R_ENOPKG;
+       }
+
+       ret = pkgmgrinfo_appinfo_get_root_path(handle, &app_root_path);
+       if (ret != PMINFO_R_OK || !app_root_path) {
+               _return_value_to_caller(job->req_id, g_variant_new("(i)", ret));
+               pkgmgrinfo_appinfo_destroy_appinfo(handle);
+               return PKGMGR_R_ESYSTEM;
+       }
+
+       if (strncasecmp(job->args, app_root_path, strlen(app_root_path)) != 0 ||
+                       strstr(job->args, "..") != NULL ||
+                       access(job->args, F_OK) != 0) {
+               ERR("invalid path[%s]", job->args);
+               _return_value_to_caller(job->req_id, g_variant_new("(i)", ret));
+               pkgmgrinfo_appinfo_destroy_appinfo(handle);
+               return PKGMGR_R_EINVAL;
+       }
+
+       pkgmgrinfo_appinfo_destroy_appinfo(handle);
+       ret = pkgmgr_parser_update_app_icon_info_in_usr_db(job->pkgid,
+                       job->target_uid, job->args);
+       _return_value_to_caller(job->req_id, g_variant_new("(i)", ret));
+
+       return ret;
+}
+
 static int __process_migrate_external_image(struct backend_job *job)
 {
        char *backend_cmd;
@@ -1894,6 +2018,10 @@ gboolean queue_job(void *data)
                ret = __process_set_app_label(job);
                _free_backend_job(job);
                break;
+       case REQUEST_TYPE_SET_APP_ICON:
+               ret = __process_set_app_icon(job);
+               _free_backend_job(job);
+               break;
        case REQUEST_TYPE_MIGRATE_EXTERNAL_IMAGE:
                __set_backend_busy(x);
                __set_power_lock();