2 * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include <sys/prctl.h>
25 #include <sys/socket.h>
28 #include <sys/types.h>
30 #include <sys/signalfd.h>
31 #include <linux/limits.h>
35 #include <bundle_internal.h>
38 #include "signal_util.h"
39 #include "security_util.h"
40 #include "file_util.h"
41 #include "debug_util.h"
45 #define AUL_PR_NAME 16
47 static int __real_send(int clifd, int ret)
49 if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
51 _E("send failed due to EPIPE.\n");
56 _E("send fail to client");
64 static void __send_result_to_caller(int clifd, int ret)
68 _W("Check app launching");
74 _E("launching failed");
75 __real_send(clifd, ret);
79 res = _proc_check_cmdline_bypid(ret);
81 _E("The app process might be terminated "
82 "while we are wating %d", ret);
83 __real_send(clifd, -1); /* abnormally launched */
87 if (__real_send(clifd, ret) < 0) {
88 if (kill(ret, SIGKILL) == -1)
89 _E("Failed to send SIGKILL: %d", errno);
95 static int __prepare_exec(const char *appid, const char *app_path,
96 appinfo_t *appinfo, bundle *kb)
99 char process_name[AUL_PR_NAME];
102 /* Set new session ID & new process group ID */
103 /* In linux, child can set new session ID without check permission */
107 _D("appid: %s / pkg_type: %s / app_path: %s",
108 appid, appinfo->pkg_type, app_path);
109 if ((ret = _set_access(appid)) != 0) {
110 _E("Failed to set privileges "
111 "- check your package's credential: %d", ret);
115 /* SET DUMPABLE - for coredump */
116 prctl(PR_SET_DUMPABLE, 1);
118 /* SET PROCESS NAME */
119 if (app_path == NULL) {
120 _D("app_path should not be NULL - check menu db");
124 file_name = strrchr(app_path, '/') + 1;
125 if (file_name == NULL) {
126 _D("can't locate file name to execute");
130 memset(process_name, '\0', AUL_PR_NAME);
131 snprintf(process_name, AUL_PR_NAME, "%s", file_name);
132 prctl(PR_SET_NAME, process_name);
135 _set_env(appinfo, kb);
140 static int __prepare_fork(bundle *kb, const char *appid)
143 const char **str_array = NULL;
146 if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
147 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
148 if (str_array == NULL)
151 str = bundle_get_val(kb, AUL_K_SDK);
158 _prepare_debug_tool(kb, appid, str_array, len);
163 static int __get_caller_pid(bundle *kb)
168 str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
172 str = bundle_get_val(kb, AUL_K_CALLER_PID);
184 static int __redirect_stdfds(int caller_pid)
191 snprintf(buf, sizeof(buf), "/proc/%d/fd/1", caller_pid);
192 fd = open(buf, O_WRONLY);
194 _E("Failed to open caller(%d) stdout", caller_pid);
202 snprintf(buf, sizeof(buf), "/proc/%d/fd/2", caller_pid);
203 fd = open(buf, O_WRONLY);
205 _E("Failed to open caller(%d) stderr", caller_pid);
215 static int __normal_fork_exec(int argc, char **argv)
217 _D("start real fork and exec\n");
219 if (execv(argv[0], argv) < 0) { /* Flawfinder: ignore */
221 _E("such a file is no executable - %s", argv[0]);
223 _E("unknown executable error - %s", argv[0]);
232 static void __real_launch(const char *app_path, bundle *kb)
238 app_argv = _create_argc_argv(kb, &app_argc, app_path);
239 if (app_argv == NULL)
242 for (i = 0; i < app_argc; i++)
243 _D("input argument %d : %s##", i, app_argv[i]);
245 PERF("setup argument done");
247 __normal_fork_exec(app_argc, app_argv);
250 static int __start_process(const char *appid, const char *app_path,
251 bundle *kb, appinfo_t *appinfo)
253 char sock_path[PATH_MAX];
258 if (__prepare_fork(kb, appinfo->debug_appid) < 0)
264 _D("lock up test log(no error): fork done");
266 _signal_unblock_sigchld();
269 max_fd = sysconf(_SC_OPEN_MAX);
270 for (iter_fd = 3; iter_fd <= max_fd; iter_fd++)
273 snprintf(sock_path, sizeof(sock_path), "%s/%d/%d",
274 SOCKET_PATH, getuid(), getpid());
277 if (__redirect_stdfds(__get_caller_pid(kb)))
278 _E("Failed to redirect caller fds");
280 PERF("prepare exec - fisrt done");
281 _D("lock up test log(no error): prepare exec - first done");
283 if (__prepare_exec(appid, app_path, appinfo, kb) < 0) {
284 _E("preparing work fail to launch "
285 "- can not launch %s", appid);
289 PERF("prepare exec - second done");
290 _D("lock up test log(no error): prepare exec - second done");
291 __real_launch(app_path, kb);
296 _D("==> real launch pid: %d %s", pid, app_path);
301 static gboolean __handle_sigchld(gpointer data)
303 GPollFD *gpollfd = (GPollFD *)data;
304 int fd = gpollfd->fd;
305 struct signalfd_siginfo siginfo;
309 s = read(fd, &siginfo, sizeof(struct signalfd_siginfo));
313 if (s != sizeof(struct signalfd_siginfo)) {
314 _E("error reading sigchld info");
318 _debug_launchpad_sigchld(&siginfo);
324 static gboolean __handle_launch_event(gpointer data)
326 GPollFD *gpollfd = (GPollFD *)data;
327 int fd = gpollfd->fd;
329 app_pkt_t *pkt = NULL;
330 appinfo_t *appinfo = NULL;
331 const char *app_path = NULL;
336 pkt = _recv_pkt_raw(fd, &clifd, &cr);
338 _E("packet is NULL");
342 kb = bundle_decode(pkt->data, pkt->len);
344 _E("bundle decode error");
349 PERF("packet processing start");
351 appinfo = _appinfo_create(kb);
352 if (appinfo == NULL) {
353 _E("_appinfo_create() is failed.");
357 app_path = appinfo->app_path;
358 if (app_path == NULL) {
359 _E("app_path is NULL");
363 if (app_path[0] != '/') {
364 _E("app_path is not absolute path: %s", app_path);
368 _D("appid: %s", appinfo->appid);
369 _D("exec: %s", appinfo->app_path);
370 _D("debug appid: %s", appinfo->debug_appid);
371 _D("hwacc: %s", appinfo->hwacc);
373 _modify_bundle(kb, cr.pid, appinfo, pkt->cmd);
374 if (appinfo->appid == NULL) {
375 _E("unable to get appid from appinfo");
379 PERF("get package infomation & modify bundle done");
381 pid = __start_process(appinfo->appid, app_path, kb, appinfo);
384 __send_result_to_caller(clifd, pid);
387 _send_app_launch_signal(pid, appinfo->appid);
389 _appinfo_free(appinfo);
394 if (_get_valgrind_option())
395 _wait_for_valgrind_output();
400 static gboolean __glib_check(GSource *src)
405 fd_list = src->poll_fds;
407 tmp = (GPollFD *)fd_list->data;
409 (G_IO_IN | G_IO_PRI | G_IO_HUP | G_IO_NVAL)))
411 fd_list = fd_list->next;
417 static gboolean __glib_dispatch(GSource *src, GSourceFunc callback,
420 return callback(data);
423 static gboolean __glib_prepare(GSource *src, gint *timeout)
428 static void __glib_finalize(GSource *src)
433 fd_list = src->poll_fds;
435 gpollfd = (GPollFD *)fd_list->data;
439 fd_list = fd_list->next;
443 static GSourceFuncs funcs = {
444 .prepare = __glib_prepare,
445 .check = __glib_check,
446 .dispatch = __glib_dispatch,
447 .finalize = __glib_finalize
450 static int __poll_fd(int fd, GSourceFunc callback)
456 src = g_source_new(&funcs, sizeof(GSource));
462 gpollfd = (GPollFD *)g_malloc(sizeof(GPollFD));
463 if (gpollfd == NULL) {
465 g_source_destroy(src);
470 gpollfd->events = G_IO_IN;
472 g_source_add_poll(src, gpollfd);
473 g_source_set_callback(src, callback, (gpointer)gpollfd, NULL);
474 g_source_set_priority(src, G_PRIORITY_DEFAULT);
476 r = g_source_attach(src, NULL);
479 g_source_destroy(src);
486 static int __init_sigchld_fd(void)
490 fd = _signal_get_sigchld_fd();
492 _E("Failed to get sigchld fd");
496 if (__poll_fd(fd, (GSourceFunc)__handle_sigchld) < 0) {
504 static int __init_debug_launchpad_fd(int argc, char **argv)
511 /* create debug-launchpad socket */
512 fd = _create_server_sock();
514 _E("Failed to create server socket");
518 if (__poll_fd(fd, (GSourceFunc)__handle_launch_event) < 0) {
526 static int __before_loop(int argc, char **argv)
528 if (__init_sigchld_fd() < 0) {
529 _E("Failed to initialize sigchld fd.");
533 if (__init_debug_launchpad_fd(argc, argv) < 0) {
534 _E("Failed to initialize launchpad fd.");
541 int main(int argc, char **argv)
545 loop = g_main_loop_new(NULL, FALSE);
547 _E("Failed to create glib main loop.");
551 if (__before_loop(argc, argv) < 0) {
552 _E("Failed to initiailze debug-launchapd.");
556 g_main_loop_run(loop);