From 4e715370a48e77a92ce6d0462fd178b94b2bf959 Mon Sep 17 00:00:00 2001 From: Semun Lee Date: Fri, 8 Jul 2016 14:59:41 +0900 Subject: [PATCH 01/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 02/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 03/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 04/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 05/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 06/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 07/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 From 7568225b899d175c66e651290183e32c77089520 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 8 Aug 2016 11:44:42 +0900 Subject: [PATCH 08/16] Remove checking socket creation Change-Id: Ife3d6350aad080fb2173935e30229e0e58a26ca9 Signed-off-by: Hwankyu Jhun --- inc/launchpad_common.h | 4 +- src/launchpad.c | 34 ++------------ src/launchpad_common.c | 120 +++---------------------------------------------- src/launchpad_lib.c | 2 - src/launchpad_loader.c | 14 +----- 5 files changed, 12 insertions(+), 162 deletions(-) diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h index 8b70af4..5ac9977 100644 --- a/inc/launchpad_common.h +++ b/inc/launchpad_common.h @@ -83,7 +83,6 @@ typedef struct { char *loader_name; } appinfo_t; -char *_proc_get_cmdline_bypid(int pid); void _modify_bundle(bundle *kb, int caller_pid, appinfo_t *menu_info, int cmd); int _create_server_sock(const char *name); @@ -94,14 +93,13 @@ void _set_sock_option(int fd, int cli); void _set_env(appinfo_t *menu_info, bundle *kb); char **_create_argc_argv(bundle *kb, int *margc); char *_get_libdir(const char *path); -void _prepare_listen_sock(void); int _delete_sock_path(int pid, uid_t uid); 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); +int _close_all_fds(void); void _get_cpu_idle(long long *total, long long *idle); int _mount_legacy_app_path(const char *app_root_path, diff --git a/src/launchpad.c b/src/launchpad.c index 4fb2490..01c91b8 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -327,11 +327,7 @@ 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"); + _W("send result: %d", ret); if (clifd == -1) return; @@ -342,28 +338,6 @@ 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", - ret); - __real_send(clifd, -1); /* abnormally launched*/ - return; - } - if (__real_send(clifd, ret) < 0) __kill_process(ret); } @@ -402,7 +376,7 @@ static int __exec_loader_process(void *arg) __signal_unblock_sigchld(); __signal_fini(); - _close_all_fds(0); + _close_all_fds(); if (execv(argv[LOADER_ARG_PATH], argv) < 0) _E("Failed to prepare candidate_process"); @@ -591,8 +565,6 @@ static int __prepare_exec(const char *appid, const char *app_path, if (*file_name == '\0') return PAD_ERR_INVALID_PATH; - _prepare_listen_sock(); - memset(process_name, '\0', AUL_PR_NAME); snprintf(process_name, AUL_PR_NAME, "%s", file_name); prctl(PR_SET_NAME, process_name); @@ -621,7 +593,7 @@ static int __exec_app_process(void *arg) __signal_unblock_sigchld(); __signal_fini(); - _close_all_fds(0); + _close_all_fds(); _delete_sock_path(getpid(), getuid()); ret = _mount_legacy_app_path(launch_arg->menu_info->root_path, diff --git a/src/launchpad_common.c b/src/launchpad_common.c index c4ffa98..f4f6739 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -37,16 +37,6 @@ #include "key.h" #define MAX_PATH_LEN 1024 -#define BINSH_NAME "/bin/sh" -#define BINSH_SIZE 7 -#define VALGRIND_NAME "/home/developer/sdk_tools/valgrind/usr/bin/valgrind" -#define VALGRIND_SIZE 51 -#define BASH_NAME "/bin/bash" -#define BASH_SIZE 9 -#define OPROFILE_NAME "/usr/bin/oprofile_command" -#define OPROFILE_SIZE 25 -#define OPTION_VALGRIND_NAME "valgrind" -#define OPTION_VALGRIND_SIZE 8 #define MAX_CMD_BUFSZ 1024 #define LEGACY_APP_ROOT_PATH "/opt/usr/apps" @@ -225,12 +215,8 @@ int _create_server_sock(const char *name) { struct sockaddr_un saddr; int fd; - int ret; - if (name) - fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); - else - fd = socket(AF_UNIX, SOCK_STREAM, 0); + fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); /* support above version 2.6.27*/ if (fd < 0) { if (errno == EINVAL) { @@ -248,34 +234,9 @@ int _create_server_sock(const char *name) memset(&saddr, 0, sizeof(saddr)); saddr.sun_family = AF_UNIX; - if (name) { - snprintf(saddr.sun_path, sizeof(saddr.sun_path), - "%s/daemons/%d/%s", - SOCKET_PATH, getuid(), name); - } else { - snprintf(saddr.sun_path, sizeof(saddr.sun_path), - "%s/apps/%d/%d", - SOCKET_PATH, getuid(), getpid()); - ret = mkdir(saddr.sun_path, 0700); - if (ret != 0) { - if (errno == EEXIST) { - if (access(saddr.sun_path, R_OK) != 0) { - _E("Failed to access %s directory - %d", - saddr.sun_path, errno); - close(fd); - return -1; - } - } else { - _E("Failed to create %s directory - %d", - saddr.sun_path, errno); - close(fd); - return -1; - } - } - snprintf(saddr.sun_path, sizeof(saddr.sun_path), - "%s/apps/%d/%d/.app-sock", - SOCKET_PATH, getuid(), getpid()); - } + snprintf(saddr.sun_path, sizeof(saddr.sun_path), + "%s/daemons/%d/%s", + SOCKET_PATH, getuid(), name); unlink(saddr.sun_path); if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { @@ -398,55 +359,6 @@ error: return -1; } -char *_proc_get_cmdline_bypid(int pid) -{ - char buf[MAX_CMD_BUFSZ]; - int ret; - char *ptr; - int len; - - snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid); - ret = __read_proc(buf, buf, sizeof(buf)); - if (ret <= 0) - return NULL; - - /* support app launched by shell script*/ - if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0) - return strdup(&buf[BINSH_SIZE + 1]); - else if (strncmp(buf, VALGRIND_NAME, VALGRIND_SIZE) == 0) { - ptr = buf; - - /* buf comes with double null-terminated string */ - while (1) { - while (*ptr) - ptr++; - ptr++; - - if (!(*ptr)) - break; - - /* ignore trailing "--" */ - if (strncmp(ptr, "-", 1) != 0) - break; - } - - return strdup(ptr); - } else if (strncmp(buf, BASH_NAME, BASH_SIZE) == 0) { - if (strncmp(&buf[BASH_SIZE + 1], OPROFILE_NAME, - OPROFILE_SIZE) == 0) { - if (strncmp(&buf[BASH_SIZE + OPROFILE_SIZE + 2], - OPTION_VALGRIND_NAME, - OPTION_VALGRIND_SIZE) == 0) { - len = BASH_SIZE + OPROFILE_SIZE + - OPTION_VALGRIND_SIZE + 3; - return strdup(&buf[len]); - } - } - } - - return strdup(buf); -} - appinfo_t *_appinfo_create(bundle *kb) { appinfo_t *menu_info; @@ -747,19 +659,6 @@ int _proc_get_attr_by_pid(int pid, char *buf, int size) return 0; } -void _prepare_listen_sock(void) -{ - int fd; - char buf[12]; - - fd = _create_server_sock(NULL); - if (fd < 0) - return; - - snprintf(buf, sizeof(buf), "%d", fd); - setenv("AUL_LISTEN_SOCK", buf, 1); -} - static int __delete_dir(const char *path) { DIR *dp; @@ -810,7 +709,7 @@ int _delete_sock_path(int pid, uid_t uid) return 0; } -int _close_all_fds(const int except) +int _close_all_fds(void) { DIR *dp; struct dirent dentry; @@ -822,10 +721,8 @@ int _close_all_fds(const int except) if (dp == NULL) { /* fallback */ max_fd = sysconf(_SC_OPEN_MAX); - for (fd = 3; fd < max_fd; fd++) { - if (fd != except) - close(fd); - } + for (fd = 3; fd < max_fd; fd++) + close(fd); return 0; } @@ -841,9 +738,6 @@ int _close_all_fds(const int except) if (fd == dirfd(dp)) continue; - if (fd == except) - continue; - close(fd); } closedir(dp); diff --git a/src/launchpad_lib.c b/src/launchpad_lib.c index f063fcc..71da029 100644 --- a/src/launchpad_lib.c +++ b/src/launchpad_lib.c @@ -100,8 +100,6 @@ static int __prepare_exec(const char *appid, const char *app_path, return -1; } - _prepare_listen_sock(); - memset(process_name, '\0', AUL_PR_NAME); snprintf(process_name, AUL_PR_NAME, "%s", file_name); prctl(PR_SET_NAME, process_name); diff --git a/src/launchpad_loader.c b/src/launchpad_loader.c index 23b0cb9..0b7c3a6 100644 --- a/src/launchpad_loader.c +++ b/src/launchpad_loader.c @@ -267,18 +267,6 @@ static int __loader_launch_cb(int argc, char **argv, const char *app_path, return 0; } -static void __close_fds(void) -{ - int fd = -1; - const char *sockfd; - - sockfd = getenv("AUL_LISTEN_SOCK"); - if (sockfd) - fd = atoi(sockfd); - - _close_all_fds(fd); -} - static int __loader_terminate_cb(int argc, char **argv, void *user_data) { void *handle; @@ -345,7 +333,7 @@ do_exec: } else { SECURE_LOGD("[candidate] Exec application (%s)", __argv[LOADER_ARG_PATH]); - __close_fds(); + _close_all_fds(); if (libdir) setenv("LD_LIBRARY_PATH", libdir, 1); free(libdir); -- 2.7.4 From eb0ef86c354bfa3e5ad8c0e97629d881a3dcda1f Mon Sep 17 00:00:00 2001 From: Junghoon Park Date: Wed, 10 Aug 2016 17:47:43 +0900 Subject: [PATCH 09/16] Clear cmdline up for loaders Change-Id: I744fd9680fba342063ded302a6fd851272a5aec3 Signed-off-by: Junghoon Park --- src/launchpad_lib.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/launchpad_lib.c b/src/launchpad_lib.c index 71da029..2723280 100644 --- a/src/launchpad_lib.c +++ b/src/launchpad_lib.c @@ -311,9 +311,12 @@ static int __before_loop(int argc, char **argv) /* TODO : should be add to check permission in the kernel*/ setsid(); + memset(argv[LOADER_ARG_TYPE], 0, strlen(argv[LOADER_ARG_TYPE])); + memset(argv[LOADER_ARG_ID], 0, strlen(argv[LOADER_ARG_ID])); if (argc > 3) { extra = bundle_decode((bundle_raw *)argv[LOADER_ARG_EXTRA], strlen(argv[LOADER_ARG_EXTRA])); + memset(argv[LOADER_ARG_EXTRA], 0, strlen(argv[LOADER_ARG_EXTRA])); } if (__loader_callbacks->create) { -- 2.7.4 From 45beac6eb3b4bfe354a60a3a9cdd911bde9a3e6a Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 19 Aug 2016 10:58:44 +0900 Subject: [PATCH 10/16] Move service file from default.target to basic.target Change-Id: Ia6234460170cc8fddda66e84d161ac7c7e3ac38b Signed-off-by: Hwankyu Jhun --- packaging/launchpad-process-pool.service | 1 + packaging/launchpad.spec | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packaging/launchpad-process-pool.service b/packaging/launchpad-process-pool.service index a627161..2d633ec 100644 --- a/packaging/launchpad-process-pool.service +++ b/packaging/launchpad-process-pool.service @@ -4,6 +4,7 @@ [Unit] Description=Start the USER Access Control Agent +DefaultDependencies=false [Service] ExecStartPre=-/usr/bin/mkdir -p /run/aul/daemons/%U diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 48e1bc7..878d84b 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -63,12 +63,12 @@ _APPFW_FEATURE_PRIORITY_CHANGE=ON rm -rf %{buildroot} %make_install -mkdir -p %{buildroot}%{_unitdir_user}/default.target.wants +mkdir -p %{buildroot}%{_unitdir_user}/basic.target.wants mkdir -p %{buildroot}%{_unitdir_user}/sockets.target.wants install -m 0644 %SOURCE101 %{buildroot}%{_unitdir_user}/launchpad-process-pool.service install -m 0644 %SOURCE102 %{buildroot}%{_unitdir_user}/launchpad-process-pool.socket ln -sf ../launchpad-process-pool.socket %{buildroot}%{_unitdir_user}/sockets.target.wants/launchpad-process-pool.socket -ln -sf ../launchpad-process-pool.service %{buildroot}%{_unitdir_user}/default.target.wants/launchpad-process-pool.service +ln -sf ../launchpad-process-pool.service %{buildroot}%{_unitdir_user}/basic.target.wants/launchpad-process-pool.service mkdir -p %{buildroot}/usr/share/license cp %{_builddir}/%{name}-%{version}/LICENSE %{buildroot}/usr/share/license/%{name} @@ -82,7 +82,7 @@ cp %{_builddir}/%{name}-%{version}/LICENSE %{buildroot}/usr/share/license/%{nam %{_unitdir_user}/launchpad-process-pool.service %{_unitdir_user}/launchpad-process-pool.socket %{_unitdir_user}/sockets.target.wants/launchpad-process-pool.socket -%{_unitdir_user}/default.target.wants/launchpad-process-pool.service +%{_unitdir_user}/basic.target.wants/launchpad-process-pool.service %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.* -- 2.7.4 From b4223b56a7faf56d9bee58cba2d4b06b1906c9d5 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 29 Aug 2016 20:48:01 +0900 Subject: [PATCH 11/16] Adjust coding style Change-Id: I08f25d4b1dd4d62c0967d4886a6609da75e0b312 Signed-off-by: Hwankyu Jhun --- src/launchpad.c | 12 +++++++----- src/launchpad_common.c | 5 ++--- src/launchpad_lib.c | 3 ++- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/launchpad.c b/src/launchpad.c index 01c91b8..38c22c6 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -416,10 +416,10 @@ static int __prepare_candidate_process(int type, int loader_id) if (pid == -1) { _E("Failed to fork candidate_process"); return -1; - } else { - cpt->pid = pid; } + cpt->pid = pid; + return 0; } @@ -602,8 +602,9 @@ static int __exec_app_process(void *arg) _W("Failed to mount legacy app path(%d)", errno); PERF("prepare exec - first done"); - if ((ret = __prepare_exec(launch_arg->appid, launch_arg->app_path, - launch_arg->menu_info, launch_arg->kb)) < 0) + ret = __prepare_exec(launch_arg->appid, launch_arg->app_path, + launch_arg->menu_info, launch_arg->kb); + if (ret < 0) return ret; PERF("prepare exec - second done"); @@ -970,7 +971,8 @@ static int __dispatch_cmd_hint(bundle *kb, int detection_method) _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); + cpc->idle_checker = g_timeout_add(CPU_CHECKER_TIMEOUT, + __handle_idle_checker, cpc); } iter = g_list_next(iter); diff --git a/src/launchpad_common.c b/src/launchpad_common.c index f4f6739..a7b74da 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -77,8 +77,7 @@ void _get_cpu_idle(long long *total, long long *idle) long long sum = 0; long long val; long long iv = 0; - - char buf[4]= { 0, }; + char buf[4] = { 0, }; fp = fopen("/proc/stat", "rt"); @@ -90,7 +89,7 @@ void _get_cpu_idle(long long *total, long long *idle) return; } - for (i = 0; i < 10; i++){ + for (i = 0; i < 10; i++) { if (fscanf(fp, "%lld", &val) == -1) { fclose(fp); return; diff --git a/src/launchpad_lib.c b/src/launchpad_lib.c index 2723280..0997ce1 100644 --- a/src/launchpad_lib.c +++ b/src/launchpad_lib.c @@ -316,7 +316,8 @@ static int __before_loop(int argc, char **argv) if (argc > 3) { extra = bundle_decode((bundle_raw *)argv[LOADER_ARG_EXTRA], strlen(argv[LOADER_ARG_EXTRA])); - memset(argv[LOADER_ARG_EXTRA], 0, strlen(argv[LOADER_ARG_EXTRA])); + memset(argv[LOADER_ARG_EXTRA], 0, + strlen(argv[LOADER_ARG_EXTRA])); } if (__loader_callbacks->create) { -- 2.7.4 From a58b4b3c5ca848c2d064591e579e830408f607e4 Mon Sep 17 00:00:00 2001 From: Semun Lee Date: Tue, 30 Aug 2016 10:32:17 +0900 Subject: [PATCH 12/16] Remove mounting legacy app path /opt/usr/apps will be bind-mounted to $HOME/apps_rw. launchpad doesn't need to mount legacy app path. Change-Id: I23217dcb2a1b571a350d7eb6633ee56a636380e4 Signed-off-by: Semun Lee --- inc/launchpad_common.h | 3 --- packaging/launchpad.spec | 4 ++-- src/launchpad.c | 11 --------- src/launchpad_common.c | 59 ------------------------------------------------ src/launchpad_lib.c | 5 ---- 5 files changed, 2 insertions(+), 80 deletions(-) diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h index 5ac9977..f1907c1 100644 --- a/inc/launchpad_common.h +++ b/inc/launchpad_common.h @@ -102,8 +102,5 @@ int _proc_get_attr_by_pid(int pid, char *buf, int size); int _close_all_fds(void); void _get_cpu_idle(long long *total, long long *idle); -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 878d84b..d11ed9d 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -83,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}/basic.target.wants/launchpad-process-pool.service -%caps(cap_sys_admin,cap_mac_admin,cap_setgid=ei) %{_bindir}/launchpad-process-pool -%caps(cap_sys_admin,cap_setgid=ei) %{_bindir}/launchpad-loader +%caps(cap_mac_admin,cap_setgid=ei) %{_bindir}/launchpad-process-pool +%caps(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 38c22c6..e573ea3 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -355,12 +355,6 @@ static int __fork_app_process(int (*child_fn)(void *), void *arg) } if (pid == 0) { - ret = unshare(CLONE_NEWNS); - if (ret != 0) { - _E("failed to unshare mount namespace (%d)", errno); - exit(ret); - } - ret = child_fn(arg); _E("failed to exec app process (%d)", errno); exit(ret); @@ -596,11 +590,6 @@ static int __exec_app_process(void *arg) _close_all_fds(); _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(launch_arg->appid, launch_arg->app_path, launch_arg->menu_info, launch_arg->kb); diff --git a/src/launchpad_common.c b/src/launchpad_common.c index a7b74da..aa4b909 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -39,8 +39,6 @@ #define MAX_PATH_LEN 1024 #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 @@ -744,60 +742,3 @@ int _close_all_fds(void) 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; - } - - 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(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 0997ce1..42c8b28 100644 --- a/src/launchpad_lib.c +++ b/src/launchpad_lib.c @@ -112,7 +112,6 @@ static int __default_launch_cb(bundle *kb, const char *appid, 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,10 +129,6 @@ 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)) { -- 2.7.4 From e40a70a28697005e1e34edab14bf7f8e091d2a79 Mon Sep 17 00:00:00 2001 From: Semun Lee Date: Thu, 8 Sep 2016 13:03:23 +0900 Subject: [PATCH 13/16] Remove RTLD_DEEPBIND I found many Tizen Store applications have potential problem of symbol conflict as they include some glib symbols in its executable. We cannot deal this issue in general way. For workaround, they can be launched by removing RTLD_DEEPBIND flag from dlopen of executable file. Change-Id: I6635b7e14fb7e79d2895476c705f4f97eaecfcb9 Signed-off-by: Semun Lee --- src/launchpad_loader.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/launchpad_loader.c b/src/launchpad_loader.c index 0b7c3a6..8559b73 100644 --- a/src/launchpad_loader.c +++ b/src/launchpad_loader.c @@ -298,8 +298,7 @@ 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_NODELETE); + RTLD_LAZY | RTLD_GLOBAL | RTLD_NODELETE); if (handle == NULL) { _E("dlopen failed(%s). Please complile with -fPIE and " \ "link with -pie flag", dlerror()); -- 2.7.4 From 47f641de4382b96e96acd1d1895fd4e609730069 Mon Sep 17 00:00:00 2001 From: Michal Bloch Date: Mon, 10 Oct 2016 17:12:00 +0200 Subject: [PATCH 14/16] Move close_all_fds right before exec Some FDs (specifically, the ones used for dlog logging) are in use between current close_all_fds call spot and exec Change-Id: Ie64fad2cef350c2e2931da6a3c21200471b23fdb Signed-off-by: Michal Bloch --- src/launchpad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/launchpad.c b/src/launchpad.c index e573ea3..a0c8a8b 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -489,6 +489,7 @@ static int __normal_fork_exec(int argc, char **argv) setenv("LD_LIBRARY_PATH", libdir, 1); free(libdir); + _close_all_fds(); if (execv(argv[LOADER_ARG_PATH], argv) < 0) { /* Flawfinder: ignore */ if (errno == EACCES) { _E("such a file is no executable - %s", @@ -587,7 +588,6 @@ static int __exec_app_process(void *arg) __signal_unblock_sigchld(); __signal_fini(); - _close_all_fds(); _delete_sock_path(getpid(), getuid()); PERF("prepare exec - first done"); -- 2.7.4 From f2e530f18886354e182123308264a84c738377f3 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 13 Oct 2016 13:20:29 +0900 Subject: [PATCH 15/16] Support script file to register static launchers Change-Id: I8d689122d43409502b7a13277ed63dfa86862600 Signed-off-by: Hwankyu Jhun --- CMakeLists.txt | 1 + inc/launcher_info.h | 30 ++++++ src/launcher_info.c | 258 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/launchpad.c | 106 +++++++++++++++++---- 4 files changed, 377 insertions(+), 18 deletions(-) create mode 100644 inc/launcher_info.h create mode 100644 src/launcher_info.c diff --git a/CMakeLists.txt b/CMakeLists.txt index c4edd07..28ad574 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,6 +98,7 @@ SET(${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES src/launchpad.c src/launchpad_common.c src/loader_info.c + src/launcher_info.c ) ADD_EXECUTABLE(${LAUNCHPAD_PROCESS_POOL} ${${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES}) diff --git a/inc/launcher_info.h b/inc/launcher_info.h new file mode 100644 index 0000000..c8a470b --- /dev/null +++ b/inc/launcher_info.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LAUNCHER_INFO_H__ +#define __LAUNCHER_INFO_H__ + +#include + +typedef struct launcher_info_s *launcher_info_h; + +GList *_launcher_info_load(const char *path); +void _launcher_info_unload(GList *info); +launcher_info_h _launcher_info_find(GList *info_list, const char *app_type); +const char *_launcher_info_get_exe(launcher_info_h launcher_info); +GList *_launcher_info_get_extra_args(launcher_info_h launcher_info); + +#endif /* __LAUNCHER_INFO_H__ */ diff --git a/src/launcher_info.c b/src/launcher_info.c new file mode 100644 index 0000000..06b46ab --- /dev/null +++ b/src/launcher_info.c @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include + +#include "launcher_info.h" +#include "launchpad_common.h" + +#define TAG_LAUNCHER "[LAUNCHER]" +#define TAG_NAME "NAME" +#define TAG_EXE "EXE" +#define TAG_APP_TYPE "APP_TYPE" +#define TAG_EXTRA_ARG "EXTRA_ARG" + +struct launcher_info_s { + char *name; + char *exe; + GList *app_types; + GList *extra_args; +}; + +static struct launcher_info_s *__create_launcher_info(void) +{ + struct launcher_info_s *info; + + info = calloc(1, sizeof(struct launcher_info_s)); + if (info == NULL) { + _E("out of memory"); + return NULL; + } + + return info; +} + +static void __destroy_launcher_info(gpointer data) +{ + struct launcher_info_s *info = (struct launcher_info_s *)data; + + if (info == NULL) + return; + + if (info->extra_args) + g_list_free_full(info->extra_args, free); + if (info->app_types) + g_list_free_full(info->app_types, free); + if (info->exe) + free(info->exe); + if (info->name) + free(info->name); + free(info); +} + +static void __parse_app_types(struct launcher_info_s *info, char *line) +{ + char *token; + char *saveptr = NULL; + char tok[LINE_MAX]; + + token = strtok_r(line, "|", &saveptr); + while (token) { + tok[0] = '\0'; + sscanf(token, "%s", tok); + if (tok[0] != '\0' && strcasecmp(tok, "null") != 0) { + info->app_types = g_list_append(info->app_types, + strdup(tok)); + } + token = strtok_r(NULL, "|", &saveptr); + } +} + +static GList *__parse_file(GList *list, const char *path) +{ + FILE *fp; + char buf[LINE_MAX]; + char tok1[LINE_MAX]; + char tok2[LINE_MAX]; + struct launcher_info_s *info = NULL; + + fp = fopen(path, "rt"); + if (fp == NULL) + return list; + + while (fgets(buf, sizeof(buf), fp) != NULL) { + tok1[0] = '\0'; + tok2[0] = '\0'; + sscanf(buf, "%s %s", tok1, tok2); + + if (strcasecmp(TAG_LAUNCHER, tok1) == 0) { + if (info) { + _D("name: %s, exe: %s", info->name, info->exe); + list = g_list_append(list, info); + } + + info = __create_launcher_info(); + if (info == NULL) + break; + + continue; + } + + if (tok1[0] == '\0' || tok2[0] == '\0' || tok1[0] == '#') + continue; + if (info == NULL) + continue; + + if (strcasecmp(TAG_NAME, tok1) == 0) { + info->name = strdup(tok2); + if (info->name == NULL) { + _E("out of memory"); + __destroy_launcher_info(info); + info = NULL; + break; + } + } else if (strcasecmp(TAG_EXE, tok1) == 0) { + info->exe = strdup(tok2); + if (info->exe == NULL) { + _E("out of memory"); + __destroy_launcher_info(info); + info = NULL; + break; + } + if (access(info->exe, F_OK | X_OK) != 0) { + _E("Failed to access %s", info->exe); + __destroy_launcher_info(info); + info = NULL; + } + } else if (strcasecmp(TAG_APP_TYPE, tok1) == 0) { + __parse_app_types(info, &buf[strlen(tok1)]); + if (info->app_types == NULL) { + _E("app_types is NULL"); + __destroy_launcher_info(info); + info = NULL; + break; + } + } else if (strcasecmp(TAG_EXTRA_ARG, tok1) == 0) { + info->extra_args = g_list_append(info->extra_args, + strdup(tok2)); + } + } + fclose(fp); + + if (info) { + _D("name: %s, exe: %s", info->name, info->exe); + list = g_list_append(list, info); + } + + return list; +} + +GList *_launcher_info_load(const char *path) +{ + DIR *dp; + struct dirent dentry; + struct dirent *result = NULL; + GList *list = NULL; + char buf[PATH_MAX]; + char *ext; + + if (path == NULL) + return NULL; + + dp = opendir(path); + if (dp == NULL) + return NULL; + + while (readdir_r(dp, &dentry, &result) == 0 && result != NULL) { + if (dentry.d_name[0] == '.') + continue; + + ext = strrchr(dentry.d_name, '.'); + if (ext && strcmp(ext, ".launcher") == 0) { + snprintf(buf, sizeof(buf), "%s/%s", + path, dentry.d_name); + list = __parse_file(list, buf); + } + } + closedir(dp); + + return list; +} + +void _launcher_info_unload(GList *info) +{ + if (info == NULL) + return; + + g_list_free_full(info, __destroy_launcher_info); +} + +static int __comp_str(gconstpointer a, gconstpointer b) +{ + if (a == NULL || b == NULL) + return -1; + + return strcmp(a, b); +} + +static int __comp_app_type(gconstpointer a, gconstpointer b) +{ + struct launcher_info_s *info = (struct launcher_info_s *)a; + + if (info == NULL || info->app_types == NULL || b == NULL) + return -1; + + if (g_list_find_custom(info->app_types, b, __comp_str)) + return 0; + + return -1; +} + +launcher_info_h _launcher_info_find(GList *info_list, const char *app_type) +{ + GList *list; + + if (info_list == NULL || app_type == NULL) + return NULL; + + list = g_list_find_custom(info_list, app_type, __comp_app_type); + if (list == NULL) + return NULL; + + return (launcher_info_h)list->data; +} + +const char *_launcher_info_get_exe(launcher_info_h info) +{ + if (info == NULL) + return NULL; + + return info->exe; +} + +GList *_launcher_info_get_extra_args(launcher_info_h info) +{ + if (info == NULL) + return NULL; + + return info->extra_args; +} diff --git a/src/launchpad.c b/src/launchpad.c index a0c8a8b..7917433 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -41,6 +41,7 @@ #include "key.h" #include "launchpad.h" #include "loader_info.h" +#include "launcher_info.h" #define AUL_PR_NAME 16 #define EXEC_CANDIDATE_EXPIRED 5 @@ -50,6 +51,7 @@ #define PROCESS_POOL_LAUNCHPAD_SOCK ".launchpad-process-pool-sock" #define LOADER_PATH_DEFAULT "/usr/bin/launchpad-loader" #define LOADER_INFO_PATH "/usr/share/aul" +#define LAUNCHER_INFO_PATH LOADER_INFO_PATH #define REGULAR_UID_MIN 5000 #define PAD_ERR_FAILED -1 #define PAD_ERR_REJECTED -2 @@ -82,11 +84,19 @@ typedef struct { int loader_id; } loader_context_t; +struct app_launch_arg { + const char *appid; + const char *app_path; + appinfo_t *menu_info; + bundle *kb; +}; + static int __sys_hwacc; static GList *loader_info_list; static int user_slot_offset; static GList *candidate_slot_list; static app_labels_monitor *label_monitor; +static GList *launcher_info_list; static candidate_process_context_t *__add_slot(int type, int loader_id, int caller_pid, const char *loader_path, const char *extra, @@ -504,11 +514,66 @@ static int __normal_fork_exec(int argc, char **argv) return 0; } -static void __real_launch(const char *app_path, bundle *kb) +static int __set_launcher_info(int *argc, char ***argv, const char *app_type) +{ + launcher_info_h launcher_info; + char **new_argv; + int new_argc; + const char *exe; + GList *extra_args; + int extra_argc; + const char *extra_arg; + GList *iter; + int i; + + launcher_info = _launcher_info_find(launcher_info_list, app_type); + if (launcher_info == NULL) + return 0; + + exe = _launcher_info_get_exe(launcher_info); + if (exe == NULL) { + _E("Failed to get launcher exe"); + return -1; + } + + extra_args = _launcher_info_get_extra_args(launcher_info); + extra_argc = g_list_length(extra_args) + 1; + + new_argc = *argc + extra_argc; + new_argv = (char **)realloc(*argv, sizeof(char *) * new_argc); + if (new_argv == NULL) { + _E("Failed to reallocate memory"); + return -1; + } + + for (i = new_argc; i >= extra_argc; i--) + new_argv[i] = new_argv[i - extra_argc]; + + i = LOADER_ARG_PATH; + new_argv[i++] = strdup(exe); + + iter = g_list_first(extra_args); + while (iter) { + extra_arg = (char *)iter->data; + if (extra_arg) + new_argv[i++] = strdup(extra_arg); + + iter = g_list_next(iter); + } + + *argc = new_argc; + *argv = new_argv; + + return 0; +} + +static void __real_launch(const char *app_path, bundle *kb, + appinfo_t *menu_info) { int app_argc; char **app_argv; int i; + int ret; if (bundle_get_val(kb, AUL_K_DEBUG) != NULL) putenv("TIZEN_DEBUGGING_PORT=1"); @@ -516,12 +581,15 @@ static void __real_launch(const char *app_path, bundle *kb) app_argv = _create_argc_argv(kb, &app_argc); app_argv[LOADER_ARG_PATH] = strdup(app_path); - for (i = 0; i < app_argc; i++) { - if ((i % 2) == 1) - continue; - SECURE_LOGD("input argument %d : %s##", i, app_argv[i]); + ret = __set_launcher_info(&app_argc, &app_argv, menu_info->app_type); + if (ret < 0) { + _E("Failed to set launcher info"); + exit(-1); } + for (i = 0; i < app_argc; i += 2) + SECURE_LOGD("input argument %d : %s##", i, app_argv[i]); + PERF("setup argument done"); __normal_fork_exec(app_argc, app_argv); } @@ -570,13 +638,6 @@ static int __prepare_exec(const char *appid, const char *app_path, return 0; } -struct app_launch_arg { - const char *appid; - const char *app_path; - appinfo_t *menu_info; - bundle *kb; -}; - static int __exec_app_process(void *arg) { struct app_launch_arg *launch_arg = arg; @@ -597,7 +658,8 @@ static int __exec_app_process(void *arg) return ret; PERF("prepare exec - second done"); - __real_launch(launch_arg->app_path, launch_arg->kb); + __real_launch(launch_arg->app_path, launch_arg->kb, + launch_arg->menu_info); return PAD_ERR_FAILED; } @@ -607,14 +669,14 @@ static int __launch_directly(const char *appid, const char *app_path, int clifd, candidate_process_context_t *cpc) { struct app_launch_arg arg; + int pid; 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); - + pid = __fork_app_process(__exec_app_process, &arg); if (pid <= 0) _E("failed to fork app process"); @@ -1434,7 +1496,6 @@ static int __add_default_slots(void) _loader_info_dispose(loader_info_list); loader_info_list = _loader_info_load(LOADER_INFO_PATH); - if (loader_info_list == NULL) return -1; @@ -1490,9 +1551,19 @@ static int __before_loop(int argc, char **argv) VCONFKEY_SETAPPL_APP_HW_ACCELERATION); } + launcher_info_list = _launcher_info_load(LAUNCHER_INFO_PATH); + return 0; } +static void __after_loop(void) +{ + _launcher_info_unload(launcher_info_list); + + if (label_monitor) + security_manager_app_labels_monitor_finish(label_monitor); +} + #ifdef _APPFW_FEATURE_PRIORITY_CHANGE static void __set_priority(void) { @@ -1528,8 +1599,7 @@ int main(int argc, char **argv) #endif g_main_loop_run(mainloop); - if (label_monitor) - security_manager_app_labels_monitor_finish(label_monitor); + __after_loop(); return -1; } -- 2.7.4 From d8df094776e77842517c62f3eb2be959061d2151 Mon Sep 17 00:00:00 2001 From: Hawnkyu Jhun Date: Wed, 28 Sep 2016 21:09:56 +0900 Subject: [PATCH 16/16] Support script file to register static debug tools +---------------+--------------------------------+ | [Debugger] | Description | +---------------+--------------------------------+ | Name | Debug tool name | | Exe | Executable file | | App_type | Application type | | Extra_key | Bundle key of extra arguments | | Extra_env | Bundle key of extra environment| | | variables | | Unlink | Remove the specified file | | Attach | Attach to running process | +---------------+--------------------------------+ Change-Id: I09bf0562375d04b73ad0d076d8328fb70ca7e496 Signed-off-by: Hawnkyu Jhun --- CMakeLists.txt | 4 + inc/debugger_info.h | 33 +++++ inc/key.h | 44 +++--- inc/launchpad_debug.h | 31 +++++ packaging/default.debugger.in | 20 +++ packaging/launchpad.spec | 3 +- src/debugger_info.c | 295 ++++++++++++++++++++++++++++++++++++++++ src/launchpad.c | 165 +++++++++++++++++----- src/launchpad_debug.c | 308 ++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 850 insertions(+), 53 deletions(-) create mode 100644 inc/debugger_info.h create mode 100644 inc/launchpad_debug.h create mode 100644 packaging/default.debugger.in create mode 100644 src/debugger_info.c create mode 100644 src/launchpad_debug.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 28ad574..2c0aa51 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,6 +99,8 @@ SET(${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES src/launchpad_common.c src/loader_info.c src/launcher_info.c + src/debugger_info.c + src/launchpad_debug.c ) ADD_EXECUTABLE(${LAUNCHPAD_PROCESS_POOL} ${${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES}) @@ -108,6 +110,8 @@ SET_TARGET_PROPERTIES(${LAUNCHPAD_PROCESS_POOL} PROPERTIES SKIP_BUILD_RPATH TRUE ) # remove rpath option that is automatically generated by cmake. +CONFIGURE_FILE(packaging/default.debugger.in packaging/default.debugger @ONLY) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/packaging/default.debugger DESTINATION share/aul) INSTALL(TARGETS ${LAUNCHPAD_PROCESS_POOL} DESTINATION bin) CONFIGURE_FILE(packaging/default.loader.in packaging/default.loader @ONLY) diff --git a/inc/debugger_info.h b/inc/debugger_info.h new file mode 100644 index 0000000..7f61846 --- /dev/null +++ b/inc/debugger_info.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DEBUGGER_INFO_H__ +#define __DEBUGGER_INFO_H__ + +#include + +typedef struct debugger_info_s *debugger_info_h; + +GList *_debugger_info_load(const char *path); +void _debugger_info_unload(GList *info); +debugger_info_h _debugger_info_find(GList *info_list, const char *name); +const char *_debugger_info_get_exe(debugger_info_h info); +GList *_debugger_info_get_extra_key_list(debugger_info_h info); +GList *_debugger_info_get_extra_env_list(debugger_info_h info); +GList *_debugger_info_get_unlink_list(debugger_info_h info); +const char *_debugger_info_get_attach(debugger_info_h info); + +#endif /* __DEBUGGER_INFO_H__ */ diff --git a/inc/key.h b/inc/key.h index 7d0201f..e83bb14 100644 --- a/inc/key.h +++ b/inc/key.h @@ -21,28 +21,30 @@ extern "C" { #endif -#define AUL_K_STARTTIME "__AUL_STARTTIME__" -#define AUL_K_EXEC "__AUL_EXEC__" -#define AUL_K_PACKAGETYPE "__AUL_PACKAGETYPE__" -#define AUL_K_APP_TYPE "__AUL_APP_TYPE__" -#define AUL_K_HWACC "__AUL_HWACC__" -#define AUL_K_APPID "__AUL_APPID__" -#define AUL_K_PID "__AUL_PID__" -#define AUL_K_TASKMANAGE "__AUL_TASKMANAGE__" -#define AUL_K_INTERNAL_POOL "__AUL_INTERNAL_POOL__" -#define AUL_K_PKGID "__AUL_PKGID_" -#define AUL_K_DEBUG "__AUL_DEBUG__" +#define AUL_K_STARTTIME "__AUL_STARTTIME__" +#define AUL_K_EXEC "__AUL_EXEC__" +#define AUL_K_PACKAGETYPE "__AUL_PACKAGETYPE__" +#define AUL_K_APP_TYPE "__AUL_APP_TYPE__" +#define AUL_K_HWACC "__AUL_HWACC__" +#define AUL_K_APPID "__AUL_APPID__" +#define AUL_K_PID "__AUL_PID__" +#define AUL_K_TASKMANAGE "__AUL_TASKMANAGE__" +#define AUL_K_INTERNAL_POOL "__AUL_INTERNAL_POOL__" +#define AUL_K_PKGID "__AUL_PKGID_" +#define AUL_K_DEBUG "__AUL_DEBUG__" #define AUL_K_PRIVACY_APPID "__AUL_PRIVACY_APPID__" -#define AUL_K_COMP_TYPE "__AUL_COMP_TYPE__" -#define AUL_K_CALLER_PID "__AUL_CALLER_PID__" -#define AUL_K_LOADER_ID "__AUL_LOADER_ID__" -#define AUL_K_LOADER_PATH "__AUL_LOADER_PATH__" -#define AUL_K_LOADER_EXTRA "__AUL_LOADER_EXTRA__" -#define AUL_K_WAYLAND_DISPLAY "__AUL_WAYLAND_DISPLAY__" -#define AUL_K_WAYLAND_WORKING_DIR "__AUL_WAYLAND_WORKING_DIR__" -#define AUL_K_ROOT_PATH "__AUL_ROOT_PATH__" -#define AUL_K_API_VERSION "__AUL_API_VERSION__" -#define AUL_K_LOADER_NAME "__AUL_LOADER_NAME__" +#define AUL_K_COMP_TYPE "__AUL_COMP_TYPE__" +#define AUL_K_CALLER_PID "__AUL_CALLER_PID__" +#define AUL_K_LOADER_ID "__AUL_LOADER_ID__" +#define AUL_K_LOADER_PATH "__AUL_LOADER_PATH__" +#define AUL_K_LOADER_EXTRA "__AUL_LOADER_EXTRA__" +#define AUL_K_WAYLAND_DISPLAY "__AUL_WAYLAND_DISPLAY__" +#define AUL_K_WAYLAND_WORKING_DIR "__AUL_WAYLAND_WORKING_DIR__" +#define AUL_K_ROOT_PATH "__AUL_ROOT_PATH__" +#define AUL_K_API_VERSION "__AUL_API_VERSION__" +#define AUL_K_LOADER_NAME "__AUL_LOADER_NAME__" +#define AUL_K_SDK "__AUL_SDK__" +#define AUL_K_ORG_CALLER_PID "__AUL_ORG_CALLER_PID__" #ifdef __cplusplus } diff --git a/inc/launchpad_debug.h b/inc/launchpad_debug.h new file mode 100644 index 0000000..8bdb6ef --- /dev/null +++ b/inc/launchpad_debug.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LAUNCHPAD_DEBUG_H__ +#define __LAUNCHPAD_DEBUG_H__ + +#include +#include + +int _debug_create_argv(int *argc, char ***argv, bool *attach); +void _debug_destroy_argv(int argc, char **argv); +int _debug_get_caller_pid(bundle *kb); +void _debug_prepare_debugger(bundle *kb); +int _debug_init(void); +void _debug_fini(void); + +#endif /* __LAUNCHPAD_DEBUG_H__ */ + diff --git a/packaging/default.debugger.in b/packaging/default.debugger.in new file mode 100644 index 0000000..ee2e717 --- /dev/null +++ b/packaging/default.debugger.in @@ -0,0 +1,20 @@ +[DEBUGGER] +NAME VALGRIND +EXE /opt/usr/home/owner/share/tmp/sdk_tools/valgrind/usr/bin/valgrind +APP_TYPE capp|c++app +EXTRA_KEY __DLP_VALGRIND_ARG__ +UNLINK /tmp/valgrind_result.txt +UNLINK /tmp/valgrind_result.xml + +[DEBUGGER] +NAME DEBUG +EXE /opt/usr/home/owner/share/tmp/sdk_tools/gdbserver/gdbserver +APP_TYPE capp|c++app +EXTRA_KEY __DLP_DEBUG_ARG__ + +[DEBUGGER] +NAME ATTACH +EXE /opt/usr/home/owner/share/tmp/sdk_tools/gdbserver/gdbserver +APP_TYPE capp|c++app +EXTRA_KEY __DLP_ATTACH_ARG__ +ATTACH true diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index d11ed9d..06b6eb3 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -79,11 +79,12 @@ cp %{_builddir}/%{name}-%{version}/LICENSE %{buildroot}/usr/share/license/%{nam %manifest launchpad.manifest %{_prefix}/share/license/%{name} %{_prefix}/share/aul/default.loader +%{_prefix}/share/aul/default.debugger %{_unitdir_user}/launchpad-process-pool.service %{_unitdir_user}/launchpad-process-pool.socket %{_unitdir_user}/sockets.target.wants/launchpad-process-pool.socket %{_unitdir_user}/basic.target.wants/launchpad-process-pool.service -%caps(cap_mac_admin,cap_setgid=ei) %{_bindir}/launchpad-process-pool +%caps(cap_mac_admin,cap_dac_override,cap_setgid=ei) %{_bindir}/launchpad-process-pool %caps(cap_setgid=ei) %{_bindir}/launchpad-loader %attr(0644,root,root) %{_libdir}/liblaunchpad.so.* diff --git a/src/debugger_info.c b/src/debugger_info.c new file mode 100644 index 0000000..4af4a2d --- /dev/null +++ b/src/debugger_info.c @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include + +#include "launchpad_common.h" +#include "debugger_info.h" + +#define TAG_DEBUGGER "[DEBUGGER]" +#define TAG_NAME "NAME" +#define TAG_EXE "EXE" +#define TAG_APP_TYPE "APP_TYPE" +#define TAG_EXTRA_KEY "EXTRA_KEY" +#define TAG_EXTRA_ENV "EXTRA_ENV" +#define TAG_UNLINK "UNLINK" +#define TAG_ATTACH "ATTACH" + +struct debugger_info_s { + char *name; + char *exe; + GList *app_types; + GList *extra_key_list; + GList *extra_env_list; + GList *unlink_list; + char *attach; +}; + +static struct debugger_info_s *__create_debugger_info(void) +{ + struct debugger_info_s *info; + + info = calloc(1, sizeof(struct debugger_info_s)); + if (info == NULL) { + _E("out of memory"); + return NULL; + } + + return info; +} + +static void __destroy_debugger_info(gpointer data) +{ + struct debugger_info_s *info = (struct debugger_info_s *)data; + + if (info == NULL) + return; + + if (info->attach) + free(info->attach); + if (info->unlink_list) + g_list_free_full(info->unlink_list, free); + if (info->extra_env_list) + g_list_free_full(info->extra_env_list, free); + if (info->extra_key_list) + g_list_free_full(info->extra_key_list, free); + if (info->app_types) + g_list_free_full(info->app_types, free); + if (info->exe) + free(info->exe); + if (info->name) + free(info->name); + free(info); +} + +static void __parse_app_types(struct debugger_info_s *info, char *line) +{ + char *token; + char *saveptr = NULL; + char tok[LINE_MAX]; + + token = strtok_r(line, "|", &saveptr); + while (token) { + tok[0] = '\0'; + sscanf(token, "%s", tok); + if (tok[0] != '\0' && strcasecmp(tok, "null") != 0) { + info->app_types = g_list_append(info->app_types, + strdup(tok)); + } + token = strtok_r(NULL, "|", &saveptr); + } +} + +static GList *__parse_file(GList *list, const char *path) +{ + FILE *fp; + char buf[LINE_MAX]; + char tok1[LINE_MAX]; + char tok2[LINE_MAX]; + struct debugger_info_s *info = NULL; + + fp = fopen(path, "rt"); + if (fp == NULL) + return list; + + while (fgets(buf, sizeof(buf), fp) != NULL) { + tok1[0] = '\0'; + tok2[0] = '\0'; + sscanf(buf, "%s %s", tok1, tok2); + + if (strcasecmp(TAG_DEBUGGER, tok1) == 0) { + if (info) { + _D("name: %s, exe: %s", info->name, info->exe); + list = g_list_append(list, info); + } + + info = __create_debugger_info(); + if (info == NULL) + break; + + continue; + } + + if (tok1[0] == '\0' || tok2[0] == '\0' || tok1[0] == '#') + continue; + if (info == NULL) + continue; + + if (strcasecmp(TAG_NAME, tok1) == 0) { + info->name = strdup(tok2); + if (info->name == NULL) { + _E("out of memory"); + __destroy_debugger_info(info); + info = NULL; + break; + } + } else if (strcasecmp(TAG_EXE, tok1) == 0) { + info->exe = strdup(tok2); + if (info->exe == NULL) { + _E("out of memory"); + __destroy_debugger_info(info); + info = NULL; + break; + } + } else if (strcasecmp(TAG_APP_TYPE, tok1) == 0) { + __parse_app_types(info, &buf[strlen(tok1)]); + if (info->app_types == NULL) { + _E("app_types is NULL"); + __destroy_debugger_info(info); + info = NULL; + break; + } + } else if (strcasecmp(TAG_EXTRA_KEY, tok1) == 0) { + info->extra_key_list = g_list_append( + info->extra_key_list, strdup(tok2)); + } else if (strcasecmp(TAG_EXTRA_ENV, tok1) == 0) { + info->extra_env_list = g_list_append( + info->extra_env_list, strdup(tok2)); + } else if (strcasecmp(TAG_UNLINK, tok1) == 0) { + info->unlink_list = g_list_append(info->unlink_list, + strdup(tok2)); + } else if (strcasecmp(TAG_ATTACH, tok1) == 0) { + info->attach = strdup(tok2); + if (info->attach == NULL) { + _E("attach is NULL"); + __destroy_debugger_info(info); + info = NULL; + break; + } + } + } + fclose(fp); + + if (info) { + _D("name: %s, exe: %s", info->name, info->exe); + list = g_list_append(list, info); + } + + return list; +} + +GList *_debugger_info_load(const char *path) +{ + DIR *dp; + struct dirent dentry; + struct dirent *result = NULL; + GList *list = NULL; + char buf[PATH_MAX]; + char *ext; + + if (path == NULL) + return NULL; + + dp = opendir(path); + if (dp == NULL) + return NULL; + + while (readdir_r(dp, &dentry, &result) == 0 && result != NULL) { + if (dentry.d_name[0] == '.') + continue; + + ext = strrchr(dentry.d_name, '.'); + if (ext && strcmp(ext, ".debugger") == 0) { + snprintf(buf, sizeof(buf), "%s/%s", + path, dentry.d_name); + list = __parse_file(list, buf); + } + } + closedir(dp); + + return list; +} + +void _debugger_info_unload(GList *info) +{ + if (info == NULL) + return; + + g_list_free_full(info, __destroy_debugger_info); +} + +static int __comp_name(gconstpointer a, gconstpointer b) +{ + struct debugger_info_s *info = (struct debugger_info_s *)a; + + if (info == NULL || info->name == NULL || b == NULL) + return -1; + + if (strcasecmp(info->name, b) == 0) + return 0; + + return -1; +} + +debugger_info_h _debugger_info_find(GList *info_list, const char *name) +{ + GList *list; + + if (info_list == NULL || name == NULL) + return NULL; + + list = g_list_find_custom(info_list, name, __comp_name); + if (list == NULL) + return NULL; + + return (debugger_info_h)list->data; +} + +const char *_debugger_info_get_exe(debugger_info_h info) +{ + if (info == NULL) + return NULL; + + return info->exe; +} + +GList *_debugger_info_get_extra_key_list(debugger_info_h info) +{ + if (info == NULL) + return NULL; + + return info->extra_key_list; +} + +GList *_debugger_info_get_extra_env_list(debugger_info_h info) +{ + if (info == NULL) + return NULL; + + return info->extra_env_list; +} + +GList *_debugger_info_get_unlink_list(debugger_info_h info) +{ + if (info == NULL) + return NULL; + + return info->unlink_list; +} + +const char *_debugger_info_get_attach(debugger_info_h info) +{ + if (info == NULL) + return NULL; + + return info->attach; +} diff --git a/src/launchpad.c b/src/launchpad.c index 7917433..09e0431 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -42,6 +42,7 @@ #include "launchpad.h" #include "loader_info.h" #include "launcher_info.h" +#include "launchpad_debug.h" #define AUL_PR_NAME 16 #define EXEC_CANDIDATE_EXPIRED 5 @@ -91,6 +92,11 @@ struct app_launch_arg { bundle *kb; }; +struct app_arg { + int argc; + char **argv; +}; + static int __sys_hwacc; static GList *loader_info_list; static int user_slot_offset; @@ -488,16 +494,17 @@ static int __send_launchpad_loader(candidate_process_context_t *cpc, return pid; } -static int __normal_fork_exec(int argc, char **argv) +static int __normal_fork_exec(int argc, char **argv, const char *app_path) { - char *libdir = NULL; + char *libdir; _D("start real fork and exec"); - libdir = _get_libdir(argv[LOADER_ARG_PATH]); - if (libdir) + libdir = _get_libdir(app_path); + if (libdir) { setenv("LD_LIBRARY_PATH", libdir, 1); - free(libdir); + free(libdir); + } _close_all_fds(); if (execv(argv[LOADER_ARG_PATH], argv) < 0) { /* Flawfinder: ignore */ @@ -514,15 +521,14 @@ static int __normal_fork_exec(int argc, char **argv) return 0; } -static int __set_launcher_info(int *argc, char ***argv, const char *app_type) +static int __create_launcher_argv(int *argc, char ***argv, const char *app_type) { + int launcher_argc; + char **launcher_argv; launcher_info_h launcher_info; - char **new_argv; - int new_argc; const char *exe; - GList *extra_args; - int extra_argc; const char *extra_arg; + GList *extra_args; GList *iter; int i; @@ -537,30 +543,111 @@ static int __set_launcher_info(int *argc, char ***argv, const char *app_type) } extra_args = _launcher_info_get_extra_args(launcher_info); - extra_argc = g_list_length(extra_args) + 1; - - new_argc = *argc + extra_argc; - new_argv = (char **)realloc(*argv, sizeof(char *) * new_argc); - if (new_argv == NULL) { - _E("Failed to reallocate memory"); + launcher_argc = g_list_length(extra_args) + 1; + launcher_argv = (char **)calloc(launcher_argc, sizeof(char *)); + if (launcher_argv == NULL) { + _E("out of memory"); return -1; } - for (i = new_argc; i >= extra_argc; i--) - new_argv[i] = new_argv[i - extra_argc]; - i = LOADER_ARG_PATH; - new_argv[i++] = strdup(exe); + launcher_argv[i++] = strdup(exe); iter = g_list_first(extra_args); while (iter) { - extra_arg = (char *)iter->data; + extra_arg = (const char *)iter->data; if (extra_arg) - new_argv[i++] = strdup(extra_arg); + launcher_argv[i++] = strdup(extra_arg); iter = g_list_next(iter); } + *argc = launcher_argc; + *argv = launcher_argv; + + + return 0; +} + +static void __destroy_launcher_argv(int argc, char **argv) +{ + int i; + + if (argv == NULL) + return; + + for (i = 0; i < argc; i++) + free(argv[i]); + free(argv); +} + +static int __create_app_argv(int *argc, char ***argv, const char *app_path, + bundle *kb, const char *app_type) +{ + int new_argc; + char **new_argv; + bool attach = false; + struct app_arg debug_arg = {0,}; + struct app_arg launcher_arg = {0,}; + struct app_arg arg = {0,}; + int ret; + int i; + int c; + + ret = _debug_create_argv(&debug_arg.argc, &debug_arg.argv, &attach); + if (ret < 0) { + _E("Failed to create debugger argv"); + return -1; + } + + if (attach) { + *argc = debug_arg.argc; + *argv = debug_arg.argv; + return 0; + } + + ret = __create_launcher_argv(&launcher_arg.argc, &launcher_arg.argv, + app_type); + if (ret < 0) { + _E("Failed to create launcher argv"); + _debug_destroy_argv(debug_arg.argc, debug_arg.argv); + return -1; + } + + arg.argc = bundle_export_to_argv(kb, &arg.argv); + if (arg.argc <= 0) { + _E("Failed to export bundle"); + __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv); + _debug_destroy_argv(debug_arg.argc, debug_arg.argv); + return -1; + } + arg.argv[LOADER_ARG_PATH] = strdup(app_path); + + new_argc = debug_arg.argc + launcher_arg.argc + arg.argc; + if (new_argc == arg.argc) { + *argc = arg.argc; + *argv = arg.argv; + return 0; + } + + new_argv = (char **)calloc(new_argc + 1, sizeof(char *)); + if (new_argv == NULL) { + _E("out of memory"); + free(arg.argv[LOADER_ARG_PATH]); + bundle_free_exported_argv(arg.argc, &arg.argv); + __destroy_launcher_argv(launcher_arg.argc, launcher_arg.argv); + _debug_destroy_argv(debug_arg.argc, debug_arg.argv); + return -1; + } + + c = LOADER_ARG_PATH; + for (i = 0; i < debug_arg.argc; i++) + new_argv[c++] = debug_arg.argv[i]; + for (i = 0; i < launcher_arg.argc; i++) + new_argv[c++] = launcher_arg.argv[i]; + for (i = 0; i < arg.argc; i++) + new_argv[c++] = arg.argv[i]; + *argc = new_argc; *argv = new_argv; @@ -570,7 +657,7 @@ static int __set_launcher_info(int *argc, char ***argv, const char *app_type) static void __real_launch(const char *app_path, bundle *kb, appinfo_t *menu_info) { - int app_argc; + int app_argc = 0; char **app_argv; int i; int ret; @@ -578,20 +665,18 @@ static void __real_launch(const char *app_path, bundle *kb, if (bundle_get_val(kb, AUL_K_DEBUG) != NULL) putenv("TIZEN_DEBUGGING_PORT=1"); - app_argv = _create_argc_argv(kb, &app_argc); - app_argv[LOADER_ARG_PATH] = strdup(app_path); - - ret = __set_launcher_info(&app_argc, &app_argv, menu_info->app_type); + ret = __create_app_argv(&app_argc, &app_argv, app_path, + kb, menu_info->app_type); if (ret < 0) { - _E("Failed to set launcher info"); + _E("Failed to create app argv"); exit(-1); } - for (i = 0; i < app_argc; i += 2) + for (i = 0; i < app_argc; i++) SECURE_LOGD("input argument %d : %s##", i, app_argv[i]); PERF("setup argument done"); - __normal_fork_exec(app_argc, app_argv); + __normal_fork_exec(app_argc, app_argv, app_path); } static int __prepare_exec(const char *appid, const char *app_path, @@ -646,6 +731,9 @@ static int __exec_app_process(void *arg) PERF("fork done"); _D("lock up test log(no error) : fork done"); + if (bundle_get_type(launch_arg->kb, AUL_K_SDK) != BUNDLE_TYPE_NONE) + _debug_prepare_debugger(launch_arg->kb); + __signal_unblock_sigchld(); __signal_fini(); @@ -1081,7 +1169,9 @@ static int __check_caller_by_pid(int pid) if (ret < 0) return -1; - if (strcmp(buf, "User") == 0) + if (strcmp(buf, "User") == 0 || + strcmp(buf, "System") == 0 || + strcmp(buf, "System::Privileged") == 0) return 0; return -1; @@ -1153,6 +1243,7 @@ static gboolean __handle_launch_event(gpointer data) int type = -1; int loader_id; int ret; + int caller_pid; traceBegin(TTRACE_TAG_APPLICATION_MANAGER, "LAUNCHPAD:LAUNCH"); pkt = _recv_pkt_raw(fd, &clifd, &cr); @@ -1174,6 +1265,17 @@ static gboolean __handle_launch_event(gpointer data) goto end; } + if (bundle_get_type(kb, AUL_K_SDK) != BUNDLE_TYPE_NONE) { + caller_pid = _debug_get_caller_pid(kb); + if (caller_pid > 0) { + if (__check_caller_by_pid(caller_pid) < 0) { + _E("Invalid caller pid"); + goto end; + } + } + _debug_init(); + } + switch (pkt->cmd) { case PAD_CMD_VISIBILITY: ret = __dispatch_cmd_hint(kb, METHOD_VISIBILITY); @@ -1558,6 +1660,7 @@ static int __before_loop(int argc, char **argv) static void __after_loop(void) { + _debug_fini(); _launcher_info_unload(launcher_info_list); if (label_monitor) diff --git a/src/launchpad_debug.c b/src/launchpad_debug.c new file mode 100644 index 0000000..10afec8 --- /dev/null +++ b/src/launchpad_debug.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +#include "launchpad_common.h" +#include "launchpad_debug.h" +#include "debugger_info.h" +#include "key.h" + +#define DEBUGGER_INFO_PATH "/usr/share/aul" + +static int debug_initialized; +static GList *debugger_info_list; +static debugger_info_h debugger_info; +static GList *extra_argv_list; + +int _debug_create_argv(int *argc, char ***argv, bool *attach) +{ + int new_argc; + char **new_argv; + const char *exe; + const char *extra_argv; + const char *attach_str; + GList *iter; + int i; + + if (argc == NULL || argv == NULL || attach == NULL) { + _E("[DEBUG] Invalid parameter"); + return -1; + } + + if (debugger_info == NULL) + return 0; + + exe = _debugger_info_get_exe(debugger_info); + if (exe == NULL) + return -1; + + attach_str = _debugger_info_get_attach(debugger_info); + if (attach_str && strcasecmp(attach_str, "true") == 0) + *attach = true; + + new_argc = g_list_length(extra_argv_list) + 1; + new_argv = (char **)calloc(new_argc, sizeof(char *)); + if (new_argv == NULL) { + _E("out of memory"); + return -1; + } + + i = LOADER_ARG_PATH; + new_argv[i++] = strdup(exe); + + iter = g_list_first(extra_argv_list); + while (iter) { + extra_argv = (const char *)iter->data; + if (extra_argv) + new_argv[i++] = strdup(extra_argv); + + iter = g_list_next(iter); + } + + *argc = new_argc; + *argv = new_argv; + _D("[DEBUG] argc: %d, argv[0]: %s", + new_argc, new_argv[LOADER_ARG_PATH]); + + return 0; +} + +void _debug_destroy_argv(int argc, char **argv) +{ + int i; + + if (argv == NULL) + return; + + for (i = 0; i < argc; i++) + free(argv[i]); + free(argv); +} + +int _debug_get_caller_pid(bundle *kb) +{ + const char *pid_str; + int pid; + + pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID); + if (pid_str == NULL) + pid_str = bundle_get_val(kb, AUL_K_CALLER_PID); + + if (pid_str == NULL) + return -1; + + pid = atoi(pid_str); + if (pid <= 1) + return -1; + + return pid; +} + +static int __redirect_std_fds(bundle *kb) +{ + char path[PATH_MAX]; + char err_buf[1024]; + int fd; + int caller_pid; + + if (kb == NULL) { + _E("[DEBUG] Invalid parameter"); + return -1; + } + + caller_pid = _debug_get_caller_pid(kb); + if (caller_pid < 0) { + _E("[DEBUG] Failed to get caller pid"); + return -1; + } + + /* stdout */ + snprintf(path, sizeof(path), "/proc/%d/fd/1", caller_pid); + fd = open(path, O_WRONLY); + if (fd < 0) { + _E("[DEBUG] Failed to open %s [%s]", path, + strerror_r(errno, err_buf, sizeof(err_buf))); + return -1; + } + dup2(fd, 1); + close(fd); + + /* stderr */ + snprintf(path, sizeof(path), "/proc/%d/fd/2", caller_pid); + fd = open(path, O_WRONLY); + if (fd < 0) { + _E("[DEBUG] Failed to open %s [%s]", path, + strerror_r(errno, err_buf, sizeof(err_buf))); + return -1; + } + dup2(fd, 2); + close(fd); + + return 0; +} + +static void __add_extra_argv(gpointer data, gpointer user_data) +{ + const char *key = (const char *)data; + bundle *kb = (bundle *)user_data; + const char *str; + const char **str_arr = NULL; + int len = 0; + int i; + + if (key == NULL || kb == NULL) + return; + + _D("[DEBUG] key: %s", key); + if (bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) { + str_arr = bundle_get_str_array(kb, key, &len); + } else { + str = bundle_get_val(kb, key); + if (str) { + str_arr = &str; + len = 1; + } + } + + for (i = 0; i < len; i++) { + if (str_arr[i] == NULL) + break; + + extra_argv_list = g_list_append(extra_argv_list, + strdup(str_arr[i])); + } + + if (str_arr) + bundle_del(kb, key); +} + +static void __set_debug_env(gpointer data, gpointer user_data) +{ + const char *key = (const char *)data; + bundle *kb = (bundle *)user_data; + const char *str; + const char **str_arr = NULL; + int len = 0; + int i; + char buf[LINE_MAX] = {0,}; + + if (key == NULL || kb == NULL) + return; + + _D("[DEBUG] key: %s", key); + if (bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) { + str_arr = bundle_get_str_array(kb, key, &len); + } else { + str = bundle_get_val(kb, key); + if (str) { + str_arr = &str; + len = 1; + } + } + + if (str_arr == NULL) + return; + + strncat(buf, str_arr[0], sizeof(buf) - strlen(buf) - 1); + for (i = 1; i < len; i++) { + if (str_arr[i] == NULL) + break; + + strncat(buf, ",", sizeof(buf) - strlen(buf) - 1); + strncat(buf, str_arr[1], sizeof(buf) - strlen(buf) - 1); + } + + bundle_del(kb, key); + _D("[DEBUG] name: %s, value: %s", key, buf); + setenv(key, buf, 1); +} + +static void __remove_file(gpointer data, gpointer user_data) +{ + const char *file = (const char *)data; + + if (file == NULL) + return; + + _D("[DEBUG] file: %s", file); + if (access(file, F_OK) == 0) { + if (remove(file) != 0) + _W("[DEBUG] Failed to remove %s", file); + } +} + +void _debug_prepare_debugger(bundle *kb) +{ + const char *debugger; + GList *list; + int ret; + + if (kb == NULL) + return; + + debugger = bundle_get_val(kb, AUL_K_SDK); + if (debugger == NULL) + return; + + _D("[DEBUG] debugger: %s", debugger); + debugger_info = _debugger_info_find(debugger_info_list, debugger); + if (debugger_info == NULL) + return; + + ret = __redirect_std_fds(kb); + if (ret < 0) + _E("[DEBUG] Failed to redirect standard fds"); + + list = _debugger_info_get_unlink_list(debugger_info); + g_list_foreach(list, __remove_file, NULL); + + list = _debugger_info_get_extra_env_list(debugger_info); + g_list_foreach(list, __set_debug_env, kb); + + list = _debugger_info_get_extra_key_list(debugger_info); + g_list_foreach(list, __add_extra_argv, kb); +} + +int _debug_init(void) +{ + if (debug_initialized) + return 0; + + debugger_info_list = _debugger_info_load(DEBUGGER_INFO_PATH); + if (debugger_info_list == NULL) + return -1; + + debug_initialized = 1; + + return 0; +} + +void _debug_fini(void) +{ + if (!debug_initialized) + return; + + _debugger_info_unload(debugger_info_list); +} -- 2.7.4