Fix exception handling about label monitor 29/134929/9
authorHwankyu Jhun <h.jhun@samsung.com>
Tue, 20 Jun 2017 09:24:46 +0000 (18:24 +0900)
committerHwankyu Jhun <h.jhun@samsung.com>
Wed, 21 Jun 2017 01:03:43 +0000 (10:03 +0900)
Even though label monitor initialization is failed, the launchpad
doesn't stop initializing. And, if the loader has cap_mac_admin cap,
the launchpad will prepare the loader process to execute an application
for improving launch performance. When the label_monitor variable is null,
the launchpad checks wheather the loader has cap_mac_admin cap or NOT.

Change-Id: Ic8103e1897e38e4e7ded96e9c78551bd64776b8a
Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
CMakeLists.txt
inc/launchpad_common.h
packaging/launchpad.spec
src/launchpad.c

index 6a03d54..a742c61 100755 (executable)
@@ -13,6 +13,7 @@ PKG_CHECK_MODULES(${this_target_pool} REQUIRED
        ttrace
        vconf
        libtzplatform-config
+       libcap
        )
 
 FOREACH(flag ${${this_target_pool}_CFLAGS})
index c7c1012..5bc4142 100644 (file)
@@ -65,6 +65,8 @@
        }                               \
 } while (0)
 
+#define ARRAY_SIZE(x) ((sizeof(x)) / sizeof(x[0]))
+
 enum loader_arg {
        LOADER_ARG_PATH,
        LOADER_ARG_TYPE,
index 94750df..9d3f09f 100644 (file)
@@ -22,6 +22,7 @@ BuildRequires:  pkgconfig(security-manager)
 BuildRequires:  pkgconfig(aul)
 BuildRequires:  pkgconfig(ttrace)
 BuildRequires:  pkgconfig(libtzplatform-config)
+BuildRequires:  pkgconfig(libcap)
 
 Requires(post): /sbin/ldconfig
 Requires(post): /usr/bin/systemctl
index fde83a9..a415891 100755 (executable)
@@ -23,6 +23,7 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <sys/stat.h>
+#include <sys/capability.h>
 #include <sched.h>
 #include <stdbool.h>
 #include <malloc.h>
@@ -1586,29 +1587,86 @@ static int __init_sigchild_fd(void)
 
 static int __init_label_monitor_fd(void)
 {
+       int r;
        int fd = -1;
        guint pollfd;
 
-       if (security_manager_app_labels_monitor_init(&label_monitor)
-                       != SECURITY_MANAGER_SUCCESS)
-               return -1;
-       if (security_manager_app_labels_monitor_process(label_monitor)
-                       != SECURITY_MANAGER_SUCCESS)
+       r = security_manager_app_labels_monitor_init(&label_monitor);
+       if (r != SECURITY_MANAGER_SUCCESS)
                return -1;
-       security_manager_app_labels_monitor_get_fd(label_monitor, &fd);
 
+       r = security_manager_app_labels_monitor_process(label_monitor);
+       if (r != SECURITY_MANAGER_SUCCESS)
+               goto err;
+
+       security_manager_app_labels_monitor_get_fd(label_monitor, &fd);
        if (fd < 0) {
                _E("failed to get fd");
-               return -1;
+               goto err;
        }
 
        pollfd = __poll_fd(fd, G_IO_IN,
                        (GSourceFunc)__handle_label_monitor, 0, 0);
-       if (pollfd == 0) {
+       if (pollfd == 0)
+               goto err;
+
+       return 0;
+
+err:
+       if (fd > 0)
                close(fd);
+
+       if (label_monitor) {
+               security_manager_app_labels_monitor_finish(label_monitor);
+               label_monitor = NULL;
+       }
+
+       return -1;
+}
+
+static int __verify_loader_caps(const char *loader)
+{
+       cap_t cap_d;
+       cap_flag_value_t eff_state;
+       cap_flag_value_t inh_state;
+       cap_value_t values[] = {CAP_SETGID, CAP_MAC_ADMIN};
+       int r;
+       int i;
+       int size = ARRAY_SIZE(values);
+
+       /* If Dytransition feature is enabled, CAP_MAC_ADMIN is unnecessary */
+       if (label_monitor)
+               size--;
+
+       cap_d = cap_get_file(loader);
+       if (!cap_d) {
+               _E("Failed to get cap from file(%s)", loader);
                return -1;
        }
 
+       for (i = 0; i < size; i++) {
+               r = cap_get_flag(cap_d, values[i], CAP_INHERITABLE, &inh_state);
+               if (r != 0) {
+                       _E("Failed to get cap inh - errno(%d)", errno);
+                       cap_free(cap_d);
+                       return -1;
+               }
+
+               r = cap_get_flag(cap_d, values[i], CAP_EFFECTIVE, &eff_state);
+               if (r != 0) {
+                       _E("Failed to get cap eff - errno(%d)", errno);
+                       cap_free(cap_d);
+                       return -1;
+               }
+
+               if ((inh_state != CAP_SET) || (eff_state != CAP_SET)) {
+                       _E("The %s doesn't have %d cap", loader, values[i]);
+                       cap_free(cap_d);
+                       return -1;
+               }
+       }
+       cap_free(cap_d);
+
        return 0;
 }
 
@@ -1634,6 +1692,9 @@ static void __add_slot_from_info(gpointer data, gpointer user_data)
        }
 
        if (access(info->exe, F_OK | X_OK) == 0) {
+               if (__verify_loader_caps(info->exe) < 0)
+                       return;
+
                if (info->extra)
                        bundle_encode(info->extra, &extra, &len);
 
@@ -1697,12 +1758,6 @@ static int __before_loop(int argc, char **argv)
                return -1;
        }
 
-       ret = __init_label_monitor_fd();
-       if (ret != 0) {
-               _E("__init_launchpad_fd() failed");
-               return -1;
-       }
-
        ret = vconf_get_int(VCONFKEY_SETAPPL_APP_HW_ACCELERATION, &__sys_hwacc);
        if (ret != VCONF_OK) {
                _E("Failed to get vconf int: %s",
@@ -1716,6 +1771,10 @@ static int __before_loop(int argc, char **argv)
                                VCONFKEY_SETAPPL_APP_HW_ACCELERATION);
        }
 
+       ret = __init_label_monitor_fd();
+       if (ret != 0)
+               _W("Failed to initialize label monitor");
+
        __add_default_slots();
        launcher_info_list = _launcher_info_load(LAUNCHER_INFO_PATH);