diff options
author | Yunchan Cho <yunchan.cho@samsung.com> | 2013-08-30 10:24:34 +0900 |
---|---|---|
committer | Yunchan Cho <yunchan.cho@samsung.com> | 2013-09-21 20:06:06 +0900 |
commit | 016aa878b0e64576eea47af0a6448046b655012a (patch) | |
tree | 014900273736f5497cc52c321569cedd7d009a90 | |
parent | 9433bd480ce50541276d97951bb74cbf848d268f (diff) | |
download | web-provider-016aa878b0e64576eea47af0a6448046b655012a.tar.gz web-provider-016aa878b0e64576eea47af0a6448046b655012a.tar.bz2 web-provider-016aa878b0e64576eea47af0a6448046b655012a.zip |
Set inheritable bit of 'CAP_MAC_ADMIN' capability upon launching web-provider
[Issue#] N/A
[Problem] WebProcess forked by web-provider cannot have CAP_MAC_ADMIN capability
[Cause] web-provider (parent process of WebProcess) did not have the inheritable bit set to '1'.
In order for WebProcess executable can have CAP_MAC_ADMIN feature,
the parent process associated with it (e.g., web-provider) also need this bit set to '1'.
[Solution] Set the inheritable bit of web-provider as soon as it is launched.
As the inheritable bit can't be set by setcap command in shell
(though, we can still set permitted/effective bits in a shell)
we set the following to /usr/app/livebox.web-provider/bin/web-provider.
in order to permit web-provider to change its inheritable capability.
// qemu doesn't provide setcap command, so we use setfattr command for granting capabilities to executable file
# setfattr -n security.capability -v 0sAQAAAgABAAAAAAAAAgAAAAAAAAA= /usr/apps/livebox.web-provider/bin/web-provider
Change-Id: I3486aec6b688bd3ce99abb52de2de7b4254b5a32
-rwxr-xr-x | packaging/livebox.web-provider.spec | 11 | ||||
-rw-r--r-- | src/Daemon/CMakeLists.txt | 2 | ||||
-rwxr-xr-x | src/Daemon/main.cpp | 100 |
3 files changed, 81 insertions, 32 deletions
diff --git a/packaging/livebox.web-provider.spec b/packaging/livebox.web-provider.spec index b9eaeb0..f980621 100755 --- a/packaging/livebox.web-provider.spec +++ b/packaging/livebox.web-provider.spec @@ -7,6 +7,7 @@ Group: main/app License: Flora License, Version 1.1 Source0: %{name}-%{version}.tar.gz BuildRequires: cmake, gettext-tools +BuildRequires: libcap, libcap-devel BuildRequires: pkgconfig(aul) BuildRequires: pkgconfig(appcore-efl) BuildRequires: pkgconfig(dlog) @@ -61,10 +62,12 @@ mkdir -p %{buildroot}%{app_data} %post killall -9 web-provider /usr/bin/web_provider_reset_db.sh -if [ -f /usr/lib/rpm-plugins/msm.so ]; then - echo "smack setting..." - chsmack -a 'livebox.web-provider::db' /opt/usr/dbspace/.web_provider.db - chsmack -a 'livebox.web-provider::db' /opt/usr/dbspace/.web_provider.db-journal +if [ `grep -c smack /proc/filesystems` -eq 1 ] +then + echo "smack setting..." + chsmack -a 'livebox.web-provider::db' /opt/usr/dbspace/.web_provider.db + chsmack -a 'livebox.web-provider::db' /opt/usr/dbspace/.web_provider.db-journal + setfattr -n security.capability -v 0sAQAAAgABAAAAAAAAAgAAAAAAAAA= %{_prefix}/apps/livebox.web-provider/bin/web-provider fi chown 5000:5000 %{app_data} chmod 755 %{app_data} diff --git a/src/Daemon/CMakeLists.txt b/src/Daemon/CMakeLists.txt index 25e6b6b..589c422 100644 --- a/src/Daemon/CMakeLists.txt +++ b/src/Daemon/CMakeLists.txt @@ -52,7 +52,7 @@ SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES ) TARGET_LINK_LIBRARIES(${TARGET_NAME} - ${${DEPS}_LDFLAGS} "-ldl" + ${${DEPS}_LDFLAGS} "-ldl -lcap" ${${DEPS}_LIBRARIES} ${TARGET_PLUGIN} ${TARGET_CORE} diff --git a/src/Daemon/main.cpp b/src/Daemon/main.cpp index 84e6b77..9c07d3b 100755 --- a/src/Daemon/main.cpp +++ b/src/Daemon/main.cpp @@ -17,22 +17,43 @@ * @file main.cpp * @author Yunchan Cho (yunchan.cho@samsung.com) */ + +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/capability.h> +#include <Elementary.h> #include <aul.h> #include <app.h> -#include <Elementary.h> #include <Core/Util/Log.h> #include "BoxDaemon.h" -static bool app_create(void *data) +static bool appCreateCallback(void *data) { LogD("app create"); elm_config_preferred_engine_set("software_x11"); return true; } -static void app_reset(service_h service, void *data) +static void appTerminateCallback(void *data) +{ + BoxDaemon *daemon = static_cast<BoxDaemon *>(data); + daemon->stop(); +} + +static void appPauseCallback(void *data) { - LogD("app reset"); + LogD("app pasue"); +} + +static void appResumeCallback(void *data) +{ + LogD("app resume"); +} + +static void appServiceCallback(service_h service, void *data) +{ + LogD("app service"); int ret; char* name; @@ -51,41 +72,66 @@ static void app_reset(service_h service, void *data) daemon->handleAppService(service); } -static void app_pause(void *data) +static bool grantProcessCapability() { -} + cap_user_header_t header; + cap_user_data_t data; -static void app_resume(void *data) -{ -} + header = static_cast<cap_user_header_t>(malloc(sizeof(*header))); + data = static_cast<cap_user_data_t>(calloc(sizeof(*data), _LINUX_CAPABILITY_U32S_3)); -static void app_terminate(void *data) -{ - BoxDaemon *daemon = static_cast<BoxDaemon *>(data); - daemon->stop(); + header->pid = getpid(); + header->version = _LINUX_CAPABILITY_VERSION_3; + + // read already granted capabilities of this process + if (capget(header, data) < 0) { + LogD("capget error"); + delete [] header; + delete [] data; + return false; + } + + // set only inheritable bit for CAP_MAC_ADMIN to '1' + data[CAP_TO_INDEX(CAP_MAC_ADMIN)].inheritable |= CAP_TO_MASK(CAP_MAC_ADMIN); + + // remove capabilities not needed any more + data[CAP_TO_INDEX(CAP_MAC_ADMIN)].permitted &= ~CAP_TO_MASK(CAP_MAC_ADMIN); + data[CAP_TO_INDEX(CAP_MAC_ADMIN)].effective &= ~CAP_TO_MASK(CAP_MAC_ADMIN); + data[CAP_TO_INDEX(CAP_SETPCAP)].permitted &= ~CAP_TO_MASK(CAP_SETPCAP); + data[CAP_TO_INDEX(CAP_SETPCAP)].effective &= ~CAP_TO_MASK(CAP_SETPCAP); + + bool ret = true; + if (capset(header, data) < 0) { + LogD("capset error"); + ret = false; + } + + delete [] header; + delete [] data; + + return ret; } int main (int argc, char *argv[]) { - int ret; + // set inheritable bit for CAP_MAC_ADMIN + // so that WebProcess will have CAP_MAC_ADMIN capability + if (!grantProcessCapability()) { + return -1; + } + // set the appcore callbacks app_event_callback_s ops; memset(&ops, 0x00, sizeof(app_event_callback_s)); BoxDaemon daemon; - ops.create = app_create; - ops.terminate = app_terminate; - ops.pause = app_pause; - ops.resume = app_resume; - ops.service = app_reset; - -#if !defined(TIZEN_PUBLIC) - setenv("COREGL_FASTPATH", "1", 1); -#endif - setenv("CAIRO_GL_COMPOSITOR", "msaa", 1); - setenv("CAIRO_GL_LAZY_FLUSHING", "yes", 1); - setenv("ELM_IMAGE_CACHE", "0", 1); + ops.create = appCreateCallback; + ops.terminate = appTerminateCallback; + ops.pause = appPauseCallback; + ops.resume = appResumeCallback; + ops.service = appServiceCallback; - ret = app_efl_main(&argc, &argv, &ops, &daemon); + // start appcore + int ret = app_efl_main(&argc, &argv, &ops, &daemon); return ret; } |