Remove the exception for gdbserver
[platform/core/appfw/debug-launchpad.git] / src / debug-launchpad.c
1 /*
2  * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #define _GNU_SOURCE
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <fcntl.h>
24 #include <sys/prctl.h>
25 #include <sys/socket.h>
26 #include <sys/un.h>
27 #include <sys/wait.h>
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <sys/signalfd.h>
31 #include <linux/limits.h>
32 #include <glib.h>
33 #include <dlog.h>
34 #include <bundle.h>
35 #include <bundle_internal.h>
36
37 #include "common.h"
38 #include "signal_util.h"
39 #include "security_util.h"
40 #include "file_util.h"
41 #include "debug_util.h"
42 #include "perf.h"
43 #include "defs.h"
44
45 #define AUL_PR_NAME 16
46
47 static int __real_send(int clifd, int ret)
48 {
49         if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) {
50                 if (errno == EPIPE) {
51                         _E("send failed due to EPIPE.\n");
52                         close(clifd);
53                         return -1;
54                 }
55
56                 _E("send fail to client");
57         }
58
59         close(clifd);
60
61         return 0;
62 }
63
64 static void __send_result_to_caller(int clifd, int ret)
65 {
66         int res;
67
68         _W("Check app launching");
69
70         if (clifd == -1)
71                 return;
72
73         if (ret <= 1) {
74                 _E("launching failed");
75                 __real_send(clifd, ret);
76                 return;
77         }
78
79         res = _proc_check_cmdline_bypid(ret);
80         if (res < 0) {
81                 _E("The app process might be terminated while we are wating %d", ret);
82                 __real_send(clifd, -1); /* abnormally launched */
83                 return;
84         }
85
86         if (__real_send(clifd, ret) < 0) {
87                 if (kill(ret, SIGKILL) == -1)
88                         _E("Failed to send SIGKILL: %d", errno);
89         }
90
91         return;
92 }
93
94 static int __prepare_exec(const char *appid, const char *app_path,
95                 appinfo_t *appinfo, bundle *kb)
96 {
97         char *file_name;
98         char process_name[AUL_PR_NAME];
99         int ret;
100
101         /* Set new session ID & new process group ID */
102         /* In linux, child can set new session ID without check permission */
103         setsid();
104
105         /* SET PRIVILEGES */
106         _D("appid: %s / pkg_type: %s / app_path: %s",
107                         appid, appinfo->pkg_type, app_path);
108         if ((ret = _set_access(appid)) != 0) {
109                 _E("Failed to set privileges - check your package's credential: %d", ret);
110                 return -1;
111         }
112
113         /* SET DUMPABLE - for coredump */
114         prctl(PR_SET_DUMPABLE, 1);
115
116         /* SET PROCESS NAME */
117         if (app_path == NULL) {
118                 _D("app_path should not be NULL - check menu db");
119                 return -1;
120         }
121
122         file_name = strrchr(app_path, '/') + 1;
123         if (file_name == NULL) {
124                 _D("can't locate file name to execute");
125                 return -1;
126         }
127
128         memset(process_name, '\0', AUL_PR_NAME);
129         snprintf(process_name, AUL_PR_NAME, "%s", file_name);
130         prctl(PR_SET_NAME, process_name);
131
132         /* SET ENVIROMENT */
133         _set_env(appinfo, kb);
134
135         return 0;
136 }
137
138 static int __prepare_fork(bundle *kb, const char *appid)
139 {
140         const char *str;
141         const char **str_array = NULL;
142         int len = 0;
143
144         if (bundle_get_type(kb, AUL_K_SDK) & BUNDLE_TYPE_ARRAY) {
145                 str_array = bundle_get_str_array(kb, AUL_K_SDK, &len);
146                 if (str_array == NULL)
147                         return -1;
148         } else {
149                 str = bundle_get_val(kb, AUL_K_SDK);
150                 if (str) {
151                         str_array = &str;
152                         len = 1;
153                 }
154         }
155
156         _prepare_debug_tool(kb, appid, str_array, len);
157
158         return 0;
159 }
160
161 static int __get_caller_pid(bundle *kb)
162 {
163         const char *str;
164         int pid;
165
166         str = bundle_get_val(kb, AUL_K_ORG_CALLER_PID);
167         if (str)
168                 goto end;
169
170         str = bundle_get_val(kb, AUL_K_CALLER_PID);
171         if (str == NULL)
172                 return -1;
173
174 end:
175         pid = atoi(str);
176         if (pid <= 1)
177                 return -1;
178
179         return pid;
180 }
181
182 static int __redirect_stdfds(int caller_pid)
183 {
184         char buf[PATH_MAX];
185         int fd;
186         int ret = 0;
187
188         /* stdout */
189         snprintf(buf, sizeof(buf), "/proc/%d/fd/1", caller_pid);
190         fd = open(buf, O_WRONLY);
191         if (fd < 0) {
192                 _E("Failed to open caller(%d) stdout", caller_pid);
193                 ret = 1;
194         } else {
195                 dup2(fd, 1);
196                 close(fd);
197         }
198
199         /* stderr */
200         snprintf(buf, sizeof(buf), "/proc/%d/fd/2", caller_pid);
201         fd = open(buf, O_WRONLY);
202         if (fd < 0) {
203                 _E("Failed to open caller(%d) stderr", caller_pid);
204                 ret += 2;
205         } else {
206                 dup2(fd, 2);
207                 close(fd);
208         }
209
210         return ret;
211 }
212
213 static int __normal_fork_exec(int argc, char **argv)
214 {
215         _D("start real fork and exec\n");
216
217         if (execv(argv[0], argv) < 0) { /* Flawfinder: ignore */
218                 if (errno == EACCES)
219                         _E("such a file is no executable - %s", argv[0]);
220                 else
221                         _E("unknown executable error - %s", argv[0]);
222
223                 return -1;
224         }
225
226         /* never reach */
227         return 0;
228 }
229
230 static void __real_launch(const char *app_path, bundle *kb)
231 {
232         int app_argc;
233         char **app_argv;
234         int i;
235
236         app_argv = _create_argc_argv(kb, &app_argc, app_path);
237         if (app_argv == NULL)
238                 return;
239
240         for (i = 0; i < app_argc; i++)
241                 _D("input argument %d : %s##", i, app_argv[i]);
242
243         PERF("setup argument done");
244
245         __normal_fork_exec(app_argc, app_argv);
246 }
247
248 static int __start_process(const char *appid, const char *app_path,
249                 bundle *kb, appinfo_t *appinfo)
250 {
251         char sock_path[PATH_MAX];
252         int pid;
253         int max_fd;
254         int iter_fd;
255
256         if (__prepare_fork(kb, appinfo->debug_appid) < 0)
257                 return -1;
258
259         pid = fork();
260         if (pid == 0) {
261                 PERF("fork done");
262                 _D("lock up test log(no error): fork done");
263
264                 _signal_unblock_sigchld();
265                 _signal_fini();
266
267                 max_fd = sysconf(_SC_OPEN_MAX);
268                 for (iter_fd = 3; iter_fd <= max_fd; iter_fd++)
269                         close(iter_fd);
270
271                 snprintf(sock_path, sizeof(sock_path), "%s/%d/%d",
272                                 SOCKET_PATH, getuid(), getpid());
273                 unlink(sock_path);
274
275                 if (__redirect_stdfds(__get_caller_pid(kb)))
276                         _E("Failed to redirect caller fds");
277
278                 PERF("prepare exec - fisrt done");
279                 _D("lock up test log(no error): prepare exec - first done");
280
281                 if (__prepare_exec(appid, app_path, appinfo, kb) < 0) {
282                         _E("preparing work fail to launch - can not launch %s", appid);
283                         exit(-1);
284                 }
285
286                 PERF("prepare exec - second done");
287                 _D("lock up test log(no error): prepare exec - second done");
288                 __real_launch(app_path, kb);
289
290                 exit(-1);
291         }
292
293         _D("==> real launch pid: %d %s", pid, app_path);
294
295         return pid;
296 }
297
298 static gboolean __handle_sigchld(gpointer data)
299 {
300         GPollFD *gpollfd = (GPollFD *)data;
301         int fd = gpollfd->fd;
302         struct signalfd_siginfo siginfo;
303         ssize_t s;
304
305         do {
306                 s = read(fd, &siginfo, sizeof(struct signalfd_siginfo));
307                 if (s == 0)
308                         break;
309
310                 if (s != sizeof(struct signalfd_siginfo)) {
311                         _E("error reading sigchld info");
312                         break;
313                 }
314
315                 _debug_launchpad_sigchld(&siginfo);
316         } while (s > 0);
317
318         return TRUE;
319 }
320
321 static gboolean __handle_launch_event(gpointer data)
322 {
323         GPollFD *gpollfd = (GPollFD *)data;
324         int fd = gpollfd->fd;
325         bundle *kb = NULL;
326         app_pkt_t *pkt = NULL;
327         appinfo_t *appinfo = NULL;
328         const char *app_path = NULL;
329         int pid = -1;
330         int clifd = -1;
331         struct ucred cr;
332
333         pkt = _recv_pkt_raw(fd, &clifd, &cr);
334         if (pkt == NULL) {
335                 _E("packet is NULL");
336                 return TRUE;
337         }
338
339         kb = bundle_decode(pkt->data, pkt->len);
340         if (kb == NULL) {
341                 _E("bundle decode error");
342                 goto end;
343         }
344
345         INIT_PERF(kb);
346         PERF("packet processing start");
347
348         appinfo = _appinfo_create(kb);
349         if (appinfo == NULL) {
350                 _E("_appinfo_create() is failed.");
351                 goto end;
352         }
353
354         app_path = appinfo->app_path;
355         if (app_path == NULL) {
356                 _E("app_path is NULL");
357                 goto end;
358         }
359
360         if (app_path[0] != '/') {
361                 _E("app_path is not absolute path: %s", app_path);
362                 goto end;
363         }
364
365         _D("appid: %s", appinfo->appid);
366         _D("exec: %s", appinfo->app_path);
367         _D("debug appid: %s", appinfo->debug_appid);
368         _D("hwacc: %s", appinfo->hwacc);
369
370         _modify_bundle(kb, cr.pid, appinfo, pkt->cmd);
371         if (appinfo->appid == NULL) {
372                 _E("unable to get appid from appinfo");
373                 goto end;
374         }
375
376         PERF("get package infomation & modify bundle done");
377
378         pid = __start_process(appinfo->appid, app_path, kb, appinfo);
379
380 end:
381         __send_result_to_caller(clifd, pid);
382
383         if (pid > 0)
384                 _send_app_launch_signal(pid, appinfo->appid);
385         if (appinfo)
386                 _appinfo_free(appinfo);
387         if (kb)
388                 bundle_free(kb);
389         if (pkt)
390                 free(pkt);
391         if (_get_valgrind_option())
392                 _wait_for_valgrind_output();
393
394         return TRUE;
395 }
396
397 static gboolean __glib_check(GSource *src)
398 {
399         GSList *fd_list;
400         GPollFD *tmp;
401
402         fd_list = src->poll_fds;
403         do {
404                 tmp = (GPollFD *)fd_list->data;
405                 if ((tmp->revents & (G_IO_IN | G_IO_PRI | G_IO_HUP | G_IO_NVAL)))
406                         return TRUE;
407                 fd_list = fd_list->next;
408         } while (fd_list);
409
410         return FALSE;
411 }
412
413 static gboolean __glib_dispatch(GSource *src, GSourceFunc callback, gpointer data)
414 {
415         return callback(data);
416 }
417
418 static gboolean __glib_prepare(GSource *src, gint *timeout)
419 {
420         return FALSE;
421 }
422
423 static GSourceFuncs funcs = {
424         .prepare = __glib_prepare,
425         .check = __glib_check,
426         .dispatch = __glib_dispatch,
427         .finalize = NULL
428 };
429
430 static int __poll_fd(int fd, GSourceFunc callback)
431 {
432         int r;
433         GPollFD *gpollfd;
434         GSource *src;
435
436         src = g_source_new(&funcs, sizeof(GSource));
437         if (src == NULL) {
438                 _E("out of memory");
439                 return -1;
440         }
441
442         gpollfd = (GPollFD *)g_malloc(sizeof(GPollFD));
443         if (gpollfd == NULL) {
444                 _E("out of memory");
445                 g_source_destroy(src);
446                 return -1;
447         }
448
449         gpollfd->fd = fd;
450         gpollfd->events = G_IO_IN;
451
452         g_source_add_poll(src, gpollfd);
453         g_source_set_callback(src, callback, (gpointer)gpollfd, NULL);
454         g_source_set_priority(src, G_PRIORITY_DEFAULT);
455
456         r = g_source_attach(src, NULL);
457         if (r == 0) {
458                 g_free(gpollfd);
459                 g_source_destroy(src);
460                 return -1;
461         }
462
463         return r;
464 }
465
466 static int __init_sigchld_fd(void)
467 {
468         int fd;
469
470         fd = _signal_get_sigchld_fd();
471         if (fd < 0) {
472                 _E("Failed to get sigchld fd");
473                 return -1;
474         }
475
476         if (__poll_fd(fd, (GSourceFunc)__handle_sigchld) < 0) {
477                 close(fd);
478                 return -1;
479         }
480
481         return 0;
482 }
483
484 static int __init_debug_launchpad_fd(int argc, char **argv)
485 {
486         int fd;
487
488         /* signal init */
489         _signal_init();
490
491         /* create debug-launchpad socket */
492         fd = _create_server_sock();
493         if (fd < 0) {
494                 _E("Failed to create server socket");
495                 return -1;
496         }
497
498         if (__poll_fd(fd, (GSourceFunc)__handle_launch_event) < 0) {
499                 close(fd);
500                 return -1;
501         }
502
503         return 0;
504 }
505
506 static int __before_loop(int argc, char **argv)
507 {
508         if (__init_sigchld_fd() < 0) {
509                 _E("Failed to initialize sigchld fd.");
510                 return -1;
511         }
512
513         if (__init_debug_launchpad_fd(argc, argv) < 0) {
514                 _E("Failed to initialize launchpad fd.");
515                 return -1;
516         }
517
518         return 0;
519 }
520
521 int main(int argc, char **argv)
522 {
523         GMainLoop *loop;
524
525         loop = g_main_loop_new(NULL, FALSE);
526         if (loop == NULL) {
527                 _E("Failed to create glib main loop.");
528                 return -1;
529         }
530
531         if (__before_loop(argc, argv) < 0) {
532                 _E("Failed to initiailze debug-launchapd.");
533                 return -1;
534         }
535
536         g_main_loop_run(loop);
537
538         return 0;
539 }
540