From 59254a4a543a892b0723791d9175c7d5e0d1c712 Mon Sep 17 00:00:00 2001 From: "Junghoon, Park" Date: Wed, 4 Nov 2015 16:16:03 +0900 Subject: [PATCH 2/7] initial release Change-Id: I3a001fa3c414abbaea717ee38af0119c06b32ce6 Signed-off-by: Junghoon, Park --- CMakeLists.txt | 74 ++ LICENSE | 202 +++++ inc/key.h | 41 + inc/launchpad_common.h | 88 +++ inc/menu_db_util.h | 104 +++ inc/perf.h | 62 ++ inc/preexec.h | 182 +++++ inc/preload.h | 163 ++++ inc/process_pool_preload.h | 106 +++ inc/sigchild.h | 234 ++++++ launchpad.manifest | 5 + .../launchpad-process-pool-preload-list.txt | 0 packaging/launchpad-process-pool.service | 10 + packaging/launchpad-process-pool.socket | 10 + packaging/launchpad.spec | 86 +++ packaging/preload_list.txt | 4 + src/launchpad.c | 721 ++++++++++++++++++ src/launchpad_common.c | 665 ++++++++++++++++ src/launchpad_loader.c | 491 ++++++++++++ 19 files changed, 3248 insertions(+) create mode 100755 CMakeLists.txt create mode 100644 LICENSE create mode 100644 inc/key.h create mode 100644 inc/launchpad_common.h create mode 100755 inc/menu_db_util.h create mode 100644 inc/perf.h create mode 100755 inc/preexec.h create mode 100644 inc/preload.h create mode 100644 inc/process_pool_preload.h create mode 100644 inc/sigchild.h create mode 100644 launchpad.manifest create mode 100644 packaging/launchpad-process-pool-preload-list.txt create mode 100644 packaging/launchpad-process-pool.service create mode 100644 packaging/launchpad-process-pool.socket create mode 100644 packaging/launchpad.spec create mode 100644 packaging/preload_list.txt create mode 100755 src/launchpad.c create mode 100644 src/launchpad_common.c create mode 100644 src/launchpad_loader.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 00000000..b36e0baf --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,74 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +SET (this_target launchpad) + +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(${this_target} REQUIRED + dlog + ecore + elementary + libsystemd-daemon + dbus-glib-1 + vconf + security-manager + bundle + ) + +FOREACH(flag ${${this_target}_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" ) +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fdata-sections -ffunction-sections -Wl,--gc-sections") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -D_FILE_OFFSET_BITS=64") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_C_FLAGS_RELEASE "-O2") +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") +SET(CMAKE_SKIP_BUILD_RPATH TRUE) + +ADD_DEFINITIONS("-DSHARE_PREFIX=\"/usr/share/aul\"") +IF(_APPFW_FEATURE_PRIORITY_CHANGE) + ADD_DEFINITIONS("-D_APPFW_FEATURE_PRIORITY_CHANGE") +ENDIF(_APPFW_FEATURE_PRIORITY_CHANGE) + +ADD_DEFINITIONS("-DLAUNCHPAD_LOG") +ADD_DEFINITIONS("-DPRELOAD_ACTIVATE") +ADD_DEFINITIONS("-DPREEXEC_ACTIVATE") +#ADD_DEFINITIONS("-DPERF_ACTIVATE") + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc) + +SET(LAUNCHPAD_LOADER "launchpad-loader") +SET(${LAUNCHPAD_LOADER}_SOURCE_FILES + src/launchpad_loader.c + src/launchpad_common.c + ) +ADD_EXECUTABLE(${LAUNCHPAD_LOADER} ${${LAUNCHPAD_LOADER}_SOURCE_FILES}) + +TARGET_LINK_LIBRARIES(${LAUNCHPAD_LOADER} "-ldl") +TARGET_LINK_LIBRARIES(${LAUNCHPAD_LOADER} ${${this_target}_LDFLAGS} "-pie") + +SET_TARGET_PROPERTIES(${LAUNCHPAD_LOADER} + PROPERTIES SKIP_BUILD_RPATH TRUE + ) # remove rpath option that is automatically generated by cmake. +INSTALL(TARGETS ${LAUNCHPAD_LOADER} DESTINATION bin) + +SET(LAUNCHPAD_PROCESS_POOL "launchpad-process-pool") + +SET(${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES + src/launchpad.c + src/launchpad_common.c + ) +ADD_EXECUTABLE(${LAUNCHPAD_PROCESS_POOL} ${${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES}) + +TARGET_LINK_LIBRARIES(${LAUNCHPAD_PROCESS_POOL} ${${this_target}_LDFLAGS} "-pie") + +SET_TARGET_PROPERTIES(${LAUNCHPAD_PROCESS_POOL} + PROPERTIES SKIP_BUILD_RPATH TRUE + ) # remove rpath option that is automatically generated by cmake. + +INSTALL(TARGETS ${LAUNCHPAD_PROCESS_POOL} DESTINATION bin) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/packaging/launchpad-process-pool-preload-list.txt DESTINATION share/aul) + diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/inc/key.h b/inc/key.h new file mode 100644 index 00000000..d2e5e2f1 --- /dev/null +++ b/inc/key.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __KEY_H__ +#define __KEY_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define AUL_K_STARTTIME "__AUL_STARTTIME__" +#define AUL_K_EXEC "__AUL_EXEC__" +#define AUL_K_PACKAGETYPE "__AUL_PACKAGETYPE__" +#define AUL_K_HWACC "__AUL_HWACC__" +#define AUL_K_APPID "__AUL_APPID__" +#define AUL_K_PID "__AUL_PID__" +#define AUL_K_TASKMANAGE "__AUL_TASKMANAGE__" +#define AUL_K_INTERNAL_POOL "__AUL_INTERNAL_POOL__" +#define AUL_K_PKGID "__AUL_PKGID_" +#define AUL_K_DEBUG "__AUL_DEBUG__" +#define AUL_K_PRIVACY_APPID "__AUL_PRIVACY_APPID__" + +#ifdef __cplusplus +} +#endif + +#endif /* __KEY_H__ */ + diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h new file mode 100644 index 00000000..7fa81cdd --- /dev/null +++ b/inc/launchpad_common.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LAUNCHPAD_COMMON__ +#define __LAUNCHPAD_COMMON__ + +#include +#include +#include +#include +#ifndef __USE_GNU + #define __USE_GNU +#endif +#include +#include + +#include "menu_db_util.h" + +#ifdef LAUNCHPAD_LOG +#undef LOG_TAG +#define LOG_TAG "LAUNCHPAD" +#endif + +#define MAX_LOCAL_BUFSZ 128 +#define AUL_SOCK_MAXBUFF 65535 + +#define _E(fmt, arg...) LOGE(fmt, ##arg) +#define _D(fmt, arg...) LOGD(fmt, ##arg) +#define _W(fmt, arg...) LOGW(fmt, ##arg) + +#define retvm_if(expr, val, fmt, arg...) do { \ + if (expr) { \ + _E(fmt, ##arg); \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ +} while (0) + +#define retv_if(expr, val) do { \ + if (expr) { \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ +} while (0) + +typedef struct _app_pkt_t { + int cmd; + int len; + unsigned char data[1]; +} app_pkt_t; + +enum LAUNCHPAD_TYPE { + LAUNCHPAD_TYPE_UNSUPPORTED = -1, + LAUNCHPAD_TYPE_COMMON, + LAUNCHPAD_TYPE_SW, + LAUNCHPAD_TYPE_HW, + LAUNCHPAD_TYPE_MAX +}; + +char *_proc_get_cmdline_bypid(int pid); +app_info_from_db *_get_app_info_from_bundle_by_pkgname(const char *pkgname, bundle *kb); +void _modify_bundle(bundle * kb, int caller_pid, app_info_from_db * menu_info, int cmd); + +int _create_server_sock(int pid); +app_pkt_t *_recv_pkt_raw(int fd, int *clifd, struct ucred *cr); +int _send_pkt_raw(int client_fd, app_pkt_t *pkt); +int _listen_candidate_process(int type); +int _connect_to_launchpad(int type); +int _accept_candidate_process(int server_fd, int* out_client_fd, int* out_client_pid); +void _refuse_candidate_process(int server_fd); +void _set_oom(void); +void _set_env(app_info_from_db * menu_info, bundle * kb); +char** _create_argc_argv(bundle * kb, int *margc); + +#endif diff --git a/inc/menu_db_util.h b/inc/menu_db_util.h new file mode 100755 index 00000000..2b190256 --- /dev/null +++ b/inc/menu_db_util.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __MENU_DB_UTIL_H_ +#define __MENU_DB_UTIL_H_ + +#include +#include +#include + +#define MAX_PATH_LEN 1024 + +typedef struct { + char *pkg_name; /* appid */ + char *app_path; /* exec */ + char *original_app_path; /* exec */ + char *pkg_type; /* x_slp_packagetype */ + char *hwacc; /* hwacceleration */ + char *taskmanage; /* taskmanage */ + char *pkg_id; +} app_info_from_db; + +static inline char *_get_pkgname(app_info_from_db *menu_info) +{ + return menu_info ? menu_info->pkg_name : NULL; +} + +static inline char *_get_pkgid(app_info_from_db *menu_info) +{ + return menu_info ? menu_info->pkg_id : NULL; +} + +static inline char *_get_app_path(app_info_from_db *menu_info) +{ + int i = 0; + int path_len = -1; + + if (!menu_info || menu_info->app_path == NULL) + return NULL; + + while (menu_info->app_path[i] != 0) { + if (menu_info->app_path[i] == ' ' + || menu_info->app_path[i] == '\t') { + path_len = i; + break; + } + i++; + } + + if (path_len == 0) { + free(menu_info->app_path); + menu_info->app_path = NULL; + } else if (path_len > 0) { + char *tmp_app_path = malloc(sizeof(char) * (path_len + 1)); + if(tmp_app_path == NULL) + return NULL; + snprintf(tmp_app_path, path_len + 1, "%s", menu_info->app_path); + free(menu_info->app_path); + menu_info->app_path = tmp_app_path; + } + + return menu_info->app_path; +} + +static inline char *_get_original_app_path(app_info_from_db *menu_info) +{ + return menu_info ? menu_info->original_app_path : NULL; +} + +static inline void _free_app_info_from_db(app_info_from_db *menu_info) +{ + if (menu_info != NULL) { + if (menu_info->pkg_name != NULL) + free(menu_info->pkg_name); + if (menu_info->app_path != NULL) + free(menu_info->app_path); + if (menu_info->original_app_path != NULL) + free(menu_info->original_app_path); + if (menu_info->pkg_type != NULL) + free(menu_info->pkg_type); + if (menu_info->hwacc != NULL) + free(menu_info->hwacc); + if (menu_info->taskmanage != NULL) + free(menu_info->taskmanage); + if (menu_info->pkg_id != NULL) + free(menu_info->pkg_id); + free(menu_info); + } +} + +#endif diff --git a/inc/perf.h b/inc/perf.h new file mode 100644 index 00000000..1dd847f3 --- /dev/null +++ b/inc/perf.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PERF_H__ +#define __PERF_H__ + +#ifdef PERF_ACTIVATE + +#include +static struct timeval __g_base_time = { + .tv_sec = 0, + .tv_usec = 0 +}; + +#define INIT_PERF(kb)\ +do {\ + const char *tmp;\ + struct timeval tv;\ + tmp = bundle_get_val(kb, AUL_K_STARTTIME);\ + if (tmp != NULL)\ + sscanf(tmp, "%ld/%ld", &tv.tv_sec, &tv.tv_usec);\ + else\ + gettimeofday(&tv, NULL);\ + __g_base_time.tv_sec = tv.tv_sec;\ + __g_base_time.tv_usec = tv.tv_usec;\ +} while (0); + +#define PERF(fmt, arg...)\ +do {\ + struct timeval cur;\ + struct timeval res;\ + gettimeofday(&cur, NULL);\ + if (__g_base_time.tv_sec != 0) {\ + timersub(&cur, &__g_base_time, &res);\ + printf("%c[1;31m[%s,%d] %ld sec %ld msec "fmt" %c[0m\n",\ + 27, __FUNCTION__, __LINE__, \ + res.tv_sec, res.tv_usec/1000, ##arg, 27);\ + } \ +} while (0); + +#else + +#define INIT_PERF(kb) +#define PERF(fmt, arg...) + +#endif + +#endif + diff --git a/inc/preexec.h b/inc/preexec.h new file mode 100755 index 00000000..98de3c61 --- /dev/null +++ b/inc/preexec.h @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef PREEXEC_ACTIVATE + +#include +#include +#define PREEXEC_FILE SHARE_PREFIX"/preexec_list.txt" + +static int preexec_initialized = 0; + +GSList *preexec_list = NULL; + +typedef struct _preexec_list_t { + char *pkg_type; + char *so_path; + int (*dl_do_pre_exe) (char *, char *); +} preexec_list_t; + +static void __preexec_list_free() +{ + GSList *iter = NULL; + preexec_list_t *type_t; + + for (iter = preexec_list; iter != NULL; iter = g_slist_next(iter)) { + type_t = iter->data; + if (type_t) { + if (type_t->pkg_type) + free(type_t->pkg_type); + if (type_t->so_path) + free(type_t->so_path); + free(type_t); + } + } + g_slist_free(preexec_list); + preexec_initialized = 0; + return; +} + +static inline void __preexec_init(int argc, char **argv) +{ + void *handle = NULL; + FILE *preexec_file; + char *saveptr = NULL; + char line[MAX_LOCAL_BUFSZ]; + char *type = NULL; + char *sopath = NULL; + char *symbol = NULL; + int (*func) (char *, char *) = NULL; + preexec_list_t *type_t = NULL; + + preexec_file = fopen(PREEXEC_FILE, "rt"); + if (preexec_file == NULL) { + _E("no preexec\n"); + return; + } + + _D("preexec start\n"); + + while (fgets(line, MAX_LOCAL_BUFSZ, preexec_file) > 0) { + /* Parse each line */ + if (line[0] == '#' || line[0] == '\0') + continue; + + type = strtok_r(line, ":\f\n\r\t\v ", &saveptr); + if (type == NULL) + continue; + sopath = strtok_r(NULL, ",\f\n\r\t\v ", &saveptr); + if (sopath == NULL) + continue; + symbol = strtok_r(NULL, ",\f\n\r\t\v ", &saveptr); + if (symbol == NULL) + continue; + + type_t = (preexec_list_t *) calloc(1, sizeof(preexec_list_t)); + if (type_t == NULL) { + _E("no available memory\n"); + __preexec_list_free(); + fclose(preexec_file); + return; + } + + handle = dlopen(sopath, RTLD_GLOBAL | RTLD_LAZY); + if (handle == NULL) { + free(type_t); + continue; + } + _D("preexec %s %s# - handle : %x\n", type, sopath, handle); + + func = dlsym(handle, symbol); + if (func == NULL) { + _E("failed to get symbol type:%s path:%s\n", + type, sopath); + free(type_t); + dlclose(handle); + handle = NULL; + continue; + } + + type_t->pkg_type = strdup(type); + if (type_t->pkg_type == NULL) { + _E("no available memory\n"); + free(type_t); + __preexec_list_free(); + fclose(preexec_file); + return; + } + type_t->so_path = strdup(sopath); + if (type_t->so_path == NULL) { + _E("no available memory\n"); + free(type_t->pkg_type); + free(type_t); + __preexec_list_free(); + fclose(preexec_file); + return; + } + type_t->dl_do_pre_exe = func; + + preexec_list = g_slist_append(preexec_list, (void *)type_t); + } + + fclose(preexec_file); + preexec_initialized = 1; +} + +static inline void __preexec_run(const char *pkg_type, const char *pkg_name, + const char *app_path) +{ + GSList *iter = NULL; + preexec_list_t *type_t; + + if (!preexec_initialized || !pkg_type) + return; + + for (iter = preexec_list; iter != NULL; iter = g_slist_next(iter)) { + type_t = iter->data; + if (type_t) { + if (!strcmp(pkg_type, type_t->pkg_type)) { + if (type_t->dl_do_pre_exe != NULL) { + type_t->dl_do_pre_exe((char *)pkg_name, + (char *)app_path); + _D("called dl_do_pre_exe() type: %s", + pkg_type); + } else { + _E("no symbol for this type: %s", + pkg_type); + } + } + } + } + +} + +#else + +static void __preexec_list_free() +{ +} + +static inline void __preexec_init(int argc, char **argv) +{ +} + +static inline void __preexec_run(const char *pkg_type, const char *pkg_name, + const char *app_path) +{ +} + +#endif diff --git a/inc/preload.h b/inc/preload.h new file mode 100644 index 00000000..eb1e9edc --- /dev/null +++ b/inc/preload.h @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#ifdef PRELOAD_ACTIVATE + +#include +#define PRELOAD_FILE SHARE_PREFIX"/preload_list.txt" + +#define EFL_PREINIT_FUNC "elm_quicklaunch_init" +#define EFL_SHUTDOWN_FUNC "elm_quicklaunch_shutdown" + +static int preload_initialized = 0; +static int g_argc; +static char **g_argv; +static int max_cmdline_size = 0; + +static int (*dl_einit) () = NULL; +static int (*dl_efini) () = NULL; + +static inline void __preload_init(int argc, char **argv) +{ + void *handle = NULL; + char soname[MAX_LOCAL_BUFSZ]; + FILE *preload_list; + int (*func)() = NULL; + int i; + + g_argc = argc; + g_argv = argv; + for (i = 0; i < argc; i++) { + max_cmdline_size += (strlen(argv[i]) + 1); + } + _D("max_cmdline_size = %d", max_cmdline_size); + + preload_list = fopen(PRELOAD_FILE, "rt"); + if (preload_list == NULL) { + _E("no preload\n"); + return; + } + + while (fgets(soname, MAX_LOCAL_BUFSZ, preload_list) > 0) { + soname[strlen(soname) - 1] = 0; + handle = dlopen((const char *) soname, RTLD_NOW); + if (handle == NULL) + continue; + _D("preload %s# - handle : %x\n", soname, handle); + + func = dlsym(handle, EFL_PREINIT_FUNC); + if (func != NULL) { + _D("get pre-initialization function\n"); + dl_einit = func; + func = dlsym(handle, EFL_SHUTDOWN_FUNC); + if (func != NULL) { + _D("get shutdown function\n"); + dl_efini = func; + } + } + } + + fclose(preload_list); + preload_initialized = 1; +} + +static inline int preinit_init() +{ + if (dl_einit != NULL) + dl_einit(0, NULL); + _D("pre-initialzation on"); + return 0; +} + +static inline int preinit_fini() +{ + if (dl_efini != NULL) + dl_efini(); + _D("pre-initialization off"); + return 0; +} + +/* TODO : how to set cmdline gracefully ?? */ +static inline int __change_cmdline(char *cmdline) +{ + if (strlen(cmdline) > max_cmdline_size + 1) { + _E("cmdline exceed max size : %d", max_cmdline_size); + return -1; + } + + memset(g_argv[0], '\0', max_cmdline_size); + snprintf(g_argv[0], max_cmdline_size, "%s", cmdline); + + return 0; +} + +static inline void __preload_exec(int argc, char **argv) +{ + void *handle = NULL; + int (*dl_main) (int, char **); + char *error = NULL; + + if (!preload_initialized) + return; + + handle = dlopen(argv[0], RTLD_LAZY | RTLD_GLOBAL); + if (handle == NULL) { + _E("dlopen(\"%s\") failed", argv[0]); + if ((error = dlerror()) != NULL) { + _E("dlopen error: %s", error); + } + return; + } + + dlerror(); + + dl_main = dlsym(handle, "main"); + if (dl_main != NULL) { + if (__change_cmdline(argv[0]) < 0) { + _E("change cmdline fail"); + dlclose(handle); + return; + } + +#ifdef _APPFW_FEATURE_PRIORITY_CHANGE + int res = setpriority(PRIO_PROCESS, 0, 0); + if (res == -1) + { + SECURE_LOGE("Setting process (%d) priority to 0 failed, errno: %d (%s)", + getpid(), errno, strerror(errno)); + } +#endif + dl_main(argc, argv); + } else { + _E("dlsym not founded. bad preloaded app - check fpie pie"); + if ((error = dlerror()) != NULL) { + _E("dlsym error: %s", error); + } + dlclose(handle); + return; + } + + exit(0); +} + +#else + +static inline void __preload_init(); +static inline void __preload_exec(int argc, char **argv); + +#endif + diff --git a/inc/process_pool_preload.h b/inc/process_pool_preload.h new file mode 100644 index 00000000..d2b1d418 --- /dev/null +++ b/inc/process_pool_preload.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __PROCESS_POOL_PRELOAD_H__ +#define __PROCESS_POOL_PRELOAD_H__ + +#include +#include +#include +#include + +#define PROCESS_POOL_PRELOAD_FILE SHARE_PREFIX"/launchpad-process-pool-preload-list.txt" + +static int g_dlopen_size = 5; +static int g_dlopen_count = 0; +static void** g_dlopen_handle_list = NULL; + +static inline int __preload_save_dlopen_handle(void *handle) +{ + if (!handle) + return 1; + + if (g_dlopen_count == g_dlopen_size || !g_dlopen_handle_list) { + void** tmp = + realloc(g_dlopen_handle_list, 2 * g_dlopen_size * sizeof(void *)); + if (NULL == tmp) { + _E("out of memory\n"); + dlclose(handle); + return 1; + } + g_dlopen_size *= 2; + g_dlopen_handle_list = tmp; + } + g_dlopen_handle_list[g_dlopen_count++] = handle; + return 0; +} + +static inline void __preload_fini_for_process_pool(void) +{ + int i = 0; + if (!g_dlopen_handle_list) + return; + + for (i = 0; i < g_dlopen_count; ++i) { + void *handle = g_dlopen_handle_list[i]; + if (handle) { + if (0 != dlclose(handle)) + _E("dlclose failed\n"); + } + } + free(g_dlopen_handle_list); + g_dlopen_handle_list = NULL; + g_dlopen_size = 5; + g_dlopen_count = 0; +} + +static inline void __preload_init_for_process_pool(void) +{ + if (atexit(__preload_fini_for_process_pool) != 0) + _E("Cannot register atexit callback. Libraries will not be unloaded"); + + void *handle = NULL; + char soname[MAX_LOCAL_BUFSZ] = { 0, }; + FILE *preload_list = NULL; + + preload_list = fopen(PROCESS_POOL_PRELOAD_FILE, "rt"); + if (preload_list == NULL) { + _E("no preload\n"); + return; + } + + while (fgets(soname, MAX_LOCAL_BUFSZ, preload_list) > 0) { + size_t len = strnlen(soname, MAX_LOCAL_BUFSZ); + if (len > 0) + soname[len - 1] = '\0'; + + handle = dlopen((const char *) soname, RTLD_NOW); + if (handle == NULL) { + _E("dlopen(\"%s\") was failed!", soname); + continue; + } + + if (__preload_save_dlopen_handle(handle) != 0) { + _E("Cannot save handle, no more preloads"); + break; + } + _D("preload %s# - handle : %x\n", soname, handle); + } + + fclose(preload_list); +} + +#endif //__PROCESS_POOL_PRELOAD_H__ diff --git a/inc/sigchild.h b/inc/sigchild.h new file mode 100644 index 00000000..1c93d727 --- /dev/null +++ b/inc/sigchild.h @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#define AUL_DBUS_PATH "/aul/dbus_handler" +#define AUL_DBUS_SIGNAL_INTERFACE "org.tizen.aul.signal" +#define AUL_DBUS_APPDEAD_SIGNAL "app_dead" +#define AUL_DBUS_APPLAUNCH_SIGNAL "app_launch" + +static DBusConnection *bus = NULL; +static sigset_t oldmask; + +static inline void __socket_garbage_collector() +{ + DIR *dp; + struct dirent *dentry; + char tmp[MAX_LOCAL_BUFSZ]; + + snprintf(tmp, sizeof(tmp), "/run/user/%d", getuid()); + dp = opendir(tmp); + if (dp == NULL) + return; + + while ((dentry = readdir(dp)) != NULL) { + if (!isdigit(dentry->d_name[0])) + continue; + + snprintf(tmp, MAX_LOCAL_BUFSZ, "/proc/%s", dentry->d_name); + if (access(tmp, F_OK) < 0) { /* Flawfinder: ignore */ + snprintf(tmp, MAX_LOCAL_BUFSZ, "/run/user/%d/%s", getuid(), + dentry->d_name); + unlink(tmp); + continue; + } + } + closedir(dp); +} + +static inline int __send_app_dead_signal_dbus(int dead_pid) +{ + DBusMessage *message; + + // send over session dbus for other applications + if (bus == NULL) + return -1; + + message = dbus_message_new_signal(AUL_DBUS_PATH, + AUL_DBUS_SIGNAL_INTERFACE, + AUL_DBUS_APPDEAD_SIGNAL); + + if (dbus_message_append_args(message, + DBUS_TYPE_UINT32, &dead_pid, + DBUS_TYPE_INVALID) == FALSE) { + _E("Failed to load data error"); + return -1; + } + + if (dbus_connection_send(bus, message, NULL) == FALSE) { + _E("dbus send error"); + return -1; + } + + dbus_connection_flush(bus); + dbus_message_unref(message); + + _D("send_app_dead_signal_dbus done (pid=%d)\n",dead_pid); + + return 0; +} + +static inline int __send_app_launch_signal_dbus(int launch_pid) +{ + DBusMessage *message; + + if (bus == NULL) + return -1; + + message = dbus_message_new_signal(AUL_DBUS_PATH, + AUL_DBUS_SIGNAL_INTERFACE, + AUL_DBUS_APPLAUNCH_SIGNAL); + + if (dbus_message_append_args(message, + DBUS_TYPE_UINT32, &launch_pid, + DBUS_TYPE_INVALID) == FALSE) { + _E("Failed to load data error"); + return -1; + } + + if (dbus_connection_send(bus, message, NULL) == FALSE) { + _E("dbus send error"); + return -1; + } + + dbus_connection_flush(bus); + dbus_message_unref(message); + + _D("send_app_launch_signal_dbus done (pid=%d)",launch_pid); + + return 0; +} + +static int __sigchild_action(void *data) +{ + pid_t dead_pid; + char buf[MAX_LOCAL_BUFSZ]; + + dead_pid = (pid_t)(intptr_t)data; + if (dead_pid <= 0) + goto end; + + __send_app_dead_signal_dbus(dead_pid); + + snprintf(buf, MAX_LOCAL_BUFSZ, "/run/user/%d/%d", getuid(), dead_pid); + unlink(buf); + + __socket_garbage_collector(); + end: + return 0; +} + +static void __launchpad_process_sigchld(struct signalfd_siginfo *info) +{ + int status; + pid_t child_pid; + pid_t child_pgid; + + child_pgid = getpgid(info->ssi_pid); + _D("dead_pid = %d pgid = %d", info->ssi_pid, child_pgid); + + while ((child_pid = waitpid(-1, &status, WNOHANG)) > 0) { + if (child_pid == child_pgid) + killpg(child_pgid, SIGKILL); + __sigchild_action((void *)(intptr_t)child_pid); + } + + return; +} + +static inline int __signal_init(void) +{ + int i; + DBusError error; + + dbus_error_init(&error); + dbus_threads_init_default(); + bus = dbus_bus_get_private(DBUS_BUS_SESSION, &error); + if (!bus) { + _E("Failed to connect to the D-BUS daemon: %s", error.message); + dbus_error_free(&error); + return -1; + } + + for (i = 0; i < _NSIG; i++) { + switch (i) { + /* controlled by sys-assert package*/ + case SIGQUIT: + case SIGILL: + case SIGABRT: + case SIGBUS: + case SIGFPE: + case SIGSEGV: + case SIGPIPE: + break; + default: + signal(i, SIG_DFL); + break; + } + } + + return 0; +} + +static inline int __signal_get_sigchld_fd(void) +{ + sigset_t mask; + int sfd; + + sigemptyset(&mask); + sigaddset(&mask, SIGCHLD); + + if (sigprocmask(SIG_BLOCK, &mask, &oldmask) == -1) + _E("failed to sigprocmask"); + + sfd = signalfd(-1, &mask, SFD_NONBLOCK | SFD_CLOEXEC); + if (sfd == -1) { + _E("failed to create signal for SIGCHLD"); + return -1; + } + + return sfd; +} + +static inline int __signal_unblock_sigchld(void) +{ + if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0) { + _E("SIG_SETMASK error"); + return -1; + } + + _D("SIGCHLD unblocked"); + return 0; +} + +static inline int __signal_fini(void) +{ + if (bus) + dbus_connection_close(bus); + +#ifndef PRELOAD_ACTIVATE + int i; + for (i = 0; i < _NSIG; i++) + signal(i, SIG_DFL); +#endif + return 0; +} + diff --git a/launchpad.manifest b/launchpad.manifest new file mode 100644 index 00000000..97e8c313 --- /dev/null +++ b/launchpad.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/launchpad-process-pool-preload-list.txt b/packaging/launchpad-process-pool-preload-list.txt new file mode 100644 index 00000000..e69de29b diff --git a/packaging/launchpad-process-pool.service b/packaging/launchpad-process-pool.service new file mode 100644 index 00000000..0667cd51 --- /dev/null +++ b/packaging/launchpad-process-pool.service @@ -0,0 +1,10 @@ +# +# Systemd script to Launch AMD Session agent +# + +[Unit] +Description=Start the USER Access Control Agent + +[Service] +ExecStart=/bin/sh -l -c "/usr/bin/launchpad-process-pool" +Sockets=launchpad-process-pool.socket diff --git a/packaging/launchpad-process-pool.socket b/packaging/launchpad-process-pool.socket new file mode 100644 index 00000000..611fcc74 --- /dev/null +++ b/packaging/launchpad-process-pool.socket @@ -0,0 +1,10 @@ +[Socket] +ListenStream=/run/user/%U/-5 +ListenStream=/run/user/%U/.launchpad-type0 +ListenStream=/run/user/%U/.launchpad-type1 +ListenStream=/run/user/%U/.launchpad-type2 + +Service=launchpad-process-pool.service + +[Install] +WantedBy=sockets.target diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec new file mode 100644 index 00000000..b0ac4ccb --- /dev/null +++ b/packaging/launchpad.spec @@ -0,0 +1,86 @@ +Name: launchpad +Summary: Launchpad for launching applications +Version: 0.2.3.14 +Release: 1 +Group: Application Framework/Daemons +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +Source101: launchpad-process-pool.service +Source102: launchpad-process-pool.socket + + +BuildRequires: cmake +BuildRequires: pkgconfig(bundle) +BuildRequires: pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(sqlite3) +BuildRequires: pkgconfig(ecore) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(libsystemd-daemon) +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(security-manager) + +Requires(post): /sbin/ldconfig +Requires(post): /usr/bin/systemctl +Requires(postun): /sbin/ldconfig +Requires(postun): /usr/bin/systemctl +Requires(preun): /usr/bin/systemctl + +%define appfw_feature_priority_change 0 + +%description +Launchpad for launching applications + +%package devel +Summary: Launchpad for launching applications (devel) +Group: Development/Libraries +Requires: %{name} = %{version}-%{release} + +%description devel +Launchpad for launching applications (devel) + +%prep +%setup -q + +%build +%if 0%{?sec_build_binary_debug_enable} +export CFLAGS="$CFLAGS -DTIZEN_DEBUG_ENABLE" +export CXXFLAGS="$CXXFLAGS -DTIZEN_DEBUG_ENABLE" +export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" +%endif +%if 0%{?appfw_feature_priority_change} +_APPFW_FEATURE_PRIORITY_CHANGE=ON +%endif + +cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} \ + -D_APPFW_FEATURE_PRIORITY_CHANGE:BOOL=${_APPFW_FEATURE_PRIORITY_CHANGE} + +make %{?jobs:-j%jobs} + +%install +rm -rf %{buildroot} + +%make_install +mkdir -p %{buildroot}%{_unitdir_user}/default.target.wants +mkdir -p %{buildroot}%{_unitdir_user}/sockets.target.wants +install -m 0644 %SOURCE101 %{buildroot}%{_unitdir_user}/launchpad-process-pool.service +install -m 0644 %SOURCE102 %{buildroot}%{_unitdir_user}/launchpad-process-pool.socket +ln -sf ../launchpad-process-pool.socket %{buildroot}%{_unitdir_user}/sockets.target.wants/launchpad-process-pool.socket +ln -sf ../launchpad-process-pool.service %{buildroot}%{_unitdir_user}/default.target.wants/launchpad-process-pool.service + +mkdir -p %{buildroot}/usr/share/license +cp %{_builddir}/%{name}-%{version}/LICENSE %{buildroot}/usr/share/license/%{name} + +%post + +%files +%manifest launchpad.manifest +%{_prefix}/share/license/%{name} +%{_prefix}/share/aul/launchpad-process-pool-preload-list.txt +%{_unitdir_user}/launchpad-process-pool.service +%{_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_mac_override,cap_setgid=ei) %{_bindir}/launchpad-process-pool +%caps(cap_mac_admin,cap_mac_override,cap_setgid=ei) %{_bindir}/launchpad-loader + diff --git a/packaging/preload_list.txt b/packaging/preload_list.txt new file mode 100644 index 00000000..3ccda07f --- /dev/null +++ b/packaging/preload_list.txt @@ -0,0 +1,4 @@ +/usr/lib/libappcore-efl.so.1 +/usr/lib/libappcore-common.so.1 +/usr/lib/libcapi-appfw-application.so.0 +/usr/lib/ecore/immodules/libisf-imf-module.so diff --git a/src/launchpad.c b/src/launchpad.c new file mode 100755 index 00000000..129cc202 --- /dev/null +++ b/src/launchpad.c @@ -0,0 +1,721 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "perf.h" +#include "launchpad_common.h" +#include "sigchild.h" +#include "key.h" + +#define AUL_PR_NAME 16 +#define AUL_POLL_CNT 15 +#define EXEC_CANDIDATE_EXPIRED 5 +#define EXEC_CANDIDATE_WAIT 1 +#define DIFF(a,b) (((a)>(b))?(a)-(b):(b)-(a)) +#define CANDIDATE_NONE 0 +#define PROCESS_POOL_LAUNCHPAD_PID -5 + +typedef struct { + int pid; + int send_fd; + int last_exec_time; +} candidate; + +enum { + LAUNCH_PAD = 0, + POOL_TYPE = 1, + CANDIDATE_TYPE = LAUNCHPAD_TYPE_MAX + 1, + SIGCHLD_FD = LAUNCHPAD_TYPE_MAX * 2 + 1, + POLLFD_MAX = LAUNCHPAD_TYPE_MAX * 2 + 2 +}; + +static int initialized = 0; +static candidate __candidate[LAUNCHPAD_TYPE_MAX] = { + { CANDIDATE_NONE, -1, 0 }, + { CANDIDATE_NONE, -1, 0 } +}; +static int launchpad_fd = -1; +static int pool_fd[LAUNCHPAD_TYPE_MAX] = { -1, -1, -1 }; + +static int __set_access(const char* appId, const char* pkg_type, + const char* app_path) +{ + return security_manager_prepare_app(appId) == SECURITY_MANAGER_SUCCESS ? 0 : -1; +} + +static int __get_launchpad_type(const char* internal_pool, const char* hwacc) +{ + if (internal_pool && strncmp(internal_pool, "true", 4) == 0 && hwacc) { + if (strncmp(hwacc, "NOT_USE", 7) == 0) { + _D("[launchpad] launchpad type: S/W(%d)", LAUNCHPAD_TYPE_SW); + return LAUNCHPAD_TYPE_SW; + } + if (strncmp(hwacc, "USE", 3) == 0) { + _D("[launchpad] launchpad type: H/W(%d)", LAUNCHPAD_TYPE_HW); + return LAUNCHPAD_TYPE_HW; + } + /* TODO: FIXME + if (strncmp(hwacc, "SYS", 3) == 0) { + int r; + int sys_hwacc = -1; + + r = vconf_get_int(VCONFKEY_SETAPPL_APP_HW_ACCELERATION, &sys_hwacc); + if (r != VCONF_OK) + _E("failed to get vconf int: %s", VCONFKEY_SETAPPL_APP_HW_ACCELERATION); + + SECURE_LOGD("sys hwacc: %d", sys_hwacc); + + if (sys_hwacc == SETTING_HW_ACCELERATION_ON) { + _D("[launchpad] launchpad type: H/W(%d)", LAUNCHPAD_TYPE_HW); + return LAUNCHPAD_TYPE_HW; + } + if (sys_hwacc == SETTING_HW_ACCELERATION_OFF) { + _D("[launchpad] launchpad type: S/W(%d)", LAUNCHPAD_TYPE_SW); + return LAUNCHPAD_TYPE_SW; + } + }*/ + } + + _D("[launchpad] launchpad type: COMMON(%d)", LAUNCHPAD_TYPE_COMMON); + return LAUNCHPAD_TYPE_COMMON; +} + +static int __candidate_process_real_launch(int candidate_fd, app_pkt_t *pkt) +{ + return _send_pkt_raw(candidate_fd, pkt); +} + +static int __real_send(int clifd, int ret) +{ + if (send(clifd, &ret, sizeof(int), MSG_NOSIGNAL) < 0) { + if (errno == EPIPE) { + _E("send failed due to EPIPE.\n"); + close(clifd); + return -1; + } + _E("send fail to client"); + } + + close(clifd); + return 0; +} + +static void __send_result_to_caller(int clifd, int ret, const char* app_path) +{ + char *cmdline; + int wait_count; + int cmdline_changed = 0; + int cmdline_exist = 0; + int r; + + _W("Check app launching"); + + if (clifd == -1) + return; + + if (ret <= 1) { + _E("launching failed"); + __real_send(clifd, ret); + return; + } + /* check normally was launched?*/ + wait_count = 1; + do { + cmdline = _proc_get_cmdline_bypid(ret); + if (cmdline == NULL) { + _E("error founded when being launched with %d", ret); + if (cmdline_exist || cmdline_changed) { + _E("The app process might be terminated while we are wating %d", ret); + break; + } + } else if (strcmp(cmdline, app_path) == 0) { + /* Check app main loop is prepared or not */ + _D("-- now wait app mainloop creation --"); + free(cmdline); + cmdline_changed = 1; + + char sock_path[UNIX_PATH_MAX] = { 0, }; + snprintf(sock_path, UNIX_PATH_MAX, "/run/user/%d/%d", getuid(), ret); + if (access(sock_path, F_OK) == 0) + break; + + } else { + _D("-- now wait cmdline changing --"); + cmdline_exist = 1; + free(cmdline); + } + usleep(100 * 1000); /* 100ms sleep*/ + wait_count++; + + } while (wait_count <= 50); /* max 100*50ms will be sleep*/ + + if ((!cmdline_exist) && (!cmdline_changed)) { + __real_send(clifd, -1); /* abnormally launched*/ + return; + } + + if (!cmdline_changed) + _E("process launched, but cmdline not changed"); + + if (__real_send(clifd, ret) < 0) { + r = kill(ret, SIGKILL); + if (r == -1) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + _E("send SIGKILL: %s", strerror_r(errno, err_str, sizeof(err_str))); + } + } + + return; +} + +static void __prepare_candidate_process(int type) +{ + int pid; + + __candidate[type].last_exec_time = time(NULL); + pid = fork(); + + if (pid == 0) { /* child */ + char type_str[2] = {0,}; + + /* execute with very long (1024 bytes) argument in order to prevent argv overflow caused by dlopen */ + char *argv[] = {"/usr/bin/launchpad-loader", NULL, + " ", NULL + }; + __signal_unblock_sigchld(); + + type_str[0] = '0' + type; + argv[1] = type_str; + if (execv(argv[0], argv) < 0) + _E("Failed to prepare candidate_process"); + else + _D("Succeeded to prepare candidate_process"); + + exit(-1); + } +} + +static void __sleep_safe(time_t sec) +{ + struct timespec delay, remain; + delay.tv_sec = sec; + delay.tv_nsec = 0; + remain.tv_sec = 0; + remain.tv_nsec = 0; + + while (nanosleep(&delay, &remain)) { + if (errno == EINTR) { + delay.tv_sec = remain.tv_sec; + delay.tv_nsec = remain.tv_nsec; + } else { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + _D("nanosleep() failed, errno: %d (%s)", errno, + strerror_r(errno, err_str, sizeof(err_str))); + break; + } + } +} + +static int __send_launchpad_loader(int type, app_pkt_t *pkt, + const char *app_path, int clifd) +{ + char sock_path[UNIX_PATH_MAX] = { 0, }; + int pid = -1; + + snprintf(sock_path, UNIX_PATH_MAX, "/run/user/%d/%d", getuid(), + __candidate[type].pid); + unlink(sock_path); + + __candidate_process_real_launch(__candidate[type].send_fd, pkt); + SECURE_LOGD("Request to candidate process, pid: %d, bin path: %s", + __candidate[type].pid, app_path); + + pid = __candidate[type].pid; + close(__candidate[type].send_fd); + + __candidate[type].pid = CANDIDATE_NONE; + __candidate[type].send_fd = -1; + + /* Temporary log: launch time checking */ + //SECURE_LOG(LOG_DEBUG, "LAUNCH", "[%s:Platform:launchpad:done]", app_path); + + __send_result_to_caller(clifd, pid, app_path); //to AMD + + __sleep_safe(1); //1 sec + __prepare_candidate_process(type); + + _D("Prepare another candidate process"); + return pid; +} + +static int __normal_fork_exec(int argc, char **argv) +{ + _D("start real fork and exec\n"); + + if (execv(argv[0], argv) < 0) { /* Flawfinder: ignore */ + if (errno == EACCES) + _E("such a file is no executable - %s", argv[0]); + else + _E("unknown executable error - %s", argv[0]); + return -1; + } + /* never reach*/ + return 0; +} + +static void __real_launch(const char *app_path, bundle * kb) +{ + int app_argc; + char **app_argv; + int i; + + if (bundle_get_val(kb, AUL_K_DEBUG) != NULL) + putenv("TIZEN_DEBUGGING_PORT=1"); + + app_argv = _create_argc_argv(kb, &app_argc); + app_argv[0] = strdup(app_path); + + for (i = 0; i < app_argc; i++) { + if ((i % 2) == 1) + continue; + SECURE_LOGD("input argument %d : %s##", i, app_argv[i]); + } + + PERF("setup argument done"); + __normal_fork_exec(app_argc, app_argv); +} + +static int __prepare_exec(const char *appId, const char *app_path, + app_info_from_db * menu_info, bundle * kb) +{ + char *file_name; + char process_name[AUL_PR_NAME]; + int ret; + + /* Set new session ID & new process group ID*/ + /* In linux, child can set new session ID without check permission */ + /* TODO : should be add to check permission in the kernel*/ + setsid(); + + /* SET OOM*/ + _set_oom(); + + /* SET PRIVILEGES*/ + if (bundle_get_val(kb, AUL_K_PRIVACY_APPID) == NULL) { + _D("appId: %s / pkg_type : %s / app_path : %s ", appId, menu_info->pkg_type, + app_path); + if ((ret = __set_access(appId, menu_info->pkg_type, app_path)) != 0) { + _D("fail to set privileges - check your package's credential : %d\n", ret); + return -1; + } + } + /* SET DUMPABLE - for coredump*/ + prctl(PR_SET_DUMPABLE, 1); + + /* SET PROCESS NAME*/ + if (app_path == NULL) { + _D("app_path should not be NULL - check menu db"); + return -1; + } + file_name = strrchr(app_path, '/') + 1; + if (file_name == NULL) { + _D("can't locate file name to execute"); + return -1; + } + memset(process_name, '\0', AUL_PR_NAME); + snprintf(process_name, AUL_PR_NAME, "%s", file_name); + prctl(PR_SET_NAME, process_name); + + /* SET ENVIROMENT*/ + _set_env(menu_info, kb); + + return 0; +} + +static int __launch_directly(const char *appid, const char *app_path, int clifd, + bundle* kb, app_info_from_db *menu_info) +{ + char sock_path[UNIX_PATH_MAX] = {0,}; + int pid = fork(); + + if (pid == 0) { + PERF("fork done"); + _D("lock up test log(no error) : fork done"); + + close(clifd); + __signal_unblock_sigchld(); + __signal_fini(); + + snprintf(sock_path, UNIX_PATH_MAX, "/run/user/%d/%d", getuid(), getpid()); + unlink(sock_path); + + PERF("prepare exec - first done"); + _D("lock up test log(no error) : prepare exec - first done"); + + if (__prepare_exec(appid, app_path, + menu_info, kb) < 0) { + SECURE_LOGE("preparing work fail to launch - " + "can not launch %s\n", appid); + exit(-1); + } + + PERF("prepare exec - second done"); + _D("lock up test log(no error) : prepare exec - second done"); + __real_launch(app_path, kb); + + exit(-1); + } + SECURE_LOGD("==> real launch pid : %d %s\n", pid, app_path); + + return pid; +} + +static void __launchpad_main_loop(int launchpad_fd, int *pool_fd) +{ + bundle *kb = NULL; + app_pkt_t *pkt = NULL; + app_info_from_db *menu_info = NULL; + + const char *pkg_name = NULL; + const char *internal_pool = NULL; + const char *app_path = NULL; + int pid = -1; + int clifd = -1; + struct ucred cr; + int type = -1; + + pkt = _recv_pkt_raw(launchpad_fd, &clifd, &cr); + if (!pkt) { + _E("packet is NULL"); + goto end; + } + + kb = bundle_decode(pkt->data, pkt->len); + if (!kb) { + _E("bundle decode error"); + goto end; + } + + INIT_PERF(kb); + PERF("packet processing start"); + + pkg_name = bundle_get_val(kb, AUL_K_APPID); + SECURE_LOGD("pkg name : %s\n", pkg_name); + + menu_info = _get_app_info_from_bundle_by_pkgname(pkg_name, kb); + if (menu_info == NULL) { + _E("such pkg no found"); + goto end; + } + + app_path = _get_app_path(menu_info); + if (app_path == NULL) { + _E("app_path is NULL"); + goto end; + } + if (app_path[0] != '/') { + _E("app_path is not absolute path"); + goto end; + } + + if (menu_info->hwacc == NULL) { + _E("[launchpad] Failed to find H/W acceleration type"); + goto end; + } + + internal_pool = bundle_get_val(kb, AUL_K_EXEC); + SECURE_LOGD("exec : %s\n", internal_pool); + internal_pool = bundle_get_val(kb, AUL_K_INTERNAL_POOL); + + SECURE_LOGD("internal pool : %s\n", internal_pool); + SECURE_LOGD("hwacc : %s\n", menu_info->hwacc); + type = __get_launchpad_type(internal_pool, menu_info->hwacc); + if (type < 0) { + _E("failed to get launchpad type"); + goto end; + } + + _modify_bundle(kb, cr.pid, menu_info, pkt->cmd); + pkg_name = _get_pkgname(menu_info); + if (pkg_name == NULL) { + _E("unable to get pkg_name from menu_info"); + goto end; + } + + PERF("get package information & modify bundle done"); + + if ((type >= 0) && (type < LAUNCHPAD_TYPE_MAX) + && (__candidate[type].pid != CANDIDATE_NONE) + && (DIFF(__candidate[type].last_exec_time, time(NULL)) > EXEC_CANDIDATE_WAIT)) { + _W("Launch on type-based process-pool"); + pid = __send_launchpad_loader(type, pkt, app_path, clifd); + } else if ((__candidate[LAUNCHPAD_TYPE_COMMON].pid != CANDIDATE_NONE) + && (DIFF(__candidate[LAUNCHPAD_TYPE_COMMON].last_exec_time, + time(NULL)) > EXEC_CANDIDATE_WAIT)) { + _W("Launch on common type process-pool"); + pid = __send_launchpad_loader(LAUNCHPAD_TYPE_COMMON, pkt, app_path, clifd); + } else { + _W("Candidate is not prepared"); + pid = __launch_directly(pkg_name, app_path, clifd, kb, menu_info); + __send_result_to_caller(clifd, pid, app_path); + } + clifd = -1; + +end: + if (clifd != -1) + close(clifd); + + if (pid > 0) { + __send_app_launch_signal_dbus(pid); + } + + if (menu_info != NULL) + _free_app_info_from_db(menu_info); + + if (kb != NULL) + bundle_free(kb); + if (pkt != NULL) + free(pkt); + + /* Active Flusing for Daemon */ + if (initialized > AUL_POLL_CNT) { + malloc_trim(0); + initialized = 1; + } +} + +static int __launchpad_pre_init(int argc, char **argv) +{ + int fd; + + /* signal init*/ + __signal_init(); + + /* create launchpad sock */ + fd = _create_server_sock(PROCESS_POOL_LAUNCHPAD_PID); + if (fd < 0) { + _E("server sock error %d", fd); + return -1; + } + + return fd; +} + +static int __launchpad_post_init() +{ + /* Setting this as a global variable to keep track + of launchpad poll cnt */ + /* static int initialized = 0;*/ + + if (initialized) { + ++initialized; + return 0; + } + + ++initialized; + + return 0; +} + +static int __init_pfds(struct pollfd *pfds, int argc, char **argv) +{ + int sigchld_fd = -1; + int i; + + /* init without concerning X & EFL*/ + launchpad_fd = __launchpad_pre_init(argc, argv); + if (launchpad_fd < 0) { + _E("launchpad pre init failed"); + exit(-1); + } + pfds[LAUNCH_PAD].fd = launchpad_fd; + pfds[LAUNCH_PAD].events = POLLIN; + pfds[LAUNCH_PAD].revents = 0; + + for (i = 0; i < LAUNCHPAD_TYPE_MAX; ++i) { + pool_fd[i] = _listen_candidate_process(i); + if (pool_fd[i] == -1) { + _E("[launchpad] Listening the socket to the type %d candidate process failed.", + i); + return -1; + } + pfds[POOL_TYPE + i].fd = pool_fd[i]; + pfds[POOL_TYPE + i].events = POLLIN; + pfds[POOL_TYPE + i].revents = 0; + } + + sigchld_fd = __signal_get_sigchld_fd(); + if (sigchld_fd == -1) { + _E("failed to get sigchld fd"); + return -1; + } + pfds[SIGCHLD_FD].fd = sigchld_fd; + pfds[SIGCHLD_FD].events = POLLIN; + pfds[SIGCHLD_FD].revents = 0; + + return 0; +} + +static int __loop_begin(struct pollfd *pfds) +{ + int i; + + while (1) { + for (i = 0; i < LAUNCHPAD_TYPE_MAX; ++i) { + if (__candidate[i].pid == CANDIDATE_NONE) { + pfds[CANDIDATE_TYPE + i].fd = -1; + pfds[CANDIDATE_TYPE + i].events = 0; + pfds[CANDIDATE_TYPE + i].revents = 0; + + if (DIFF(__candidate[i].last_exec_time, time(NULL)) > EXEC_CANDIDATE_EXPIRED) + __prepare_candidate_process(i); + } + } + + if (poll(pfds, POLLFD_MAX, -1) < 0) + continue; + + _D("pfds[LAUNCH_PAD].revent : 0x%x", pfds[LAUNCH_PAD].revents) ; + for (i = 0; i < LAUNCHPAD_TYPE_MAX; ++i) { + _D("pfds[POOL_TYPE + %d].revents : 0x%x", i, pfds[POOL_TYPE + i].revents) ; + _D("pfds[CANDIDATE_TYPE + %d].revents : 0x%x", i, + pfds[CANDIDATE_TYPE + i].revents); + } + + /* init with concerning X & EFL (because of booting + * sequence problem)*/ + if (__launchpad_post_init() < 0) { + _E("launcpad post init failed"); + return -1; + } + + if ((pfds[SIGCHLD_FD].revents & POLLIN) != 0) { + struct signalfd_siginfo siginfo; + ssize_t s; + + do { + s = read(pfds[SIGCHLD_FD].fd, &siginfo, sizeof(struct signalfd_siginfo)); + if (s == 0) + break; + + if (s != sizeof(struct signalfd_siginfo)) { + _E("error reading sigchld info"); + break; + } + __launchpad_process_sigchld(&siginfo); + } while (s > 0); + } + + if ((pfds[LAUNCH_PAD].revents & POLLIN) != 0) { + _D("pfds[LAUNCH_PAD].revents & POLLIN"); + __launchpad_main_loop(pfds[LAUNCH_PAD].fd, pool_fd); + } + + for (i = 0; i < LAUNCHPAD_TYPE_MAX; ++i) { + if ((pfds[POOL_TYPE + i].revents & POLLIN) != 0) { + int server_fd, client_fd; + int client_pid; + + server_fd = pfds[POOL_TYPE + i].fd; + + _D("pfds[POOL_TYPE + %d].revents & POLLIN", i); + + if (__candidate[i].pid == CANDIDATE_NONE) { + _accept_candidate_process(server_fd, &client_fd, &client_pid); + + __candidate[i].pid = client_pid; + __candidate[i].send_fd = client_fd; + + pfds[CANDIDATE_TYPE + i].fd = client_fd; + pfds[CANDIDATE_TYPE + i].events = POLLIN | POLLHUP; + pfds[CANDIDATE_TYPE + i].revents = 0; + + SECURE_LOGD("Type %d candidate process was connected, pid: %d", i, + __candidate[i].pid); + } else { + _refuse_candidate_process(server_fd); + _E("Refused candidate process connection"); + } + } + + if ((pfds[CANDIDATE_TYPE + i].revents & (POLLHUP | POLLNVAL)) != 0) { + SECURE_LOGD("pfds[CANDIDATE_TYPE + %d].revents & (POLLHUP|POLLNVAL), pid: %d", + i, __candidate[i].pid); + + if (pfds[CANDIDATE_TYPE + i].fd > -1) + close(pfds[CANDIDATE_TYPE + i].fd); + + __candidate[i].pid = CANDIDATE_NONE; + __candidate[i].send_fd = -1; + + pfds[CANDIDATE_TYPE + i].fd = -1; + pfds[CANDIDATE_TYPE + i].events = 0; + pfds[CANDIDATE_TYPE + i].revents = 0; + } + } + } + + return 0; +} + +int main(int argc, char **argv) +{ + int i; + struct pollfd pfds[POLLFD_MAX]; + + memset(pfds, 0x00, sizeof(pfds)); + if (__init_pfds(pfds, argc, argv) != 0) + goto error; + +#ifdef _APPFW_FEATURE_PRIORITY_CHANGE + int res = setpriority(PRIO_PROCESS, 0, -12); + if (res == -1) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("Setting process (%d) priority to -12 failed, errno: %d (%s)", + getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); + } +#endif + if (__loop_begin(pfds) == 0) + return 0; + +error: + if (launchpad_fd != -1) + close(launchpad_fd); + + for (i = 0; i < LAUNCHPAD_TYPE_MAX; ++i) { + if (pool_fd[i] != -1) + close(pool_fd[i]); + if (__candidate[i].send_fd != -1) + close(__candidate[i].send_fd); + } + + return -1; +} diff --git a/src/launchpad_common.c b/src/launchpad_common.c new file mode 100644 index 00000000..984cc5c8 --- /dev/null +++ b/src/launchpad_common.c @@ -0,0 +1,665 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "launchpad_common.h" +#include "key.h" + +#define BINSH_NAME "/bin/sh" +#define BINSH_SIZE 7 +#define VALGRIND_NAME "/home/developer/sdk_tools/valgrind/usr/bin/valgrind" +#define VALGRIND_SIZE 51 +#define BASH_NAME "/bin/bash" +#define BASH_SIZE 9 +#define OPROFILE_NAME "/usr/bin/oprofile_command" +#define OPROFILE_SIZE 25 +#define OPTION_VALGRIND_NAME "valgrind" +#define OPTION_VALGRIND_SIZE 8 +#define MAX_CMD_BUFSZ 1024 + +#define SOCKET_PATH "/run/user" +#define LAUNCHPAD_TYPE ".launchpad-type" +#define MAX_PENDING_CONNECTIONS 10 +#define CONNECT_RETRY_TIME 100 * 1000 +#define CONNECT_RETRY_COUNT 3 +#define AUL_PKT_HEADER_SIZE (sizeof(int) + sizeof(int)) + +#define APP_START 0 +#define APP_OPEN 1 +#define APP_RESUME 2 +#define APP_START_RES 3 + +static int __read_proc(const char *path, char *buf, int size) +{ + int fd; + int ret; + + if (buf == NULL || path == NULL) + return -1; + + fd = open(path, O_RDONLY); + if (fd < 0) + return -1; + + ret = read(fd, buf, size - 1); + if (ret <= 0) { + close(fd); + return -1; + } else + buf[ret] = 0; + + close(fd); + + return ret; +} + +static void __set_sock_option(int fd, int cli) +{ + int size; + struct timeval tv = { 5, 200 * 1000 }; /* 5.2 sec */ + + size = AUL_SOCK_MAXBUFF; + setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)); + setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); + if (cli) + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); +} + +static int __parse_app_path(const char *arg, char *out, int out_size) +{ + register int i; + int state = 1; + char *start_out = out; + + if (arg == NULL || out == NULL) { + /* Handles null buffer*/ + return 0; + } + + for (i = 0; out_size > 1; i++) { + switch (state) { + case 1: + switch (arg[i]) { + case ' ': + case '\t': + state = 5; + break; + case '\0': + state = 7; + break; + case '\"': + state = 2; + break; + case '\\': + state = 4; + break; + default: + *out = arg[i]; + out++; + out_size--; + break; + } + break; + case 2: /* escape start*/ + switch (arg[i]) { + case '\0': + state = 6; + break; + case '\"': + state = 1; + break; + default: + *out = arg[i]; + out++; + out_size--; + break; + } + break; + case 4: /* character escape*/ + if (arg[i] == '\0') { + state = 6; + } else { + *out = arg[i]; + out++; + out_size--; + state = 1; + } + break; + case 5: /* token*/ + if (out != start_out) { + *out = '\0'; + out_size--; + return i; + } + i--; + state = 1; + break; + case 6: + return -1; /* error*/ + case 7: /* terminate*/ + *out = '\0'; + out_size--; + return 0; + default: + state = 6; + break; /* error*/ + } + } + + if (out_size == 1) + *out = '\0'; + + /* Buffer overflow*/ + return -2; +} + +int _create_server_sock(int pid) +{ + struct sockaddr_un saddr; + int fd; + + fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + /* support above version 2.6.27*/ + if (fd < 0) { + if (errno == EINVAL) { + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) { + _E("second chance - socket create error"); + return -1; + } + } else { + _E("socket error"); + return -1; + } + } + + memset(&saddr, 0, sizeof(saddr)); + saddr.sun_family = AF_UNIX; + snprintf(saddr.sun_path, UNIX_PATH_MAX, "/run/user/%d/%d", getuid(), pid); + unlink(saddr.sun_path); + + if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { + _E("bind error"); + close(fd); + return -1; + } + + if (chmod(saddr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + /* Flawfinder: ignore*/ + _E("failed to change the socket permission"); + close(fd); + return -1; + } + + __set_sock_option(fd, 0); + + if (listen(fd, 128) == -1) { + _E("listen error"); + close(fd); + return -1; + } + + return fd; +} + +app_pkt_t *_recv_pkt_raw(int fd, int *clifd, struct ucred *cr) +{ + int len; + int ret; + struct sockaddr_un aul_addr = { 0, }; + int sun_size; + app_pkt_t *pkt = NULL; + int cl = sizeof(struct ucred); + unsigned char buf[AUL_SOCK_MAXBUFF]; + int cmd; + int datalen; + + sun_size = sizeof(struct sockaddr_un); + + if ((*clifd = accept(fd, (struct sockaddr *)&aul_addr, + (socklen_t *) &sun_size)) == -1) { + if (errno != EINTR) + _E("accept error"); + return NULL; + } + + if (getsockopt(*clifd, SOL_SOCKET, SO_PEERCRED, cr, + (socklen_t *) &cl) < 0) { + _E("peer information error"); + close(*clifd); + return NULL; + } + + __set_sock_option(*clifd, 1); + +retry_recv: + /* receive header(cmd, datalen) */ + len = recv(*clifd, buf, AUL_PKT_HEADER_SIZE, 0); + if (len < 0) + if (errno == EINTR) + goto retry_recv; + + if (len < AUL_PKT_HEADER_SIZE) { + _E("recv error"); + close(*clifd); + return NULL; + } + memcpy(&cmd, buf, sizeof(int)); + memcpy(&datalen, buf + sizeof(int), sizeof(int)); + + /* allocate for a null byte */ + pkt = (app_pkt_t *)calloc(1, AUL_PKT_HEADER_SIZE + datalen + 1); + if (pkt == NULL) { + close(*clifd); + return NULL; + } + pkt->cmd = cmd; + pkt->len = datalen; + + len = 0; + while ( len != pkt->len ) { + ret = recv(*clifd, pkt->data + len, pkt->len - len, 0); + if (ret < 0) { + _E("recv error %d %d", len, pkt->len); + free(pkt); + close(*clifd); + return NULL; + } + len += ret; + _D("recv len %d %d", len, pkt->len); + } + + return pkt; +} + +int _send_pkt_raw(int client_fd, app_pkt_t *pkt) +{ + int send_ret = 0; + int pkt_size = 0; + + if (client_fd == -1 || pkt == NULL) { + _E("arguments error!"); + goto error; + } + + pkt_size = sizeof(pkt->cmd) + sizeof(pkt->len) + pkt->len; + + send_ret = send(client_fd, pkt, pkt_size, 0); + _D("send(%d) : %d / %d", client_fd, send_ret, pkt_size); + + if (send_ret == -1) { + _E("send error!"); + goto error; + } else if (send_ret != pkt_size) { + _E("send byte fail!"); + goto error; + } + + return 0; + +error: + return -1; +} + +char *_proc_get_cmdline_bypid(int pid) +{ + char buf[MAX_CMD_BUFSZ]; + int ret; + + snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid); + ret = __read_proc(buf, buf, sizeof(buf)); + if (ret <= 0) + return NULL; + + /* support app launched by shell script*/ + if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0) { + return strdup(&buf[BINSH_SIZE + 1]); + } else if (strncmp(buf, VALGRIND_NAME, VALGRIND_SIZE) == 0) { + char* ptr = buf; + + // buf comes with double null-terminated string + while (1) { + while (*ptr) { + ptr++; + } + ptr++; + + if (!(*ptr)) + break; + + // ignore trailing "--" + if (strncmp(ptr, "-", 1) != 0) + break; + } + + return strdup(ptr); + } else if (strncmp(buf, BASH_NAME, BASH_SIZE) == 0) { + if (strncmp(&buf[BASH_SIZE + 1], OPROFILE_NAME, OPROFILE_SIZE) == 0) { + if (strncmp(&buf[BASH_SIZE + OPROFILE_SIZE + 2], OPTION_VALGRIND_NAME, + OPTION_VALGRIND_SIZE) == 0) { + return strdup(&buf[BASH_SIZE + OPROFILE_SIZE + OPTION_VALGRIND_SIZE + 3]); + } + } + } + + return strdup(buf); +} + +app_info_from_db *_get_app_info_from_bundle_by_pkgname(const char *pkgname, bundle *kb) +{ + app_info_from_db *menu_info; + const char *ptr = NULL; + + menu_info = calloc(1, sizeof(app_info_from_db)); + if (menu_info == NULL) + return NULL; + + menu_info->pkg_name = strdup(pkgname); + ptr = bundle_get_val(kb, AUL_K_EXEC); + if (ptr) + menu_info->app_path = strdup(ptr); + if (menu_info->app_path != NULL) + menu_info->original_app_path = strdup(menu_info->app_path); + ptr = bundle_get_val(kb, AUL_K_PACKAGETYPE); + if (ptr) + menu_info->pkg_type = strdup(ptr); + ptr = bundle_get_val(kb, AUL_K_HWACC); + if (ptr) + menu_info->hwacc = strdup(ptr); + ptr = bundle_get_val(kb, AUL_K_TASKMANAGE); + if (ptr) + menu_info->taskmanage = strdup(ptr); + ptr = bundle_get_val(kb, AUL_K_PKGID); + if (ptr) + menu_info->pkg_id = strdup(ptr); + + if (!_get_app_path(menu_info)) { + _free_app_info_from_db(menu_info); + return NULL; + } + + return menu_info; +} + +void _modify_bundle(bundle * kb, int caller_pid, app_info_from_db * menu_info, int cmd) +{ + bundle_del(kb, AUL_K_APPID); + bundle_del(kb, AUL_K_EXEC); + bundle_del(kb, AUL_K_PACKAGETYPE); + bundle_del(kb, AUL_K_HWACC); + bundle_del(kb, AUL_K_TASKMANAGE); + + /* Parse app_path to retrieve default bundle*/ + if (cmd == APP_START || cmd == APP_START_RES || cmd == APP_OPEN + || cmd == APP_RESUME) { + char *ptr; + char exe[MAX_PATH_LEN]; + int flag; + + ptr = _get_original_app_path(menu_info); + + flag = __parse_app_path(ptr, exe, sizeof(exe)); + if (flag > 0) { + char key[256]; + char value[256]; + + ptr += flag; + SECURE_LOGD("parsing app_path: EXEC - %s\n", exe); + + do { + flag = __parse_app_path(ptr, key, sizeof(key)); + if (flag <= 0) + break; + ptr += flag; + + flag = __parse_app_path(ptr, value, sizeof(value)); + if (flag < 0) + break; + ptr += flag; + + /*bundle_del(kb, key);*/ + bundle_add(kb, key, value); + } while (flag > 0); + } else if (flag == 0) + _D("parsing app_path: No arguments\n"); + else + _D("parsing app_path: Invalid argument\n"); + } +} + +int _listen_candidate_process(int type) +{ + struct sockaddr_un addr; + int fd = -1; + int listen_fds = 0; + int i; + + _D("[launchpad] enter, type: %d", type); + + memset(&addr, 0x00, sizeof(struct sockaddr_un)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%d/%s%d", SOCKET_PATH, getuid(), + LAUNCHPAD_TYPE, type); + + listen_fds = sd_listen_fds(0); + if (listen_fds < 0) { + _E("Invalid systemd environment"); + return -1; + } else if (listen_fds > 0) { + for (i = 0; i < listen_fds; i++) { + fd = SD_LISTEN_FDS_START + i; + if (sd_is_socket_unix(fd, SOCK_STREAM, 1, addr.sun_path, 0)) + return fd; + } + _E("Socket not found: %s", addr.sun_path); + return -1; + } + + fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (fd < 0) { + _E("Socket error"); + goto error; + } + + unlink(addr.sun_path); + + _D("bind to %s", addr.sun_path); + if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + _E("bind error"); + goto error; + } + + _D("chmod %s", addr.sun_path); + if (chmod(addr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + _E("chmod error"); + goto error; + } + + _D("listen to %s", addr.sun_path); + if (listen(fd, MAX_PENDING_CONNECTIONS) == -1) { + _E("listen error"); + goto error; + } + + SECURE_LOGD("[launchpad] done, listen fd: %d", fd); + return fd; + +error: + if (fd != -1) + close(fd); + + return -1; +} + +int _connect_to_launchpad(int type) +{ + struct sockaddr_un addr; + int fd = -1; + int retry = CONNECT_RETRY_COUNT; + int send_ret = -1; + int client_pid = getpid(); + + _D("[launchpad] enter, type: %d", type); + + fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (fd < 0) { + _E("socket error"); + goto error; + } + + memset(&addr, 0x00, sizeof(struct sockaddr_un)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%d/%s%d", SOCKET_PATH, getuid(), + LAUNCHPAD_TYPE, type); + + _D("connect to %s", addr.sun_path); + while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + if (errno != ETIMEDOUT || retry <= 0) { + _E("connect error : %d", errno); + goto error; + } + + usleep(CONNECT_RETRY_TIME); + --retry; + _D("re-connect to %s (%d)", addr.sun_path, retry); + } + + send_ret = send(fd, &client_pid, sizeof(client_pid), 0); + _D("send(%d) : %d", client_pid, send_ret); + + if (send_ret == -1) { + _E("send error"); + goto error; + } + + SECURE_LOGD("[launchpad] done, connect fd: %d", fd); + return fd; + +error: + if (fd != -1) + close(fd); + + return -1; +} + +int _accept_candidate_process(int server_fd, int* out_client_fd, + int* out_client_pid) +{ + int client_fd = -1, client_pid = 0, recv_ret = 0; + + if (server_fd == -1 || out_client_fd == NULL || out_client_pid == NULL) { + _E("arguments error!"); + goto error; + } + + client_fd = accept(server_fd, NULL, NULL); + + if (client_fd == -1) { + _E("accept error!"); + goto error; + } + + recv_ret = recv(client_fd, &client_pid, sizeof(client_pid), MSG_WAITALL); + + if (recv_ret == -1) { + _E("recv error!"); + goto error; + } + + *out_client_fd = client_fd; + *out_client_pid = client_pid; + + return *out_client_fd; + +error: + if (client_fd != -1) + close(client_fd); + + return -1; +} + +void _refuse_candidate_process(int server_fd) +{ + int client_fd = -1; + + if (server_fd == -1) { + _E("arguments error!"); + goto error; + } + + client_fd = accept(server_fd, NULL, NULL); + if (client_fd == -1) { + _E("accept error!"); + goto error; + } + + close(client_fd); + _D("refuse connection!"); + +error: + return; +} + +void _set_oom(void) +{ + char buf[MAX_LOCAL_BUFSZ]; + FILE *fp; + + /* we should reset oomadj value as default because child + inherits from parent oom_adj*/ + snprintf(buf, MAX_LOCAL_BUFSZ, "/proc/%d/oom_adj", getpid()); + fp = fopen(buf, "w"); + if (fp == NULL) + return; + fprintf(fp, "%d", -16); + fclose(fp); +} + +void _set_env(app_info_from_db * menu_info, bundle * kb) +{ + const char *str; + + str = bundle_get_val(kb, AUL_K_STARTTIME); + if (str != NULL) + setenv("APP_START_TIME", str, 1); + + if (menu_info->hwacc != NULL) + setenv("HWACC", menu_info->hwacc, 1); + if (menu_info->taskmanage != NULL) + setenv("TASKMANAGE", menu_info->taskmanage, 1); +} + +char** _create_argc_argv(bundle * kb, int *margc) +{ + char **argv; + int argc; + + argc = bundle_export_to_argv(kb, &argv); + + *margc = argc; + return argv; +} + diff --git a/src/launchpad_loader.c b/src/launchpad_loader.c new file mode 100644 index 00000000..525b61ce --- /dev/null +++ b/src/launchpad_loader.c @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "menu_db_util.h" +#include "launchpad_common.h" +#include "preload.h" +#include "process_pool_preload.h" +#include "preexec.h" +#include "key.h" + +#define AUL_PR_NAME 16 +#define LOWEST_PRIO 20 + +static char *__appid; +static char *__pkgid; +static bundle *_s_bundle; + +static int __set_access(const char* appId, const char* pkg_type, + const char* app_path) +{ + return security_manager_prepare_app(appId) == SECURITY_MANAGER_SUCCESS ? 0 : -1; +} + +static int __candidate_process_prepare_exec(const char *pkg_name, + const char *app_path, app_info_from_db *menu_info, + bundle *kb, int type) +{ + const char *file_name = NULL; + char process_name[AUL_PR_NAME] = { 0, }; + int ret = 0; + + __preexec_run(menu_info->pkg_type, pkg_name, app_path); + + /* SET PRIVILEGES*/ + SECURE_LOGD("[candidata] pkg_name : %s / pkg_type : %s / app_path : %s", + pkg_name, menu_info->pkg_type, app_path); + if ((ret = __set_access(pkg_name, menu_info->pkg_type, app_path)) < 0) { + _D("fail to set privileges - check your package's credential : %d\n", ret); + return -1; + } + + /* + * SET DUMPABLE - for coredump + * This dumpable flag should be set after calling perm_app_set_privilege() + */ + prctl(PR_SET_DUMPABLE, 1); + + /* SET PROCESS NAME*/ + if (app_path == NULL) { + _D("app_path should not be NULL - check menu db"); + return -1; + } + + file_name = strrchr(app_path, '/') + 1; + if (file_name == NULL) { + _D("can't locate file name to execute"); + return -1; + } + memset(process_name, '\0', AUL_PR_NAME); + snprintf(process_name, AUL_PR_NAME, "%s", file_name); + prctl(PR_SET_NAME, process_name); + + /* SET ENVIROMENT*/ + _set_env(menu_info, kb); + + return 0; +} + +static void __at_exit_to_release_bundle() +{ + if (_s_bundle) { + bundle_free(_s_bundle); + _s_bundle = NULL; + } +} + +static void __release_appid_at_exit(void) +{ + if (__appid != NULL) { + free(__appid); + } + if (__pkgid != NULL) { + free(__pkgid); + } +} + +static void __candidate_process_launchpad_main_loop(app_pkt_t* pkt, + char* out_app_path, int* out_argc, char ***out_argv, + int type) +{ + bundle *kb = NULL; + app_info_from_db *menu_info = NULL; + + const char *app_id = NULL; + const char *app_path = NULL; + //const char *pkg_id = NULL; + + kb = bundle_decode(pkt->data, pkt->len); + if (!kb) { + _E("bundle decode error"); + exit(-1); + } + + if (_s_bundle != NULL) + bundle_free(_s_bundle); + + _s_bundle = kb; + atexit(__at_exit_to_release_bundle); + + app_id = bundle_get_val(kb, AUL_K_APPID); + if (app_id == NULL) { + _E("Unable to get app_id"); + exit(-1); + } + + menu_info = _get_app_info_from_bundle_by_pkgname(app_id, kb); + if (menu_info == NULL) { + _D("such pkg no found"); + exit(-1); + } + + if (type < 0) { + _E("Invalid launchpad type: %d", type); + exit(-1); + } + + SECURE_LOGD("app id: %s, launchpad type: %d", app_id, type); + + app_path = _get_app_path(menu_info); + if (app_path == NULL) { + _E("app_path is NULL"); + exit(-1); + } + + if (app_path[0] != '/') { + _E("app_path is not absolute path"); + exit(-1); + } + + _modify_bundle(kb, /*cr.pid - unused parameter*/ 0, menu_info, pkt->cmd); + + // caching appid + app_id = _get_pkgname(menu_info); + if (app_id == NULL) { + _E("unable to get app_id from menu_info"); + exit(-1); + } + SECURE_LOGD("app id: %s", app_id); +#if 0 + //TODO : FIXME + __appid = strdup(app_id); + if (__appid == NULL) { + _E("Out of memory"); + exit(-1); + } + //aul_set_preinit_appid(__appid); //TODO + + // caching pkgid + pkg_id = _get_pkgid(menu_info); + if (pkg_id == NULL) { + _E("unable to get pkg_id from menu_info"); + exit(-1); + } + SECURE_LOGD("pkg id: %s", pkg_id); + + __pkgid = strdup(pkg_id); + if (__pkgid == NULL) { + _E("Out of memory"); + exit(-1); + } + //aul_set_preinit_pkgid(__pkgid); //TODO +#endif + + atexit(__release_appid_at_exit); + +#ifdef _APPFW_FEATURE_PRIORITY_CHANGE + const char *high_priority = bundle_get_val(kb, AUL_K_HIGHPRIORITY); + _D("high_priority: %s", high_priority); + + if (strncmp(high_priority, "true", 4) == 0) { + int res = setpriority(PRIO_PROCESS, 0, -10); + if (res == -1) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("Setting process (%d) priority to -10 failed, errno: %d (%s)", + getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); + } + } + bundle_del(kb, AUL_K_HIGHPRIORITY); +#endif + + if (__candidate_process_prepare_exec(app_id, app_path, menu_info, kb, + type) < 0) { + _E("__candidate_process_prepare_exec() failed"); + if (access(app_path, F_OK | R_OK)) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("access() failed for file: \"%s\", error: %d (%s)", + app_path, errno, strerror_r(errno, err_str, sizeof(err_str))); + } + exit(-1); + } + + if (out_app_path != NULL && out_argc != NULL && out_argv != NULL) { + int i = 0; + + memset(out_app_path, '\0', strlen(out_app_path)); + sprintf(out_app_path, "%s", app_path); + + *out_argv = _create_argc_argv(kb, out_argc); + (*out_argv)[0] = out_app_path; + + for (i = 0; i < *out_argc; i++) + SECURE_LOGD("input argument %d : %s##", i, (*out_argv)[i]); + } else + exit(-1); + + if (menu_info != NULL) + _free_app_info_from_db(menu_info); +} + +static Eina_Bool __candidate_proces_fd_handler(void* data, + Ecore_Fd_Handler *handler) +{ + int type = data ? *((int *)data) : LAUNCHPAD_TYPE_UNSUPPORTED; + int fd = ecore_main_fd_handler_fd_get(handler); + + if (fd == -1) { + _D("[candidate] ECORE_FD_GET"); + exit(-1); + } + + if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) { + _D("[candidate] ECORE_FD_ERROR"); + close(fd); + exit(-1); + } + + if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) { + _D("[candidate] ECORE_FD_READ"); + app_pkt_t* pkt = (app_pkt_t*) malloc(sizeof(char) * AUL_SOCK_MAXBUFF); + if (!pkt) { + _D("[candidate] out of memory1"); + exit(-1); + } + memset(pkt, 0, AUL_SOCK_MAXBUFF); + + int recv_ret = recv(fd, pkt, AUL_SOCK_MAXBUFF, 0); + close(fd); + if (recv_ret == -1) { + _D("[condidate] recv error!"); + free(pkt); + exit(-1); + } + _D("[candidate] recv_ret: %d, pkt->len: %d", recv_ret, pkt->len); + + ecore_main_fd_handler_del(handler); + + __candidate_process_launchpad_main_loop(pkt, g_argv[0], &g_argc, &g_argv, type); + SECURE_LOGD("[candidate] real app argv[0]: %s, real app argc: %d", g_argv[0], + g_argc); + free(pkt); + + ecore_main_loop_quit(); + _D("[candidate] ecore main loop quit"); + } + + return ECORE_CALLBACK_CANCEL; +} + +static void __init_window(void) +{ +#if 0 //TODO : FIXME + Evas_Object *win = elm_win_add(NULL, "package_name", ELM_WIN_BASIC); + if (win) { + aul_set_preinit_window(win); + + Evas_Object *bg = elm_bg_add(win); + if (bg) { + evas_object_size_hint_weight_set(bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, bg); + aul_set_preinit_background(bg); + } else { + _E("[candidate] elm_bg_add() failed"); + } + + Evas_Object *conform = elm_conformant_add(win); + if (conform) { + evas_object_size_hint_weight_set(conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); + elm_win_resize_object_add(win, conform); + aul_set_preinit_conformant(conform); + } else { + _E("elm_conformant_add() failed"); + } + } else { + _E("[candidate] elm_win_add() failed"); + } +#endif +} + +static void __init_theme(void) +{ + char *theme = elm_theme_list_item_path_get(eina_list_data_get( + elm_theme_list_get(NULL)), NULL); + Eina_Bool is_exist = edje_file_group_exists(theme, "*"); + if (!is_exist) + _D("theme path: %s", theme); + + if (theme) + free(theme); +} + +static int __before_loop(int type, int argc, char **argv) +{ + int elm_init_cnt = 0; + Ecore_Fd_Handler *fd_handler = NULL; + int client_fd; + + __preload_init(argc, argv); + __preload_init_for_process_pool(); + __preexec_init(argc, argv); + +#ifdef _APPFW_FEATURE_BOOST_PRIORITY + res = setpriority(PRIO_PROCESS, 0, LOWEST_PRIO); + if (res == -1) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("Setting process (%d) priority to %d failed, errno: %d (%s)", + getpid(), LOWEST_PRIO, errno, strerror_r(errno, err_str, sizeof(err_str))); + } +#endif + _D("[candidate] Another candidate process was forked."); + + /* Set new session ID & new process group ID*/ + /* In linux, child can set new session ID without check permission */ + /* TODO : should be add to check permission in the kernel*/ + setsid(); + + /* SET OOM*/ + _set_oom(); + + client_fd = _connect_to_launchpad(type); + if (client_fd == -1) { + _D("Connecting to candidate process was failed."); + return -1; + } + + elm_init_cnt = elm_init(g_argc, g_argv); + _D("[candidate] elm init, returned: %d", elm_init_cnt); + + switch (type) { + case LAUNCHPAD_TYPE_SW: + elm_config_accel_preference_set("none"); + __init_window(); + break; + + case LAUNCHPAD_TYPE_HW: + elm_config_accel_preference_set("hw"); + __init_window(); + break; + + case LAUNCHPAD_TYPE_COMMON: + __init_theme(); + break; + } + + fd_handler = ecore_main_fd_handler_add(client_fd, + (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR), + __candidate_proces_fd_handler, &type, NULL, NULL); + if (fd_handler == NULL) { + _D("fd_handler is NULL"); + return -1; + } + + _D("[candidate] ecore handler add"); +#ifdef _APPFW_FEATURE_BOOST_PRIORITY + res = setpriority(PRIO_PGRP, 0, 0); + if (res == -1) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("Setting process (%d) priority to 0 failed, errno: %d (%s)", + getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); + } +#endif + return 0; +} + +static int __after_loop(void) +{ + void *handle = NULL; + int res; + int (*dl_main)(int, char **); + + SECURE_LOGD("[candidate] Launch real application (%s)", g_argv[0]); + handle = dlopen(g_argv[0], RTLD_LAZY | RTLD_GLOBAL); + if (handle == NULL) { + _E("dlopen failed(%s). Please complile with -fPIE and link with -pie flag", + dlerror()); + goto do_exec; + } + + dlerror(); + + dl_main = dlsym(handle, "main"); + if (dl_main != NULL) + res = dl_main(g_argc, g_argv); + else { + _E("dlsym not founded(%s). Please export 'main' function", dlerror()); + dlclose(handle); + goto do_exec; + } + + dlclose(handle); + return res; + +do_exec: + if (access(g_argv[0], F_OK | R_OK)) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("access() failed for file: \"%s\", error: %d (%s)", + g_argv[0], errno, strerror_r(errno, err_str, sizeof(err_str))); + } else { + SECURE_LOGD("[candidate] Exec application (%s)", g_argv[0]); + if (execv(g_argv[0], g_argv) < 0) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("execv() failed for file: \"%s\", error: %d (%s)", + g_argv[0], errno, strerror_r(errno, err_str, sizeof(err_str))); + } + } + + return -1; +} + +int main(int argc, char **argv) +{ + static int type = LAUNCHPAD_TYPE_UNSUPPORTED; + + if (argc < 2) { + _E("too few argument."); + return -1; + } + + type = argv[1][0] - '0'; + if (type < 0 || type >= LAUNCHPAD_TYPE_MAX) { + _E("invalid argument. (type: %d)", type); + return -1; + } + + //temp - this requires some optimization. + sleep(1); + _D("sleeping 1 sec..."); + + if (__before_loop(type, argc, argv) != 0) + return -1; + + _D("[candidate] ecore main loop begin"); + ecore_main_loop_begin(); + + return __after_loop(); +} -- 2.34.1 From b697f1cbbfedb8398abb4a2304abc51e5023d153 Mon Sep 17 00:00:00 2001 From: "Junghoon, Park" Date: Fri, 6 Nov 2015 15:16:44 +0900 Subject: [PATCH 3/7] apply some APIs from aul - modify cmakefile - apply preinit window - apply preinit pkgid/appid Change-Id: I8d8a7ff0b5f6dcbd8c6c9c1fdabec89a9afc76b9 Signed-off-by: Junghoon, Park --- CMakeLists.txt | 47 +++++++----- inc/launchpad_common.h | 6 +- packaging/launchpad.spec | 2 +- src/launchpad.c | 150 +++++++++++++++++++++++++++++++++++---- src/launchpad_common.c | 128 +-------------------------------- src/launchpad_loader.c | 16 ++--- 6 files changed, 179 insertions(+), 170 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b36e0baf..867449e8 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,10 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) -SET (this_target launchpad) +SET (this_target_pool launchpad_pool) +SET (this_target_loader launchpad_loader) INCLUDE(FindPkgConfig) -PKG_CHECK_MODULES(${this_target} REQUIRED +PKG_CHECK_MODULES(${this_target_pool} REQUIRED dlog - ecore - elementary libsystemd-daemon dbus-glib-1 vconf @@ -13,16 +12,32 @@ PKG_CHECK_MODULES(${this_target} REQUIRED bundle ) -FOREACH(flag ${${this_target}_CFLAGS}) - SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +FOREACH(flag ${${this_target_pool}_CFLAGS}) + SET(EXTRA_CFLAGS_pool "${EXTRA_CFLAGS_pool} ${flag}") ENDFOREACH(flag) -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -Wl,-zdefs" ) -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fPIE") -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fdata-sections -ffunction-sections -Wl,--gc-sections") -SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -D_FILE_OFFSET_BITS=64") -SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +PKG_CHECK_MODULES(${this_target_loader} REQUIRED + dlog + ecore + elementary + security-manager + bundle + aul + ) + +FOREACH(flag ${${this_target_loader}_CFLAGS}) + SET(EXTRA_CFLAGS_loader "${EXTRA_CFLAGS_loader} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} -Wl,-zdefs" ) +SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} -fvisibility=hidden") +SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} -fPIE") +SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} -fdata-sections -ffunction-sections -Wl,--gc-sections") +SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} -D_FILE_OFFSET_BITS=64") + +SET(EXTRA_CFLAGS_pool "${EXTRA_CFLAGS_pool} ${EXTRA_CFLAGS_common}") +SET(EXTRA_CFLAGS_loader "${EXTRA_CFLAGS_loader} ${EXTRA_CFLAGS_common}") + SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") SET(CMAKE_C_FLAGS_RELEASE "-O2") SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") @@ -48,8 +63,8 @@ SET(${LAUNCHPAD_LOADER}_SOURCE_FILES ADD_EXECUTABLE(${LAUNCHPAD_LOADER} ${${LAUNCHPAD_LOADER}_SOURCE_FILES}) TARGET_LINK_LIBRARIES(${LAUNCHPAD_LOADER} "-ldl") -TARGET_LINK_LIBRARIES(${LAUNCHPAD_LOADER} ${${this_target}_LDFLAGS} "-pie") - +TARGET_LINK_LIBRARIES(${LAUNCHPAD_LOADER} ${${this_target_loader}_LDFLAGS} "-pie") +SET_TARGET_PROPERTIES(${LAUNCHPAD_LOADER} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_loader}) SET_TARGET_PROPERTIES(${LAUNCHPAD_LOADER} PROPERTIES SKIP_BUILD_RPATH TRUE ) # remove rpath option that is automatically generated by cmake. @@ -63,8 +78,8 @@ SET(${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES ) ADD_EXECUTABLE(${LAUNCHPAD_PROCESS_POOL} ${${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES}) -TARGET_LINK_LIBRARIES(${LAUNCHPAD_PROCESS_POOL} ${${this_target}_LDFLAGS} "-pie") - +TARGET_LINK_LIBRARIES(${LAUNCHPAD_PROCESS_POOL} ${${this_target_pool}_LDFLAGS} "-pie") +SET_TARGET_PROPERTIES(${LAUNCHPAD_PROCESS_POOL} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_pool}) SET_TARGET_PROPERTIES(${LAUNCHPAD_PROCESS_POOL} PROPERTIES SKIP_BUILD_RPATH TRUE ) # remove rpath option that is automatically generated by cmake. diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h index 7fa81cdd..e677be73 100644 --- a/inc/launchpad_common.h +++ b/inc/launchpad_common.h @@ -34,6 +34,9 @@ #define LOG_TAG "LAUNCHPAD" #endif +#define SOCKET_PATH "/run/user" +#define LAUNCHPAD_LOADER_SOCKET_NAME ".launchpad-type" +#define MAX_PENDING_CONNECTIONS 10 #define MAX_LOCAL_BUFSZ 128 #define AUL_SOCK_MAXBUFF 65535 @@ -77,10 +80,7 @@ void _modify_bundle(bundle * kb, int caller_pid, app_info_from_db * menu_info, i int _create_server_sock(int pid); app_pkt_t *_recv_pkt_raw(int fd, int *clifd, struct ucred *cr); int _send_pkt_raw(int client_fd, app_pkt_t *pkt); -int _listen_candidate_process(int type); int _connect_to_launchpad(int type); -int _accept_candidate_process(int server_fd, int* out_client_fd, int* out_client_pid); -void _refuse_candidate_process(int server_fd); void _set_oom(void); void _set_env(app_info_from_db * menu_info, bundle * kb); char** _create_argc_argv(bundle * kb, int *margc); diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index b0ac4ccb..73fad0eb 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -12,13 +12,13 @@ Source102: launchpad-process-pool.socket BuildRequires: cmake BuildRequires: pkgconfig(bundle) BuildRequires: pkgconfig(dbus-glib-1) -BuildRequires: pkgconfig(sqlite3) BuildRequires: pkgconfig(ecore) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(libsystemd-daemon) BuildRequires: pkgconfig(elementary) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(security-manager) +BuildRequires: pkgconfig(aul) Requires(post): /sbin/ldconfig Requires(post): /usr/bin/systemctl diff --git a/src/launchpad.c b/src/launchpad.c index 129cc202..09d20aaf 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -22,10 +22,13 @@ #include #include #include +#include #include #include #include #include +#include +#include #include "perf.h" #include "launchpad_common.h" @@ -62,6 +65,128 @@ static candidate __candidate[LAUNCHPAD_TYPE_MAX] = { static int launchpad_fd = -1; static int pool_fd[LAUNCHPAD_TYPE_MAX] = { -1, -1, -1 }; +static void __refuse_candidate_process(int server_fd) +{ + int client_fd = -1; + + if (server_fd == -1) { + _E("arguments error!"); + goto error; + } + + client_fd = accept(server_fd, NULL, NULL); + if (client_fd == -1) { + _E("accept error!"); + goto error; + } + + close(client_fd); + _D("refuse connection!"); + +error: + return; +} + +static int __accept_candidate_process(int server_fd, int* out_client_fd, + int* out_client_pid) +{ + int client_fd = -1, client_pid = 0, recv_ret = 0; + + if (server_fd == -1 || out_client_fd == NULL || out_client_pid == NULL) { + _E("arguments error!"); + goto error; + } + + client_fd = accept(server_fd, NULL, NULL); + + if (client_fd == -1) { + _E("accept error!"); + goto error; + } + + recv_ret = recv(client_fd, &client_pid, sizeof(client_pid), MSG_WAITALL); + + if (recv_ret == -1) { + _E("recv error!"); + goto error; + } + + *out_client_fd = client_fd; + *out_client_pid = client_pid; + + return *out_client_fd; + +error: + if (client_fd != -1) + close(client_fd); + + return -1; +} + +static int __listen_candidate_process(int type) +{ + struct sockaddr_un addr; + int fd = -1; + int listen_fds = 0; + int i; + + _D("[launchpad] enter, type: %d", type); + + memset(&addr, 0x00, sizeof(struct sockaddr_un)); + addr.sun_family = AF_UNIX; + snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%d/%s%d", SOCKET_PATH, getuid(), + LAUNCHPAD_LOADER_SOCKET_NAME, type); + + listen_fds = sd_listen_fds(0); + if (listen_fds < 0) { + _E("Invalid systemd environment"); + return -1; + } else if (listen_fds > 0) { + for (i = 0; i < listen_fds; i++) { + fd = SD_LISTEN_FDS_START + i; + if (sd_is_socket_unix(fd, SOCK_STREAM, 1, addr.sun_path, 0)) + return fd; + } + _E("Socket not found: %s", addr.sun_path); + return -1; + } + + fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (fd < 0) { + _E("Socket error"); + goto error; + } + + unlink(addr.sun_path); + + _D("bind to %s", addr.sun_path); + if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + _E("bind error"); + goto error; + } + + _D("chmod %s", addr.sun_path); + if (chmod(addr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { + _E("chmod error"); + goto error; + } + + _D("listen to %s", addr.sun_path); + if (listen(fd, MAX_PENDING_CONNECTIONS) == -1) { + _E("listen error"); + goto error; + } + + SECURE_LOGD("[launchpad] done, listen fd: %d", fd); + return fd; + +error: + if (fd != -1) + close(fd); + + return -1; +} + static int __set_access(const char* appId, const char* pkg_type, const char* app_path) { @@ -79,7 +204,6 @@ static int __get_launchpad_type(const char* internal_pool, const char* hwacc) _D("[launchpad] launchpad type: H/W(%d)", LAUNCHPAD_TYPE_HW); return LAUNCHPAD_TYPE_HW; } - /* TODO: FIXME if (strncmp(hwacc, "SYS", 3) == 0) { int r; int sys_hwacc = -1; @@ -98,7 +222,7 @@ static int __get_launchpad_type(const char* internal_pool, const char* hwacc) _D("[launchpad] launchpad type: S/W(%d)", LAUNCHPAD_TYPE_SW); return LAUNCHPAD_TYPE_SW; } - }*/ + } } _D("[launchpad] launchpad type: COMMON(%d)", LAUNCHPAD_TYPE_COMMON); @@ -560,7 +684,7 @@ static int __init_pfds(struct pollfd *pfds, int argc, char **argv) pfds[LAUNCH_PAD].revents = 0; for (i = 0; i < LAUNCHPAD_TYPE_MAX; ++i) { - pool_fd[i] = _listen_candidate_process(i); + pool_fd[i] = __listen_candidate_process(i); if (pool_fd[i] == -1) { _E("[launchpad] Listening the socket to the type %d candidate process failed.", i); @@ -648,19 +772,19 @@ static int __loop_begin(struct pollfd *pfds) _D("pfds[POOL_TYPE + %d].revents & POLLIN", i); if (__candidate[i].pid == CANDIDATE_NONE) { - _accept_candidate_process(server_fd, &client_fd, &client_pid); - - __candidate[i].pid = client_pid; - __candidate[i].send_fd = client_fd; + if (__accept_candidate_process(server_fd, &client_fd, &client_pid) >= 0) { + __candidate[i].pid = client_pid; + __candidate[i].send_fd = client_fd; - pfds[CANDIDATE_TYPE + i].fd = client_fd; - pfds[CANDIDATE_TYPE + i].events = POLLIN | POLLHUP; - pfds[CANDIDATE_TYPE + i].revents = 0; + pfds[CANDIDATE_TYPE + i].fd = client_fd; + pfds[CANDIDATE_TYPE + i].events = POLLIN | POLLHUP; + pfds[CANDIDATE_TYPE + i].revents = 0; - SECURE_LOGD("Type %d candidate process was connected, pid: %d", i, - __candidate[i].pid); + SECURE_LOGD("Type %d candidate process was connected, pid: %d", i, + __candidate[i].pid); + } } else { - _refuse_candidate_process(server_fd); + __refuse_candidate_process(server_fd); _E("Refused candidate process connection"); } } diff --git a/src/launchpad_common.c b/src/launchpad_common.c index 984cc5c8..6b86b45d 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "launchpad_common.h" #include "key.h" @@ -40,8 +39,6 @@ #define OPTION_VALGRIND_SIZE 8 #define MAX_CMD_BUFSZ 1024 -#define SOCKET_PATH "/run/user" -#define LAUNCHPAD_TYPE ".launchpad-type" #define MAX_PENDING_CONNECTIONS 10 #define CONNECT_RETRY_TIME 100 * 1000 #define CONNECT_RETRY_COUNT 3 @@ -411,6 +408,7 @@ void _modify_bundle(bundle * kb, int caller_pid, app_info_from_db * menu_info, i bundle_del(kb, AUL_K_PACKAGETYPE); bundle_del(kb, AUL_K_HWACC); bundle_del(kb, AUL_K_TASKMANAGE); + bundle_del(kb, AUL_K_PKGID); /* Parse app_path to retrieve default bundle*/ if (cmd == APP_START || cmd == APP_START_RES || cmd == APP_OPEN @@ -450,70 +448,6 @@ void _modify_bundle(bundle * kb, int caller_pid, app_info_from_db * menu_info, i } } -int _listen_candidate_process(int type) -{ - struct sockaddr_un addr; - int fd = -1; - int listen_fds = 0; - int i; - - _D("[launchpad] enter, type: %d", type); - - memset(&addr, 0x00, sizeof(struct sockaddr_un)); - addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%d/%s%d", SOCKET_PATH, getuid(), - LAUNCHPAD_TYPE, type); - - listen_fds = sd_listen_fds(0); - if (listen_fds < 0) { - _E("Invalid systemd environment"); - return -1; - } else if (listen_fds > 0) { - for (i = 0; i < listen_fds; i++) { - fd = SD_LISTEN_FDS_START + i; - if (sd_is_socket_unix(fd, SOCK_STREAM, 1, addr.sun_path, 0)) - return fd; - } - _E("Socket not found: %s", addr.sun_path); - return -1; - } - - fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); - if (fd < 0) { - _E("Socket error"); - goto error; - } - - unlink(addr.sun_path); - - _D("bind to %s", addr.sun_path); - if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - _E("bind error"); - goto error; - } - - _D("chmod %s", addr.sun_path); - if (chmod(addr.sun_path, (S_IRWXU | S_IRWXG | S_IRWXO)) < 0) { - _E("chmod error"); - goto error; - } - - _D("listen to %s", addr.sun_path); - if (listen(fd, MAX_PENDING_CONNECTIONS) == -1) { - _E("listen error"); - goto error; - } - - SECURE_LOGD("[launchpad] done, listen fd: %d", fd); - return fd; - -error: - if (fd != -1) - close(fd); - - return -1; -} - int _connect_to_launchpad(int type) { struct sockaddr_un addr; @@ -533,7 +467,7 @@ int _connect_to_launchpad(int type) memset(&addr, 0x00, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%d/%s%d", SOCKET_PATH, getuid(), - LAUNCHPAD_TYPE, type); + LAUNCHPAD_LOADER_SOCKET_NAME, type); _D("connect to %s", addr.sun_path); while (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { @@ -565,64 +499,6 @@ error: return -1; } -int _accept_candidate_process(int server_fd, int* out_client_fd, - int* out_client_pid) -{ - int client_fd = -1, client_pid = 0, recv_ret = 0; - - if (server_fd == -1 || out_client_fd == NULL || out_client_pid == NULL) { - _E("arguments error!"); - goto error; - } - - client_fd = accept(server_fd, NULL, NULL); - - if (client_fd == -1) { - _E("accept error!"); - goto error; - } - - recv_ret = recv(client_fd, &client_pid, sizeof(client_pid), MSG_WAITALL); - - if (recv_ret == -1) { - _E("recv error!"); - goto error; - } - - *out_client_fd = client_fd; - *out_client_pid = client_pid; - - return *out_client_fd; - -error: - if (client_fd != -1) - close(client_fd); - - return -1; -} - -void _refuse_candidate_process(int server_fd) -{ - int client_fd = -1; - - if (server_fd == -1) { - _E("arguments error!"); - goto error; - } - - client_fd = accept(server_fd, NULL, NULL); - if (client_fd == -1) { - _E("accept error!"); - goto error; - } - - close(client_fd); - _D("refuse connection!"); - -error: - return; -} - void _set_oom(void) { char buf[MAX_LOCAL_BUFSZ]; diff --git a/src/launchpad_loader.c b/src/launchpad_loader.c index 525b61ce..b755989d 100644 --- a/src/launchpad_loader.c +++ b/src/launchpad_loader.c @@ -24,19 +24,18 @@ #include #include #include -#include #include #include #include -#include #include +#include #include "menu_db_util.h" #include "launchpad_common.h" #include "preload.h" #include "process_pool_preload.h" #include "preexec.h" -#include "key.h" + #define AUL_PR_NAME 16 #define LOWEST_PRIO 20 @@ -123,7 +122,7 @@ static void __candidate_process_launchpad_main_loop(app_pkt_t* pkt, const char *app_id = NULL; const char *app_path = NULL; - //const char *pkg_id = NULL; + const char *pkg_id = NULL; kb = bundle_decode(pkt->data, pkt->len); if (!kb) { @@ -176,14 +175,12 @@ static void __candidate_process_launchpad_main_loop(app_pkt_t* pkt, exit(-1); } SECURE_LOGD("app id: %s", app_id); -#if 0 - //TODO : FIXME __appid = strdup(app_id); if (__appid == NULL) { _E("Out of memory"); exit(-1); } - //aul_set_preinit_appid(__appid); //TODO + aul_set_preinit_appid(__appid); // caching pkgid pkg_id = _get_pkgid(menu_info); @@ -198,8 +195,7 @@ static void __candidate_process_launchpad_main_loop(app_pkt_t* pkt, _E("Out of memory"); exit(-1); } - //aul_set_preinit_pkgid(__pkgid); //TODO -#endif + aul_set_preinit_pkgid(__pkgid); atexit(__release_appid_at_exit); @@ -300,7 +296,6 @@ static Eina_Bool __candidate_proces_fd_handler(void* data, static void __init_window(void) { -#if 0 //TODO : FIXME Evas_Object *win = elm_win_add(NULL, "package_name", ELM_WIN_BASIC); if (win) { aul_set_preinit_window(win); @@ -325,7 +320,6 @@ static void __init_window(void) } else { _E("[candidate] elm_win_add() failed"); } -#endif } static void __init_theme(void) -- 2.34.1 From ad1a35219f47af9788b1a9ed0477215604b25a39 Mon Sep 17 00:00:00 2001 From: "Junghoon, Park" Date: Fri, 13 Nov 2015 17:45:35 +0900 Subject: [PATCH 4/7] add library for making launchpad-loader Change-Id: Ic929c89fa1f8b77172846423a1658009b142a99e Signed-off-by: Junghoon, Park --- CMakeLists.txt | 35 +++- inc/launchpad.h | 64 ++++++ inc/launchpad_common.h | 8 - launchpad.pc.in | 13 ++ packaging/launchpad.spec | 13 +- src/launchpad.c | 1 + src/launchpad_lib.c | 382 ++++++++++++++++++++++++++++++++++++ src/launchpad_loader.c | 407 ++++++++------------------------------- 8 files changed, 583 insertions(+), 340 deletions(-) create mode 100644 inc/launchpad.h create mode 100644 launchpad.pc.in create mode 100644 src/launchpad_lib.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 867449e8..0eccf724 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,8 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.6) SET (this_target_pool launchpad_pool) SET (this_target_loader launchpad_loader) +SET (this_target_lib launchpad) +SET (VERSION_MAJOR 0) INCLUDE(FindPkgConfig) PKG_CHECK_MODULES(${this_target_pool} REQUIRED @@ -29,6 +31,17 @@ FOREACH(flag ${${this_target_loader}_CFLAGS}) SET(EXTRA_CFLAGS_loader "${EXTRA_CFLAGS_loader} ${flag}") ENDFOREACH(flag) +PKG_CHECK_MODULES(${this_target_lib} REQUIRED + dlog + bundle + aul + security-manager + ) + +FOREACH(flag ${${this_target_lib}_CFLAGS}) + SET(EXTRA_CFLAGS_lib "${EXTRA_CFLAGS_lib} ${flag}") +ENDFOREACH(flag) + SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} -Wl,-zdefs" ) SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} -fvisibility=hidden") SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} -fPIE") @@ -37,6 +50,7 @@ SET(EXTRA_CFLAGS_common "${EXTRA_CFLAGS_common} -D_FILE_OFFSET_BITS=64") SET(EXTRA_CFLAGS_pool "${EXTRA_CFLAGS_pool} ${EXTRA_CFLAGS_common}") SET(EXTRA_CFLAGS_loader "${EXTRA_CFLAGS_loader} ${EXTRA_CFLAGS_common}") +SET(EXTRA_CFLAGS_lib "${EXTRA_CFLAGS_lib} ${EXTRA_CFLAGS_common}") SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") SET(CMAKE_C_FLAGS_RELEASE "-O2") @@ -55,10 +69,12 @@ ADD_DEFINITIONS("-DPREEXEC_ACTIVATE") INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/inc) +# launchpad-loader SET(LAUNCHPAD_LOADER "launchpad-loader") SET(${LAUNCHPAD_LOADER}_SOURCE_FILES src/launchpad_loader.c src/launchpad_common.c + src/launchpad_lib.c ) ADD_EXECUTABLE(${LAUNCHPAD_LOADER} ${${LAUNCHPAD_LOADER}_SOURCE_FILES}) @@ -70,8 +86,8 @@ SET_TARGET_PROPERTIES(${LAUNCHPAD_LOADER} ) # remove rpath option that is automatically generated by cmake. INSTALL(TARGETS ${LAUNCHPAD_LOADER} DESTINATION bin) +# launchpad-process-pool SET(LAUNCHPAD_PROCESS_POOL "launchpad-process-pool") - SET(${LAUNCHPAD_PROCESS_POOL}_SOURCE_FILES src/launchpad.c src/launchpad_common.c @@ -87,3 +103,20 @@ SET_TARGET_PROPERTIES(${LAUNCHPAD_PROCESS_POOL} INSTALL(TARGETS ${LAUNCHPAD_PROCESS_POOL} DESTINATION bin) INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/packaging/launchpad-process-pool-preload-list.txt DESTINATION share/aul) +# liblaunchpad +SET(LAUNCHPAD_LIB "launchpad") +ADD_LIBRARY(${LAUNCHPAD_LIB} SHARED + src/launchpad_lib.c + src/launchpad_common.c + ) +SET_TARGET_PROPERTIES(${LAUNCHPAD_LIB} PROPERTIES SOVERSION ${VERSION_MAJOR}) +SET_TARGET_PROPERTIES(${LAUNCHPAD_LIB} PROPERTIES VERSION ${VERSION}) +SET_TARGET_PROPERTIES(${LAUNCHPAD_LIB} PROPERTIES COMPILE_FLAGS ${EXTRA_CFLAGS_lib}) +TARGET_LINK_LIBRARIES(${LAUNCHPAD_LIB} ${${this_target_lib}_LDFLAGS} "-ldl") +INSTALL(TARGETS ${LAUNCHPAD_LIB} DESTINATION ${LIB_INSTALL_DIR} COMPONENT RuntimeLibraries) +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/inc/launchpad.h DESTINATION include/launchpad) +CONFIGURE_FILE(launchpad.pc.in launchpad.pc @ONLY) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/launchpad.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig) + + + diff --git a/inc/launchpad.h b/inc/launchpad.h new file mode 100644 index 00000000..37d50ed0 --- /dev/null +++ b/inc/launchpad.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __LAUNCHPAD_H__ +#define __LAUNCHPAD_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*loader_create_cb)(int argc, char **argv, int type, void *user_data); +typedef int (*loader_launch_cb)(int argc, char **argv, const char *app_path, + const char *appid, const char *pkgid, const char *pkg_type, void *user_data); +typedef int (*loader_terminate_cb)(int argc, char **argv, void *user_data); + +typedef void (*loader_receiver_cb)(int fd); +typedef void (*loader_loop_begin_cb)(void *user_data); +typedef void (*loader_loop_quit_cb)(void *user_data); +typedef void (*loader_add_fd_cb)(void *user_data, int fd, loader_receiver_cb receiver); +typedef void (*loader_remove_fd_cb)(void *user_data, int fd); + +typedef struct { + loader_create_cb create; + loader_launch_cb launch; + loader_terminate_cb terminate; +} loader_lifecycle_callback_s; + +typedef struct { + loader_loop_begin_cb loop_begin; + loader_loop_quit_cb loop_quit; + loader_add_fd_cb add_fd; + loader_remove_fd_cb remove_fd; +} loader_adapter_s; + +enum LAUNCHPAD_TYPE { + LAUNCHPAD_TYPE_UNSUPPORTED = -1, + LAUNCHPAD_TYPE_COMMON, + LAUNCHPAD_TYPE_SW, + LAUNCHPAD_TYPE_HW, + LAUNCHPAD_TYPE_MAX +}; + +int launchpad_loader_main(int argc, char **argv, loader_lifecycle_callback_s *callbacks, loader_adapter_s *adapter, void *user_data); + + +#ifdef __cplusplus +} +#endif + +#endif /* __LAUNCHPAD_H__ */ + diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h index e677be73..0934a0ce 100644 --- a/inc/launchpad_common.h +++ b/inc/launchpad_common.h @@ -65,14 +65,6 @@ typedef struct _app_pkt_t { unsigned char data[1]; } app_pkt_t; -enum LAUNCHPAD_TYPE { - LAUNCHPAD_TYPE_UNSUPPORTED = -1, - LAUNCHPAD_TYPE_COMMON, - LAUNCHPAD_TYPE_SW, - LAUNCHPAD_TYPE_HW, - LAUNCHPAD_TYPE_MAX -}; - char *_proc_get_cmdline_bypid(int pid); app_info_from_db *_get_app_info_from_bundle_by_pkgname(const char *pkgname, bundle *kb); void _modify_bundle(bundle * kb, int caller_pid, app_info_from_db * menu_info, int cmd); diff --git a/launchpad.pc.in b/launchpad.pc.in new file mode 100644 index 00000000..a3da8bfa --- /dev/null +++ b/launchpad.pc.in @@ -0,0 +1,13 @@ +# Package Information for pkg-config + +prefix=/usr +exec_prefix=@EXEC_PREFIX@ +libdir=@LIB_INSTALL_DIR@ +includedir=@INCLUDE_INSTALL_DIR@ + +Name: liblaunchpad +Description: launchpad library for making other types of loader +Version: @VERSION@ +Requires: bundle dlog aul +Libs: -L${libdir} -llaunchpad +Cflags: -I${includedir} -I${includedir}/launchpad diff --git a/packaging/launchpad.spec b/packaging/launchpad.spec index 73fad0eb..8d87f02c 100644 --- a/packaging/launchpad.spec +++ b/packaging/launchpad.spec @@ -52,10 +52,10 @@ export FFLAGS="$FFLAGS -DTIZEN_DEBUG_ENABLE" _APPFW_FEATURE_PRIORITY_CHANGE=ON %endif -cmake -DCMAKE_INSTALL_PREFIX=%{_prefix} \ - -D_APPFW_FEATURE_PRIORITY_CHANGE:BOOL=${_APPFW_FEATURE_PRIORITY_CHANGE} - -make %{?jobs:-j%jobs} +%cmake -DVERSION=%{version} \ + -D_APPFW_FEATURE_PRIORITY_CHANGE:BOOL=${_APPFW_FEATURE_PRIORITY_CHANGE} \ + . +%__make %{?_smp_mflags} %install rm -rf %{buildroot} @@ -83,4 +83,9 @@ cp %{_builddir}/%{name}-%{version}/LICENSE %{buildroot}/usr/share/license/%{nam %{_unitdir_user}/default.target.wants/launchpad-process-pool.service %caps(cap_mac_admin,cap_mac_override,cap_setgid=ei) %{_bindir}/launchpad-process-pool %caps(cap_mac_admin,cap_mac_override,cap_setgid=ei) %{_bindir}/launchpad-loader +%attr(0644,root,root) %{_libdir}/liblaunchpad.so.* +%files devel +%{_includedir}/launchpad/*.h +%{_libdir}/*.so +%{_libdir}/pkgconfig/*.pc diff --git a/src/launchpad.c b/src/launchpad.c index 09d20aaf..0d5e7425 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -34,6 +34,7 @@ #include "launchpad_common.h" #include "sigchild.h" #include "key.h" +#include "launchpad.h" #define AUL_PR_NAME 16 #define AUL_POLL_CNT 15 diff --git a/src/launchpad_lib.c b/src/launchpad_lib.c new file mode 100644 index 00000000..c22cd3a4 --- /dev/null +++ b/src/launchpad_lib.c @@ -0,0 +1,382 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "launchpad_common.h" +#include "launchpad.h" +#include "preexec.h" + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +#define AUL_PR_NAME 16 +#define LOWEST_PRIO 20 + +static loader_lifecycle_callback_s *__loader_callbacks; +static loader_adapter_s *__loader_adapter; +static void *__loader_user_data; +static int __argc; +static char **__argv; +static bundle *__bundle; +static char *__appid; +static char *__pkgid; +static int __loader_type = LAUNCHPAD_TYPE_UNSUPPORTED; + +static void __at_exit_to_release_bundle() +{ + if (__bundle) { + bundle_free(__bundle); + __bundle = NULL; + } +} + +static void __release_appid_at_exit(void) +{ + if (__appid != NULL) { + free(__appid); + } + if (__pkgid != NULL) { + free(__pkgid); + } +} + +static int __set_access(const char* appId, const char* pkg_type, + const char* app_path) +{ + return security_manager_prepare_app(appId) == SECURITY_MANAGER_SUCCESS ? 0 : -1; +} + +static int __prepare_exec(const char *appid, const char *app_path, + const char *pkg_type, int type) +{ + const char *file_name = NULL; + char process_name[AUL_PR_NAME] = { 0, }; + int ret = 0; + + __preexec_run(pkg_type, appid, app_path); + + /* SET PRIVILEGES*/ + SECURE_LOGD("[candidata] appid : %s / pkg_type : %s / app_path : %s", + appid, pkg_type, app_path); + if ((ret = __set_access(appid, pkg_type, app_path)) < 0) { + _D("fail to set privileges - check your package's credential : %d\n", ret); + return -1; + } + + /* + * SET DUMPABLE - for coredump + * This dumpable flag should be set after calling perm_app_set_privilege() + */ + prctl(PR_SET_DUMPABLE, 1); + + /* SET PROCESS NAME*/ + if (app_path == NULL) { + _D("app_path should not be NULL - check menu db"); + return -1; + } + + file_name = strrchr(app_path, '/') + 1; + if (file_name == NULL) { + _D("can't locate file name to execute"); + return -1; + } + memset(process_name, '\0', AUL_PR_NAME); + snprintf(process_name, AUL_PR_NAME, "%s", file_name); + prctl(PR_SET_NAME, process_name); + + return 0; +} + +static int __default_launch_cb(bundle *kb, const char *appid, + const char *app_path, const char *pkg_type, int loader_type) +{ +#ifdef _APPFW_FEATURE_PRIORITY_CHANGE + const char *high_priority = bundle_get_val(kb, AUL_K_HIGHPRIORITY); + _D("high_priority: %s", high_priority); + + if (strncmp(high_priority, "true", 4) == 0) { + int res = setpriority(PRIO_PROCESS, 0, -10); + if (res == -1) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("Setting process (%d) priority to -10 failed, errno: %d (%s)", + getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); + } + } + bundle_del(kb, AUL_K_HIGHPRIORITY); +#endif + + 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)) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("access() failed for file: \"%s\", error: %d (%s)", + app_path, errno, strerror_r(errno, err_str, sizeof(err_str))); + } + exit(-1); + } + + return 0; +} + +static int __candidate_process_launchpad_main_loop(app_pkt_t* pkt, + char* out_app_path, int* out_argc, char ***out_argv, int type) +{ + bundle *kb = NULL; + app_info_from_db *menu_info = NULL; + const char *app_id = NULL; + const char *app_path = NULL; + const char *pkg_id = NULL; + int tmp_argc = 0; + char **tmp_argv = NULL; + int ret = -1; + + kb = bundle_decode(pkt->data, pkt->len); + if (!kb) { + _E("bundle decode error"); + exit(-1); + } + + if (__bundle != NULL) + bundle_free(__bundle); + + __bundle = kb; + atexit(__at_exit_to_release_bundle); + + app_id = bundle_get_val(kb, AUL_K_APPID); + if (app_id == NULL) { + _E("Unable to get app_id"); + exit(-1); + } + + menu_info = _get_app_info_from_bundle_by_pkgname(app_id, kb); + if (menu_info == NULL) { + _D("such pkg no found"); + exit(-1); + } + + if (type < 0) { + _E("Invalid launchpad type: %d", type); + exit(-1); + } + + SECURE_LOGD("app id: %s, launchpad type: %d", app_id, type); + + app_path = _get_app_path(menu_info); + if (app_path == NULL) { + _E("app_path is NULL"); + exit(-1); + } + + if (app_path[0] != '/') { + _E("app_path is not absolute path"); + exit(-1); + } + + _modify_bundle(kb, /*cr.pid - unused parameter*/ 0, menu_info, pkt->cmd); + + app_id = _get_pkgname(menu_info); + if (app_id == NULL) { + _E("unable to get app_id from menu_info"); + exit(-1); + } + SECURE_LOGD("app id: %s", app_id); + __appid = strdup(app_id); + if (__appid == NULL) { + _E("Out of memory"); + exit(-1); + } + aul_set_preinit_appid(__appid); + + pkg_id = _get_pkgid(menu_info); + if (pkg_id == NULL) { + _E("unable to get pkg_id from menu_info"); + exit(-1); + } + SECURE_LOGD("pkg id: %s", pkg_id); + + __pkgid = strdup(pkg_id); + if (__pkgid == NULL) { + _E("Out of memory"); + exit(-1); + } + aul_set_preinit_pkgid(__pkgid); + atexit(__release_appid_at_exit); + + tmp_argv = _create_argc_argv(kb, &tmp_argc); + + __default_launch_cb(kb, __appid, app_path, menu_info->pkg_type, type); + + if (__loader_callbacks->launch) { + ret = __loader_callbacks->launch(tmp_argc, tmp_argv, app_path, __appid, __pkgid, + menu_info->pkg_type, __loader_user_data); + } + + /* SET ENVIROMENT*/ + _set_env(menu_info, kb); + + if (out_app_path != NULL && out_argc != NULL && out_argv != NULL) { + int i = 0; + + memset(out_app_path, '\0', strlen(out_app_path)); + sprintf(out_app_path, "%s", app_path); + + *out_argv = tmp_argv; + *out_argc = tmp_argc; + (*out_argv)[0] = out_app_path; + + for (i = 0; i < *out_argc; i++) + SECURE_LOGD("input argument %d : %s##", i, (*out_argv)[i]); + } else + exit(-1); + + if (menu_info != NULL) + _free_app_info_from_db(menu_info); + + return ret; +} + +static void __receiver_cb(int fd) +{ + _D("[candidate] ECORE_FD_READ"); + app_pkt_t* pkt = (app_pkt_t*) malloc(sizeof(char) * AUL_SOCK_MAXBUFF); + if (!pkt) { + _D("[candidate] out of memory1"); + exit(-1); + } + memset(pkt, 0, AUL_SOCK_MAXBUFF); + + int ret = -1; + int recv_ret = recv(fd, pkt, AUL_SOCK_MAXBUFF, 0); + + if (recv_ret == -1) { + _D("[condidate] recv error!"); + close(fd); + free(pkt); + exit(-1); + } + _D("[candidate] recv_ret: %d, pkt->len: %d", recv_ret, pkt->len); + + __loader_adapter->remove_fd(__loader_user_data, fd); + ret = __candidate_process_launchpad_main_loop(pkt, __argv[0], &__argc, &__argv, + __loader_type); + SECURE_LOGD("[candidate] real app argv[0]: %s, real app argc: %d", __argv[0], + __argc); + close(fd); + free(pkt); + + if (ret >= 0) { + __loader_adapter->loop_quit(__loader_user_data); + _D("[candidate] ecore main loop quit"); + } +} + +static int __before_loop(int argc, char **argv) +{ + int client_fd; + int ret = -1; + + client_fd = _connect_to_launchpad(__loader_type); + if (client_fd == -1) { + _D("Connecting to candidate process was failed."); + return -1; + } + +#ifdef _APPFW_FEATURE_BOOST_PRIORITY + int res = setpriority(PRIO_PROCESS, 0, LOWEST_PRIO); + + if (res == -1) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("Setting process (%d) priority to %d failed, errno: %d (%s)", + getpid(), LOWEST_PRIO, errno, strerror_r(errno, err_str, sizeof(err_str))); + } +#endif + __preexec_init(argc, argv); + if (__loader_callbacks->create) { + __loader_callbacks->create(argc, argv, __loader_type, __loader_user_data); + __loader_adapter->add_fd(__loader_user_data, client_fd, __receiver_cb); + ret = 0; + } + +#ifdef _APPFW_FEATURE_BOOST_PRIORITY + res = setpriority(PRIO_PGRP, 0, 0); + if (res == -1) { + char err_str[MAX_LOCAL_BUFSZ] = { 0, }; + + SECURE_LOGE("Setting process (%d) priority to 0 failed, errno: %d (%s)", + getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); + } +#endif + return ret; +} + +static int __after_loop(void) +{ + if (__loader_callbacks->terminate) { + return __loader_callbacks->terminate(__argc, __argv, __loader_user_data); + } + return -1; +} + + +API int launchpad_loader_main(int argc, char **argv, + loader_lifecycle_callback_s *callbacks, loader_adapter_s *adapter, + void *user_data) +{ + if (argc < 2) { + _E("too few argument."); + return -1; + } + + __loader_type = argv[1][0] - '0'; + if (__loader_type < 0 || __loader_type >= LAUNCHPAD_TYPE_MAX) { + _E("invalid argument. (type: %d)", __loader_type); + return -1; + } + + if (callbacks == NULL) { + _E("invalid argument. callback is null"); + return -1; + } + + if (adapter == NULL) { + _E("invalid argument. adapter is null"); + return -1; + } + + if (adapter->loop_begin == NULL || adapter->loop_quit == NULL + || adapter->add_fd == NULL || adapter->remove_fd == NULL) { + _E("invalid argument. adapter callback is null"); + return -1; + } + + __loader_callbacks = callbacks; + __loader_adapter = adapter; + __loader_user_data = user_data; + __argc = argc; + __argv = argv; + + //temp - this requires some optimization. + sleep(1); + _D("sleeping 1 sec..."); + + if (__before_loop(argc, argv) != 0) + return -1; + + _D("[candidate] ecore main loop begin"); + __loader_adapter->loop_begin(__loader_user_data); + + return __after_loop(); +} + + diff --git a/src/launchpad_loader.c b/src/launchpad_loader.c index b755989d..8f081c71 100644 --- a/src/launchpad_loader.c +++ b/src/launchpad_loader.c @@ -17,282 +17,21 @@ #define _GNU_SOURCE #include #include -#include #include -#include #include #include -#include -#include #include -#include #include -#include #include #include "menu_db_util.h" #include "launchpad_common.h" #include "preload.h" #include "process_pool_preload.h" -#include "preexec.h" +#include "launchpad.h" - -#define AUL_PR_NAME 16 -#define LOWEST_PRIO 20 - -static char *__appid; -static char *__pkgid; -static bundle *_s_bundle; - -static int __set_access(const char* appId, const char* pkg_type, - const char* app_path) -{ - return security_manager_prepare_app(appId) == SECURITY_MANAGER_SUCCESS ? 0 : -1; -} - -static int __candidate_process_prepare_exec(const char *pkg_name, - const char *app_path, app_info_from_db *menu_info, - bundle *kb, int type) -{ - const char *file_name = NULL; - char process_name[AUL_PR_NAME] = { 0, }; - int ret = 0; - - __preexec_run(menu_info->pkg_type, pkg_name, app_path); - - /* SET PRIVILEGES*/ - SECURE_LOGD("[candidata] pkg_name : %s / pkg_type : %s / app_path : %s", - pkg_name, menu_info->pkg_type, app_path); - if ((ret = __set_access(pkg_name, menu_info->pkg_type, app_path)) < 0) { - _D("fail to set privileges - check your package's credential : %d\n", ret); - return -1; - } - - /* - * SET DUMPABLE - for coredump - * This dumpable flag should be set after calling perm_app_set_privilege() - */ - prctl(PR_SET_DUMPABLE, 1); - - /* SET PROCESS NAME*/ - if (app_path == NULL) { - _D("app_path should not be NULL - check menu db"); - return -1; - } - - file_name = strrchr(app_path, '/') + 1; - if (file_name == NULL) { - _D("can't locate file name to execute"); - return -1; - } - memset(process_name, '\0', AUL_PR_NAME); - snprintf(process_name, AUL_PR_NAME, "%s", file_name); - prctl(PR_SET_NAME, process_name); - - /* SET ENVIROMENT*/ - _set_env(menu_info, kb); - - return 0; -} - -static void __at_exit_to_release_bundle() -{ - if (_s_bundle) { - bundle_free(_s_bundle); - _s_bundle = NULL; - } -} - -static void __release_appid_at_exit(void) -{ - if (__appid != NULL) { - free(__appid); - } - if (__pkgid != NULL) { - free(__pkgid); - } -} - -static void __candidate_process_launchpad_main_loop(app_pkt_t* pkt, - char* out_app_path, int* out_argc, char ***out_argv, - int type) -{ - bundle *kb = NULL; - app_info_from_db *menu_info = NULL; - - const char *app_id = NULL; - const char *app_path = NULL; - const char *pkg_id = NULL; - - kb = bundle_decode(pkt->data, pkt->len); - if (!kb) { - _E("bundle decode error"); - exit(-1); - } - - if (_s_bundle != NULL) - bundle_free(_s_bundle); - - _s_bundle = kb; - atexit(__at_exit_to_release_bundle); - - app_id = bundle_get_val(kb, AUL_K_APPID); - if (app_id == NULL) { - _E("Unable to get app_id"); - exit(-1); - } - - menu_info = _get_app_info_from_bundle_by_pkgname(app_id, kb); - if (menu_info == NULL) { - _D("such pkg no found"); - exit(-1); - } - - if (type < 0) { - _E("Invalid launchpad type: %d", type); - exit(-1); - } - - SECURE_LOGD("app id: %s, launchpad type: %d", app_id, type); - - app_path = _get_app_path(menu_info); - if (app_path == NULL) { - _E("app_path is NULL"); - exit(-1); - } - - if (app_path[0] != '/') { - _E("app_path is not absolute path"); - exit(-1); - } - - _modify_bundle(kb, /*cr.pid - unused parameter*/ 0, menu_info, pkt->cmd); - - // caching appid - app_id = _get_pkgname(menu_info); - if (app_id == NULL) { - _E("unable to get app_id from menu_info"); - exit(-1); - } - SECURE_LOGD("app id: %s", app_id); - __appid = strdup(app_id); - if (__appid == NULL) { - _E("Out of memory"); - exit(-1); - } - aul_set_preinit_appid(__appid); - - // caching pkgid - pkg_id = _get_pkgid(menu_info); - if (pkg_id == NULL) { - _E("unable to get pkg_id from menu_info"); - exit(-1); - } - SECURE_LOGD("pkg id: %s", pkg_id); - - __pkgid = strdup(pkg_id); - if (__pkgid == NULL) { - _E("Out of memory"); - exit(-1); - } - aul_set_preinit_pkgid(__pkgid); - - atexit(__release_appid_at_exit); - -#ifdef _APPFW_FEATURE_PRIORITY_CHANGE - const char *high_priority = bundle_get_val(kb, AUL_K_HIGHPRIORITY); - _D("high_priority: %s", high_priority); - - if (strncmp(high_priority, "true", 4) == 0) { - int res = setpriority(PRIO_PROCESS, 0, -10); - if (res == -1) { - char err_str[MAX_LOCAL_BUFSZ] = { 0, }; - - SECURE_LOGE("Setting process (%d) priority to -10 failed, errno: %d (%s)", - getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); - } - } - bundle_del(kb, AUL_K_HIGHPRIORITY); -#endif - - if (__candidate_process_prepare_exec(app_id, app_path, menu_info, kb, - type) < 0) { - _E("__candidate_process_prepare_exec() failed"); - if (access(app_path, F_OK | R_OK)) { - char err_str[MAX_LOCAL_BUFSZ] = { 0, }; - - SECURE_LOGE("access() failed for file: \"%s\", error: %d (%s)", - app_path, errno, strerror_r(errno, err_str, sizeof(err_str))); - } - exit(-1); - } - - if (out_app_path != NULL && out_argc != NULL && out_argv != NULL) { - int i = 0; - - memset(out_app_path, '\0', strlen(out_app_path)); - sprintf(out_app_path, "%s", app_path); - - *out_argv = _create_argc_argv(kb, out_argc); - (*out_argv)[0] = out_app_path; - - for (i = 0; i < *out_argc; i++) - SECURE_LOGD("input argument %d : %s##", i, (*out_argv)[i]); - } else - exit(-1); - - if (menu_info != NULL) - _free_app_info_from_db(menu_info); -} - -static Eina_Bool __candidate_proces_fd_handler(void* data, - Ecore_Fd_Handler *handler) -{ - int type = data ? *((int *)data) : LAUNCHPAD_TYPE_UNSUPPORTED; - int fd = ecore_main_fd_handler_fd_get(handler); - - if (fd == -1) { - _D("[candidate] ECORE_FD_GET"); - exit(-1); - } - - if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) { - _D("[candidate] ECORE_FD_ERROR"); - close(fd); - exit(-1); - } - - if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) { - _D("[candidate] ECORE_FD_READ"); - app_pkt_t* pkt = (app_pkt_t*) malloc(sizeof(char) * AUL_SOCK_MAXBUFF); - if (!pkt) { - _D("[candidate] out of memory1"); - exit(-1); - } - memset(pkt, 0, AUL_SOCK_MAXBUFF); - - int recv_ret = recv(fd, pkt, AUL_SOCK_MAXBUFF, 0); - close(fd); - if (recv_ret == -1) { - _D("[condidate] recv error!"); - free(pkt); - exit(-1); - } - _D("[candidate] recv_ret: %d, pkt->len: %d", recv_ret, pkt->len); - - ecore_main_fd_handler_del(handler); - - __candidate_process_launchpad_main_loop(pkt, g_argv[0], &g_argc, &g_argv, type); - SECURE_LOGD("[candidate] real app argv[0]: %s, real app argc: %d", g_argv[0], - g_argc); - free(pkt); - - ecore_main_loop_quit(); - _D("[candidate] ecore main loop quit"); - } - - return ECORE_CALLBACK_CANCEL; -} +static Ecore_Fd_Handler *__fd_handler; +static loader_receiver_cb __receiver; static void __init_window(void) { @@ -334,26 +73,12 @@ static void __init_theme(void) free(theme); } -static int __before_loop(int type, int argc, char **argv) +static void __loader_create_cb(int argc, char **argv, int type, void *user_data) { int elm_init_cnt = 0; - Ecore_Fd_Handler *fd_handler = NULL; - int client_fd; __preload_init(argc, argv); __preload_init_for_process_pool(); - __preexec_init(argc, argv); - -#ifdef _APPFW_FEATURE_BOOST_PRIORITY - res = setpriority(PRIO_PROCESS, 0, LOWEST_PRIO); - if (res == -1) { - char err_str[MAX_LOCAL_BUFSZ] = { 0, }; - - SECURE_LOGE("Setting process (%d) priority to %d failed, errno: %d (%s)", - getpid(), LOWEST_PRIO, errno, strerror_r(errno, err_str, sizeof(err_str))); - } -#endif - _D("[candidate] Another candidate process was forked."); /* Set new session ID & new process group ID*/ /* In linux, child can set new session ID without check permission */ @@ -363,12 +88,6 @@ static int __before_loop(int type, int argc, char **argv) /* SET OOM*/ _set_oom(); - client_fd = _connect_to_launchpad(type); - if (client_fd == -1) { - _D("Connecting to candidate process was failed."); - return -1; - } - elm_init_cnt = elm_init(g_argc, g_argv); _D("[candidate] elm init, returned: %d", elm_init_cnt); @@ -387,36 +106,22 @@ static int __before_loop(int type, int argc, char **argv) __init_theme(); break; } +} - fd_handler = ecore_main_fd_handler_add(client_fd, - (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR), - __candidate_proces_fd_handler, &type, NULL, NULL); - if (fd_handler == NULL) { - _D("fd_handler is NULL"); - return -1; - } - - _D("[candidate] ecore handler add"); -#ifdef _APPFW_FEATURE_BOOST_PRIORITY - res = setpriority(PRIO_PGRP, 0, 0); - if (res == -1) { - char err_str[MAX_LOCAL_BUFSZ] = { 0, }; - - SECURE_LOGE("Setting process (%d) priority to 0 failed, errno: %d (%s)", - getpid(), errno, strerror_r(errno, err_str, sizeof(err_str))); - } -#endif +static int __loader_launch_cb(int argc, char **argv, const char *app_path, + const char *appid, const char *pkgid, const char *pkg_type, void *user_data) +{ return 0; } -static int __after_loop(void) +static int __loader_terminate_cb(int argc, char **argv, void *user_data) { void *handle = NULL; int res; int (*dl_main)(int, char **); - SECURE_LOGD("[candidate] Launch real application (%s)", g_argv[0]); - handle = dlopen(g_argv[0], RTLD_LAZY | RTLD_GLOBAL); + SECURE_LOGD("[candidate] Launch real application (%s)", argv[0]); + handle = dlopen(argv[0], RTLD_LAZY | RTLD_GLOBAL); if (handle == NULL) { _E("dlopen failed(%s). Please complile with -fPIE and link with -pie flag", dlerror()); @@ -427,7 +132,7 @@ static int __after_loop(void) dl_main = dlsym(handle, "main"); if (dl_main != NULL) - res = dl_main(g_argc, g_argv); + res = dl_main(argc, argv); else { _E("dlsym not founded(%s). Please export 'main' function", dlerror()); dlclose(handle); @@ -438,48 +143,96 @@ static int __after_loop(void) return res; do_exec: - if (access(g_argv[0], F_OK | R_OK)) { + if (access(argv[0], F_OK | R_OK)) { char err_str[MAX_LOCAL_BUFSZ] = { 0, }; SECURE_LOGE("access() failed for file: \"%s\", error: %d (%s)", - g_argv[0], errno, strerror_r(errno, err_str, sizeof(err_str))); + argv[0], errno, strerror_r(errno, err_str, sizeof(err_str))); } else { SECURE_LOGD("[candidate] Exec application (%s)", g_argv[0]); - if (execv(g_argv[0], g_argv) < 0) { + if (execv(argv[0], argv) < 0) { char err_str[MAX_LOCAL_BUFSZ] = { 0, }; SECURE_LOGE("execv() failed for file: \"%s\", error: %d (%s)", - g_argv[0], errno, strerror_r(errno, err_str, sizeof(err_str))); + argv[0], errno, strerror_r(errno, err_str, sizeof(err_str))); } } return -1; + } -int main(int argc, char **argv) +static Eina_Bool __process_fd_handler(void* data, Ecore_Fd_Handler *handler) { - static int type = LAUNCHPAD_TYPE_UNSUPPORTED; + int fd = ecore_main_fd_handler_fd_get(handler); - if (argc < 2) { - _E("too few argument."); - return -1; + if (fd == -1) { + _D("[candidate] ECORE_FD_GET"); + exit(-1); } - type = argv[1][0] - '0'; - if (type < 0 || type >= LAUNCHPAD_TYPE_MAX) { - _E("invalid argument. (type: %d)", type); - return -1; + if (ecore_main_fd_handler_active_get(handler, ECORE_FD_ERROR)) { + _D("[candidate] ECORE_FD_ERROR"); + close(fd); + exit(-1); } - //temp - this requires some optimization. - sleep(1); - _D("sleeping 1 sec..."); + if (ecore_main_fd_handler_active_get(handler, ECORE_FD_READ)) { + if (__receiver) + __receiver(fd); + } - if (__before_loop(type, argc, argv) != 0) - return -1; + return ECORE_CALLBACK_CANCEL; +} - _D("[candidate] ecore main loop begin"); +static void __adapter_loop_begin(void *user_data) +{ ecore_main_loop_begin(); +} + +static void __adapter_loop_quit(void *user_data) +{ + ecore_main_loop_quit(); +} - return __after_loop(); +static void __adapter_add_fd(void *user_data, int fd, + loader_receiver_cb receiver) +{ + __fd_handler = ecore_main_fd_handler_add(fd, + (Ecore_Fd_Handler_Flags)(ECORE_FD_READ | ECORE_FD_ERROR), + __process_fd_handler, NULL, NULL, NULL); + if (__fd_handler == NULL) { + _D("fd_handler is NULL"); + close(fd); + exit(-1); + } + + __receiver = receiver; +} + +static void __adapter_remove_fd(void *user_data, int fd) +{ + if (__fd_handler) { + ecore_main_fd_handler_del(__fd_handler); + __fd_handler = NULL; + __receiver = NULL; + } +} + +int main(int argc, char **argv) +{ + loader_lifecycle_callback_s callbacks = { + .create = __loader_create_cb, + .launch = __loader_launch_cb, + .terminate = __loader_terminate_cb + }; + + loader_adapter_s adapter = { + .loop_begin = __adapter_loop_begin, + .loop_quit = __adapter_loop_quit, + .add_fd = __adapter_add_fd, + .remove_fd = __adapter_remove_fd + }; + + return launchpad_loader_main(argc, argv, &callbacks, &adapter, NULL); } -- 2.34.1 From 9f6121118ea3af0e790ed65639b6b178d70bd579 Mon Sep 17 00:00:00 2001 From: "Junghoon, Park" Date: Tue, 17 Nov 2015 14:28:57 +0900 Subject: [PATCH 5/7] add common code into launchpad_lib file Change-Id: I08f9c42dc8dfd09d098b93376210ed1f4821ec22 Signed-off-by: Junghoon, Park --- inc/launchpad_common.h | 1 - src/launchpad.c | 3 --- src/launchpad_common.c | 15 --------------- src/launchpad_lib.c | 6 ++++++ src/launchpad_loader.c | 8 -------- 5 files changed, 6 insertions(+), 27 deletions(-) diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h index 0934a0ce..ddd2fabd 100644 --- a/inc/launchpad_common.h +++ b/inc/launchpad_common.h @@ -73,7 +73,6 @@ int _create_server_sock(int pid); app_pkt_t *_recv_pkt_raw(int fd, int *clifd, struct ucred *cr); int _send_pkt_raw(int client_fd, app_pkt_t *pkt); int _connect_to_launchpad(int type); -void _set_oom(void); void _set_env(app_info_from_db * menu_info, bundle * kb); char** _create_argc_argv(bundle * kb, int *margc); diff --git a/src/launchpad.c b/src/launchpad.c index 0d5e7425..423126ba 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -449,9 +449,6 @@ static int __prepare_exec(const char *appId, const char *app_path, /* TODO : should be add to check permission in the kernel*/ setsid(); - /* SET OOM*/ - _set_oom(); - /* SET PRIVILEGES*/ if (bundle_get_val(kb, AUL_K_PRIVACY_APPID) == NULL) { _D("appId: %s / pkg_type : %s / app_path : %s ", appId, menu_info->pkg_type, diff --git a/src/launchpad_common.c b/src/launchpad_common.c index 6b86b45d..afa2deef 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -499,21 +499,6 @@ error: return -1; } -void _set_oom(void) -{ - char buf[MAX_LOCAL_BUFSZ]; - FILE *fp; - - /* we should reset oomadj value as default because child - inherits from parent oom_adj*/ - snprintf(buf, MAX_LOCAL_BUFSZ, "/proc/%d/oom_adj", getpid()); - fp = fopen(buf, "w"); - if (fp == NULL) - return; - fprintf(fp, "%d", -16); - fclose(fp); -} - void _set_env(app_info_from_db * menu_info, bundle * kb) { const char *str; diff --git a/src/launchpad_lib.c b/src/launchpad_lib.c index c22cd3a4..376c3c0b 100644 --- a/src/launchpad_lib.c +++ b/src/launchpad_lib.c @@ -302,6 +302,12 @@ static int __before_loop(int argc, char **argv) } #endif __preexec_init(argc, argv); + + /* Set new session ID & new process group ID*/ + /* In linux, child can set new session ID without check permission */ + /* TODO : should be add to check permission in the kernel*/ + setsid(); + if (__loader_callbacks->create) { __loader_callbacks->create(argc, argv, __loader_type, __loader_user_data); __loader_adapter->add_fd(__loader_user_data, client_fd, __receiver_cb); diff --git a/src/launchpad_loader.c b/src/launchpad_loader.c index 8f081c71..13e3a3f5 100644 --- a/src/launchpad_loader.c +++ b/src/launchpad_loader.c @@ -80,14 +80,6 @@ static void __loader_create_cb(int argc, char **argv, int type, void *user_data) __preload_init(argc, argv); __preload_init_for_process_pool(); - /* Set new session ID & new process group ID*/ - /* In linux, child can set new session ID without check permission */ - /* TODO : should be add to check permission in the kernel*/ - setsid(); - - /* SET OOM*/ - _set_oom(); - elm_init_cnt = elm_init(g_argc, g_argv); _D("[candidate] elm init, returned: %d", elm_init_cnt); -- 2.34.1 From 0c7aa078fad4d1df81e38472962fbd49a1355f30 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 20 Nov 2015 15:56:18 +0900 Subject: [PATCH 6/7] fix launchpad fd smack issue - close all open fds before launching an app - change launchpad-process-pool socket name - fix socket activation about launchpad-process-pool Change-Id: Ic1035199a2401e2d322230468cd3764adb4547b4 Signed-off-by: Hwankyu Jhun --- inc/launchpad_common.h | 2 +- packaging/launchpad-process-pool.socket | 5 +-- src/launchpad.c | 49 ++++++++++++++----------- src/launchpad_common.c | 4 +- src/launchpad_lib.c | 2 +- 5 files changed, 33 insertions(+), 29 deletions(-) diff --git a/inc/launchpad_common.h b/inc/launchpad_common.h index ddd2fabd..71779e23 100644 --- a/inc/launchpad_common.h +++ b/inc/launchpad_common.h @@ -69,7 +69,7 @@ char *_proc_get_cmdline_bypid(int pid); app_info_from_db *_get_app_info_from_bundle_by_pkgname(const char *pkgname, bundle *kb); void _modify_bundle(bundle * kb, int caller_pid, app_info_from_db * menu_info, int cmd); -int _create_server_sock(int pid); +int _create_server_sock(const char *name); app_pkt_t *_recv_pkt_raw(int fd, int *clifd, struct ucred *cr); int _send_pkt_raw(int client_fd, app_pkt_t *pkt); int _connect_to_launchpad(int type); diff --git a/packaging/launchpad-process-pool.socket b/packaging/launchpad-process-pool.socket index 611fcc74..6d68ff58 100644 --- a/packaging/launchpad-process-pool.socket +++ b/packaging/launchpad-process-pool.socket @@ -1,8 +1,5 @@ [Socket] -ListenStream=/run/user/%U/-5 -ListenStream=/run/user/%U/.launchpad-type0 -ListenStream=/run/user/%U/.launchpad-type1 -ListenStream=/run/user/%U/.launchpad-type2 +ListenStream=/run/user/%U/.launchpad-process-pool-sock Service=launchpad-process-pool.service diff --git a/src/launchpad.c b/src/launchpad.c index 423126ba..82b8029a 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -42,7 +42,7 @@ #define EXEC_CANDIDATE_WAIT 1 #define DIFF(a,b) (((a)>(b))?(a)-(b):(b)-(a)) #define CANDIDATE_NONE 0 -#define PROCESS_POOL_LAUNCHPAD_PID -5 +#define PROCESS_POOL_LAUNCHPAD_SOCK ".launchpad-process-pool-sock" typedef struct { int pid; @@ -128,8 +128,6 @@ static int __listen_candidate_process(int type) { struct sockaddr_un addr; int fd = -1; - int listen_fds = 0; - int i; _D("[launchpad] enter, type: %d", type); @@ -138,20 +136,6 @@ static int __listen_candidate_process(int type) snprintf(addr.sun_path, UNIX_PATH_MAX, "%s/%d/%s%d", SOCKET_PATH, getuid(), LAUNCHPAD_LOADER_SOCKET_NAME, type); - listen_fds = sd_listen_fds(0); - if (listen_fds < 0) { - _E("Invalid systemd environment"); - return -1; - } else if (listen_fds > 0) { - for (i = 0; i < listen_fds; i++) { - fd = SD_LISTEN_FDS_START + i; - if (sd_is_socket_unix(fd, SOCK_STREAM, 1, addr.sun_path, 0)) - return fd; - } - _E("Socket not found: %s", addr.sun_path); - return -1; - } - fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); if (fd < 0) { _E("Socket error"); @@ -486,15 +470,20 @@ static int __launch_directly(const char *appid, const char *app_path, int clifd, { char sock_path[UNIX_PATH_MAX] = {0,}; int pid = fork(); + int max_fd; + int iter_fd; if (pid == 0) { PERF("fork done"); _D("lock up test log(no error) : fork done"); - close(clifd); __signal_unblock_sigchld(); __signal_fini(); + max_fd = sysconf(_SC_OPEN_MAX); + for (iter_fd = 3; iter_fd <= max_fd; iter_fd++) + close(iter_fd); + snprintf(sock_path, UNIX_PATH_MAX, "/run/user/%d/%d", getuid(), getpid()); unlink(sock_path); @@ -633,6 +622,21 @@ end: } } +static int __create_sock_activation(void) +{ + int fds; + + fds = sd_listen_fds(0); + if (fds == 1) + return SD_LISTEN_FDS_START; + else if (fds > 1) + _E("Too many file descriptors received.\n"); + else + _D("There is no socket stream"); + + return -1; +} + static int __launchpad_pre_init(int argc, char **argv) { int fd; @@ -641,10 +645,13 @@ static int __launchpad_pre_init(int argc, char **argv) __signal_init(); /* create launchpad sock */ - fd = _create_server_sock(PROCESS_POOL_LAUNCHPAD_PID); + fd = __create_sock_activation(); if (fd < 0) { - _E("server sock error %d", fd); - return -1; + fd = _create_server_sock(PROCESS_POOL_LAUNCHPAD_SOCK); + if (fd < 0) { + _E("server sock error %d", fd); + return -1; + } } return fd; diff --git a/src/launchpad_common.c b/src/launchpad_common.c index afa2deef..f37c369f 100644 --- a/src/launchpad_common.c +++ b/src/launchpad_common.c @@ -173,7 +173,7 @@ static int __parse_app_path(const char *arg, char *out, int out_size) return -2; } -int _create_server_sock(int pid) +int _create_server_sock(const char *name) { struct sockaddr_un saddr; int fd; @@ -195,7 +195,7 @@ int _create_server_sock(int pid) memset(&saddr, 0, sizeof(saddr)); saddr.sun_family = AF_UNIX; - snprintf(saddr.sun_path, UNIX_PATH_MAX, "/run/user/%d/%d", getuid(), pid); + snprintf(saddr.sun_path, UNIX_PATH_MAX, "/run/user/%d/%s", getuid(), name); unlink(saddr.sun_path); if (bind(fd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) { diff --git a/src/launchpad_lib.c b/src/launchpad_lib.c index 376c3c0b..5aca7a6a 100644 --- a/src/launchpad_lib.c +++ b/src/launchpad_lib.c @@ -267,11 +267,11 @@ static void __receiver_cb(int fd) _D("[candidate] recv_ret: %d, pkt->len: %d", recv_ret, pkt->len); __loader_adapter->remove_fd(__loader_user_data, fd); + close(fd); ret = __candidate_process_launchpad_main_loop(pkt, __argv[0], &__argc, &__argv, __loader_type); SECURE_LOGD("[candidate] real app argv[0]: %s, real app argc: %d", __argv[0], __argc); - close(fd); free(pkt); if (ret >= 0) { -- 2.34.1 From b137d2e6c5efbf4c13a874fb958e3cbaa7492698 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 24 Nov 2015 17:39:16 +0900 Subject: [PATCH 7/7] remove calling __sleep_safe func Change-Id: Ib551ff6e0e98fb38a9c3d7a32ea8e77ba27259c2 Signed-off-by: Hwankyu Jhun --- src/launchpad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/launchpad.c b/src/launchpad.c index 82b8029a..b9fcdc30 100755 --- a/src/launchpad.c +++ b/src/launchpad.c @@ -377,7 +377,7 @@ static int __send_launchpad_loader(int type, app_pkt_t *pkt, __send_result_to_caller(clifd, pid, app_path); //to AMD - __sleep_safe(1); //1 sec + /* __sleep_safe(1); */ /* 1 sec */ __prepare_candidate_process(type); _D("Prepare another candidate process"); -- 2.34.1