Support 2.x apps which use their own shared libraries 27/59227/5 accepted/tizen/mobile/20160216.001612 accepted/tizen/tv/20160216.001625 accepted/tizen/wearable/20160216.001644 submit/tizen/20160215.013052
authorSangyoon Jang <s89.jang@samsung.com>
Thu, 11 Feb 2016 12:39:03 +0000 (21:39 +0900)
committerSangyoon Jang <s89.jang@samsung.com>
Fri, 12 Feb 2016 06:04:45 +0000 (15:04 +0900)
Some applications from Tizen 2.x were compiled with '-rpath'
pointing at their lib directory which starts as '/opt/usr/apps/...'.
But this path is not adapted to Tizen 3.0.

We cannot set LD_LIBRARY_PATH directly by some security issues,
we make the loader have empty rpath to the dynamic linker looks in the CWD
forcely. And then, change working directory before calling dlopen() to
find libraries well.

Change-Id: I8111e5ca087ea07c52866d77deb7f53332957346
Signed-off-by: Sangyoon Jang <s89.jang@samsung.com>
CMakeLists.txt
inc/launchpad_common.h
src/launchpad.c
src/launchpad_common.c
src/launchpad_loader.c

index 8dec658..d66a245 100755 (executable)
@@ -55,7 +55,6 @@ SET(EXTRA_CFLAGS_lib "${EXTRA_CFLAGS_lib} ${EXTRA_CFLAGS_common}")
 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)
@@ -78,7 +77,10 @@ SET(${LAUNCHPAD_LOADER}_SOURCE_FILES
        )
 ADD_EXECUTABLE(${LAUNCHPAD_LOADER} ${${LAUNCHPAD_LOADER}_SOURCE_FILES})
 
-TARGET_LINK_LIBRARIES(${LAUNCHPAD_LOADER} "-ldl")
+# To support 2.x applications which use their own shared libraries.
+# Since we cannot set LD_LIBRARY_PATH directly by security issue, we make the
+# dynamic linker looks in the CWD forcely.
+TARGET_LINK_LIBRARIES(${LAUNCHPAD_LOADER} "-ldl -Wl,-rpath,:")
 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}
index 434c793..7fb9ff6 100644 (file)
@@ -95,6 +95,7 @@ int _send_pkt_raw(int client_fd, app_pkt_t *pkt);
 int  _connect_to_launchpad(int type, int id);
 void _set_env(appinfo_t *menu_info, bundle * kb);
 char** _create_argc_argv(bundle * kb, int *margc);
+char *_get_libdir(const char *path);
 
 appinfo_t* _appinfo_create(bundle *kb);
 void _appinfo_free(appinfo_t *menu_info);
index 6738667..58985ad 100755 (executable)
@@ -456,7 +456,14 @@ static int __send_launchpad_loader(candidate_process_context_t *cpc, app_pkt_t *
 
 static int __normal_fork_exec(int argc, char **argv)
 {
-       _D("start real fork and exec\n");
+       char *libdir = NULL;
+
+       _D("start real fork and exec");
+
+       libdir = _get_libdir(argv[0]);
+       if (libdir)
+               setenv("LD_LIBRARY_PATH", libdir, 1);
+       free(libdir);
 
        if (execv(argv[0], argv) < 0) { /* Flawfinder: ignore */
                if (errno == EACCES)
index 49fe6f9..6cc911c 100644 (file)
@@ -27,6 +27,7 @@
 #include <errno.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <linux/limits.h>
 
 #include "launchpad_common.h"
 #include "key.h"
@@ -614,3 +615,21 @@ char** _create_argc_argv(bundle * kb, int *margc)
        return argv;
 }
 
+char *_get_libdir(const char *path)
+{
+       char *path_dup;
+       char buf[PATH_MAX];
+       char *ptr;
+
+       path_dup = strdup(path);
+       ptr = strrchr(path_dup, '/');
+       *ptr = '\0';
+
+       snprintf(buf, sizeof(buf), "%s/../lib/", path_dup);
+       free(path_dup);
+
+       if (access(buf, F_OK) == -1)
+               return NULL;
+
+       return strdup(buf);
+}
index 0320baa..3ce3c11 100644 (file)
 
 #define _GNU_SOURCE
 #include <stdio.h>
+#include <stdbool.h>
 #include <dlfcn.h>
 #include <sys/prctl.h>
 #include <unistd.h>
 #include <sys/types.h>
+#include <linux/limits.h>
 #include <Elementary.h>
 #include <bundle_internal.h>
 #include <aul.h>
@@ -108,12 +110,33 @@ static int __loader_launch_cb(int argc, char **argv, const char *app_path,
 
 static int __loader_terminate_cb(int argc, char **argv, void *user_data)
 {
-       void *handle = NULL;
+       void *handle;
        int res;
        int (*dl_main)(int, char **);
-       char err_str[MAX_LOCAL_BUFSZ] = { 0, };
+       char err_str[MAX_LOCAL_BUFSZ];
+       char old_cwd[PATH_MAX];
+       bool restore = false;
+       char *libdir = NULL;
 
        SECURE_LOGD("[candidate] Launch real application (%s)", argv[0]);
+
+       if (getcwd(old_cwd, sizeof(old_cwd)) == NULL)
+               goto do_dlopen;
+
+       libdir = _get_libdir(argv[0]);
+       if (libdir == NULL)
+               goto do_dlopen;
+
+       /* To support 2.x applications which use their own shared libraries.
+        * We set '-rpath' to make the dynamic linker looks in the CWD forcely,
+        * so here we change working directory to find shared libraries well.
+        */
+       if (chdir(libdir))
+               _E("failed to chdir: %d", errno);
+       else
+               restore = true;
+
+do_dlopen:
        handle = dlopen(argv[0], RTLD_LAZY | RTLD_GLOBAL);
        if (handle == NULL) {
                _E("dlopen failed(%s). Please complile with -fPIE and link with -pie flag",
@@ -123,24 +146,31 @@ static int __loader_terminate_cb(int argc, char **argv, void *user_data)
 
        dlerror();
 
+       if (restore && chdir(old_cwd))
+               _E("failed to chdir: %d", errno);
+
        dl_main = dlsym(handle, "main");
-       if (dl_main != NULL)
-               res = dl_main(argc, argv);
-       else {
+       if (dl_main == NULL) {
                _E("dlsym not founded(%s). Please export 'main' function", dlerror());
                dlclose(handle);
                goto do_exec;
        }
 
+       free(libdir);
+       res = dl_main(argc, argv);
        dlclose(handle);
+
        return res;
 
 do_exec:
-       if (access(argv[0], F_OK | R_OK))
+       if (access(argv[0], F_OK | R_OK)) {
                SECURE_LOGE("access() failed for file: \"%s\", error: %d (%s)",
                        argv[0], errno, strerror_r(errno, err_str, sizeof(err_str)));
-       else {
+       else {
                SECURE_LOGD("[candidate] Exec application (%s)", __argv[0]);
+               if (libdir)
+                       setenv("LD_LIBRARY_PATH", libdir, 1);
+               free(libdir);
                if (execv(argv[0], argv) < 0)
                        SECURE_LOGE("execv() failed for file: \"%s\", error: %d (%s)",
                                argv[0], errno, strerror_r(errno, err_str, sizeof(err_str)));