From 430dbe2e74269dd7f4a2389d7bc98c8f755cdaa4 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 6 Jul 2016 15:24:16 +0900 Subject: [PATCH 01/16] Modify closing all open fds Change-Id: Iafd862f582e9eb9bbeecf542c2dafcb510798cfb Signed-off-by: Hwankyu Jhun --- inc/launchpad_common.h | 1 + src/launchpad.c | 7 +------ src/launchpad_common.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/launchpad_loader.c | 7 +------ 4 files changed, 44 insertions(+), 12 deletions(-) diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h index 4f13aaa..1c07962 100644 --- a/inc/launchpad_common.h +++ b/inc/launchpad_common.h @@ -116,6 +116,7 @@ appinfo_t *_appinfo_create(bundle *kb); void _appinfo_free(appinfo_t *menu_info); char *_appinfo_get_app_path(appinfo_t *menu_info); int _proc_get_attr_by_pid(int pid, char *buf, int size); +int _close_all_fds(int except); #endif /* __LAUNCHPAD_COMMON_H__ */ diff --git a/src/launchpad.c b/src/launchpad.c index c12abc6..4d85ea9 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -544,8 +544,6 @@ static int __launch_directly(const char *appid, const char *app_path, int clifd, candidate_process_context_t *cpc) { int pid = fork(); - int max_fd; - int iter_fd; if (pid == 0) { PERF("fork done"); @@ -554,10 +552,7 @@ static int __launch_directly(const char *appid, const char *app_path, int clifd, __signal_unblock_sigchld(); __signal_fini(); - max_fd = sysconf(_SC_OPEN_MAX); - for (iter_fd = 3; iter_fd <= max_fd; iter_fd++) - close(iter_fd); - + _close_all_fds(0); _delete_sock_path(getpid(), getuid()); PERF("prepare exec - first done"); diff --git a/src/launchpad_common.c b/src/launchpad_common.c index f9f318d..810dc9f 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -764,3 +764,44 @@ int _delete_sock_path(int pid, uid_t uid) return 0; } +int _close_all_fds(const int except) +{ + DIR *dp; + struct dirent dentry; + struct dirent *result = NULL; + int fd; + int max_fd; + + dp = opendir("/proc/self/fd"); + if (dp == NULL) { + /* fallback */ + max_fd = sysconf(_SC_OPEN_MAX); + for (fd = 3; fd < max_fd; fd++) { + if (fd != except) + close(fd); + } + + return 0; + } + + while (readdir_r(dp, &dentry, &result) == 0 && result) { + if (!isdigit(dentry.d_name[0])) + continue; + + fd = atoi(dentry.d_name); + if (fd < 3) + continue; + + if (fd == dirfd(dp)) + continue; + + if (fd == except) + continue; + + close(fd); + } + closedir(dp); + + return 0; +} + diff --git a/src/launchpad_loader.c b/src/launchpad_loader.c index 2e9d18b..c7d7220 100644 --- a/src/launchpad_loader.c +++ b/src/launchpad_loader.c @@ -266,8 +266,6 @@ static int __loader_launch_cb(int argc, char **argv, const char *app_path, static void __close_fds(void) { - int iter_fd; - int max_fd = sysconf(_SC_OPEN_MAX); int fd = -1; const char *sockfd; @@ -275,10 +273,7 @@ static void __close_fds(void) if (sockfd) fd = atoi(sockfd); - for (iter_fd = 3; iter_fd <= max_fd; iter_fd++) { - if (iter_fd != fd) - close(iter_fd); - } + _close_all_fds(fd); } static int __loader_terminate_cb(int argc, char **argv, void *user_data) -- 2.7.4 From 17b8e02a1ff7f3eb87dd28c56ac4d562608328ba Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 7 Jul 2016 19:06:22 +0900 Subject: [PATCH 02/16] Add the appid and the pkgid to the enviornment Change-Id: I6bed8f9e62f738944c1702536bddd61576f07a81 Signed-off-by: Hwankyu Jhun --- src/launchpad_common.c | 4 ++++ src/launchpad_lib.c | 45 +++++---------------------------------------- 2 files changed, 9 insertions(+), 40 deletions(-) diff --git a/src/launchpad_common.c b/src/launchpad_common.c index 810dc9f..7109129 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -637,6 +637,10 @@ void _set_env(appinfo_t *menu_info, bundle *kb) setenv("TASKMANAGE", menu_info->taskmanage, 1); if (menu_info->root_path != NULL) setenv("AUL_ROOT_PATH", menu_info->root_path, 1); + if (menu_info->appid != NULL) + setenv("AUL_APPID", menu_info->appid, 1); + if (menu_info->pkgid != NULL) + setenv("AUL_PKGID", menu_info->pkgid, 1); str = bundle_get_val(kb, AUL_K_WAYLAND_DISPLAY); if (str != NULL) diff --git a/src/launchpad_lib.c b/src/launchpad_lib.c index ec2b1d2..3cb5daf 100644 --- a/src/launchpad_lib.c +++ b/src/launchpad_lib.c @@ -47,9 +47,6 @@ static void *__loader_user_data; static int __argc; static char **__argv; static bundle *__bundle; -static char *__appid; -static char *__pkgid; -static char *__root_path; static int __loader_type = LAUNCHPAD_TYPE_UNSUPPORTED; static int __loader_id; @@ -59,18 +56,6 @@ static void __at_exit_to_release_bundle() bundle_free(__bundle); } -static void __release_at_exit(void) -{ - if (__appid != NULL) - free(__appid); - - if (__pkgid != NULL) - free(__pkgid); - - if (__root_path != NULL) - free(__root_path); -} - static int __prepare_exec(const char *appid, const char *app_path, const char *pkg_type, int type) { @@ -174,7 +159,6 @@ static int __candidate_process_launchpad_main_loop(app_pkt_t *pkt, __bundle = kb; atexit(__at_exit_to_release_bundle); - atexit(__release_at_exit); menu_info = _appinfo_create(kb); if (menu_info == NULL) { @@ -208,41 +192,22 @@ static int __candidate_process_launchpad_main_loop(app_pkt_t *pkt, _modify_bundle(kb, /*cr.pid - unused parameter*/ 0, menu_info, pkt->cmd); - __appid = strdup(menu_info->appid); - if (__appid == NULL) { - _E("Out of memory"); - exit(-1); - } - aul_set_preinit_appid(__appid); - if (menu_info->pkgid == NULL) { _E("unable to get pkg_id from menu_info"); exit(-1); } - SECURE_LOGD("pkg id: %s", menu_info->pkgid); - - __pkgid = strdup(menu_info->pkgid); - if (__pkgid == NULL) { - _E("Out of memory"); - exit(-1); - } - aul_set_preinit_pkgid(__pkgid); - __root_path = strdup(menu_info->root_path); - if (__root_path == NULL) { - _E("Out of memory"); - exit(-1); - } - aul_set_preinit_root_path(__root_path); + SECURE_LOGD("pkg id: %s", menu_info->pkgid); tmp_argv = _create_argc_argv(kb, &tmp_argc); - __default_launch_cb(kb, __appid, app_path, menu_info->pkg_type, type); + __default_launch_cb(kb, menu_info->appid, app_path, + menu_info->pkg_type, type); if (__loader_callbacks->launch) { ret = __loader_callbacks->launch(tmp_argc, tmp_argv, app_path, - __appid, __pkgid, menu_info->pkg_type, - __loader_user_data); + menu_info->appid, menu_info->pkgid, + menu_info->pkg_type, __loader_user_data); } /* SET ENVIROMENT*/ -- 2.7.4 From 6791e3816c0977f901d88480f5c2c6bfe83a0f3b Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Mon, 11 Jul 2016 19:09:13 +0900 Subject: [PATCH 03/16] Trim debug messages Change-Id: I1ba22ddca3763ae4f201a715fb73799e1697ad99 Signed-off-by: Junghoon Park --- src/launchpad.c | 45 ++++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/src/launchpad.c b/src/launchpad.c index 4d85ea9..f2ca786 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -50,6 +50,11 @@ #define LOADER_PATH_DEFAULT "/usr/bin/launchpad-loader" #define LOADER_INFO_PATH "/usr/share/aul" #define REGULAR_UID_MIN 5000 +#define PAD_ERR_FAILED -1 +#define PAD_ERR_REJECTED -2 +#define PAD_ERR_INVALID_ARGUMENT -3 +#define PAD_ERR_INVALID_PATH -4 + typedef struct { int type; @@ -503,29 +508,21 @@ static int __prepare_exec(const char *appid, const char *app_path, /* SET PRIVILEGES*/ if (bundle_get_val(kb, AUL_K_PRIVACY_APPID) == NULL) { - _D("appId: %s / app_path : %s ", appid, app_path); ret = security_manager_prepare_app(appid); - if (ret != SECURITY_MANAGER_SUCCESS) { - _D("fail to set privileges - check " - "your package's credential : %d\n", - ret); - return -1; - } + if (ret != SECURITY_MANAGER_SUCCESS) + return PAD_ERR_REJECTED; } /* SET DUMPABLE - for coredump*/ prctl(PR_SET_DUMPABLE, 1); /* SET PROCESS NAME*/ - if (app_path == NULL) { - _D("app_path should not be NULL - check menu db"); - return -1; - } + if (app_path == NULL) + return PAD_ERR_INVALID_ARGUMENT; + file_name = strrchr(app_path, '/') + 1; - if (file_name == NULL) { - _D("can't locate file name to execute"); - return -1; - } + if (file_name == NULL) + return PAD_ERR_INVALID_PATH; _prepare_listen_sock(); @@ -544,6 +541,7 @@ static int __launch_directly(const char *appid, const char *app_path, int clifd, candidate_process_context_t *cpc) { int pid = fork(); + int ret; if (pid == 0) { PERF("fork done"); @@ -556,19 +554,13 @@ static int __launch_directly(const char *appid, const char *app_path, int clifd, _delete_sock_path(getpid(), getuid()); PERF("prepare exec - first done"); - _D("lock up test log(no error) : prepare exec - first done"); - - if (__prepare_exec(appid, app_path, menu_info, kb) < 0) { - SECURE_LOGE("preparing work fail to launch - " - "can not launch %s\n", appid); - exit(-1); - } + if ((ret = __prepare_exec(appid, app_path, menu_info, kb)) < 0) + exit(ret); PERF("prepare exec - second done"); - _D("lock up test log(no error) : prepare exec - second done"); __real_launch(app_path, kb); - exit(-1); + exit(PAD_ERR_FAILED); } SECURE_LOGD("==> real launch pid : %d %s\n", pid, app_path); @@ -795,10 +787,9 @@ static gboolean __handle_sigchild(gpointer data) if (s == 0) break; - if (s != sizeof(struct signalfd_siginfo)) { - _E("error reading sigchld info"); + if (s != sizeof(struct signalfd_siginfo)) break; - } + __launchpad_process_sigchld(&siginfo); cpc = __find_slot_from_pid(siginfo.ssi_pid); if (cpc != NULL) { -- 2.7.4 From f1ef7c93d5f414c7a02973fbb65f2910c395981a Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Wed, 13 Jul 2016 11:44:38 +0900 Subject: [PATCH 04/16] Fix bug about disposing candidate processes Change-Id: Ic8c6ad7fec3960ac8d0a173015831982c0876f64 Signed-off-by: Junghoon Park --- src/launchpad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/launchpad.c b/src/launchpad.c index f2ca786..7c6540e 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -817,7 +817,7 @@ static gboolean __handle_label_monitor(gpointer data) while (iter) { cpc = (candidate_process_context_t *)iter->data; - if (cpc->prepared) { + if (cpc->pid > 0) { if (cpc->source > 0) { g_source_remove(cpc->source); cpc->source = 0; -- 2.7.4 From 91ea225bdcf1ca221b02c1eb923da24504bd32a2 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 14 Jul 2016 11:01:23 +0900 Subject: [PATCH 05/16] Fix the exception about getting the file name Change-Id: I1d3426a1a9f31fd93e81a92841a678d55a4c30a0 Signed-off-by: Hwankyu Jhun --- src/launchpad.c | 6 +++++- src/launchpad_lib.c | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/launchpad.c b/src/launchpad.c index 7c6540e..57a92e4 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -520,10 +520,14 @@ static int __prepare_exec(const char *appid, const char *app_path, if (app_path == NULL) return PAD_ERR_INVALID_ARGUMENT; - file_name = strrchr(app_path, '/') + 1; + file_name = strrchr(app_path, '/'); if (file_name == NULL) return PAD_ERR_INVALID_PATH; + file_name++; + if (*file_name == '\0') + return PAD_ERR_INVALID_PATH; + _prepare_listen_sock(); memset(process_name, '\0', AUL_PR_NAME); diff --git a/src/launchpad_lib.c b/src/launchpad_lib.c index 3cb5daf..3f5b1ef 100644 --- a/src/launchpad_lib.c +++ b/src/launchpad_lib.c @@ -88,8 +88,14 @@ static int __prepare_exec(const char *appid, const char *app_path, return -1; } - file_name = strrchr(app_path, '/') + 1; + file_name = strrchr(app_path, '/'); if (file_name == NULL) { + _D("file_name is NULL"); + return -1; + } + + file_name++; + if (*file_name == '\0') { _D("can't locate file name to execute"); return -1; } -- 2.7.4 From 34f7cb59af5f28b66c5b958c3fbf4a9183bc4988 Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Fri, 15 Jul 2016 17:32:22 +0900 Subject: [PATCH 06/16] Change exec label to System::Privileged Change-Id: I9139384ec602dca9333d96b133bd67b797cf1c4e Signed-off-by: Junghoon Park --- launchpad.manifest | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/launchpad.manifest b/launchpad.manifest index 97e8c31..529112f 100644 --- a/launchpad.manifest +++ b/launchpad.manifest @@ -2,4 +2,8 @@ + + + + -- 2.7.4 From 2b57faf66cf945af5d712728cc2d9b02fe739e38 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 15 Jul 2016 10:38:48 +0900 Subject: [PATCH 07/16] Adjust coding style Change-Id: Ifac527030c050873f7e3be4d59716d224c7a2eaa Signed-off-by: Hwankyu Jhun --- inc/launchpad_common.h | 15 ---------- inc/perf.h | 2 +- inc/preexec.h | 13 ++++----- inc/sigchild.h | 9 +++--- src/launchpad.c | 76 ++++++++++++++++++++++++++++++-------------------- src/launchpad_common.c | 13 +++++---- src/launchpad_lib.c | 14 +++++----- src/launchpad_loader.c | 13 +++++---- src/loader_info.c | 25 +++++++++++------ 9 files changed, 96 insertions(+), 84 deletions(-) diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h index 1c07962..4d7d43f 100644 --- a/inc/launchpad_common.h +++ b/inc/launchpad_common.h @@ -53,21 +53,6 @@ #define _D(fmt, arg...) LOGD(fmt, ##arg) #define _W(fmt, arg...) LOGW(fmt, ##arg) -#define retvm_if(expr, val, fmt, arg...) do { \ - if (expr) { \ - _E(fmt, ##arg); \ - _E("(%s) -> %s() return", #expr, __FUNCTION__); \ - return (val); \ - } \ -} while (0) - -#define retv_if(expr, val) do { \ - if (expr) { \ - _E("(%s) -> %s() return", #expr, __FUNCTION__); \ - return (val); \ - } \ -} while (0) - enum loader_arg { LOADER_ARG_PATH, LOADER_ARG_TYPE, diff --git a/inc/perf.h b/inc/perf.h index 319219c..3bc169f 100644 --- a/inc/perf.h +++ b/inc/perf.h @@ -46,7 +46,7 @@ static struct timeval __g_base_time = { if (__g_base_time.tv_sec != 0) { \ timersub(&cur, &__g_base_time, &res); \ printf("%c[1;31m[%s,%d] %ld sec %ld msec "fmt \ - " %c[0m\n", 27, __FUNCTION__, \ + " %c[0m\n", 27, __func__, \ __LINE__, res.tv_sec, \ res.tv_usec/1000, ##arg, 27);\ } \ diff --git a/inc/preexec.h b/inc/preexec.h index d6a937e..23bc9c5 100755 --- a/inc/preexec.h +++ b/inc/preexec.h @@ -20,17 +20,17 @@ #include #define PREEXEC_FILE SHARE_PREFIX"/preexec_list.txt" -static int preexec_initialized = 0; +static int preexec_initialized; -GSList *preexec_list = NULL; +static GSList *preexec_list; typedef struct _preexec_list_t { char *pkg_type; char *so_path; - int (*dl_do_pre_exe) (char *, char *); + int (*dl_do_pre_exe)(char *, char *); } preexec_list_t; -static void __preexec_list_free() +static void __preexec_list_free(void) { GSList *iter = NULL; preexec_list_t *type_t; @@ -47,7 +47,6 @@ static void __preexec_list_free() } g_slist_free(preexec_list); preexec_initialized = 0; - return; } static inline void __preexec_init(int argc, char **argv) @@ -59,7 +58,7 @@ static inline void __preexec_init(int argc, char **argv) char *type = NULL; char *sopath = NULL; char *symbol = NULL; - int (*func) (char *, char *) = NULL; + int (*func)(char *, char *) = NULL; preexec_list_t *type_t = NULL; preexec_file = fopen(PREEXEC_FILE, "rt"); @@ -166,7 +165,7 @@ static inline void __preexec_run(const char *pkg_type, const char *pkg_name, #else -static void __preexec_list_free() +static void __preexec_list_free(void) { } diff --git a/inc/sigchild.h b/inc/sigchild.h index 9ea5b0f..cfa6476 100644 --- a/inc/sigchild.h +++ b/inc/sigchild.h @@ -27,7 +27,7 @@ #define AUL_DBUS_APPDEAD_SIGNAL "app_dead" #define AUL_DBUS_APPLAUNCH_SIGNAL "app_launch" -static GDBusConnection *bus = NULL; +static GDBusConnection *bus; static sigset_t oldmask; static inline void __socket_garbage_collector(void) @@ -165,8 +165,6 @@ static void __launchpad_process_sigchld(struct signalfd_siginfo *info) killpg(child_pgid, SIGKILL); __sigchild_action(child_pid); } - - return; } static inline int __signal_init(void) @@ -233,11 +231,14 @@ static inline int __signal_unblock_sigchld(void) static inline int __signal_fini(void) { +#ifndef PRELOAD_ACTIVATE + int i; +#endif + if (bus) g_object_unref(bus); #ifndef PRELOAD_ACTIVATE - int i; for (i = 0; i < _NSIG; i++) signal(i, SIG_DFL); #endif diff --git a/src/launchpad.c b/src/launchpad.c index 57a92e4..16fadc7 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -88,9 +88,9 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, int caller_pid, const char *loader_path, const char *extra, int detection_method, int timeout_val); static int __remove_slot(int type, int loader_id); -static int __add_default_slots(); +static int __add_default_slots(void); -static int __make_loader_id() +static int __make_loader_id(void) { static int id = PAD_LOADER_ID_DYNAMIC_BASE; @@ -346,8 +346,6 @@ static void __send_result_to_caller(int clifd, int ret, const char *app_path) if (__real_send(clifd, ret) < 0) __kill_process(ret); - - return; } static int __prepare_candidate_process(int type, int loader_id) @@ -472,7 +470,7 @@ static int __normal_fork_exec(int argc, char **argv) return 0; } -static void __real_launch(const char *app_path, bundle * kb) +static void __real_launch(const char *app_path, bundle *kb) { int app_argc; char **app_argv; @@ -495,7 +493,7 @@ static void __real_launch(const char *app_path, bundle * kb) } static int __prepare_exec(const char *appid, const char *app_path, - appinfo_t *menu_info, bundle * kb) + appinfo_t *menu_info, bundle *kb) { char *file_name; char process_name[AUL_PR_NAME]; @@ -558,7 +556,8 @@ static int __launch_directly(const char *appid, const char *app_path, int clifd, _delete_sock_path(getpid(), getuid()); PERF("prepare exec - first done"); - if ((ret = __prepare_exec(appid, app_path, menu_info, kb)) < 0) + ret = __prepare_exec(appid, app_path, menu_info, kb); + if (ret < 0) exit(ret); PERF("prepare exec - second done"); @@ -667,6 +666,7 @@ static guint __poll_fd(int fd, gushort events, GSourceFunc func, int type, int r; GPollFD *gpollfd; GSource *src; + loader_context_t *lc; src = g_source_new(&funcs, sizeof(GSource)); if (!src) { @@ -674,7 +674,7 @@ static guint __poll_fd(int fd, gushort events, GSourceFunc func, int type, return 0; } - gpollfd = (GPollFD *) g_malloc(sizeof(GPollFD)); + gpollfd = (GPollFD *)g_malloc(sizeof(GPollFD)); if (!gpollfd) { _E("out of memory"); g_source_destroy(src); @@ -684,7 +684,7 @@ static guint __poll_fd(int fd, gushort events, GSourceFunc func, int type, gpollfd->events = events; gpollfd->fd = fd; - loader_context_t *lc = malloc(sizeof(loader_context_t)); + lc = malloc(sizeof(loader_context_t)); if (lc == NULL) { g_free(gpollfd); g_source_destroy(src); @@ -722,8 +722,9 @@ static gboolean __handle_loader_client_event(gpointer data) return G_SOURCE_REMOVE; if (revents & (G_IO_HUP | G_IO_NVAL)) { - SECURE_LOGE("Type %d candidate process was (POLLHUP|POLLNVAL), " - "pid: %d", cpc->type, cpc->pid); + SECURE_LOGE("Type %d candidate process was " \ + "(POLLHUP|POLLNVAL), pid: %d", + cpc->type, cpc->pid); close(cpc->send_fd); cpc->prepared = false; @@ -762,8 +763,8 @@ static gboolean __handle_loader_event(gpointer data) cpc->prepared = true; cpc->send_fd = client_fd; - SECURE_LOGD("Type %d candidate process was connected, " - "pid: %d", type, cpc->pid); + SECURE_LOGD("Type %d candidate process was connected," \ + " pid: %d", type, cpc->pid); cpc->source = __poll_fd(client_fd, G_IO_IN | G_IO_HUP, __handle_loader_client_event, type, loader_id); @@ -944,10 +945,13 @@ static candidate_process_context_t *__find_available_slot(const char *hwacc, int len = 0; int i; - if (loader_name) - type = _loader_info_find_type_by_loader_name(loader_info_list, loader_name); - else - type = _loader_info_find_type(loader_info_list, app_type, __is_hw_acc(hwacc)); + if (loader_name) { + type = _loader_info_find_type_by_loader_name(loader_info_list, + loader_name); + } else { + type = _loader_info_find_type(loader_info_list, + app_type, __is_hw_acc(hwacc)); + } cpc = __find_slot(type, PAD_LOADER_ID_STATIC); if (!cpc) return NULL; @@ -1073,11 +1077,16 @@ static gboolean __handle_launch_event(gpointer data) if (menu_info->comp_type && strcmp(menu_info->comp_type, "svcapp") == 0) { loader_id = PAD_LOADER_ID_DIRECT; - } else if ((loader_id = __get_loader_id(kb)) <= PAD_LOADER_ID_STATIC) { - cpc = __find_available_slot(menu_info->hwacc, menu_info->app_type, menu_info->loader_name); } else { - type = LAUNCHPAD_TYPE_DYNAMIC; - cpc = __find_slot(type, loader_id); + loader_id = __get_loader_id(kb); + if (loader_id <= PAD_LOADER_ID_STATIC) { + cpc = __find_available_slot(menu_info->hwacc, + menu_info->app_type, + menu_info->loader_name); + } else { + type = LAUNCHPAD_TYPE_DYNAMIC; + cpc = __find_slot(type, loader_id); + } } _modify_bundle(kb, cr.pid, menu_info, pkt->cmd); @@ -1152,7 +1161,7 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, fd = __listen_candidate_process(cpc->type, cpc->loader_id); if (fd == -1) { - _E("[launchpad] Listening the socket to " + _E("[launchpad] Listening the socket to " \ "the type %d candidate process failed.", cpc->type); free(cpc); @@ -1176,8 +1185,8 @@ static int __remove_slot(int type, int loader_id) { candidate_process_context_t *cpc; GList *iter; - iter = candidate_slot_list; + iter = candidate_slot_list; while (iter) { cpc = (candidate_process_context_t *)iter->data; if (type == cpc->type && loader_id == cpc->loader_id) { @@ -1263,7 +1272,8 @@ static int __init_label_monitor_fd(void) return -1; } - pollfd = __poll_fd(fd, G_IO_IN, (GSourceFunc)__handle_label_monitor, 0, 0); + pollfd = __poll_fd(fd, G_IO_IN, + (GSourceFunc)__handle_label_monitor, 0, 0); if (pollfd == 0) { close(fd); return -1; @@ -1278,9 +1288,11 @@ static void __add_slot_from_info(gpointer data, gpointer user_data) candidate_process_context_t *cpc; bundle_raw *extra = NULL; int len; + int ret; if (!strcmp(info->exe, "null")) { - cpc = __add_slot(LAUNCHPAD_TYPE_USER + user_slot_offset, PAD_LOADER_ID_DIRECT, + cpc = __add_slot(LAUNCHPAD_TYPE_USER + user_slot_offset, + PAD_LOADER_ID_DIRECT, 0, info->exe, NULL, 0, 0); if (cpc == NULL) return; @@ -1294,13 +1306,17 @@ static void __add_slot_from_info(gpointer data, gpointer user_data) if (info->extra) bundle_encode(info->extra, &extra, &len); - cpc = __add_slot(LAUNCHPAD_TYPE_USER + user_slot_offset, PAD_LOADER_ID_STATIC, - 0, info->exe, (char *)extra, info->detection_method, info->timeout_val); + cpc = __add_slot(LAUNCHPAD_TYPE_USER + user_slot_offset, + PAD_LOADER_ID_STATIC, + 0, info->exe, (char *)extra, + info->detection_method, info->timeout_val); if (cpc == NULL) return; - if (__prepare_candidate_process(LAUNCHPAD_TYPE_USER + user_slot_offset, - PAD_LOADER_ID_STATIC) != 0) + ret = __prepare_candidate_process( + LAUNCHPAD_TYPE_USER + user_slot_offset, + PAD_LOADER_ID_STATIC); + if (ret != 0) return; info->type = LAUNCHPAD_TYPE_USER + user_slot_offset; @@ -1381,7 +1397,7 @@ static void __set_priority(void) res = setpriority(PRIO_PROCESS, 0, -12); if (res == -1) { - SECURE_LOGE("Setting process (%d) priority to -12 failed, " + SECURE_LOGE("Setting process (%d) priority to -12 failed, " \ "errno: %d (%s)", getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); } diff --git a/src/launchpad_common.c b/src/launchpad_common.c index 7109129..42c6267 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -47,7 +47,7 @@ #define MAX_CMD_BUFSZ 1024 #define MAX_PENDING_CONNECTIONS 10 -#define CONNECT_RETRY_TIME 100 * 1000 +#define CONNECT_RETRY_TIME (100 * 1000) #define CONNECT_RETRY_COUNT 3 #define AUL_PKT_HEADER_SIZE (sizeof(int) + sizeof(int) + sizeof(int)) @@ -67,9 +67,9 @@ static int __read_proc(const char *path, char *buf, int size) if (ret <= 0) { close(fd); return -1; - } else - buf[ret] = 0; + } + buf[ret] = 0; close(fd); return ret; @@ -269,8 +269,9 @@ app_pkt_t *_recv_pkt_raw(int fd, int *clifd, struct ucred *cr) sun_size = sizeof(struct sockaddr_un); - if ((*clifd = accept(fd, (struct sockaddr *)&aul_addr, - (socklen_t *) &sun_size)) == -1) { + *clifd = accept(fd, (struct sockaddr *)&aul_addr, + (socklen_t *) &sun_size); + if (*clifd == -1) { if (errno != EINTR) _E("accept error"); return NULL; @@ -742,7 +743,7 @@ static int __delete_dir(const char *path) ret = stat(buf, &statbuf); if (ret == 0) { if (S_ISDIR(statbuf.st_mode)) - __delete_dir(buf); + __delete_dir(buf); else unlink(buf); } diff --git a/src/launchpad_lib.c b/src/launchpad_lib.c index 3f5b1ef..aa4a4b9 100644 --- a/src/launchpad_lib.c +++ b/src/launchpad_lib.c @@ -50,7 +50,7 @@ static bundle *__bundle; static int __loader_type = LAUNCHPAD_TYPE_UNSUPPORTED; static int __loader_id; -static void __at_exit_to_release_bundle() +static void __at_exit_to_release_bundle(void) { if (__bundle) bundle_free(__bundle); @@ -70,8 +70,8 @@ static int __prepare_exec(const char *appid, const char *app_path, appid, pkg_type, app_path); ret = security_manager_prepare_app(appid); if (ret != SECURITY_MANAGER_SUCCESS) { - _D("fail to set privileges - check your package's credential: " - "%d\n", ret); + _D("fail to set privileges - " \ + "check your package's credential: %d\n", ret); return -1; } @@ -121,7 +121,7 @@ static int __default_launch_cb(bundle *kb, const char *appid, if (strncmp(high_priority, "true", 4) == 0) { res = setpriority(PRIO_PROCESS, 0, -10); if (res == -1) { - SECURE_LOGE("Setting process (%d) priority " + SECURE_LOGE("Setting process (%d) priority " \ "to -10 failed, errno: %d (%s)", getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); @@ -133,7 +133,7 @@ static int __default_launch_cb(bundle *kb, const char *appid, if (__prepare_exec(appid, app_path, pkg_type, loader_type) < 0) { _E("__candidate_process_prepare_exec() failed"); if (access(app_path, F_OK | R_OK)) { - SECURE_LOGE("access() failed for file: \"%s\", " + SECURE_LOGE("access() failed for file: \"%s\", " \ "error: %d (%s)", app_path, errno, strerror_r(errno, err_str, sizeof(err_str))); } @@ -294,7 +294,7 @@ static int __before_loop(int argc, char **argv) int res = setpriority(PRIO_PROCESS, 0, LOWEST_PRIO); if (res == -1) { - SECURE_LOGE("Setting process (%d) priority to %d failed, " + SECURE_LOGE("Setting process (%d) priority to %d failed, " \ "errno: %d (%s)", getpid(), LOWEST_PRIO, errno, strerror_r(errno, err_str, sizeof(err_str))); } @@ -324,7 +324,7 @@ static int __before_loop(int argc, char **argv) #ifdef _APPFW_FEATURE_LOADER_PRIORITY res = setpriority(PRIO_PGRP, 0, 0); if (res == -1) { - SECURE_LOGE("Setting process (%d) priority to 0 failed, " + SECURE_LOGE("Setting process (%d) priority to 0 failed, " \ "errno: %d (%s)", getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); } diff --git a/src/launchpad_loader.c b/src/launchpad_loader.c index c7d7220..0868cd1 100644 --- a/src/launchpad_loader.c +++ b/src/launchpad_loader.c @@ -37,7 +37,7 @@ #define LOADER_TYPE_SW "sw-loader" -extern bundle *launchpad_loader_get_bundle(); +extern bundle *launchpad_loader_get_bundle(void); static Ecore_Fd_Handler *__fd_handler; static loader_receiver_cb __receiver; @@ -81,6 +81,7 @@ static void __init_theme(void) char *theme = elm_theme_list_item_path_get(eina_list_data_get( elm_theme_list_get(NULL)), NULL); Eina_Bool is_exist = edje_file_group_exists(theme, "*"); + if (!is_exist) _D("theme path: %s", theme); @@ -241,8 +242,10 @@ static int __loader_launch_cb(int argc, char **argv, const char *app_path, const char *hwacc; bundle *kb = launchpad_loader_get_bundle(); int acc = SW_ACC; + loader_convertible convert; - vconf_ignore_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION, __vconf_cb); + vconf_ignore_key_changed(VCONFKEY_SETAPPL_APP_HW_ACCELERATION, + __vconf_cb); if (kb == NULL) return 0; @@ -257,7 +260,7 @@ static int __loader_launch_cb(int argc, char **argv, const char *app_path, acc = HW_ACC; } - loader_convertible convert = __converter_table[__type][acc]; + convert = __converter_table[__type][acc]; if (convert) convert(); @@ -309,7 +312,7 @@ do_dlopen: handle = dlopen(argv[LOADER_ARG_PATH], RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND); if (handle == NULL) { - _E("dlopen failed(%s). Please complile with -fPIE and " + _E("dlopen failed(%s). Please complile with -fPIE and " \ "link with -pie flag", dlerror()); goto do_exec; } @@ -346,7 +349,7 @@ do_exec: setenv("LD_LIBRARY_PATH", libdir, 1); free(libdir); if (execv(argv[LOADER_ARG_PATH], argv) < 0) { - SECURE_LOGE("execv() failed for file: \"%s\", " + SECURE_LOGE("execv() failed for file: \"%s\", " \ "error: %d (%s)", argv[LOADER_ARG_PATH], errno, strerror_r(errno, err_str, sizeof(err_str))); } diff --git a/src/loader_info.c b/src/loader_info.c index b683539..c0ded9f 100644 --- a/src/loader_info.c +++ b/src/loader_info.c @@ -92,8 +92,11 @@ static void __parse_app_types(loader_info_t *info, char *line) while (token) { refined_tok[0] = '\0'; sscanf(token, "%s", refined_tok); - if (refined_tok[0] != '\0' && strcasecmp("null", refined_tok) != 0) - info->app_types = g_list_append(info->app_types, strdup(refined_tok)); + if (refined_tok[0] != '\0' && + strcasecmp("null", refined_tok) != 0) { + info->app_types = g_list_append(info->app_types, + strdup(refined_tok)); + } token = strtok_r(NULL, "|", &savedptr); } } @@ -194,7 +197,7 @@ static GList *__parse_file(GList *list, const char *path) cur_info->timeout_val = atoi(tok2); } else if (strcasecmp(TAG_EXTRA, tok1) == 0) { __parse_extra(cur_info, buf); - } else if (strcasecmp(TAG_EXTRA_ARRAY,tok1) == 0) { + } else if (strcasecmp(TAG_EXTRA_ARRAY, tok1) == 0) { __flush_extra_array(cur_info->extra, key, extra_array); extra_array = NULL; key = strdup(tok2); @@ -320,12 +323,15 @@ static int __comp_name(gconstpointer a, gconstpointer b) int _loader_info_find_type(GList *info, const char *app_type, bool hwacc) { - GList *cur = NULL; + GList *cur; - if (hwacc) - cur = g_list_find_custom(info, app_type, __comp_app_type_with_hw_acc); - else - cur = g_list_find_custom(info, app_type, __comp_app_type_with_sw_acc); + if (hwacc) { + cur = g_list_find_custom(info, app_type, + __comp_app_type_with_hw_acc); + } else { + cur = g_list_find_custom(info, app_type, + __comp_app_type_with_sw_acc); + } if (cur == NULL) return -1; @@ -399,7 +405,8 @@ int *_loader_get_alternative_types(GList *info, int type, int *len) if (!i->alternative_loaders) return NULL; - return __make_type_array(info, i->alternative_loaders, len); + return __make_type_array(info, i->alternative_loaders, + len); } cur = g_list_next(cur); } -- 2.7.4 From fe355b37562fc3f4ecb23bafbe643aea0831d019 Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Wed, 20 Jul 2016 13:28:12 +0900 Subject: [PATCH 08/16] Change exec label for launchpad-loader Change-Id: Ibb145e37aaf739bd909c613e9dfee15e72b36f75 Signed-off-by: Junghoon Park --- launchpad.manifest | 1 + 1 file changed, 1 insertion(+) diff --git a/launchpad.manifest b/launchpad.manifest index 529112f..9f9511c 100644 --- a/launchpad.manifest +++ b/launchpad.manifest @@ -4,6 +4,7 @@ + -- 2.7.4 From f8212e604ee57067279c9c54a0562b5ffaa31ddb Mon Sep 17 00:00:00 2001 From: Semun Lee Date: Wed, 20 Jul 2016 15:30:44 +0900 Subject: [PATCH 09/16] Add RTLD_NODELETE flag for dlopen preloaded libraries and application executable does not need to be unloaded during process lifetime. Change-Id: Iebf86725d24b33e12df1d163089547933b8f8031 Signed-off-by: Semun Lee --- inc/preexec.h | 2 +- src/launchpad_loader.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/inc/preexec.h b/inc/preexec.h index 23bc9c5..4b5b7cd 100755 --- a/inc/preexec.h +++ b/inc/preexec.h @@ -92,7 +92,7 @@ static inline void __preexec_init(int argc, char **argv) return; } - handle = dlopen(sopath, RTLD_GLOBAL | RTLD_LAZY); + handle = dlopen(sopath, RTLD_GLOBAL | RTLD_LAZY | RTLD_NODELETE); if (handle == NULL) { free(type_t); continue; diff --git a/src/launchpad_loader.c b/src/launchpad_loader.c index 0868cd1..23b0cb9 100644 --- a/src/launchpad_loader.c +++ b/src/launchpad_loader.c @@ -159,7 +159,7 @@ static void __preload_lib(bundle *b) return; for (i = 0; i < len; i++) { - handle = dlopen(so_array[i], RTLD_NOW); + handle = dlopen(so_array[i], RTLD_NOW | RTLD_NODELETE); _D("preload %s# - handle : %x\n", so_array[i], handle); } } @@ -310,7 +310,8 @@ static int __loader_terminate_cb(int argc, char **argv, void *user_data) do_dlopen: handle = dlopen(argv[LOADER_ARG_PATH], - RTLD_LAZY | RTLD_GLOBAL | RTLD_DEEPBIND); + RTLD_LAZY | RTLD_GLOBAL + | RTLD_DEEPBIND | RTLD_NODELETE); if (handle == NULL) { _E("dlopen failed(%s). Please complile with -fPIE and " \ "link with -pie flag", dlerror()); -- 2.7.4 From 4e715370a48e77a92ce6d0462fd178b94b2bf959 Mon Sep 17 00:00:00 2001 From: Semun Lee Date: Fri, 8 Jul 2016 14:59:41 +0900 Subject: [PATCH 10/16] Use mount namespace for backward compatiblity To supported applications with hardcoded path in their code, mount application root path to the legacy path. Change-Id: I3cfe9937f281b52c02cda80836f2a59d5cf31625 Signed-off-by: Semun Lee --- CMakeLists.txt | 1 + inc/launchpad_common.h | 3 + packaging/launchpad.spec | 5 +- src/launchpad.c | 145 +++++++++++++++++++++++++++++++++++------------ src/launchpad_common.c | 54 ++++++++++++++++++ src/launchpad_lib.c | 9 ++- 6 files changed, 178 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d5f0cbe..c4edd07 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ PKG_CHECK_MODULES(${this_target_pool} REQUIRED gio-2.0 ttrace vconf + libtzplatform-config ) FOREACH(flag ${${this_target_pool}_CFLAGS}) diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h index 4d7d43f..8263dec 100644 --- a/inc/launchpad_common.h +++ b/inc/launchpad_common.h @@ -103,5 +103,8 @@ char *_appinfo_get_app_path(appinfo_t *menu_info); int _proc_get_attr_by_pid(int pid, char *buf, int size); int _close_all_fds(int except); +int _mount_legacy_app_path(const char *app_root_path, + const char *pkgid); + #endif /* __LAUNCHPAD_COMMON_H__ */ diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index c99b544..48e1bc7 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -20,6 +20,7 @@ BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(security-manager) BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(ttrace) +BuildRequires: pkgconfig(libtzplatform-config) Requires(post): /sbin/ldconfig Requires(post): /usr/bin/systemctl @@ -82,8 +83,8 @@ cp %{_builddir}/%{name}-%{version}/LICENSE %{buildroot}/usr/share/license/%{nam %{_unitdir_user}/launchpad-process-pool.socket %{_unitdir_user}/sockets.target.wants/launchpad-process-pool.socket %{_unitdir_user}/default.target.wants/launchpad-process-pool.service -%caps(cap_mac_admin,cap_setgid=ei) %{_bindir}/launchpad-process-pool -%caps(cap_setgid=ei) %{_bindir}/launchpad-loader +%caps(cap_sys_admin,cap_mac_admin,cap_setgid=ei) %{_bindir}/launchpad-process-pool +%caps(cap_sys_admin,cap_setgid=ei) %{_bindir}/launchpad-loader %attr(0644,root,root) %{_libdir}/liblaunchpad.so.* %files devel diff --git a/src/launchpad.c b/src/launchpad.c index 16fadc7..2c73289 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -89,6 +91,7 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, int detection_method, int timeout_val); static int __remove_slot(int type, int loader_id); static int __add_default_slots(void); +static int stack_limit; static int __make_loader_id(void) { @@ -348,6 +351,46 @@ static void __send_result_to_caller(int clifd, int ret, const char *app_path) __kill_process(ret); } +static int __fork_app_process(int (*child_fn)(void *), void *arg) +{ + char *stack; + char *stack_top; + int pid; + + stack = malloc(stack_limit); + if (stack == NULL) { + _E("failed to alloc child stack"); + return -1; + } + + stack_top = stack + stack_limit; + + pid = clone(child_fn, stack_top, + CLONE_NEWNS | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, + arg); + + free(stack); + + if (pid == -1) + _E("failed to clone child process"); + + return pid; +} + +static int __exec_loader_process(void *arg) +{ + char **argv = arg; + __signal_unblock_sigchld(); + __signal_fini(); + + if (execv(argv[LOADER_ARG_PATH], argv) < 0) + _E("Failed to prepare candidate_process"); + else + _D("Succeeded to prepare candidate_process"); + + return -1; +} + static int __prepare_candidate_process(int type, int loader_id) { int pid; @@ -365,23 +408,18 @@ static int __prepare_candidate_process(int type, int loader_id) argv[LOADER_ARG_DUMMY] = argbuf; cpt->last_exec_time = time(NULL); - pid = fork(); - if (pid == 0) { /* child */ - __signal_unblock_sigchld(); - __signal_fini(); - - type_str[0] = '0' + type; - snprintf(loader_id_str, sizeof(loader_id_str), "%d", loader_id); - argv[LOADER_ARG_PATH] = cpt->loader_path; - argv[LOADER_ARG_TYPE] = type_str; - argv[LOADER_ARG_ID] = loader_id_str; - argv[LOADER_ARG_EXTRA] = cpt->loader_extra; - if (execv(argv[LOADER_ARG_PATH], argv) < 0) - _E("Failed to prepare candidate_process"); - else - _D("Succeeded to prepare candidate_process"); - - exit(-1); + + type_str[0] = '0' + type; + snprintf(loader_id_str, sizeof(loader_id_str), "%d", loader_id); + argv[LOADER_ARG_PATH] = cpt->loader_path; + argv[LOADER_ARG_TYPE] = type_str; + argv[LOADER_ARG_ID] = loader_id_str; + argv[LOADER_ARG_EXTRA] = cpt->loader_extra; + + pid = __fork_app_process(__exec_loader_process, argv); + if (pid == -1) { + _E("Failed to fork candidate_process"); + return -1; } else { cpt->pid = pid; } @@ -538,33 +576,59 @@ static int __prepare_exec(const char *appid, const char *app_path, return 0; } -static int __launch_directly(const char *appid, const char *app_path, int clifd, - bundle *kb, appinfo_t *menu_info, - candidate_process_context_t *cpc) +struct app_launch_arg { + const char *appid; + const char *app_path; + appinfo_t *menu_info; + bundle *kb; +}; + +static int __exec_app_process(void *arg) { - int pid = fork(); + struct app_launch_arg *launch_arg = arg; int ret; - if (pid == 0) { - PERF("fork done"); - _D("lock up test log(no error) : fork done"); + PERF("fork done"); + _D("lock up test log(no error) : fork done"); + + __signal_unblock_sigchld(); + __signal_fini(); - __signal_unblock_sigchld(); - __signal_fini(); + _close_all_fds(0); + _delete_sock_path(getpid(), getuid()); - _close_all_fds(0); - _delete_sock_path(getpid(), getuid()); + ret = _mount_legacy_app_path(launch_arg->menu_info->root_path, + launch_arg->menu_info->pkgid); + if (ret != 0) + _W("Failed to mount legacy app path(%d)", errno); - PERF("prepare exec - first done"); - ret = __prepare_exec(appid, app_path, menu_info, kb); - if (ret < 0) - exit(ret); + PERF("prepare exec - first done"); + if ((ret = __prepare_exec(launch_arg->appid, launch_arg->app_path, + launch_arg->menu_info, launch_arg->kb)) < 0) + return ret; - PERF("prepare exec - second done"); - __real_launch(app_path, kb); + PERF("prepare exec - second done"); + __real_launch(launch_arg->app_path, launch_arg->kb); + + return PAD_ERR_FAILED; +} + +static int __launch_directly(const char *appid, const char *app_path, int clifd, + bundle *kb, appinfo_t *menu_info, + candidate_process_context_t *cpc) +{ + struct app_launch_arg arg; + + arg.appid = appid; + arg.app_path = app_path; + arg.menu_info = menu_info; + arg.kb = kb; + + int pid = __fork_app_process(__exec_app_process, &arg); + + if (pid <= 0) + _E("failed to fork app process"); - exit(PAD_ERR_FAILED); - } SECURE_LOGD("==> real launch pid : %d %s\n", pid, app_path); return pid; @@ -1407,6 +1471,8 @@ static void __set_priority(void) int main(int argc, char **argv) { GMainLoop *mainloop = NULL; + int ret; + struct rlimit rlim; mainloop = g_main_loop_new(NULL, FALSE); if (!mainloop) { @@ -1414,6 +1480,13 @@ int main(int argc, char **argv) return -1; } + ret = getrlimit(RLIMIT_STACK, &rlim); + if (ret != 0) { + _E("failed to get stack limit size! (%d)", errno); + return -1; + } + stack_limit = rlim.rlim_cur; + if (__before_loop(argc, argv) != 0) { _E("process-pool Initialization failed!\n"); return -1; diff --git a/src/launchpad_common.c b/src/launchpad_common.c index 42c6267..a206e63 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,7 @@ #include #include #include +#include #include "launchpad_common.h" #include "key.h" @@ -46,6 +48,8 @@ #define OPTION_VALGRIND_SIZE 8 #define MAX_CMD_BUFSZ 1024 +#define LEGACY_APP_ROOT_PATH "/opt/usr/apps" + #define MAX_PENDING_CONNECTIONS 10 #define CONNECT_RETRY_TIME (100 * 1000) #define CONNECT_RETRY_COUNT 3 @@ -810,3 +814,53 @@ int _close_all_fds(const int except) return 0; } +int _mount_legacy_app_path(const char *app_root_path, + const char *pkgid) +{ + const char *user_app_dir; + int ret, i; + char legacy_app_path[PATH_MAX]; + char user_app_data_path[PATH_MAX]; + char legacy_app_data_path[PATH_MAX]; + + char *app_data_paths[5] = { + "data", + "cache", + "shared/data", + "shared/cache", + "shared/trusted" }; + + snprintf(legacy_app_path, PATH_MAX, + "%s/%s", LEGACY_APP_ROOT_PATH, pkgid); + + user_app_dir = tzplatform_getenv(TZ_USER_APP); + if (!user_app_dir) { + _E("failed to get TZ_USER_APP value"); + return -1; + } + + /* for user private app */ + if (!strncmp(app_root_path, user_app_dir, strlen(user_app_dir))) { + return mount(app_root_path, legacy_app_path, + NULL, MS_BIND, NULL); + } + + /* for global app */ + for (i = 0; i < 5; i++) { + snprintf(user_app_data_path, PATH_MAX, "%s/%s/%s", + user_app_dir, pkgid, app_data_paths[i]); + + if (access(user_app_data_path, F_OK) != 0) + continue; + + snprintf(legacy_app_data_path, PATH_MAX, "%s/%s", + legacy_app_path, app_data_paths[i]); + ret = mount(user_app_data_path, legacy_app_data_path, + NULL, MS_BIND, NULL); + if (ret != 0) + return ret; + } + + return 0; +} + diff --git a/src/launchpad_lib.c b/src/launchpad_lib.c index aa4a4b9..f063fcc 100644 --- a/src/launchpad_lib.c +++ b/src/launchpad_lib.c @@ -110,9 +110,11 @@ static int __prepare_exec(const char *appid, const char *app_path, } static int __default_launch_cb(bundle *kb, const char *appid, - const char *app_path, const char *pkg_type, int loader_type) + const char *app_path, const char *root_path, + const char *pkgid, const char *pkg_type, int loader_type) { char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + int ret; #ifdef _APPFW_FEATURE_PRIORITY_CHANGE int res; const char *high_priority = bundle_get_val(kb, AUL_K_HIGHPRIORITY); @@ -130,6 +132,10 @@ static int __default_launch_cb(bundle *kb, const char *appid, bundle_del(kb, AUL_K_HIGHPRIORITY); #endif + ret = _mount_legacy_app_path(root_path, pkgid); + if (ret != 0) + _W("Failed to mount legacy app path(%d)", errno); + if (__prepare_exec(appid, app_path, pkg_type, loader_type) < 0) { _E("__candidate_process_prepare_exec() failed"); if (access(app_path, F_OK | R_OK)) { @@ -208,6 +214,7 @@ static int __candidate_process_launchpad_main_loop(app_pkt_t *pkt, tmp_argv = _create_argc_argv(kb, &tmp_argc); __default_launch_cb(kb, menu_info->appid, app_path, + menu_info->root_path, menu_info->pkgid, menu_info->pkg_type, type); if (__loader_callbacks->launch) { -- 2.7.4 From 51b26353ea9015d647bc56b42a2c983e080ed220 Mon Sep 17 00:00:00 2001 From: Semun Lee Date: Mon, 25 Jul 2016 13:50:58 +0900 Subject: [PATCH 11/16] Mount app legacy path as private explicitly Change-Id: Iba25fb8619d04b235a6bb421a9a9fa2c7f58b695 Signed-off-by: Semun Lee --- src/launchpad_common.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/launchpad_common.c b/src/launchpad_common.c index a206e63..f6e314f 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -814,6 +814,30 @@ int _close_all_fds(const int except) return 0; } +static int __mount_and_make_private(const char *source, const char *target) +{ + int ret; + + ret = mount(NULL, "/", NULL, + MS_SLAVE | MS_REC, NULL); + if (ret != 0) { + _E("failed to set / as slave dir(%d)", ret); + return ret; + } + + ret = mount(source, target, + NULL, MS_BIND, NULL); + if (ret != 0) { + _E("failed to mount legacy dir(%d): %s to %s", + ret, source, target); + return ret; + } + + _D("end legacy path mount"); + + return ret; +} + int _mount_legacy_app_path(const char *app_root_path, const char *pkgid) { @@ -823,6 +847,8 @@ int _mount_legacy_app_path(const char *app_root_path, char user_app_data_path[PATH_MAX]; char legacy_app_data_path[PATH_MAX]; + _D("start legacy path mount"); + char *app_data_paths[5] = { "data", "cache", @@ -841,8 +867,7 @@ int _mount_legacy_app_path(const char *app_root_path, /* for user private app */ if (!strncmp(app_root_path, user_app_dir, strlen(user_app_dir))) { - return mount(app_root_path, legacy_app_path, - NULL, MS_BIND, NULL); + return __mount_and_make_private(app_root_path, legacy_app_path); } /* for global app */ @@ -855,8 +880,8 @@ int _mount_legacy_app_path(const char *app_root_path, snprintf(legacy_app_data_path, PATH_MAX, "%s/%s", legacy_app_path, app_data_paths[i]); - ret = mount(user_app_data_path, legacy_app_data_path, - NULL, MS_BIND, NULL); + ret = __mount_and_make_private(user_app_data_path, + legacy_app_data_path); if (ret != 0) return ret; } -- 2.7.4 From 2c573e60a5834ee4aa981f533c7cef05db3217ca Mon Sep 17 00:00:00 2001 From: Semun Lee Date: Mon, 25 Jul 2016 14:17:55 +0900 Subject: [PATCH 12/16] Make / slave only once for mounting legacy path Change-Id: I9f8cc6053095ba6218facb64596cbefa96f9c11f Signed-off-by: Semun Lee --- src/launchpad_common.c | 40 +++++++++++----------------------------- 1 file changed, 11 insertions(+), 29 deletions(-) diff --git a/src/launchpad_common.c b/src/launchpad_common.c index f6e314f..0e9d63b 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -814,30 +814,6 @@ int _close_all_fds(const int except) return 0; } -static int __mount_and_make_private(const char *source, const char *target) -{ - int ret; - - ret = mount(NULL, "/", NULL, - MS_SLAVE | MS_REC, NULL); - if (ret != 0) { - _E("failed to set / as slave dir(%d)", ret); - return ret; - } - - ret = mount(source, target, - NULL, MS_BIND, NULL); - if (ret != 0) { - _E("failed to mount legacy dir(%d): %s to %s", - ret, source, target); - return ret; - } - - _D("end legacy path mount"); - - return ret; -} - int _mount_legacy_app_path(const char *app_root_path, const char *pkgid) { @@ -847,8 +823,6 @@ int _mount_legacy_app_path(const char *app_root_path, char user_app_data_path[PATH_MAX]; char legacy_app_data_path[PATH_MAX]; - _D("start legacy path mount"); - char *app_data_paths[5] = { "data", "cache", @@ -865,9 +839,17 @@ int _mount_legacy_app_path(const char *app_root_path, return -1; } + ret = mount(NULL, "/", NULL, + MS_SLAVE | MS_REC, NULL); + if (ret != 0) { + _E("failed to set / as slave dir(%d)", ret); + return ret; + } + /* for user private app */ if (!strncmp(app_root_path, user_app_dir, strlen(user_app_dir))) { - return __mount_and_make_private(app_root_path, legacy_app_path); + return mount(app_root_path, legacy_app_path, NULL, + MS_BIND, NULL); } /* for global app */ @@ -880,8 +862,8 @@ int _mount_legacy_app_path(const char *app_root_path, snprintf(legacy_app_data_path, PATH_MAX, "%s/%s", legacy_app_path, app_data_paths[i]); - ret = __mount_and_make_private(user_app_data_path, - legacy_app_data_path); + ret = mount(user_app_data_path, legacy_app_data_path, NULL, + MS_BIND, NULL); if (ret != 0) return ret; } -- 2.7.4 From a807134e50aacb942b3719e443d303d50d221f67 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 28 Jul 2016 11:43:36 +0900 Subject: [PATCH 13/16] Close all open fds before executing a loader Change-Id: I556b4083c7bbe333d1cfe0708d40daed151bcacd Signed-off-by: Hwankyu Jhun --- inc/sigchild.h | 3 --- src/launchpad.c | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/inc/sigchild.h b/inc/sigchild.h index cfa6476..aaad0e5 100644 --- a/inc/sigchild.h +++ b/inc/sigchild.h @@ -235,9 +235,6 @@ static inline int __signal_fini(void) int i; #endif - if (bus) - g_object_unref(bus); - #ifndef PRELOAD_ACTIVATE for (i = 0; i < _NSIG; i++) signal(i, SIG_DFL); diff --git a/src/launchpad.c b/src/launchpad.c index 2c73289..d55074f 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -380,9 +380,12 @@ static int __fork_app_process(int (*child_fn)(void *), void *arg) static int __exec_loader_process(void *arg) { char **argv = arg; + __signal_unblock_sigchld(); __signal_fini(); + _close_all_fds(0); + if (execv(argv[LOADER_ARG_PATH], argv) < 0) _E("Failed to prepare candidate_process"); else -- 2.7.4 From 8549676d9cc54c2e44ee93972b82879661f68fb0 Mon Sep 17 00:00:00 2001 From: Semun Lee Date: Thu, 28 Jul 2016 19:08:25 +0900 Subject: [PATCH 14/16] Use fork/unshare instead of clone Change-Id: I687a275ed1a35fbc5a08b8e40fc3875da175ef05 Signed-off-by: Semun Lee --- src/launchpad.c | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) diff --git a/src/launchpad.c b/src/launchpad.c index d55074f..2728b27 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include @@ -91,7 +90,6 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, int detection_method, int timeout_val); static int __remove_slot(int type, int loader_id); static int __add_default_slots(void); -static int stack_limit; static int __make_loader_id(void) { @@ -353,26 +351,27 @@ static void __send_result_to_caller(int clifd, int ret, const char *app_path) static int __fork_app_process(int (*child_fn)(void *), void *arg) { - char *stack; - char *stack_top; int pid; + int ret; + + pid = fork(); - stack = malloc(stack_limit); - if (stack == NULL) { - _E("failed to alloc child stack"); + if (pid == -1) { + _E("failed to fork child process"); return -1; } - stack_top = stack + stack_limit; - - pid = clone(child_fn, stack_top, - CLONE_NEWNS | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, - arg); - - free(stack); + if (pid == 0) { + ret = unshare(CLONE_NEWNS); + if (ret != 0) { + _E("failed to unshare mount namespace (%d)", errno); + exit(ret); + } - if (pid == -1) - _E("failed to clone child process"); + ret = child_fn(arg); + _E("failed to exec app process (%d)", errno); + exit(ret); + } return pid; } @@ -1474,8 +1473,6 @@ static void __set_priority(void) int main(int argc, char **argv) { GMainLoop *mainloop = NULL; - int ret; - struct rlimit rlim; mainloop = g_main_loop_new(NULL, FALSE); if (!mainloop) { @@ -1483,13 +1480,6 @@ int main(int argc, char **argv) return -1; } - ret = getrlimit(RLIMIT_STACK, &rlim); - if (ret != 0) { - _E("failed to get stack limit size! (%d)", errno); - return -1; - } - stack_limit = rlim.rlim_cur; - if (__before_loop(argc, argv) != 0) { _E("process-pool Initialization failed!\n"); return -1; -- 2.7.4 From 69ac0df9d2e377dd7d387262e8278fd66ce03a42 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 29 Jul 2016 13:14:59 +0900 Subject: [PATCH 15/16] Wait socket creation Change-Id: Ic1a45c7f78618725a5ff2568e0fc7760e9fb7d4e Signed-off-by: Hwankyu Jhun --- src/launchpad.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/launchpad.c b/src/launchpad.c index 2728b27..202ccbb 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -325,6 +325,8 @@ static int __real_send(int clifd, int ret) static void __send_result_to_caller(int clifd, int ret, const char *app_path) { char *cmdline; + int count = 0; + char path[PATH_MAX]; _W("Check app launching"); @@ -337,6 +339,20 @@ static void __send_result_to_caller(int clifd, int ret, const char *app_path) return; } + snprintf(path, sizeof(path), "/run/aul/apps/%d/%d/.app-sock", + getuid(), ret); + _D("socket path: %s", path); + do { + if (access(path, F_OK) == 0) { + _D("%s exists", path); + break; + } + + _D("-- now wait socket creation --"); + usleep(50 * 1000); + count++; + } while (count < 20); + cmdline = _proc_get_cmdline_bypid(ret); if (cmdline == NULL) { _E("The app process might be terminated while we are wating %d", -- 2.7.4 From 11d2bf8c325bcb220b037df04ae9e12c98f3ac61 Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Mon, 25 Jul 2016 10:20:39 +0900 Subject: [PATCH 16/16] Check cpu idle time to prepare candidate process Change-Id: Ie2c0551a417a2a06ab2891e6a467701e215178c3 Signed-off-by: Junghoon Park --- inc/launchpad_common.h | 1 + packaging/default.loader.in | 8 +++--- src/launchpad.c | 63 +++++++++++++++++++++++++++++++++++++++++++-- src/launchpad_common.c | 37 ++++++++++++++++++++++++++ 4 files changed, 103 insertions(+), 6 deletions(-) diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h index 8263dec..8b70af4 100644 --- a/inc/launchpad_common.h +++ b/inc/launchpad_common.h @@ -102,6 +102,7 @@ void _appinfo_free(appinfo_t *menu_info); char *_appinfo_get_app_path(appinfo_t *menu_info); int _proc_get_attr_by_pid(int pid, char *buf, int size); int _close_all_fds(int except); +void _get_cpu_idle(long long *total, long long *idle); int _mount_legacy_app_path(const char *app_root_path, const char *pkgid); diff --git a/packaging/default.loader.in b/packaging/default.loader.in index 0ea64e5..d0d151c 100644 --- a/packaging/default.loader.in +++ b/packaging/default.loader.in @@ -3,8 +3,8 @@ NAME hw-loader1 EXE /usr/bin/launchpad-loader APP_TYPE capp|c++app HW_ACC ON -DETECTION_METHOD TIMEOUT -TIMEOUT 2000 +DETECTION_METHOD TIMEOUT|VISIBILITY +TIMEOUT 5000 EXTRA loader_type hw-loader EXTRA_ARRAY preload EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/libappcore-efl.so.1 @@ -22,8 +22,8 @@ ALTERNATIVE_LOADER common-loader1 NAME common-loader1 EXE /usr/bin/launchpad-loader APP_TYPE capp|c++app -DETECTION_METHOD TIMEOUT -TIMEOUT 2000 +DETECTION_METHOD TIMEOUT|VISIBILITY +TIMEOUT 5000 EXTRA loader_type common-loader EXTRA_ARRAY preload EXTRA_ARRAY_VAL @LIB_INSTALL_DIR@/libappcore-efl.so.1 diff --git a/src/launchpad.c b/src/launchpad.c index 202ccbb..4fb2490 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -55,7 +55,7 @@ #define PAD_ERR_REJECTED -2 #define PAD_ERR_INVALID_ARGUMENT -3 #define PAD_ERR_INVALID_PATH -4 - +#define CPU_CHECKER_TIMEOUT 1000 typedef struct { int type; @@ -71,6 +71,9 @@ typedef struct { char *loader_extra; int detection_method; int timeout_val; + long long cpu_total_time; + long long cpu_idle_time; + guint idle_checker; } candidate_process_context_t; typedef struct { @@ -421,6 +424,7 @@ static int __prepare_candidate_process(int type, int loader_id) if (cpt == NULL) return -1; + _D("prepare candidate process"); memset(argbuf, ' ', LOADER_ARG_LEN); argbuf[LOADER_ARG_LEN - 1] = '\0'; argv[LOADER_ARG_DUMMY] = argbuf; @@ -497,6 +501,11 @@ static int __send_launchpad_loader(candidate_process_context_t *cpc, cpc->timer = 0; } + if (cpc->idle_checker > 0) { + g_source_remove(cpc->idle_checker); + cpc->idle_checker = 0; + } + __set_timer(cpc); return pid; } @@ -816,6 +825,10 @@ static gboolean __handle_loader_client_event(gpointer data) if (cpc->timer > 0) g_source_remove(cpc->timer); cpc->timer = 0; + if (cpc->idle_checker > 0) + g_source_remove(cpc->idle_checker); + cpc->idle_checker = 0; + __prepare_candidate_process(cpc->type, cpc->loader_id); return G_SOURCE_REMOVE; @@ -915,6 +928,11 @@ static gboolean __handle_label_monitor(gpointer data) cpc->timer = 0; } + if (cpc->idle_checker > 0) { + g_source_remove(cpc->idle_checker); + cpc->idle_checker = 0; + } + _D("Dispose candidate process %d", cpc->pid); __kill_process(cpc->pid); close(cpc->send_fd); @@ -930,10 +948,37 @@ static gboolean __handle_label_monitor(gpointer data) return G_SOURCE_CONTINUE; } +static gboolean __handle_idle_checker(gpointer data) +{ + long long total = 0; + long long idle = 0; + int per; + candidate_process_context_t *cpc = data; + + _get_cpu_idle(&total, &idle); + if (total == cpc->cpu_total_time) + total++; + + per = (idle - cpc->cpu_idle_time) * 100 / (total - cpc->cpu_total_time); + _D("CPU Idle : %d %d", per, cpc->type); + + if (per >= 90) { + __prepare_candidate_process(cpc->type, cpc->loader_id); + cpc->idle_checker = 0; + return G_SOURCE_REMOVE; + } + + cpc->cpu_idle_time = idle; + cpc->cpu_total_time = total; + return G_SOURCE_CONTINUE; +} + static int __dispatch_cmd_hint(bundle *kb, int detection_method) { candidate_process_context_t *cpc; GList *iter = candidate_slot_list; + long long total = 0; + long long idle = 0; _W("cmd hint %d", detection_method); while (iter) { @@ -944,7 +989,16 @@ static int __dispatch_cmd_hint(bundle *kb, int detection_method) g_source_remove(cpc->timer); cpc->timer = 0; } - __prepare_candidate_process(cpc->type, cpc->loader_id); + + if (cpc->idle_checker > 0) { + g_source_remove(cpc->idle_checker); + cpc->idle_checker = 0; + } + + _get_cpu_idle(&total, &idle); + cpc->cpu_idle_time = idle; + cpc->cpu_total_time = total; + cpc->idle_checker = g_timeout_add(CPU_CHECKER_TIMEOUT, __handle_idle_checker, cpc); } iter = g_list_next(iter); @@ -1240,6 +1294,9 @@ static candidate_process_context_t *__add_slot(int type, int loader_id, cpc->loader_extra = loader_extra ? strdup(loader_extra) : strdup(""); cpc->detection_method = detection_method; cpc->timeout_val = timeout_val; + cpc->cpu_total_time = 0; + cpc->cpu_idle_time = 0; + cpc->idle_checker = 0; fd = __listen_candidate_process(cpc->type, cpc->loader_id); if (fd == -1) { @@ -1278,6 +1335,8 @@ static int __remove_slot(int type, int loader_id) g_source_remove(cpc->timer); if (cpc->source > 0) g_source_remove(cpc->source); + if (cpc->idle_checker > 0) + g_source_remove(cpc->idle_checker); candidate_slot_list = g_list_delete_link( candidate_slot_list, iter); diff --git a/src/launchpad_common.c b/src/launchpad_common.c index 0e9d63b..c4ffa98 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "launchpad_common.h" #include "key.h" @@ -79,6 +80,42 @@ static int __read_proc(const char *path, char *buf, int size) return ret; } +void _get_cpu_idle(long long *total, long long *idle) +{ + FILE *fp; + int i; + long long sum = 0; + long long val; + long long iv = 0; + + char buf[4]= { 0, }; + + fp = fopen("/proc/stat", "rt"); + + if (fp == NULL) + return; + + if (fscanf(fp, "%3s", buf) == -1) { + fclose(fp); + return; + } + + for (i = 0; i < 10; i++){ + if (fscanf(fp, "%lld", &val) == -1) { + fclose(fp); + return; + } + sum += val; + if (i == 3) /* idle */ + iv = val; + } + + fclose(fp); + + *total = sum; + *idle = iv; +} + void _set_sock_option(int fd, int cli) { int size; -- 2.7.4