summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSemun Lee <sm79.lee@samsung.com>2016-07-08 14:59:41 +0900
committerSemun Lee <sm79.lee@samsung.com>2016-07-20 17:34:18 +0900
commit4e715370a48e77a92ce6d0462fd178b94b2bf959 (patch)
treed577afe34d490e86fbc4bb14ece34f5fd6b80016
parentf8212e604ee57067279c9c54a0562b5ffaa31ddb (diff)
downloadlaunchpad-4e715370a48e77a92ce6d0462fd178b94b2bf959.tar.gz
launchpad-4e715370a48e77a92ce6d0462fd178b94b2bf959.tar.bz2
launchpad-4e715370a48e77a92ce6d0462fd178b94b2bf959.zip
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 <sm79.lee@samsung.com>
-rwxr-xr-xCMakeLists.txt1
-rw-r--r--inc/launchpad_common.h3
-rw-r--r--packaging/launchpad.spec5
-rwxr-xr-xsrc/launchpad.c145
-rw-r--r--src/launchpad_common.c54
-rw-r--r--src/launchpad_lib.c9
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 <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
+#include <sys/resource.h>
+#include <sched.h>
#include <stdbool.h>
#include <malloc.h>
#include <bundle_internal.h>
@@ -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 <string.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/mount.h>
#include <fcntl.h>
#include <dirent.h>
#include <stdlib.h>
@@ -29,6 +30,7 @@
#include <sys/un.h>
#include <linux/limits.h>
#include <unistd.h>
+#include <tzplatform_config.h>
#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) {