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.
20 #include <sys/socket.h>
22 #include <sys/types.h>
23 #include <sys/prctl.h>
25 #include <bundle_internal.h>
27 #include <security-manager.h>
28 #include <trust-anchor.h>
32 #include "launchpad_common.h"
33 #include "launchpad.h"
37 #define API __attribute__ ((visibility("default")))
40 #define AUL_PR_NAME 16
42 static loader_lifecycle_callback_s *__loader_callbacks;
43 static loader_adapter_s *__loader_adapter;
44 static void *__loader_user_data;
47 static bundle *__bundle;
48 static int __loader_type = LAUNCHPAD_TYPE_UNSUPPORTED;
49 static int __loader_id;
51 static void __at_exit_to_release_bundle(void)
54 bundle_free(__bundle);
57 static int __prepare_exec(const char *appid, const char *app_path,
58 const char *pkg_type, int type, const char* pkgid,
59 bool global, bundle *kb)
61 const char *file_name = NULL;
62 char process_name[AUL_PR_NAME] = { 0, };
64 struct buxton_client *bxt_cli;
66 __preexec_run(pkg_type, appid, app_path);
68 ret = _enable_external_pkg(kb, pkgid, global ? GLOBAL_USER : getuid());
73 SECURE_LOGD("[candidata] appid : %s / pkg_type : %s / app_path : %s",
74 appid, pkg_type, app_path);
77 ret = trust_anchor_launch(pkgid, GLOBAL_USER);
79 ret = trust_anchor_launch(pkgid, getuid());
81 if (ret != TRUST_ANCHOR_ERROR_NONE &&
82 ret != TRUST_ANCHOR_ERROR_NOT_INSTALLED) {
83 _E("trust_anchor_launch() returns %d", ret);
87 _W("security_manager_prepare_app ++");
88 ret = security_manager_prepare_app(appid);
89 _W("security_manager_prepare_app --");
90 if (ret != SECURITY_MANAGER_SUCCESS) {
91 _E("Failed to set privileges %s:%d", appid, ret);
95 _send_cmd_to_amd(APP_STARTUP_SIGNAL);
96 _setup_stdio(basename(app_path));
98 ret = buxton_open(&bxt_cli, NULL, NULL);
100 _E("buxton_open() failed, errno(%d)", errno);
103 ret = buxton_update_client_label_sync(bxt_cli);
105 _E("buxton_update_client_label() failed, errno(%d)", errno);
106 buxton_close(bxt_cli);
109 buxton_close(bxt_cli);
112 * SET DUMPABLE - for coredump
113 * This dumpable flag should be set after
114 * calling perm_app_set_privilege().
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, '/');
125 if (file_name == NULL) {
126 _D("file_name is NULL");
131 if (*file_name == '\0') {
132 _D("can't locate file name to execute");
136 memset(process_name, '\0', AUL_PR_NAME);
137 snprintf(process_name, AUL_PR_NAME, "%s", file_name);
138 prctl(PR_SET_NAME, process_name);
140 ret = _wait_tep_mount(kb);
144 ret = _prepare_app_socket();
148 ret = _prepare_id_file();
155 static int __default_launch_cb(bundle *kb, const char *appid,
156 const char *app_path, const char *root_path,
157 const char *pkgid, const char *pkg_type, int loader_type, bool global)
159 char err_str[MAX_LOCAL_BUFSZ] = { 0, };
162 r = __prepare_exec(appid, app_path, pkg_type, loader_type, pkgid,
165 _E("__candidate_process_prepare_exec() failed");
166 if (access(app_path, F_OK | R_OK)) {
167 SECURE_LOGE("access() failed for file: \"%s\", " \
168 "error: %d (%s)", app_path, errno,
169 strerror_r(errno, err_str, sizeof(err_str)));
177 static int __candidate_process_launchpad_main_loop(app_pkt_t *pkt,
178 char *out_app_path, int *out_argc, char ***out_argv, int type)
181 appinfo_t *menu_info = NULL;
182 const char *app_path = NULL;
184 char **tmp_argv = NULL;
188 kb = bundle_decode(pkt->data, pkt->len);
190 _E("bundle decode error");
194 if (__bundle != NULL)
195 bundle_free(__bundle);
198 atexit(__at_exit_to_release_bundle);
200 menu_info = _appinfo_create(kb);
201 if (menu_info == NULL) {
202 _D("such pkg no found");
206 if (menu_info->appid == NULL) {
207 _E("Unable to get app_id");
212 _E("Invalid launchpad type: %d", type);
216 SECURE_LOGD("app id: %s, launchpad type: %d", menu_info->appid, type);
218 app_path = _appinfo_get_app_path(menu_info);
219 if (app_path == NULL) {
220 _E("app_path is NULL");
224 if (app_path[0] != '/') {
225 _E("app_path is not absolute path");
229 _modify_bundle(kb, /*cr.pid - unused parameter*/ 0, menu_info,
232 if (menu_info->pkgid == NULL) {
233 _E("unable to get pkg_id from menu_info");
237 SECURE_LOGD("pkg id: %s", menu_info->pkgid);
239 /* Set environments */
240 _set_env(menu_info, kb);
242 tmp_argv = _create_argc_argv(kb, &tmp_argc);
244 __default_launch_cb(kb, menu_info->appid, app_path,
245 menu_info->root_path, menu_info->pkgid,
246 menu_info->pkg_type, type, menu_info->global);
248 if (__loader_callbacks->launch) {
249 ret = __loader_callbacks->launch(tmp_argc, tmp_argv, app_path,
250 menu_info->appid, menu_info->pkgid,
251 menu_info->pkg_type, __loader_user_data);
254 if (out_app_path != NULL && out_argc != NULL && out_argv != NULL) {
255 memset(out_app_path, '\0', strlen(out_app_path));
256 snprintf(out_app_path, LOADER_ARG_LEN, "%s", app_path);
258 *out_argv = tmp_argv;
259 *out_argc = tmp_argc;
260 (*out_argv)[LOADER_ARG_PATH] = out_app_path;
262 for (i = 0; i < *out_argc; i++) {
263 SECURE_LOGD("input argument %d : %s##", i,
270 if (menu_info != NULL)
271 _appinfo_free(menu_info);
274 bundle_free(__bundle);
281 static void __receiver_cb(int fd)
286 _D("[candidate] ECORE_FD_READ");
287 pkt = _recv_pkt_raw(fd);
289 _D("[candidate] _recv_pkt_raw error!");
293 __loader_adapter->remove_fd(__loader_user_data, fd);
295 ret = __candidate_process_launchpad_main_loop(pkt,
296 __argv[LOADER_ARG_PATH], &__argc, &__argv,
298 SECURE_LOGD("[candidate] real app argv[0]: %s, real app argc: %d",
299 __argv[LOADER_ARG_PATH], __argc);
303 __loader_adapter->loop_quit(__loader_user_data);
304 _D("[candidate] ecore main loop quit");
308 static void __update_lang(keynode_t *node, void *user_data)
310 char *lang = vconf_keynode_get_str(node);
313 setenv("LANG", lang, 1);
316 static int __before_loop(int argc, char **argv)
320 bundle *extra = NULL;
322 if (_verify_proc_caps() < 0)
325 __preexec_init(argc, argv);
327 /* Set new session ID & new process group ID*/
328 /* In linux, child can set new session ID without check permission */
329 /* TODO : should be add to check permission in the kernel*/
332 memset(argv[LOADER_ARG_TYPE], 0, strlen(argv[LOADER_ARG_TYPE]));
333 memset(argv[LOADER_ARG_ID], 0, strlen(argv[LOADER_ARG_ID]));
335 extra = bundle_decode((bundle_raw *)argv[LOADER_ARG_EXTRA],
336 strlen(argv[LOADER_ARG_EXTRA]));
337 memset(argv[LOADER_ARG_EXTRA], 0,
338 strlen(argv[LOADER_ARG_EXTRA]));
341 if (__loader_callbacks->create) {
342 __loader_callbacks->create(extra, __loader_type,
352 client_fd = _connect_to_launchpad(__loader_type, __loader_id);
353 if (client_fd == -1) {
354 _D("Connecting to candidate process was failed.");
358 __loader_adapter->add_fd(__loader_user_data, client_fd, __receiver_cb);
360 if (vconf_notify_key_changed(VCONFKEY_LANGSET, __update_lang, NULL) != 0)
361 _E("vconf_notify_key_changed failed");
366 static int __after_loop(void)
368 vconf_ignore_key_changed(VCONFKEY_LANGSET, __update_lang);
370 if (__loader_callbacks->terminate) {
371 return __loader_callbacks->terminate(__argc, __argv,
378 bundle *launchpad_loader_get_bundle()
383 API int launchpad_loader_main(int argc, char **argv,
384 loader_lifecycle_callback_s *callbacks,
385 loader_adapter_s *adapter, void *user_data)
388 _E("too few argument.");
392 __loader_type = argv[LOADER_ARG_TYPE][0] - '0';
393 if (__loader_type < 0 || __loader_type >= LAUNCHPAD_TYPE_MAX) {
394 _E("invalid argument. (type: %d)", __loader_type);
398 __loader_id = atoi(argv[LOADER_ARG_ID]);
400 if (callbacks == NULL) {
401 _E("invalid argument. callback is null");
405 if (adapter == NULL) {
406 _E("invalid argument. adapter is null");
410 if (adapter->loop_begin == NULL || adapter->loop_quit == NULL
411 || adapter->add_fd == NULL || adapter->remove_fd == NULL) {
412 _E("invalid argument. adapter callback is null");
416 __loader_callbacks = callbacks;
417 __loader_adapter = adapter;
418 __loader_user_data = user_data;
422 if (__before_loop(argc, argv) != 0) {
423 _E("Failed to prepare running loader. type(%d)", __loader_type);
427 _D("[candidate] ecore main loop begin");
428 __loader_adapter->loop_begin(__loader_user_data);
430 return __after_loop();
433 API int launchpad_loader_set_priority(int prio)
435 return _set_priority(prio);