From 02d5471062906d1a1d59efd8bf16fd8226e890ed Mon Sep 17 00:00:00 2001 From: Young Ik Cho Date: Wed, 21 Aug 2013 10:06:30 +0900 Subject: [PATCH] add exec loader - provide different memory layout to conventional osp app Change-Id: I0c1479bb9d3edfd319bb8d02b30be60bc2d5e4dc Signed-off-by: Young Ik Cho --- CMakeLists.txt | 1 + osp-exec-loader/CMakeLists.txt | 19 +++ osp-exec-loader/exec_loader.c | 312 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 332 insertions(+) create mode 100644 osp-exec-loader/CMakeLists.txt create mode 100644 osp-exec-loader/exec_loader.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 92fa1d5..f2fea44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,4 +17,5 @@ SET(EXTRA_C_FLAGS "${EXTRA_CFLAGS} -fvisibility=hidden") ADD_SUBDIRECTORY(osp-ui-app-loader) ADD_SUBDIRECTORY(osp-service-app-loader) ADD_SUBDIRECTORY(osp-system-service-loader) +ADD_SUBDIRECTORY(osp-exec-loader) diff --git a/osp-exec-loader/CMakeLists.txt b/osp-exec-loader/CMakeLists.txt new file mode 100644 index 0000000..13a0278 --- /dev/null +++ b/osp-exec-loader/CMakeLists.txt @@ -0,0 +1,19 @@ +SET (this_target osp-exec-loader) + +SET (${this_target}_SOURCE_FILES + exec_loader.c + ) + +ADD_EXECUTABLE (${this_target} ${${this_target}_SOURCE_FILES}) + +SET(CMAKE_C_FLAGS "${OSP_DEBUG_FLAGS} ${OSP_OPT_FLAGS} ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} ${OSP_COMPILER_FLAGS}") +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden") +SET(CMAKE_CXX_FLAGS "${OSP_DEBUG_FLAGS} ${OSP_OPT_FLAGS} ${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS} ${OSP_COMPILER_FLAGS}") + +TARGET_LINK_LIBRARIES(${this_target} "-Wl,--no-undefined -Wl,--as-needed -Wl,-Ttext-segment=0x02000000") +TARGET_LINK_LIBRARIES(${this_target} "-ldl") +TARGET_LINK_LIBRARIES(${this_target} ${pkgs_LDFLAGS}) + +INSTALL(TARGETS ${this_target} DESTINATION ${LIB_INSTALL_DIR}/osp) + + diff --git a/osp-exec-loader/exec_loader.c b/osp-exec-loader/exec_loader.c new file mode 100644 index 0000000..74988dd --- /dev/null +++ b/osp-exec-loader/exec_loader.c @@ -0,0 +1,312 @@ +// +// Open Service Platform +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// 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. +// + +/** +* @file exec_loader.c +* @brief This is the implementation for the osp-exec-loader. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#undef LOG_TAG +#define LOG_TAG "LOADER" + +#define MAX_PACKAGEID 10 +#define MAX_APP_EXECUTABLE_NAME 230 +#define MAX_APPID (MAX_PACKAGEID + MAX_APP_EXECUTABLE_NAME + 1) + + +static const char APPFW_SONAME[] = "libosp-appfw.so.1"; + + +#if 0 +static void +print_args(int argc, char* argv[]) +{ + const char* p = NULL; + int i = 0; + for (; i < argc; i++) + { + p = argv[i]; + LOGD("%dth arg : [%s]", i, p); + } +} +#endif + +static void +adjust_privilege(const char* appid) +{ + void* handle = dlopen("libprivilege-control.so.0", RTLD_LAZY | RTLD_LOCAL); + if (!handle) + { + fprintf(stderr, "Cannot open libprivilege-control.so.0\n"); + return; + } + + char* msg = 0; + dlerror(); + + int (*ppriv_func)(const char*) = NULL; + + ppriv_func = (int (*)(const char*))dlsym(handle, "set_privilege"); + msg = dlerror(); + if (msg != NULL) + { + fprintf(stderr, "Dlsym error: %s\n", msg); + + dlclose(handle); + return; + } + + int ret = (*ppriv_func)(appid); + if (ret < 0) + { + fprintf(stderr, "set_privilege() returned %d\n", ret); + } + + dlclose(handle); +} + +extern int capset(cap_user_header_t hdrp, const cap_user_data_t datap); + +static int +adjust_capability(void) +{ + cap_user_header_t head = 0; + cap_user_data_t data = 0; + + head = (cap_user_header_t) malloc(sizeof(*head)); + if (head == NULL) + { + fprintf(stderr, "Memory allocation failure.\n"); + return -1; + } + + head->version = _LINUX_CAPABILITY_VERSION; + head->pid = getpid(); + + data = (cap_user_data_t) calloc(sizeof(*data), _LINUX_CAPABILITY_U32S); + if (data == NULL) + { + fprintf(stderr, "Memory allocation failure.\n"); + + free(head); + return -1; + } + + data[CAP_TO_INDEX(CAP_NET_RAW)].effective |= CAP_TO_MASK(CAP_NET_RAW); + data[CAP_TO_INDEX(CAP_NET_RAW)].permitted |= CAP_TO_MASK(CAP_NET_RAW); + + if (capset(head, data) < 0) + { + fprintf(stderr, "Capability setting error\n"); + + free(data); + free(head); + return -1; + } + + free(data); + free(head); + + return 0; +} + +static int +osp_do_pre_exe(const char* bin_path) +{ + int ret = 0; + void* handle = NULL; + char* errormsg = 0; + int (*do_pre_exec_fn)(const char*, const char*) = NULL; + + handle = dlopen("libosp-env-config.so", RTLD_LAZY | RTLD_LOCAL); + if (!handle) + { + LOGE("Failed to dlopen osp-env-config.so (%s)", dlerror()); + return -1; + } + LOGD("dlopen() ok"); + + do_pre_exec_fn = (int (*)(const char*, const char*)) dlsym(handle, "do_pre_exec"); + errormsg = dlerror(); + if (errormsg != NULL) + { + LOGE("Failed to dlsym() (%s)", errormsg); + dlclose(handle); + return -1; + } + LOGD("dlsym() ok"); + + ret = do_pre_exec_fn(NULL, bin_path); + if (ret < 0) + { + LOGE("Failed to do_pre_exe() (%d)", ret); + } + LOGD("do_pre_exec() ok"); + + dlclose(handle); + + return 0; +} + +static int +get_packageid_executable_name_from_path(const char path[], char packageid[], char executable_name[]) +{ + // path is ".../[packageid]/bin/[executable_name]" + + const char* p = strrchr(path, '/'); + if (p == NULL) + { + LOGI("Improper path %s", path); + return -1; + } + + const int path_len = strlen(path); + const int exec_len = strlen(p); + if (exec_len <= 0 || exec_len > PATH_MAX || path_len <= 0 || path_len > PATH_MAX) + { + LOGI("Improper path %s", path); + return -1; + } + + strncpy(executable_name, p + 1, exec_len); + +#ifdef _SECURE_LOG + LOGI("Exec is %s", executable_name); +#endif + + if (path_len < /* '/' */ 1 + 10 + strlen("/bin/") + exec_len) + { + LOGI("Improper path %s", path); + return -1; + } + + strncpy(packageid, p - strlen("bin/") - 10, 10); + + LOGI("PackageId is %s", packageid); + + return 1; +} + + +int +main(int argc, char* argv[]) +{ + void* handle = NULL; + char* errormsg = 0; + char packageid[MAX_PACKAGEID + 1]; + char executable_name[MAX_APP_EXECUTABLE_NAME]; + char appid[MAX_APPID]; + + void (*pAppInfoInit)(const char*, const char*, int, char* [], int) = NULL; + int (*pRealMain)(int, char* []) = NULL; + + memset(packageid, 0, sizeof(packageid)); + memset(executable_name, 0, sizeof(executable_name)); + memset(appid, 0, sizeof(appid)); + + LOGI("Initializeing : argc %d, argv 0x%x.", argc, argv); + //print_args(argc, argv); + + // convert package path to package name + get_packageid_executable_name_from_path(argv[0], packageid, executable_name); + snprintf(appid, MAX_APPID, "%s.%s", packageid, executable_name); + +#ifdef _SECURE_LOG + LOGI("app is %s", appid); +#endif + + if (getuid() == 0) + { + // self caging + osp_do_pre_exe(argv[0]); + + // adjust privilege + adjust_privilege(appid); + } + + + adjust_capability(); + + // initialize appid + appinfo_init(appid, 0); + appinfo_set_argv(argc, argv); + + // actual loading + char buffer[1024]; + + snprintf(buffer, 1024, "%s.exe", argv[0]); + + + void* so_handle = dlopen(APPFW_SONAME, RTLD_LAZY); + if (!so_handle) + { + LOGE("Failed to open framework : %s.", dlerror()); + return -1; + } + + pAppInfoInit = (void (*)(const char*, const char*, int, char*[], int)) dlsym(so_handle, "InitAppInfo"); + errormsg = dlerror(); + if (errormsg != NULL) + { + LOGE("Failed to find InitAppInfo() : %s.", errormsg); + fprintf(stderr, "Improper osp library entry : %s.\n", errormsg); + dlclose(so_handle); + return -1; + } + + handle = dlopen(buffer, RTLD_LAZY | RTLD_GLOBAL); + if (!handle) + { + LOGE("Failed to open %s : %s.", buffer, dlerror()); + dlclose(so_handle); + return -1; + } + + pRealMain = (int (*)(int, char*[])) dlsym(handle, "OspMain"); + errormsg = dlerror(); + if (errormsg != NULL) + { + LOGE("Failed to find OspMain() : %s.", errormsg); + dlclose(handle); + dlclose(so_handle); + return -1; + } + + // actual initialization + (*pAppInfoInit)(packageid, executable_name, argc, argv, -1); + (*pRealMain)(argc, argv); + + LOGI("Osp application terminates."); + + dlclose(handle); + LOGI("Osp cleanup finished for %s.", argv[0]); + + return 0; +} + -- 2.7.4