4 * Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: MooChang Kim <moochang.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
23 * simple AUL daemon - launchpad
30 #include <sys/types.h>
37 #include <sys/prctl.h>
45 #include "menu_db_util.h"
46 #include "simple_util.h"
47 #include "access_control.h"
53 #include "pkgmgr-info.h"
60 #include <sys/smack.h>
61 #include "fileutils.h"
62 #include <sys/capability.h>
64 #define _static_ static inline
66 #define SQLITE_FLUSH_MAX (1048576) /* (1024*1024) */
67 #define AUL_POLL_CNT 15
68 #define AUL_PR_NAME 16
69 #define PATH_TMP "/tmp"
70 #define PATH_DATA "/data"
72 #define SDK_CODE_COVERAGE "CODE_COVERAGE"
73 #define SDK_DEBUG "DEBUG"
74 #define SDK_DYNAMIC_ANALYSIS "DYNAMIC_ANALYSIS"
75 #define SDK_UNIT_TEST "UNIT_TEST"
76 #define SDK_VALGRIND "VALGRIND"
78 /* DLP is short for debug-launchpad */
79 #define DLP_K_DEBUG_ARG "__DLP_DEBUG_ARG__"
80 #define DLP_K_UNIT_TEST_ARG "__DLP_UNIT_TEST_ARG__"
81 #define DLP_K_VALGRIND_ARG "__DLP_VALGRIND_ARG__"
83 #define PATH_GDBSERVER "/home/developer/sdk_tools/gdbserver/gdbserver"
84 #define PATH_VALGRIND "/home/developer/sdk_tools/valgrind/usr/bin/valgrind"
85 #define PATH_DA_SO "/usr/lib/da_probe_tizen.so"
86 #define PATH_NATIVE_APP "/opt/apps/"
89 #define PATH_MEMCHECK "/opt/home/developer/sdk_tools/valgrind/usr/lib/valgrind/memcheck-arm-linux"
91 #define PATH_MEMCHECK "/opt/home/developer/sdk_tools/valgrind/usr/lib/valgrind/memcheck-x86-linux"
94 #define POLL_VALGRIND_LOGFILE 0x00000001
95 #define POLL_VALGRIND_XMLFILE 0x00000002
97 #define CAPABILITY_GET_ORIGINAL 0
98 #define CAPABILITY_SET_INHERITABLE 1
100 static int need_to_set_inh_cap_after_fork = 0;
101 static char *launchpad_cmdline;
102 static int initialized = 0;
104 static int poll_outputfile = 0;
105 static int is_gdbserver_launched;
107 void __set_env(app_info_from_db * menu_info, bundle * kb);
108 int __prepare_exec(const char *pkg_name,
109 const char *app_path, app_info_from_db * menu_info,
111 int __fake_launch_app(int cmd, int pid, bundle * kb);
112 char **__create_argc_argv(bundle * kb, int *margc, const char *app_path);
113 int __normal_fork_exec(int argc, char **argv);
114 void __real_launch(const char *app_path, bundle * kb);
115 static inline int __parser(const char *arg, char *out, int out_size);
116 void __modify_bundle(bundle * kb, int caller_pid,
117 app_info_from_db * menu_info, int cmd);
118 int __send_to_sigkill(int pid);
119 int __term_app(int pid);
120 void __real_send(int clifd, int ret);
121 void __send_result_to_caller(int clifd, int ret);
122 void __launchpad_main_loop(int main_fd);
123 int __launchpad_pre_init(int argc, char **argv);
124 int __launchpad_post_init();
126 extern ail_error_e ail_db_close(void);
130 void __set_sdk_env(app_info_from_db* menu_info, char* str) {
131 char buf_pkgname[MAX_LOCAL_BUFSZ];
132 char buf[MAX_LOCAL_BUFSZ];
135 _D("key : %s / value : %s", AUL_K_SDK, str);
136 /* http://gcc.gnu.org/onlinedocs/gcc/Cross_002dprofiling.html*/
137 /* GCOV_PREFIX contains the prefix to add to the absolute paths */
138 /* in the object file. Prefix can be absolute, or relative.*/
139 /* The default is no prefix. */
140 /* GCOV_PREFIX_STRIP indicates the how many initial directory names */
141 /* to stripoff the hardwired absolute paths. Default value is 0. */
142 if (strncmp(str, SDK_CODE_COVERAGE, strlen(str)) == 0) {
143 strncpy(buf_pkgname,_get_pkgname(menu_info),MAX_LOCAL_BUFSZ-1);
144 buf_pkgname[MAX_LOCAL_BUFSZ-1]='\0';
145 snprintf(buf, MAX_LOCAL_BUFSZ, PATH_TMP"/%s"PATH_DATA
146 , strtok(buf_pkgname,"."));
147 ret = setenv("GCOV_PREFIX", buf, 1);
148 _D("GCOV_PREFIX : %d", ret);
149 ret = setenv("GCOV_PREFIX_STRIP", "0", 1);
150 _D("GCOV_PREFIX_STRIP : %d", ret);
151 } else if (strncmp(str, SDK_DYNAMIC_ANALYSIS, strlen(str)) == 0) {
152 ret = setenv("LD_PRELOAD", PATH_DA_SO, 1);
153 _D("LD_PRELOAD : %d", ret);
158 void __set_env(app_info_from_db * menu_info, bundle * kb)
161 const char **str_array;
165 setenv("PKG_NAME", _get_pkgname(menu_info), 1);
169 str = bundle_get_val(kb, AUL_K_STARTTIME);
171 setenv("APP_START_TIME", str, 1);
173 if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
174 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
175 if(str_array != NULL) {
176 for (i = 0; i < len; i++) {
177 _D("index : [%d]", i);
178 __set_sdk_env(menu_info, (char *)str_array[i]);
182 str = bundle_get_val(kb, AUL_K_SDK);
184 __set_sdk_env(menu_info, (char *)str);
187 if (menu_info->hwacc != NULL)
188 setenv("HWACC", menu_info->hwacc, 1);
189 if (menu_info->taskmanage != NULL)
190 setenv("TASKMANAGE", menu_info->taskmanage, 1);
193 int __prepare_exec(const char *pkg_name,
194 const char *app_path, app_info_from_db * menu_info,
198 char process_name[AUL_PR_NAME];
201 /* Set new session ID & new process group ID*/
202 /* In linux, child can set new session ID without check permission */
203 /* TODO : should be add to check permission in the kernel*/
206 __preexec_run(menu_info->pkg_type, pkg_name, app_path);
209 _D("pkg_name : %s / pkg_type : %s / app_path : %s", pkg_name
210 , menu_info->pkg_type, app_path);
211 if ((ret = __set_access(pkg_name, menu_info->pkg_type, app_path)) < 0) {
212 _D("fail to set privileges - check your package's credential : %d\n"
216 /* SET DUMPABLE - for coredump*/
217 prctl(PR_SET_DUMPABLE, 1);
219 /* SET PROCESS NAME*/
220 if (app_path == NULL) {
221 _D("app_path should not be NULL - check menu db");
224 file_name = strrchr(app_path, '/') + 1;
225 if (file_name == NULL) {
226 _D("can't locate file name to execute");
229 memset(process_name, '\0', AUL_PR_NAME);
230 snprintf(process_name, AUL_PR_NAME, "%s", file_name);
231 prctl(PR_SET_NAME, process_name);
234 __set_env(menu_info, kb);
239 int __fake_launch_app(int cmd, int pid, bundle * kb)
245 bundle_encode(kb, &kb_data, &datalen);
246 if ((ret = __app_send_raw(pid, cmd, kb_data, datalen)) < 0)
247 _E("error request fake launch - error code = %d", ret);
252 char** __add_arg(bundle * kb, char **argv, int *margc, const char *key)
254 const char *str = NULL;
255 const char **str_array = NULL;
258 char ** new_argv = NULL;
260 if(bundle_get_type(kb, key) & BUNDLE_TYPE_ARRAY) {
261 str_array = bundle_get_str_array(kb, key, &len);
263 str = bundle_get_val(kb, key);
269 if(str_array != NULL) {
270 if(strncmp(key, DLP_K_DEBUG_ARG, strlen(key)) == 0
271 || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0)
273 new_argv = (char **) realloc(argv
274 , sizeof(char *) * (*margc+len+2));
276 _E("realloc fail (key = %s)", key);
279 for(i=*margc+len+1; i-(len+1)>=0; i--) {
280 new_argv[i] = new_argv[i-(len+1)];
282 // need to add new_argv[0]
283 for(i=0; i<len; i++) {
284 new_argv[1+i] = strdup(str_array[i]);
286 len++; /* gdbserver or valgrind */
287 _D("uid : %d", getuid());
288 _D("euid : %d", geteuid());
289 _D("gid : %d", getgid());
290 _D("egid : %d", getegid());
292 new_argv = (char **) realloc(argv
293 , sizeof(char *) * (*margc+len+1));
295 _E("realloc fail (key = %s)", key);
298 for(i=0; i<len; i++) {
299 new_argv[*margc+i] = strdup(str_array[i]);
302 new_argv[*margc+len] = NULL;
305 if(strncmp(key, DLP_K_DEBUG_ARG, strlen(key)) == 0
306 || strncmp(key, DLP_K_VALGRIND_ARG, strlen(key)) == 0)
308 new_argv = (char **) realloc(argv
309 , sizeof(char *) * (*margc+2));
311 _E("realloc fail (key = %s)", key);
314 for(i=*margc+1; i-1>=0; i--) {
315 new_argv[i] = new_argv[i-1];
317 // need to add new_argv[0]
322 if(new_argv==NULL) return argv;
326 char **__create_argc_argv(bundle * kb, int *margc, const char *app_path)
329 char **new_argv = NULL;
332 const char *str = NULL;
333 const char **str_array = NULL;
337 argc = bundle_export_to_argv(kb, &argv);
339 for(i=1; i<argc; i++) {
340 argv[i] = strdup(argv[i]);
342 argv[0] = strdup(app_path);
344 _E("bundle_export_to_argv error");
348 if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
349 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
351 str = bundle_get_val(kb, AUL_K_SDK);
357 if(str_array == NULL) {
362 for (i = 0; i < len; i++) {
363 if(str_array[i] == NULL) break;
364 _D("index : [%d]", i);
366 if (strncmp(str_array[i], SDK_DEBUG, strlen(str_array[i])) == 0)
368 char buf[MAX_LOCAL_BUFSZ];
369 if (argv[0]) free(argv[0]);
370 snprintf(buf,MAX_LOCAL_BUFSZ,"%s.exe",app_path);
371 // this code is added because core app don't have '.exe' excutable
372 // if '.exe' not exist then use app_path
373 if(access(buf, F_OK) != 0)
374 argv[0] = strdup(app_path);
376 argv[0] = strdup(buf);
377 new_argv = __add_arg(kb, argv, &argc, DLP_K_DEBUG_ARG);
378 new_argv[0] = strdup(PATH_GDBSERVER);
382 else if (strncmp(str_array[i], SDK_VALGRIND
383 , strlen(str_array[i])) == 0)
385 new_argv = __add_arg(kb, argv, &argc
386 , DLP_K_VALGRIND_ARG);
387 new_argv[0] = strdup(PATH_VALGRIND);
391 else if (strncmp(str_array[i], SDK_UNIT_TEST
392 , strlen(str_array[i])) == 0)
394 new_argv = __add_arg(kb, argv, &argc
395 , DLP_K_UNIT_TEST_ARG);
401 if(new_argv==NULL) return argv;
405 int __normal_fork_exec(int argc, char **argv)
407 _D("start real fork and exec\n");
409 if (execv(argv[0], argv) < 0) { /* Flawfinder: ignore */
410 if (errno == EACCES) {
411 _E("such a file is no executable - %s", argv[0]);
413 _E("unknown executable error - %s", argv[0]);
421 void __real_launch(const char *app_path, bundle * kb)
427 app_argv = __create_argc_argv(kb, &app_argc, app_path);
429 for (i = 0; i < app_argc; i++)
430 _D("input argument %d : %s##", i, app_argv[i]);
432 PERF("setup argument done");
433 _D("lock up test log(no error) : setup argument done");
435 /* Temporary log: launch time checking */
436 LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:launchpad:done]", app_path);
438 __normal_fork_exec(app_argc, app_argv);
440 for(i=0; i<app_argc; i++) {
441 if(app_argv[i]) free(app_argv[i]);
448 * Parsing original app path to retrieve default bundle
450 * -1 : Invalid sequence
451 * -2 : Buffer overflow
454 static inline int __parser(const char *arg, char *out, int out_size)
458 char *start_out = out;
460 if (arg == NULL || out == NULL) {
461 /* Handles null buffer*/
465 for (i = 0; out_size > 1; i++) {
489 case 2: /* escape start*/
504 case 4: /* character escape*/
505 if (arg[i] == '\0') {
515 if (out != start_out) {
524 return -1; /* error*/
525 case 7: /* terminate*/
542 void __modify_bundle(bundle * kb, int caller_pid,
543 app_info_from_db * menu_info, int cmd)
545 bundle_del(kb, AUL_K_PKG_NAME);
546 bundle_del(kb, AUL_K_EXEC);
547 bundle_del(kb, AUL_K_PACKAGETYPE);
548 bundle_del(kb, AUL_K_HWACC);
549 bundle_del(kb, AUL_K_TASKMANAGE);
551 /* Parse app_path to retrieve default bundle*/
552 if (cmd == APP_START || cmd == APP_START_RES || cmd == APP_OPEN
553 || cmd == APP_RESUME)
556 char exe[MAX_PATH_LEN];
559 ptr = _get_original_app_path(menu_info);
561 flag = __parser(ptr, exe, sizeof(exe));
567 _D("parsing app_path: EXEC - %s\n", exe);
570 flag = __parser(ptr, key, sizeof(key));
575 flag = __parser(ptr, value, sizeof(value));
580 /*bundle_del(kb, key);*/
581 bundle_add(kb, key, value);
583 } else if (flag == 0) {
584 _D("parsing app_path: No arguments\n");
586 _D("parsing app_path: Invalid argument\n");
591 int __send_to_sigkill(int pid)
599 if (killpg(pgid, SIGKILL) < 0)
605 int __term_app(int pid)
609 (pid, APP_TERM_BY_PID, (unsigned char *)&dummy, sizeof(int)) < 0) {
610 _D("terminate packet send error - use SIGKILL");
611 if (__send_to_sigkill(pid) < 0) {
612 _E("fail to killing - %d\n", pid);
620 static int __get_caller_pid(bundle *kb)
625 pid_str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
629 pid_str = bundle_get_val(kb, AUL_K_CALLER_PID);
641 int __foward_cmd(int cmd, bundle *kb, int cr_pid)
644 char tmp_pid[MAX_PID_STR_BUFSZ];
649 if ((pid = __get_caller_pid(kb)) < 0)
652 snprintf(tmp_pid, MAX_PID_STR_BUFSZ, "%d", cr_pid);
654 bundle_add(kb, AUL_K_CALLEE_PID, tmp_pid);
656 bundle_encode(kb, &kb_data, &datalen);
657 if ((res = __app_send_raw_with_noreply(pid, cmd, kb_data, datalen)) < 0)
665 void __real_send(int clifd, int ret)
667 if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
668 if (errno == EPIPE) {
669 _E("send failed due to EPIPE.\n");
671 _E("send fail to client");
677 void __send_result_to_caller(int clifd, int ret)
681 int cmdline_changed = 0;
682 int cmdline_exist = 0;
688 __real_send(clifd, ret);
691 /* check normally was launched?*/
694 cmdline = __proc_get_cmdline_bypid(ret);
695 if (cmdline == NULL) {
696 _E("error founded when being launched with %d", ret);
698 } else if (strcmp(cmdline, launchpad_cmdline)) {
707 _D("-- now wait to change cmdline --");
708 usleep(50 * 1000); /* 50ms sleep*/
710 } while (wait_count <= 20); /* max 50*20ms will be sleep*/
712 if ((!cmdline_exist) && (!cmdline_changed)) {
713 _E("abnormally launched");
714 __real_send(clifd, -1); /* abnormally launched*/
718 if (!cmdline_changed)
719 _E("process launched, but cmdline not changed");
721 __real_send(clifd, ret);
725 static app_info_from_db *_get_app_info_from_bundle_by_pkgname(
726 const char *pkgname, bundle *kb)
728 app_info_from_db *menu_info;
730 menu_info = calloc(1, sizeof(app_info_from_db));
731 if (menu_info == NULL) {
735 menu_info->pkg_name = strdup(pkgname);
736 menu_info->app_path = strdup(bundle_get_val(kb, AUL_K_EXEC));
737 if (menu_info->app_path != NULL)
738 menu_info->original_app_path = strdup(menu_info->app_path);
739 menu_info->pkg_type = strdup(bundle_get_val(kb, AUL_K_PACKAGETYPE));
740 menu_info->hwacc = strdup(bundle_get_val(kb, AUL_K_HWACC));
741 menu_info->taskmanage = strdup(bundle_get_val(kb, AUL_K_TASKMANAGE));
743 if (!_get_app_path(menu_info)) {
744 _free_app_info_from_db(menu_info);
754 int get_native_appid(const char* app_path, char** appid) {
755 int rc = smack_lgetlabel(app_path, appid, SMACK_LABEL_ACCESS);
757 if (rc != 0 || *appid == NULL) {
758 _E("smack_lgetlabel fail");
762 _D("get_appid return : %s", *appid);
766 int apply_smack_rules(const char* subject, const char* object
767 , const char* access_type)
769 struct smack_accesses *rules = NULL;
771 _D("apply_smack_rules : %s %s %s", subject, object, access_type);
773 if (smack_accesses_new(&rules)) {
774 _E("smack_accesses_new fail");
778 if (smack_accesses_add(rules, subject, object, access_type)) {
779 smack_accesses_free(rules);
780 _E("smack_accesses_add fail");
784 if (smack_accesses_apply(rules)) {
785 // smack_accesses_free(rules);
786 _E("smack_accesses_apply fail");
790 smack_accesses_free(rules);
795 int __prepare_valgrind_outputfile(bundle *kb)
797 const char *str = NULL;
798 const char **str_array = NULL;
802 if(bundle_get_type(kb, DLP_K_VALGRIND_ARG) & BUNDLE_TYPE_ARRAY) {
803 str_array = bundle_get_str_array(kb, DLP_K_VALGRIND_ARG, &len);
805 str = bundle_get_val(kb, DLP_K_VALGRIND_ARG);
811 if(str_array == NULL) return 0;
813 for (i = 0; i < len; i++) {
814 if(str_array[i] == NULL) break;
815 /* valgrind log file option */
816 if (strncmp(str_array[i], OPT_VALGRIND_LOGFILE
817 , sizeof(OPT_VALGRIND_LOGFILE)-1) == 0)
819 if(strcmp(str_array[i], OPT_VALGRIND_LOGFILE_FIXED))
821 _E("wrong valgrind option(%s). It should be %s"
823 , OPT_VALGRIND_LOGFILE_FIXED);
826 poll_outputfile |= POLL_VALGRIND_LOGFILE;
827 if(remove(PATH_VALGRIND_LOGFILE)){
828 _D("cannot remove %s"
829 , PATH_VALGRIND_LOGFILE);
833 /* valgrind xml file option */
834 else if (strncmp(str_array[i], OPT_VALGRIND_XMLFILE
835 , sizeof(OPT_VALGRIND_XMLFILE)-1) == 0)
837 if(strcmp(str_array[i], OPT_VALGRIND_XMLFILE_FIXED))
839 _E("wrong valgrind option(%s). It should be %s"
841 , OPT_VALGRIND_XMLFILE_FIXED);
844 poll_outputfile |= POLL_VALGRIND_XMLFILE;
845 if(remove(PATH_VALGRIND_XMLFILE)){
846 _D("cannot remove %s"
847 , PATH_VALGRIND_XMLFILE);
851 /* valgrind massif file option */
852 else if (strncmp(str_array[i], OPT_VALGRIND_MASSIFFILE
853 , sizeof(OPT_VALGRIND_MASSIFFILE)-1) == 0)
855 if(strcmp(str_array[i], OPT_VALGRIND_MASSIFFILE_FIXED))
857 _E("wrong valgrind option(%s). It should be %s"
859 , OPT_VALGRIND_MASSIFFILE_FIXED);
862 if(remove(PATH_VALGRIND_XMLFILE)){
863 _D("cannot remove %s"
864 , PATH_VALGRIND_XMLFILE);
872 extern int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
874 int __adjust_process_capability(int sv)
876 static struct __user_cap_header_struct h;
877 static struct __user_cap_data_struct inh_d[_LINUX_CAPABILITY_U32S_2];
879 if(sv == CAPABILITY_GET_ORIGINAL) {
880 h.version = _LINUX_CAPABILITY_VERSION_2;
885 inh_d[CAP_TO_INDEX(CAP_NET_RAW)].inheritable |=
886 CAP_TO_MASK(CAP_NET_RAW);
887 inh_d[CAP_TO_INDEX(CAP_SYS_CHROOT)].inheritable |=
888 CAP_TO_MASK(CAP_SYS_CHROOT);
893 if (sv == CAPABILITY_SET_INHERITABLE) {
895 if (capset(&h, inh_d) < 0) {
896 _E("Capability setting error");
904 int __adjust_file_capability(const char * path)
906 if(cap_set_file(path,cap_from_text("CAP_NET_RAW,CAP_SYS_CHROOT+i"))) {
907 _E("cap_set_file failed : %s", path);
913 int __prepare_fork(bundle *kb, char *appid)
915 const char *str = NULL;
916 const char **str_array = NULL;
919 pkgmgrinfo_pkginfo_h handle;
920 bool bPreloaded = false;
921 char *storeclientid = NULL;
923 need_to_set_inh_cap_after_fork=0;
925 if(bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
926 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
928 str = bundle_get_val(kb, AUL_K_SDK);
934 if(str_array == NULL) return 0;
936 is_gdbserver_launched = 0;
938 gdbserver_app_pid = -1;
940 for (i = 0; i < len; i++) {
941 if(str_array[i] == NULL) break;
943 if (strncmp(str_array[i], SDK_DEBUG, strlen(str_array[i])) == 0)
945 // because of security issue, prevent debugging(ptrace) for preloaded app and downloaed app
946 if(pkgmgrinfo_pkginfo_get_pkginfo(appid, &handle) == PMINFO_R_OK)
948 if(pkgmgrinfo_pkginfo_is_preload(handle, &bPreloaded) != PMINFO_R_OK)
950 if(pkgmgrinfo_pkginfo_get_storeclientid(handle, &storeclientid) != PMINFO_R_OK)
952 if(bPreloaded || (storeclientid[0] != '\0'))
954 _E("debugging is not allowed");
959 if(apply_smack_rules("sdbd",appid,"w")) {
960 _E("smack_accesses_apply fail");
964 // fixed debug-as fail issue (grant permission to use 10.0.2.2, 10.0.2.16)
965 if(apply_smack_rules(appid, "system::debugging_network", "rw")) {
966 _E("smack_accesses_apply fail");
968 if(apply_smack_rules("system::debugging_network", appid, "w")) {
969 _E("smack_accesses_apply fail");
972 // FIXME: set gdbfolder to 755 also
973 if(dlp_chmod(PATH_GDBSERVER
974 , S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP
978 _D("unable to set 755 to %s", PATH_GDBSERVER);
980 __adjust_file_capability(PATH_GDBSERVER);
981 need_to_set_inh_cap_after_fork++;
982 is_gdbserver_launched++;
985 else if (strncmp(str_array[i], SDK_VALGRIND
986 , strlen(str_array[i])) == 0)
988 if (__prepare_valgrind_outputfile(kb) == -1)
990 __adjust_file_capability(PATH_MEMCHECK);
997 /* waiting for creating outputfile by child process */
998 void __waiting_outputfile()
1001 while(poll_outputfile && wait_count<10) {
1002 /* valgrind log file */
1003 if( (poll_outputfile & POLL_VALGRIND_LOGFILE)
1004 && (access(PATH_VALGRIND_LOGFILE,F_OK)==0) )
1006 __chmod_chsmack_toread(PATH_VALGRIND_LOGFILE);
1007 poll_outputfile &= ~POLL_VALGRIND_LOGFILE;
1010 /* valgrind xml file */
1011 if( (poll_outputfile & POLL_VALGRIND_XMLFILE)
1012 && (access(PATH_VALGRIND_XMLFILE,F_OK)==0) )
1014 __chmod_chsmack_toread(PATH_VALGRIND_XMLFILE);
1015 poll_outputfile &= ~POLL_VALGRIND_XMLFILE;
1018 if(poll_outputfile) {
1019 _D("-- now wait for creating the file --");
1020 usleep(50 * 1000); /* 50ms sleep*/
1025 if(wait_count==10) _E("faild to waiting");
1029 int __stdout_stderr_redirection(int defpid)
1031 char defpath[UNIX_PATH_MAX];
1032 int deffd, result=0;
1035 snprintf(defpath, UNIX_PATH_MAX, "/proc/%d/fd/1", defpid);
1036 deffd = open(defpath,O_WRONLY);
1038 _E("opening caller(%d) stdout failed due to %s"
1039 , defpid, strerror(errno));
1047 snprintf(defpath, UNIX_PATH_MAX, "/proc/%d/fd/2", defpid);
1048 deffd = open(defpath,O_WRONLY);
1050 _E("opening caller(%d) stderr failed due to %s"
1051 , defpid,strerror(errno));
1061 void __launchpad_main_loop(int main_fd)
1064 app_pkt_t *pkt = NULL;
1065 app_info_from_db *menu_info = NULL;
1067 const char *pkg_name = NULL;
1068 const char *app_path = NULL;
1072 int is_real_launch = 0;
1074 char sock_path[UNIX_PATH_MAX] = {0,};
1075 char * appid = NULL;
1077 pkt = __app_recv_raw(main_fd, &clifd, &cr);
1079 _D("packet is NULL");
1083 kb = bundle_decode(pkt->data, pkt->len);
1085 _D("bundle decode error");
1090 PERF("packet processing start");
1092 pkg_name = bundle_get_val(kb, AUL_K_PKG_NAME);
1093 _D("pkg name : %s\n", pkg_name);
1095 menu_info = _get_app_info_from_bundle_by_pkgname(pkg_name, kb);
1096 if (menu_info == NULL) {
1097 _D("such pkg no found");
1101 app_path = _get_app_path(menu_info);
1102 if(app_path == NULL) {
1103 _E("app_path is NULL");
1106 if (app_path[0] != '/') {
1107 _D("app_path is not absolute path");
1112 int rc = get_native_appid(app_path,&appid);
1113 if(rc!=0 || appid==NULL) {
1114 _E("unable to get native appid");
1123 __modify_bundle(kb, cr.pid, menu_info, pkt->cmd);
1124 pkg_name = _get_pkgname(menu_info);
1126 PERF("get package information & modify bundle done");
1128 if(__prepare_fork(kb,appid) == -1) goto end;
1132 if(need_to_set_inh_cap_after_fork) {
1133 __adjust_process_capability(CAPABILITY_SET_INHERITABLE);
1136 _D("lock up test log(no error) : fork done");
1140 __signal_unset_sigchld();
1143 snprintf(sock_path, UNIX_PATH_MAX, "%s/%d", AUL_SOCK_PREFIX
1147 if(__stdout_stderr_redirection(__get_caller_pid(kb))) {
1148 _E("__stdout_stderr_redirection fail");
1151 PERF("prepare exec - first done");
1152 _D("lock up test log(no error) : prepare exec - first done");
1154 if (__prepare_exec(pkg_name, app_path,
1155 menu_info, kb) < 0) {
1156 _E("preparing work fail to launch - "
1157 "can not launch %s\n", pkg_name);
1161 PERF("prepare exec - second done");
1162 _D("lock up test log(no error) : prepare exec - second done");
1164 __real_launch(app_path, kb);
1169 if(is_gdbserver_launched) {
1170 char buf[MAX_LOCAL_BUFSZ];
1172 usleep(100 * 1000); /* 100ms sleep */
1173 snprintf(buf, MAX_LOCAL_BUFSZ, "%s.exe", app_path);
1174 gdbserver_app_pid = __proc_iter_cmdline(NULL, buf);
1176 if(gdbserver_app_pid == -1) {
1177 _E("faild to get app pid");
1179 gdbserver_pid = pid;
1180 pid = gdbserver_app_pid;
1184 _D("==> real launch pid : %d %s\n", pid, app_path);
1188 __send_result_to_caller(clifd, pid);
1191 if (is_real_launch) {
1193 __signal_block_sigchld();
1194 __send_app_launch_signal(pid);
1195 __signal_unblock_sigchld();
1199 if (menu_info != NULL)
1200 _free_app_info_from_db(menu_info);
1209 /* Active Flusing for Daemon */
1210 if (initialized > AUL_POLL_CNT) {
1211 sqlite3_release_memory(SQLITE_FLUSH_MAX);
1216 if(poll_outputfile) __waiting_outputfile();
1219 int __launchpad_pre_init(int argc, char **argv)
1226 /* get my(launchpad) command line*/
1227 launchpad_cmdline = __proc_get_cmdline_bypid(getpid());
1228 if (launchpad_cmdline == NULL) {
1229 _E("launchpad cmdline fail to get");
1232 _D("launchpad cmdline = %s", launchpad_cmdline);
1234 /* create launchpad sock */
1235 fd = __create_server_sock(DEBUG_LAUNCHPAD_PID);
1237 _E("server sock error");
1241 __preload_init(argc, argv);
1243 __preexec_init(argc, argv);
1248 int __launchpad_post_init()
1250 /* Setting this as a global variable to keep track
1251 of launchpad poll cnt */
1252 /* static int initialized = 0;*/
1259 if (__signal_set_sigchld() < 0)
1267 int main(int argc, char **argv)
1270 struct pollfd pfds[POLLFD_MAX];
1273 __adjust_process_capability(CAPABILITY_GET_ORIGINAL);
1275 /* init without concerning X & EFL*/
1276 main_fd = __launchpad_pre_init(argc, argv);
1278 _E("launchpad pre init failed");
1282 pfds[0].fd = main_fd;
1283 pfds[0].events = POLLIN;
1284 pfds[0].revents = 0;
1287 if (poll(pfds, POLLFD_MAX, -1) < 0)
1290 /* init with concerning X & EFL (because of booting
1292 if (__launchpad_post_init() < 0) {
1293 _E("launcpad post init failed");
1297 for (i = 0; i < POLLFD_MAX; i++) {
1298 if ((pfds[i].revents & POLLIN) != 0) {
1299 __launchpad_main_loop(pfds[i].fd);