Drop root permission when launching apps in command line
authorJihoon Chung <jihoon.chung@samsaung.com>
Thu, 26 Sep 2013 04:57:32 +0000 (13:57 +0900)
committerHoseon LEE <hoseon46.lee@samsung.com>
Mon, 14 Oct 2013 11:18:21 +0000 (20:18 +0900)
- Launching apps in command line is useful to investigate issue with printf or other tools.

[Issue#]   N/A
[Problem]  Indicator does not show correctly when launched via command line.
[Cause]    Caused by various reasons - e.g., DAC and SMACK.
           * When applications are run with "root" permission,
             some of the platform feature (DAC, SMACK, etc) will fail to initialize.
           * Indicator issue is one of the issues which will occurr
             when web application is running on the "root" permission.
[Solution] Drop root permission
           * To support normal operations when launched by command line,
             web app needs to drop "root" permission before doing something.

[Remarks] Implementation details
    * Drop "root" permission should be done before touching  platform resource.
    * Current implementation point is too early, before attaching database, to access widget dao.
    * To resolve this, using ail to get various information to use privilege API.

Change-Id: I4c3014277da924cff590a80cb01c411655418a05

packaging/wrt.spec
src/wrt-client/CMakeLists.txt
src/wrt-client/client_security_support.cpp [new file with mode: 0644]
src/wrt-client/client_security_support.h [new file with mode: 0644]
src/wrt-client/wrt-client.cpp

index 5334260..38c7677 100644 (file)
@@ -20,6 +20,7 @@ Source1001:   wrt.manifest
 BuildRequires:  cmake
 BuildRequires:  gettext
 BuildRequires:  edje-tools
+BuildRequires:  pkgconfig(ail)
 BuildRequires:  pkgconfig(aul)
 BuildRequires:  pkgconfig(glib-2.0)
 BuildRequires:  pkgconfig(ewebkit2)
index c0dd663..69ef4f0 100644 (file)
@@ -19,6 +19,7 @@ SET(WRT_CLIENT_SRCS
     ${PROJECT_SOURCE_DIR}/src/wrt-client/window_data.cpp
     ${PROJECT_SOURCE_DIR}/src/wrt-client/client_command_line_parser.cpp
     ${PROJECT_SOURCE_DIR}/src/wrt-client/client_ide_support.cpp
+    ${PROJECT_SOURCE_DIR}/src/wrt-client/client_security_support.cpp
     ${PROJECT_SOURCE_DIR}/src/wrt-client/client_service_support.cpp
     ${PROJECT_SOURCE_DIR}/src/wrt-client/client_submode_support.cpp
     ${PROJECT_SOURCE_DIR}/src/wrt-client/splash_screen_support.cpp
@@ -28,6 +29,7 @@ SET(WRT_CLIENT_SRCS
 )
 
 PKG_CHECK_MODULES(CLIENT_DEP
+    ail
     appcore-efl
     capi-appfw-application
     dpl-wrt-dao-ro
diff --git a/src/wrt-client/client_security_support.cpp b/src/wrt-client/client_security_support.cpp
new file mode 100644 (file)
index 0000000..27ae17d
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2013 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.
+ */
+/**
+ * @file    client_security_support.cpp
+ * @author  Jihoon Chung (jihoon.chung@samsung.com)
+ */
+
+#include "client_security_support.h"
+
+#include <string>
+
+#include <ail.h>
+#include <privilege-control.h>
+
+#include <dpl/exception.h>
+#include <dpl/log/secure_log.h>
+
+namespace ClientModule {
+namespace {
+class Exception
+{
+public:
+    DECLARE_EXCEPTION_TYPE(DPL::Exception, Base)
+    DECLARE_EXCEPTION_TYPE(Base, GetAppInfoFailed)
+    DECLARE_EXCEPTION_TYPE(Base, GetAppInfoStrFailed)
+    DECLARE_EXCEPTION_TYPE(Base, SetPrivilegeFailed)
+};
+
+// Function declare
+void destroyAppInfoHandle(ail_appinfo_h handle);
+void getAppInfo(const std::string& tizenAppId, ail_appinfo_h* handle);
+char* getExePath(ail_appinfo_h handle);
+char* getPackageId(ail_appinfo_h handle);
+char* getPackageType(ail_appinfo_h handle);
+
+void destroyAppInfoHandle(ail_appinfo_h handle)
+{
+    if (handle != NULL)
+        ail_destroy_appinfo(handle);
+}
+
+void getAppInfo(const std::string& tizenAppId, ail_appinfo_h* handle)
+{
+    ail_error_e ret = ail_get_appinfo(tizenAppId.c_str(), handle);
+    if (ret != AIL_ERROR_OK) {
+        _E("error ail_get_appinfo : %d", ret);
+        Throw(Exception::GetAppInfoFailed);
+    }
+}
+
+char* getExePath(ail_appinfo_h handle)
+{
+    char* str = NULL;
+    ail_error_e ret = ail_appinfo_get_str(handle, AIL_PROP_X_SLP_EXE_PATH, &str);
+    if (ret != AIL_ERROR_OK) {
+        _E("error ail_appinfo_get_str(%s) : %d", AIL_PROP_X_SLP_EXE_PATH, ret);
+        Throw(Exception::GetAppInfoStrFailed);
+    }
+    return str;
+}
+
+char* getPackageId(ail_appinfo_h handle)
+{
+    char* str = NULL;
+    ail_error_e ret = ail_appinfo_get_str(handle, AIL_PROP_X_SLP_PKGID_STR, &str);
+    if (ret != AIL_ERROR_OK) {
+        _E("error ail_appinfo_get_str(%s) : %d", AIL_PROP_X_SLP_PKGID_STR, ret);
+        Throw(Exception::GetAppInfoStrFailed);
+    }
+    return str;
+}
+
+char* getPackageType(ail_appinfo_h handle)
+{
+    char* str = NULL;
+    ail_error_e ret = ail_appinfo_get_str(handle, AIL_PROP_X_SLP_PACKAGETYPE_STR, &str);
+    if (ret != AIL_ERROR_OK) {
+        _E("error ail_appinfo_get_str(%s) : %d", AIL_PROP_X_SLP_PACKAGETYPE_STR, ret);
+        Throw(Exception::GetAppInfoStrFailed);
+    }
+    return str;
+}
+} // namespace anonymous
+
+bool SecuritySupport::setAppPrivilege(const std::string& tizenAppId)
+{
+    ail_appinfo_h handle = NULL;
+    Try
+    {
+        getAppInfo(tizenAppId, &handle);
+        char* path = getExePath(handle);
+        char* pkgId = getPackageId(handle);
+        char* type = getPackageType(handle);
+
+        _D("Package ID   : %s", pkgId);
+        _D("Package TYPE : %s", type);
+        _D("Package PATH : %s", path);
+
+        int ret = perm_app_set_privilege(pkgId, type, path);
+        if (ret != PC_OPERATION_SUCCESS) {
+            _E("error perm_app_set_privilege : (%d)", ret);
+            Throw(Exception::SetPrivilegeFailed);
+        }
+    }
+    Catch(Exception::Base)
+    {
+        destroyAppInfoHandle(handle);
+        return false;
+    }
+
+    destroyAppInfoHandle(handle);
+    return true;
+}
+} // ClientModule
diff --git a/src/wrt-client/client_security_support.h b/src/wrt-client/client_security_support.h
new file mode 100644 (file)
index 0000000..4a9696d
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013 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.
+ */
+ /**
+ * @file    client_security_support.h
+ * @author  Jihoon Chung (jihoon.chung@samsung.com)
+ */
+#ifndef CLIENT_SECURITY_SUPPORT_H_
+#define CLIENT_SECURITY_SUPPORT_H_
+
+#include <string>
+
+namespace ClientModule {
+namespace SecuritySupport {
+bool setAppPrivilege(const std::string& tizenAppId);
+} // namespace SecuritySupport
+} // namespace ClientModule
+#endif // CLIENT_SECURITY_SUPPORT_H_
\ No newline at end of file
index 406db78..fea7ea0 100644 (file)
@@ -42,6 +42,7 @@
 
 #include "client_command_line_parser.h"
 #include "client_ide_support.h"
+#include "client_security_support.h"
 #include "client_service_support.h"
 #include "client_submode_support.h"
 
@@ -57,6 +58,7 @@ const std::string VIEWMODE_TYPE_WINDOWED = "windowed";
 char const* const ELM_SWALLOW_CONTENT = "elm.swallow.content";
 const char* const BUNDLE_PATH = LIBDIR_PREFIX "/usr/lib/libwrt-injected-bundle.so";
 const char* const MESSAGE_NAME_INITIALIZE = "ToInjectedBundle::INIT";
+const unsigned int UID_ROOT = 0;
 
 // process pool
 const char* const DUMMY_PROCESS_PATH = "/usr/bin/wrt_launchpad_daemon_candidate";
@@ -1072,6 +1074,15 @@ int main(int argc,
                 ClientModule::CommandLineParser::getTizenId(argc, argv);
 
             if (!tizenId.empty()) {
+                if (UID_ROOT == getuid()) {
+                    // Drop root permission
+                    // Only launch web application by console command case has root permission
+                    if (!ClientModule::SecuritySupport::setAppPrivilege(tizenId)) {
+                        LogError("Fail to set app privilege : [" << tizenId << "]");
+                        exit(-1);
+                    }
+                }
+
                 LogDebug("Launching by fork mode");
                 // Language env setup
                 appcore_set_i18n("wrt-client", NULL);