Remove WITH_CB alarm when process was killed 56/222156/6
authorInkyun Kil <inkyun.kil@samsung.com>
Fri, 10 Jan 2020 04:30:21 +0000 (13:30 +0900)
committerInkyun Kil <inkyun.kil@samsung.com>
Thu, 16 Jan 2020 04:45:39 +0000 (13:45 +0900)
Change-Id: Ic3c60f049ab409bcfe4cb7e2454a12f02c55721d
Signed-off-by: Inkyun Kil <inkyun.kil@samsung.com>
include/alarm-internal.h
server/alarm-manager-util.c
server/alarm-manager-util.h
server/alarm-manager.c

index 0370066..b64299d 100644 (file)
@@ -111,6 +111,7 @@ typedef struct {
 
        alarm_id_t alarm_id;
        uid_t uid;
+       pid_t pid;
        char *caller_pkgid;
        char *callee_pkgid;
        char *app_unique_name;
index dce5c4b..86d274a 100644 (file)
@@ -188,6 +188,44 @@ cynara_out:
        return ret;
 }
 
+char *_get_cmdline_from_pid(pid_t pid)
+{
+       char proc_file[MAX_APP_ID_LEN] = {0,};
+       char process_name[MAX_APP_ID_LEN] = {0,};
+       int fd = 0;
+       int i = 0;
+       char *cmdline = NULL;
+
+       snprintf(proc_file, MAX_APP_ID_LEN, "/proc/%d/cmdline", pid);
+
+       fd = open(proc_file, O_RDONLY);
+       if (fd < 0) {
+               SECURE_LOGE("Caution!! pid(%d) seems to be killed.",
+                               pid);
+               return NULL;
+       } else {
+               if (read(fd, process_name, sizeof(process_name) - 1) <= 0) {
+                       LOGE("Unable to get the process name.");
+                       close(fd);
+                       return NULL;
+               }
+               close(fd);
+
+               while (process_name[i] != '\0') {
+                       if (process_name[i] == ' ') {
+                               process_name[i] = '\0';
+                               break;
+                       }
+                       ++i;
+               }
+               cmdline = strdup(process_name);
+               if (!cmdline)
+                       LOGE("Out of memory");
+       }
+
+       return cmdline;
+}
+
 int _get_pid_from_appid(const char *app_id, uid_t uid)
 {
        int pid;
index 1ff1f8e..b37019d 100644 (file)
@@ -41,6 +41,7 @@ int _compare_api_version(int *result, int pid, uid_t uid);
 bool _permit_by_config(pkgmgrinfo_appinfo_h handle, uid_t uid);
 bool _is_permitted(const char *app_id, int alarm_type, uid_t uid);
 int _get_pid_from_appid(const char *app_id, uid_t uid);
+char *_get_cmdline_from_pid(pid_t pid);
 
 void _initialize_module_log(void);
 void _save_module_log(const char *tag, const char *messgae);
index a255289..9bbb591 100644 (file)
@@ -78,6 +78,7 @@ bool is_time_changed = false; /* for calculating next duetime */
 static time_t periodic_alarm_standard_time = 0;
 
 struct running_info_t {
+       pid_t pid;
        char *appid;
        bool is_running;
 };
@@ -135,38 +136,18 @@ static bool __get_caller_unique_name(int pid, char *unique_name, int size, bool
                strncpy(unique_name, caller_appid, size - 1);
        } else {
                /* Otherwise, the unique name is /proc/pid/cmdline. */
-               char proc_file[MAX_APP_ID_LEN] = {0,};
-               char process_name[MAX_APP_ID_LEN] = {0,};
-               int fd = 0;
-               int i = 0;
+               char *cmdline;
 
                if (is_app)
                        *is_app = false;
 
-               snprintf(proc_file, MAX_APP_ID_LEN, "/proc/%d/cmdline", pid);
-
-               fd = open(proc_file, O_RDONLY);
-               if (fd < 0) {
-                       SECURE_LOGE("Caution!! pid(%d) seems to be killed.",
-                                       pid);
+               cmdline = _get_cmdline_from_pid(pid);
+               if (!cmdline)
                        return false;
-               } else {
-                       if (read(fd, process_name, sizeof(process_name) - 1) <= 0) {
-                               LOGE("Unable to get the process name.");
-                               close(fd);
-                               return false;
-                       }
-                       close(fd);
+               else
+                       strncpy(unique_name, cmdline, size - 1);
 
-                       while (process_name[i] != '\0') {
-                               if (process_name[i] == ' ') {
-                                       process_name[i] = '\0';
-                                       break;
-                               }
-                               ++i;
-                       }
-                       strncpy(unique_name, process_name, size - 1);
-               }
+               free(cmdline);
        }
 
        return true;
@@ -906,6 +887,7 @@ static bool __alarm_create_appsvc(alarm_info_t *alarm_info, alarm_id_t *alarm_id
        }
 
        __alarm_info->uid = uid;
+       __alarm_info->pid = pid;
        __alarm_info->alarm_id = -1;
        __alarm_info->requested_interval = requested_interval;
        __alarm_info->global = false;
@@ -979,6 +961,7 @@ static bool __alarm_create(alarm_info_t *alarm_info, alarm_id_t *alarm_id, uid_t
                return false;
        }
        __alarm_info->uid = uid;
+       __alarm_info->pid = pid;
        __alarm_info->alarm_id = -1;
        __alarm_info->method = method;
        __alarm_info->requested_interval = requested_interval;
@@ -1086,6 +1069,7 @@ static bool __alarm_create_noti(alarm_info_t *alarm_info, alarm_id_t *alarm_id,
                return false;
        }
        __alarm_info->uid = uid;
+       __alarm_info->pid = pid;
        __alarm_info->alarm_id = -1;
        __alarm_info->requested_interval = requested_interval;
        __alarm_info->global = false;
@@ -1483,13 +1467,14 @@ static int __app_info_iter(const aul_app_info *info, void *data)
 {
        struct running_info_t *app_info = (struct running_info_t *)data;
 
-       if (strcmp(app_info->appid, info->appid) == 0)
+       if ((app_info->pid == info->pid) &&
+               strcmp(app_info->appid, info->appid) == 0)
                app_info->is_running = true;
 
        return 0;
 }
 
-static void __expire_dbus_activation(__alarm_info_t *alarm_info)
+static int __expire_dbus_activation(__alarm_info_t *alarm_info)
 {
        const char *destination_app_service_name = NULL;
        char appid[MAX_SERVICE_NAME_LEN] = { 0, };
@@ -1521,7 +1506,7 @@ static void __expire_dbus_activation(__alarm_info_t *alarm_info)
                        strncpy(appid, alarm_info->app_service_name + 6, sizeof(appid) - 1);
        } else {
                if (strlen(alarm_info->dst_service_name) > 6)
-                       strncpy(appid,  alarm_info->dst_service_name + 6, sizeof(appid) - 1);
+                       strncpy(appid, alarm_info->dst_service_name + 6, sizeof(appid) - 1);
        }
 
        if (alarm_info->uid >= REGULAR_UID_MIN) {
@@ -1529,64 +1514,86 @@ static void __expire_dbus_activation(__alarm_info_t *alarm_info)
        }
        LOGD("appid : %s app?(%d)", appid, is_app);
 
-       /* Case #3-1. The process was killed && App type
-        * This app is launched and owner of DBus connection is changed. and then, expiration noti is sent by DBus. */
-       app_info.is_running = false;
        if (is_app) {
+               app_info.is_running = false;
+               app_info.pid = alarm_info->pid;
                app_info.appid = appid;
                aul_app_get_all_running_app_info_for_uid(__app_info_iter,
                                &app_info, alarm_info->uid);
 
                SECURE_LOGD("[alarm-server]: destination_app_id :%s", appid);
-       }
 
-       if (is_app && !app_info.is_running) {
-               __expired_alarm_t *expire_info;
-               char alarm_id_str[32] = { 0, };
+               if (app_info.is_running) {
+                       /* Case #3-1. The App process is alive.
+                        * Expiration noti is sent by DBus. */
+                       LOGD("before alarm_send_noti_to_application");
 
-               if (alarm_info->alarm_info.alarm_type & ALARM_TYPE_WITHCB) {
-                       __alarm_remove_from_list(alarm_info->uid, alarm_info->alarm_id, NULL);
-                       LOGW("[alarm-server]:This alarm_type is WITHCB");
-                       return;
-               }
+                       _alarm_send_noti_to_application_by_dbus(destination_app_service_name,
+                                       alarm_info->alarm_id, alarm_info->alarm_info.msec, alarm_info->uid); /* dbus auto activation */
+                       LOGD("after _alarm_send_noti_to_application_by_dbus");
+               } else {
+                       /* Case #3-2. The process was killed && App type
+                        * This app is launched and owner of DBus connection is changed. and then, expiration noti is sent by DBus. */
+                       __expired_alarm_t *expire_info;
+                       char alarm_id_str[32] = { 0, };
+
+                       if (alarm_info->alarm_info.alarm_type & ALARM_TYPE_WITHCB) {
+                               __alarm_remove_from_list(alarm_info->uid, alarm_info->alarm_id, NULL);
+                               LOGW("[alarm-server]:This alarm_type is WITHCB");
+                               return -2;
+                       }
 
-               expire_info = (__expired_alarm_t *)malloc(sizeof(__expired_alarm_t));
-               if (G_UNLIKELY(NULL == expire_info)) {
-                       LOGE("[alarm-server]:Malloc failed!Can't notify alarm expiry info\n");
-                       return;
-               }
-               memset(expire_info, '\0', sizeof(__expired_alarm_t));
-               strncpy(expire_info->service_name, destination_app_service_name, MAX_SERVICE_NAME_LEN-1);
-               expire_info->alarm_id = alarm_info->alarm_id;
-               expire_info->uid = alarm_info->uid;
-               g_expired_alarm_list = g_slist_append(g_expired_alarm_list, expire_info);
+                       expire_info = (__expired_alarm_t *)malloc(sizeof(__expired_alarm_t));
+                       if (G_UNLIKELY(NULL == expire_info)) {
+                               LOGE("[alarm-server]:Malloc failed!Can't notify alarm expiry info\n");
+                               return -1;
+                       }
+                       memset(expire_info, '\0', sizeof(__expired_alarm_t));
+                       strncpy(expire_info->service_name, destination_app_service_name, MAX_SERVICE_NAME_LEN-1);
+                       expire_info->alarm_id = alarm_info->alarm_id;
+                       expire_info->uid = alarm_info->uid;
+                       g_expired_alarm_list = g_slist_append(g_expired_alarm_list, expire_info);
 
-               snprintf(alarm_id_str, 31, "%d", alarm_info->alarm_id);
+                       snprintf(alarm_id_str, 31, "%d", alarm_info->alarm_id);
 
-               SECURE_LOGD("before aul_launch appid(%s) alarm_id_str(%s)", appid, alarm_id_str);
+                       SECURE_LOGD("before aul_launch appid(%s) alarm_id_str(%s)", appid, alarm_id_str);
 
-               kb = bundle_create();
-               bundle_add_str(kb, "__ALARM_MGR_ID", alarm_id_str);
+                       kb = bundle_create();
+                       bundle_add_str(kb, "__ALARM_MGR_ID", alarm_id_str);
 
-               if (alarm_info->global) {
-                       if (__find_login_user(&target_uid) < 0)
-                               LOGE("Fail to get login user\n");
-                       else
-                               aul_launch_app_for_uid(appid, kb, target_uid); /* on_bus_name_owner_changed will be called. */
-               } else {
-                       aul_launch_app_for_uid(appid, kb, alarm_info->uid); /* on_bus_name_owner_changed will be called. */
-               }
+                       if (alarm_info->global) {
+                               if (__find_login_user(&target_uid) < 0)
+                                       LOGE("Fail to get login user\n");
+                               else
+                                       aul_launch_app_for_uid(appid, kb, target_uid); /* on_bus_name_owner_changed will be called. */
+                       } else {
+                               aul_launch_app_for_uid(appid, kb, alarm_info->uid); /* on_bus_name_owner_changed will be called. */
+                       }
 
-               bundle_free(kb);
+                       bundle_free(kb);
+               }
        } else {
-               /* Case #3-2. The process is alive or was killed && non-app type(daemon)
+               /* Case #3-3. The process was killed && non-app type(daemon)
                 * Expiration noti is sent by DBus. it makes the process alive. (dbus auto activation) */
-               LOGD("before alarm_send_noti_to_application");
+               if (alarm_info->alarm_info.alarm_type & ALARM_TYPE_WITHCB) {
+                       char *cmdline = _get_cmdline_from_pid(alarm_info->pid);
+                       if (!cmdline || strcmp(cmdline, alarm_info->app_unique_name) != 0) {
+                               __alarm_remove_from_list(alarm_info->uid, alarm_info->alarm_id, NULL);
+                               LOGW("[alarm-server]:This alarm_type is WITHCB, the process was killed.");
+                               return -2;
+                       }
+
+                       if (cmdline)
+                               free(cmdline);
+               }
 
+               LOGD("before alarm_send_noti_to_application for daemon");
                _alarm_send_noti_to_application_by_dbus(destination_app_service_name,
                                alarm_info->alarm_id, alarm_info->alarm_info.msec, alarm_info->uid); /* dbus auto activation */
-               LOGD("after _alarm_send_noti_to_application_by_dbus");
+               LOGD("after _alarm_send_noti_to_application_by_dbus for daemon");
        }
+
+       return 0;
 }
 
 void _alarm_expired()
@@ -1631,9 +1638,11 @@ void _alarm_expired()
                        __expire_notification(__alarm_info);
                } else {
                /* Case #3. Expiration noti is sent by DBus.
-                * 3-1. The process was killed && App type
-                * 3-2. The process is alive or was killed && non-app type(daemon) */
-                       __expire_dbus_activation(__alarm_info);
+                * 3-1. The process is running && App type
+                * 3-2. The process was killed && App type
+                * 3-3. Non-app type(daemon) */
+                       if (__expire_dbus_activation(__alarm_info) == -2)
+                               continue;
                }
 
                LOGD("alarm_id[%d] is expired.", __alarm_info->alarm_id);