From 6f56420b6462378935cf2a8521aa5058cb9fe8c8 Mon Sep 17 00:00:00 2001 From: Janusz Kozerski Date: Mon, 6 May 2013 14:34:13 +0200 Subject: [PATCH] Add API functions smack_pid_have_access and get_smack_label_from_process. [Issue#] SSDWSSP-220 [Feature] Add new function: smack_pid_have_access. This function calls smack_have_access, and if there's no access granted then check if process have CAP_MAC_OVERRIDE. [Problem] N/A [Cause] N/A [Solution] N/A [Verification] Build, install. Change-Id: If319fd7b176d9a7e1ecb38458f6178e5e7f9865c --- CMakeLists.txt | 4 +- include/privilege-control.h | 25 ++++++++ packaging/libprivilege-control.spec | 2 + src/privilege-control.c | 112 ++++++++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 47652de..fa8827d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,10 +44,10 @@ SET(libprivilege-control_SOURCES ) SET(libprivilege-control_LDFLAGS " -module -avoid-version ") SET(libprivilege-control_CFLAGS " ${CFLAGS} -fPIC -I${include_dir}") -#SET(libprivilege-control_LIBADD " ") +SET(libprivilege-control_LIBADD "${pkgs_LDFLAGS} -lcap") ADD_LIBRARY(privilege-control SHARED ${libprivilege-control_SOURCES}) -TARGET_LINK_LIBRARIES(privilege-control ${pkgs_LDFLAGS} ${pkgs_LIBRARIES}) +TARGET_LINK_LIBRARIES(privilege-control ${libprivilege-control_LIBADD} ${pkgs_LIBRARIES}) SET_TARGET_PROPERTIES(privilege-control PROPERTIES COMPILE_FLAGS "${libprivilege-control_CFLAGS}") SET_TARGET_PROPERTIES(privilege-control PROPERTIES SOVERSION ${VERSION_MAJOR}) SET_TARGET_PROPERTIES(privilege-control PROPERTIES VERSION ${VERSION}) diff --git a/include/privilege-control.h b/include/privilege-control.h index 02b160b..0838fe8 100644 --- a/include/privilege-control.h +++ b/include/privilege-control.h @@ -21,6 +21,7 @@ #include #include +#include #ifndef _PRIVILEGE_CONTROL_H_ #define _PRIVILEGE_CONTROL_H_ @@ -58,6 +59,30 @@ int control_privilege(void) __attribute__((deprecated)); int set_privilege(const char* pkg_name) __attribute__((deprecated)); /** + * Function get process smack label base on pid. + * @param in: pid of process + * @param out: label of process + * @return PC_OPERATION_SUCCESS on success PC_ERR_* on error. + */ +int get_smack_label_from_process(pid_t pid, char smack_label[SMACK_LABEL_LEN + 1]); + +/** + * Check if process with pid have access to object. + * This function check if subject have access to object via smack_have_access() function. + * If YES then returned access granted. In NO then function check if process with pid have + * CAP_MAC_OVERRIDE capability. If YES then return access granted. + * If NO then return access denied. + * + * @param pid of process + * @param label of object to access + * @param access_type + * @return 0 (no access) or 1 (access) or -1 (error) + */ +int smack_pid_have_access(pid_t pid, + const char* object, + const char *access_type); + +/** * Set DAC and SMACK privileges for application. * This function is meant to be call by the application launcher just before * it launches an application. It will setup DAC and SMACK privileges based diff --git a/packaging/libprivilege-control.spec b/packaging/libprivilege-control.spec index ae9ed4b..3bc3e55 100644 --- a/packaging/libprivilege-control.spec +++ b/packaging/libprivilege-control.spec @@ -10,6 +10,7 @@ Source0: %{name}-%{version}.tar.gz Source1: %{name}-conf.manifest Source2: smack-default-labeling.service BuildRequires: cmake +BuildRequires: libcap-devel BuildRequires: pkgconfig(libsmack) BuildRequires: pkgconfig(dlog) @@ -20,6 +21,7 @@ development package of library to control privilege of in-house application Summary: Control privilege of application (devel) Group: Development/Libraries Requires: %{name} = %{version}-%{release} +Requires: pkgconfig(libsmack) %description devel Library to control privilege of application (devel) diff --git a/src/privilege-control.c b/src/privilege-control.c index e6f5861..8f676a4 100644 --- a/src/privilege-control.c +++ b/src/privilege-control.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include @@ -215,6 +217,116 @@ API int control_privilege(void) return PC_ERR_NOT_PERMITTED; } +/** + * TODO: this function should be moved to libsmack in open-source. + */ +API int get_smack_label_from_process(pid_t pid, char smack_label[SMACK_LABEL_LEN + 1]) +{ + C_LOGD("Enter function: %s", __func__); + int ret; + int fd AUTO_CLOSE; + int PATH_MAX_LEN = 64; + char path[PATH_MAX_LEN + 1]; + + if (pid < 0) { + ret = PC_ERR_INVALID_PARAM; + goto out; + } + + bzero(smack_label, SMACK_LABEL_LEN + 1); + if (!have_smack()) { // If no smack just return success with empty label + C_LOGD("No SMACK. Return empty label"); + ret = PC_OPERATION_SUCCESS; + goto out; + } + + bzero(path, PATH_MAX_LEN + 1); + snprintf(path, PATH_MAX_LEN, "/proc/%d/attr/current", pid); + fd = open(path, O_RDONLY); + if (fd < 0) { + C_LOGE("cannot open file %s (errno: %s)", path, strerror(errno)); + ret = PC_ERR_FILE_OPERATION; + goto out; + } + + ret = read(fd, smack_label, SMACK_LABEL_LEN); + if (ret < 0) { + C_LOGE("cannot read from file %s", path); + ret = PC_ERR_FILE_OPERATION; + goto out; + } + + ret = PC_OPERATION_SUCCESS; + +out: + return ret; +} + +API int smack_pid_have_access(pid_t pid, + const char* object, + const char *access_type) +{ + C_LOGD("Enter function: %s", __func__); + int ret; + char pid_subject_label[SMACK_LABEL_LEN + 1]; + cap_t cap; + cap_flag_value_t cap_v; + + if (!have_smack()) { + C_LOGD("No SMACK. Return access granted"); + return 1; + } + + if (pid < 0 || object == NULL || strlen(object) == 0 || + access_type == NULL || strlen(access_type) == 0) { + C_LOGE("Invalid param"); + return -1; + } + + //get SMACK label of process + ret = get_smack_label_from_process(pid, pid_subject_label); + if (PC_OPERATION_SUCCESS != ret) { + C_LOGE("get_smack_label_from_process %d failed: %d", pid, ret); + return -1; + } + C_LOGD("pid %d have label: %s", pid, pid_subject_label); + + // if read empty label then do not call smack_have_access() + if (pid_subject_label[0] != '\0') { + ret = smack_have_access(pid_subject_label, object, access_type); + if ( -1 == ret) { + C_LOGE("smack_have_access failed"); + return -1; + } + if ( 1 == ret ) { // smack_have_access return 1 (access granted) + C_LOGD("smack_have_access return 1 (access granted)"); + return 1; + } + } + + // smack_have_access return 0 (access denied). Now CAP_MAC_OVERRIDE should be checked + C_LOGD("smack_have_access return 0 (access denied)"); + cap = cap_get_pid(pid); + if (cap == NULL) { + C_LOGE("cap_get_pid failed"); + return -1; + } + ret = cap_get_flag(cap, CAP_MAC_OVERRIDE, CAP_EFFECTIVE, &cap_v); + if (0 != ret) { + C_LOGE("cap_get_flag failed"); + return -1; + } + + if (cap_v == CAP_SET) { + C_LOGD("pid %d have CAP_MAC_OVERRIDE", pid); + return 1; + + } else { + C_LOGD("pid %d have no CAP_MAC_OVERRIDE", pid); + return 0; + } +} + static int set_dac(const char *smack_label, const char *pkg_name) { C_LOGD("Enter function: %s", __func__); -- 2.7.4