From bfdd7d26cb5345f61373c682969ddffe416f8d86 Mon Sep 17 00:00:00 2001 From: steven_q Date: Wed, 13 Apr 2022 11:35:57 +0800 Subject: [PATCH] change hap_restorecon log from hilog to kmesg Signed-off-by: steven_q Change-Id: I7a3a11eed7853b0f1abe38e055e2b22de2295640 --- BUILD.gn | 3 +- .../policycoreutils/include/hap_restorecon.h | 1 + .../policycoreutils/include/selinux_log.h | 63 --------- .../policycoreutils/src/hap_restorecon.cpp | 78 +++++++---- .../policycoreutils/src/service_checker.cpp | 22 ++- interfaces/tools/service_check/test.cpp | 129 ++++++++++++------ scripts/build_contexts.py | 4 + sepolicy/base/public/hdf_service.te | 1 + sepolicy/base/public/service.te | 1 + test/BUILD.gn | 9 +- test/unittest/src/selinux_unit_test.cpp | 128 +++++++++++++++++ 11 files changed, 299 insertions(+), 140 deletions(-) delete mode 100644 interfaces/policycoreutils/include/selinux_log.h diff --git a/BUILD.gn b/BUILD.gn index baca0b811..a19e2e44b 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -90,9 +90,8 @@ ohos_shared_library("libhap_restorecon") { ":libselinux_error_static", "$THIRD_PARTY_SELINUX_DIR:libselinux", "//utils/native/base:utils", + ":libselinux_klog_static", ] - external_deps = [ "hiviewdfx_hilog_native:libhilog" ] - cflags_cc = [ "-DHILOG_ENABLE" ] cflags = [ "-D_GNU_SOURCE", "-Wall", diff --git a/interfaces/policycoreutils/include/hap_restorecon.h b/interfaces/policycoreutils/include/hap_restorecon.h index 3d2211079..2258d8d87 100644 --- a/interfaces/policycoreutils/include/hap_restorecon.h +++ b/interfaces/policycoreutils/include/hap_restorecon.h @@ -46,6 +46,7 @@ protected: static struct selabel_handle *fileContextsHandle; private: + void SetSelinuxLogCallback(); int RestoreconSb(const std::string &pathname, const struct stat *sb, const std::string &apl, const std::string &packageName); int HapContextsLookup(bool isDomain, const std::string &apl, const std::string &packageName, context_t con); diff --git a/interfaces/policycoreutils/include/selinux_log.h b/interfaces/policycoreutils/include/selinux_log.h deleted file mode 100644 index 02e73042f..000000000 --- a/interfaces/policycoreutils/include/selinux_log.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2022 Huawei Device Co., Ltd. - * 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. - */ - -#ifndef SELINUX_LOG_H -#define SELINUX_LOG_H - -#ifdef HILOG_ENABLE - -#include "hilog/log.h" - -#ifndef __cplusplus - -#define SELINUX_LOG_DEBUG(fmt, ...) HILOG_DEBUG(LOG_CORE, fmt, ##__VA_ARGS__) -#define SELINUX_LOG_INFO(fmt, ...) HILOG_INFO(LOG_CORE, fmt, ##__VA_ARGS__) -#define SELINUX_LOG_WARN(fmt, ...) HILOG_WARN(LOG_CORE, fmt, ##__VA_ARGS__) -#define SELINUX_LOG_ERROR(fmt, ...) HILOG_ERROR(LOG_CORE, fmt, ##__VA_ARGS__) -#define SELINUX_LOG_FATAL(fmt, ...) HILOG_FATAL(LOG_CORE, fmt, ##__VA_ARGS__) - -#else - -#define SELINUX_LOG_DEBUG(label, fmt, ...) OHOS::HiviewDFX::HiLog::Debug(label, fmt, ##__VA_ARGS__) -#define SELINUX_LOG_INFO(label, fmt, ...) OHOS::HiviewDFX::HiLog::Info(label, fmt, ##__VA_ARGS__) -#define SELINUX_LOG_WARN(label, fmt, ...) OHOS::HiviewDFX::HiLog::Warn(label, fmt, ##__VA_ARGS__) -#define SELINUX_LOG_ERROR(label, fmt, ...) OHOS::HiviewDFX::HiLog::Error(label, fmt, ##__VA_ARGS__) -#define SELINUX_LOG_FATAL(label, fmt, ...) OHOS::HiviewDFX::HiLog::Fatal(label, fmt, ##__VA_ARGS__) - -#endif // __cplusplus - -/* define LOG_TAG as "security_*" at your submodule, * means your submodule name such as "security_dac" */ -#undef LOG_TAG -#undef LOG_DOMAIN - -static constexpr unsigned int SECURITY_DOMAIN = 0xD002F00; - -#else - -#include -#include - -/* define LOG_TAG as "security_*" at your submodule, * means your submodule name such as "security_dac" */ -#undef LOG_TAG - -#define SELINUX_LOG_DEBUG(fmt, ...) printf("[%s] debug: %s: " fmt "\n", LOG_TAG, __func__, ##__VA_ARGS__) -#define SELINUX_LOG_INFO(fmt, ...) printf("[%s] info: %s: " fmt "\n", LOG_TAG, __func__, ##__VA_ARGS__) -#define SELINUX_LOG_WARN(fmt, ...) printf("[%s] warn: %s: " fmt "\n", LOG_TAG, __func__, ##__VA_ARGS__) -#define SELINUX_LOG_ERROR(fmt, ...) printf("[%s] error: %s: " fmt "\n", LOG_TAG, __func__, ##__VA_ARGS__) -#define SELINUX_LOG_FATAL(fmt, ...) printf("[%s] fatal: %s: " fmt "\n", LOG_TAG, __func__, ##__VA_ARGS__) - -#endif // HILOG_ENABLE - -#endif // SELINUX_LOG_H diff --git a/interfaces/policycoreutils/src/hap_restorecon.cpp b/interfaces/policycoreutils/src/hap_restorecon.cpp index eca095a40..798da2621 100644 --- a/interfaces/policycoreutils/src/hap_restorecon.cpp +++ b/interfaces/policycoreutils/src/hap_restorecon.cpp @@ -23,12 +23,11 @@ #include #include "callbacks.h" #include "selinux_error.h" -#include "selinux_log.h" +#include "selinux_klog.h" using namespace Selinux; namespace { -static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN, "Selinux"}; static const std::string SEHAP_CONTEXTS_FILE = "/system/etc/selinux/targeted/contexts/sehap_contexts"; static const std::string APL_PREFIX = "apl="; static const std::string NAME_PREFIX = "name="; @@ -43,10 +42,20 @@ static pthread_once_t FC_ONCE = PTHREAD_ONCE_INIT; struct selabel_handle *HapContext::fileContextsHandle = nullptr; std::unordered_map HapContext::sehapContextsBuff; -HapContext::HapContext() {} +HapContext::HapContext() +{ + SetSelinuxLogCallback(); +} HapContext::~HapContext() {} +static void SelinuxSetCallback() +{ + union selinux_callback cb; + cb.func_log = SelinuKLog; + selinux_set_callback(SELINUX_CB_LOG, cb); +} + struct selabel_handle *SelinuxRestoreconHandle() { struct selinux_opt selinuxOpts[] = { @@ -113,6 +122,21 @@ static bool CheckPath(const std::string &path) return false; } +static bool CheckApl(const std::string &apl) +{ + if (apl == "system_core" || apl == "system_basic" || apl == "normal") { + return true; + } + return false; +} + +void HapContext::SetSelinuxLogCallback() +{ + SetSelinuKLogLevel(SELINUX_KERROR); + __selinux_once(FC_ONCE, SelinuxSetCallback); + return; +} + void HapContext::RestoreconInit() { if (fileContextsHandle == nullptr) { @@ -142,14 +166,14 @@ bool HapContext::HapContextsLoad() if (!tmpInfo.apl.empty()) { sehapContextsBuff.emplace(tmpInfo.apl + tmpInfo.name, tmpInfo); } else { - SELINUX_LOG_INFO(LABEL, "hap_contexts read fail in line %{public}d", lineNum); + selinux_log(SELINUX_INFO, "hap_contexts read fail in line %d", lineNum); } } } else { - SELINUX_LOG_ERROR(LABEL, "Load hap_contexts fail, no such file: %{public}s", SEHAP_CONTEXTS_FILE.c_str()); + selinux_log(SELINUX_ERROR, "Load hap_contexts fail, no such file: %s", SEHAP_CONTEXTS_FILE.c_str()); return false; } - SELINUX_LOG_INFO(LABEL, "Load hap_contexts succes: %{public}s", SEHAP_CONTEXTS_FILE.c_str()); + selinux_log(SELINUX_INFO, "Load hap_contexts succes: %s", SEHAP_CONTEXTS_FILE.c_str()); contextsFile.close(); return true; } @@ -163,11 +187,11 @@ int HapContext::TypeSet(std::unordered_map::iterator &it type = iter->second.type; } if (type.size() == 0) { - SELINUX_LOG_ERROR(LABEL, "type is empty in contexts file"); + selinux_log(SELINUX_ERROR, "type is empty in contexts file"); return -SELINUX_ARG_INVALID; } if (context_type_set(con, type.c_str())) { - SELINUX_LOG_ERROR(LABEL, "%{public}s %{public}s", GetErrStr(SELINUX_SET_CONTEXT_TYPE_ERROR), type.c_str()); + selinux_log(SELINUX_ERROR, "%s %s", GetErrStr(SELINUX_SET_CONTEXT_TYPE_ERROR), type.c_str()); return -SELINUX_SET_CONTEXT_TYPE_ERROR; } return SELINUX_SUCC; @@ -182,7 +206,7 @@ int HapContext::HapContextsLookup(bool isDomain, const std::string &apl, const s } auto iter = sehapContextsBuff.find(std::string(apl) + std::string(packageName)); - if (iter != sehapContextsBuff.end()) { + if (iter != sehapContextsBuff.end() && apl != "normal") { return TypeSet(iter, isDomain, con); } else { iter = sehapContextsBuff.find(std::string(apl)); @@ -225,7 +249,7 @@ int HapContext::HapLabelLookup(const std::string &apl, const std::string &packag // check whether the context is valid if (security_check_context(secontext) < 0) { context_free(con); - SELINUX_LOG_ERROR(LABEL, "context: %{public}s, %{public}s", secontext, GetErrStr(SELINUX_CHECK_CONTEXT_ERROR)); + selinux_log(SELINUX_ERROR, "context: %s, %s", secontext, GetErrStr(SELINUX_CHECK_CONTEXT_ERROR)); return -SELINUX_CHECK_CONTEXT_ERROR; } @@ -279,7 +303,8 @@ int HapContext::RestoreconSb(const std::string &pathname, const struct stat *sb, int HapContext::HapFileRestorecon(std::vector &pathNameOrig, const std::string &apl, const std::string &packageName, unsigned int flags) { - if (apl.empty() || pathNameOrig.empty()) { + if (apl.empty() || pathNameOrig.empty() || !CheckApl(apl)) { + selinux_log(SELINUX_ERROR, "%s", GetErrStr(SELINUX_ARG_INVALID)); return -SELINUX_ARG_INVALID; } bool failFlag = false; @@ -287,7 +312,7 @@ int HapContext::HapFileRestorecon(std::vector &pathNameOrig, const int res = HapFileRestorecon(pathname.c_str(), apl, packageName, flags); if (res != SELINUX_SUCC) { failFlag = true; - SELINUX_LOG_ERROR(LABEL, "HapFileRestorecon fail for path: %{public}s, errorNo: %{public}d", + selinux_log(SELINUX_ERROR, "HapFileRestorecon fail for path: %s, errorNo: %d", pathname.c_str(), res); } } @@ -297,18 +322,19 @@ int HapContext::HapFileRestorecon(std::vector &pathNameOrig, const int HapContext::HapFileRestorecon(const std::string &pathNameOrig, const std::string &apl, const std::string &packageName, unsigned int flags) { - if (apl.empty() || pathNameOrig.empty()) { + if (apl.empty() || pathNameOrig.empty() || !CheckApl(apl)) { + selinux_log(SELINUX_ERROR, "%s", GetErrStr(SELINUX_ARG_INVALID)); return -SELINUX_ARG_INVALID; } if (is_selinux_enabled() < 1) { - SELINUX_LOG_INFO(LABEL, "Selinux not enbaled"); + selinux_log(SELINUX_INFO, "Selinux not enbaled"); return SELINUX_SUCC; } // get file_contexts handle __selinux_once(FC_ONCE, RestoreconInit); if (fileContextsHandle == nullptr) { - SELINUX_LOG_ERROR(LABEL, "Cannot get file context handle: %{public}s", strerror(errno)); + selinux_log(SELINUX_ERROR, "Cannot get file context handle: %s", strerror(errno)); return -SELINUX_PTR_NULL; } @@ -330,7 +356,7 @@ int HapContext::HapFileRestorecon(const std::string &pathNameOrig, const std::st int res = RestoreconSb(realPath, &sb, apl, packageName); if (res < 0) { - SELINUX_LOG_ERROR(LABEL, "RestoreconSb failed"); + selinux_log(SELINUX_ERROR, "RestoreconSb failed"); } return res; } @@ -340,7 +366,7 @@ int HapContext::HapFileRestorecon(const std::string &pathNameOrig, const std::st int ftsFlags = FTS_PHYSICAL | FTS_NOCHDIR; FTS *fts = fts_open(paths, ftsFlags, NULL); if (fts == nullptr) { - SELINUX_LOG_ERROR(LABEL, "%{public}s on %{public}s: %{public}s", GetErrStr(SELINUX_FTS_OPEN_ERROR), paths[0], + selinux_log(SELINUX_ERROR, "%s on %s: %s", GetErrStr(SELINUX_FTS_OPEN_ERROR), paths[0], strerror(errno)); return -SELINUX_FTS_OPEN_ERROR; } @@ -350,22 +376,22 @@ int HapContext::HapFileRestorecon(const std::string &pathNameOrig, const std::st while ((ftsent = fts_read(fts)) != NULL) { switch (ftsent->fts_info) { case FTS_DC: - SELINUX_LOG_ERROR(LABEL, "%{public}s on %{public}s", GetErrStr(SELINUX_FTS_ELOOP), ftsent->fts_path); + selinux_log(SELINUX_ERROR, "%s on %s", GetErrStr(SELINUX_FTS_ELOOP), ftsent->fts_path); (void)fts_close(fts); return -SELINUX_FTS_ELOOP; case FTS_DP: continue; case FTS_DNR: - SELINUX_LOG_ERROR(LABEL, "Read error on %{public}s, errorno: %{public}s", ftsent->fts_path, + selinux_log(SELINUX_ERROR, "Read error on %s, errorno: %s", ftsent->fts_path, strerror(errno)); fts_set(fts, ftsent, FTS_SKIP); continue; case FTS_ERR: - SELINUX_LOG_ERROR(LABEL, "Error on %{public}s, errorno: %{public}s", ftsent->fts_path, strerror(errno)); + selinux_log(SELINUX_ERROR, "Error on %s, errorno: %s", ftsent->fts_path, strerror(errno)); fts_set(fts, ftsent, FTS_SKIP); continue; case FTS_NS: - SELINUX_LOG_ERROR(LABEL, "stat error on %{public}s, errorno: %{public}s", ftsent->fts_path, + selinux_log(SELINUX_ERROR, "stat error on %s, errorno: %s", ftsent->fts_path, strerror(errno)); fts_set(fts, ftsent, FTS_SKIP); continue; @@ -381,12 +407,12 @@ int HapContext::HapFileRestorecon(const std::string &pathNameOrig, const std::st int HapContext::HapDomainSetcontext(const std::string &apl, const std::string &packageName) { - if (apl.empty()) { + if (apl.empty() || !CheckApl(apl)) { return -SELINUX_ARG_INVALID; } if (is_selinux_enabled() < 1) { - SELINUX_LOG_INFO(LABEL, "Selinux not enbaled"); + selinux_log(SELINUX_INFO, "Selinux not enbaled"); return SELINUX_SUCC; } @@ -416,13 +442,13 @@ int HapContext::HapDomainSetcontext(const std::string &apl, const std::string &p return -SELINUX_PTR_NULL; } - SELINUX_LOG_INFO(LABEL, "Hap type for %{public}s is changing from %{public}s to %{public}s", packageName.c_str(), + selinux_log(SELINUX_INFO, "Hap type for %s is changing from %s to %s", packageName.c_str(), oldTypeContext, typeContext); if (security_check_context(typeContext) < 0) { freecon(oldTypeContext); context_free(con); - SELINUX_LOG_ERROR(LABEL, "context: %{public}s, %{public}s", typeContext, + selinux_log(SELINUX_ERROR, "context: %s, %s", typeContext, GetErrStr(SELINUX_CHECK_CONTEXT_ERROR)); return -SELINUX_CHECK_CONTEXT_ERROR; } @@ -434,7 +460,7 @@ int HapContext::HapDomainSetcontext(const std::string &apl, const std::string &p return -SELINUX_SET_CONTEXT_ERROR; } } - SELINUX_LOG_INFO(LABEL, "Hap setcon finish for %{public}s", packageName.c_str()); + selinux_log(SELINUX_INFO, "Hap setcon finish for %s", packageName.c_str()); freecon(oldTypeContext); context_free(con); diff --git a/interfaces/policycoreutils/src/service_checker.cpp b/interfaces/policycoreutils/src/service_checker.cpp index 52d136b54..17416d672 100644 --- a/interfaces/policycoreutils/src/service_checker.cpp +++ b/interfaces/policycoreutils/src/service_checker.cpp @@ -29,6 +29,8 @@ namespace { static const std::string SERVICE_CONTEXTS_FILE = "/system/etc/selinux/targeted/contexts/service_contexts"; static const std::string HDF_SERVICE_CONTEXTS_FILE = "/system/etc/selinux/targeted/contexts/hdf_service_contexts"; static const std::string OBJECT_PREFIX = "u:object_r:"; +static const std::string DEFAULT_CONTEXT = "u:object_r:default_service:s0"; +static const std::string DEFAULT_HDF_CONTEXT = "u:object_r:default_hdf_service:s0"; static const int CONTEXTS_LENGTH_MIN = 16; // sizeof("x u:object_r:x:s0") static const int CONTEXTS_LENGTH_MAX = 1024; static pthread_once_t FC_ONCE = PTHREAD_ONCE_INIT; @@ -41,11 +43,17 @@ extern "C" int HdfListServiceCheck(pid_t callingPid) extern "C" int HdfGetServiceCheck(pid_t callingPid, const char *serviceName) { + if (serviceName == nullptr) { + return -SELINUX_PTR_NULL; + } return ServiceChecker::GetInstance().GetServiceCheck(callingPid, serviceName); } extern "C" int HdfAddServiceCheck(pid_t callingPid, const char *serviceName) { + if (serviceName == nullptr) { + return -SELINUX_PTR_NULL; + } return ServiceChecker::GetInstance().AddServiceCheck(callingPid, serviceName); } @@ -129,7 +137,7 @@ static int CheckServiceNameValid(const std::string &serviceName) void ServiceChecker::SetSelinuxLogCallback() { - SetSelinuKLogLevel(SELINUX_KINFO); + SetSelinuKLogLevel(SELINUX_KERROR); __selinux_once(FC_ONCE, SelinuxSetCallback); return; } @@ -182,12 +190,12 @@ int ServiceChecker::GetServiceContext(const std::string &serviceName, std::strin auto iter = serviceMap.find(serviceName); if (iter != serviceMap.end()) { - selinux_log(SELINUX_INFO, "find context: %s\n", iter->second.serviceContext.c_str()); context = iter->second.serviceContext; - return SELINUX_SUCC; + } else { + context = isHdf_ ? DEFAULT_HDF_CONTEXT : DEFAULT_CONTEXT; } - selinux_log(SELINUX_ERROR, "service %s's context not found!\n", serviceName.c_str()); - return -SELINUX_KEY_NOT_FOUND; + selinux_log(SELINUX_INFO, "find context: %s\n", context.c_str()); + return SELINUX_SUCC; } static int GetCallingContext(const pid_t &pid, std::string &context) @@ -220,7 +228,7 @@ int ServiceChecker::CheckPerm(const pid_t &callingPid, const std::string &servic { std::string srcContext = ""; int ret = GetCallingContext(callingPid, srcContext); - if (ret < 0) { + if (ret != SELINUX_SUCC) { return ret; } if (security_check_context(srcContext.c_str()) < 0) { @@ -233,7 +241,7 @@ int ServiceChecker::CheckPerm(const pid_t &callingPid, const std::string &servic } else { ret = GetServiceContext(serviceName, destContext); } - if (ret < 0) { + if (ret != SELINUX_SUCC) { return ret; } if (security_check_context(destContext.c_str()) < 0) { diff --git a/interfaces/tools/service_check/test.cpp b/interfaces/tools/service_check/test.cpp index d07e9d143..905bab7fb 100644 --- a/interfaces/tools/service_check/test.cpp +++ b/interfaces/tools/service_check/test.cpp @@ -27,32 +27,38 @@ static std::unique_ptr g_service = nullptr; struct testInput { char cmd = '\0'; bool isHdf = false; + std::string serviceName; }; static void PrintUsage() { - std::cout << "Usage:" << std::endl; - std::cout << "step 1:" << std::endl; - std::cout << "service_check (-d) -a|-g|-r|-l" << std::endl; - std::cout << "step 2:" << std::endl; - std::cout << "input service name and press 'enter' to continue, or ctrl+C to end process" << std::endl; - std::cout << "" << std::endl; std::cout << "Options:" << std::endl; std::cout << " -h (--help) show the help information. [eg: service_check -h]" << std::endl; std::cout << "***********************optinal*************************************************" << std::endl; std::cout << " -d (--isHdf) service or hdf_service. [eg: service_check -d]" << std::endl; + std::cout << " -n (--serviceName) serviceName. [eg: service_check -n service_name]" + << std::endl; std::cout << "***********************requered: 1 in 4****************************************" << std::endl; std::cout << " -a (--add) add service check. [eg: service_check -a]" << std::endl; std::cout << " -g (--get) get service check. [eg: service_check -g]" << std::endl; std::cout << " -r (--get_remote) get remote service check. [eg: service_check -r]" << std::endl; std::cout << " -l (--list) list service check. [eg: service_check -l]" << std::endl; std::cout << "" << std::endl; + std::cout << "Usage:" << std::endl; + std::cout << ">>>>>>> choice 1: continuous input parameters" << std::endl; + std::cout << "step 1:" << std::endl; + std::cout << "service_check (-d) -a|-g|-r|-l" << std::endl; + std::cout << "step 2:" << std::endl; + std::cout << "input service name and press 'enter' to continue, or ctrl+C to end process" << std::endl; + std::cout << ">>>>>>> choice 2: single input parameter" << std::endl; + std::cout << "service_check (-d) -a|-g|-r|-l -n service_name" << std::endl; + std::cout << "" << std::endl; } static void SetOptions(int argc, char *argv[], const option *options, testInput &input) { int index = 0; - const char *optStr = "dhlagr"; + const char *optStr = "dhlagrn:"; int para = 0; while ((para = getopt_long(argc, argv, optStr, options, &index)) != -1) { switch (para) { @@ -60,6 +66,10 @@ static void SetOptions(int argc, char *argv[], const option *options, testInput PrintUsage(); exit(0); } + case 'n': { + input.serviceName = optarg; + break; + } case 'd': { input.isHdf = true; break; @@ -87,59 +97,102 @@ static void SetOptions(int argc, char *argv[], const option *options, testInput } } -int main(int argc, char *argv[]) +static void TestAddService(bool isHdf, const std::string &serviceName) { - struct option options[] = { - {"help", no_argument, nullptr, 'h'}, {"add", no_argument, nullptr, 'a'}, - {"get", no_argument, nullptr, 'g'}, {"get_remote", no_argument, nullptr, 'r'}, - {"isHdf", no_argument, nullptr, 'd'}, {"list", no_argument, nullptr, 'l'}, - {nullptr, no_argument, nullptr, 0}, - }; + if (!serviceName.empty()) { + std::cout << GetErrStr(isHdf ? HdfAddServiceCheck(getpid(), serviceName.c_str()) + : g_service->AddServiceCheck(getpid(), serviceName)) + << std::endl; + exit(0); + } + std::string serName; + while (std::cin >> serName) { + std::cout << GetErrStr(isHdf ? HdfAddServiceCheck(getpid(), serName.c_str()) + : g_service->AddServiceCheck(getpid(), serName)) + << std::endl; + } +} - if (argc == 1) { - PrintUsage(); +static void TestGetService(bool isHdf, const std::string &serviceName) +{ + if (!serviceName.empty()) { + std::cout << GetErrStr(isHdf ? HdfGetServiceCheck(getpid(), serviceName.c_str()) + : g_service->GetServiceCheck(getpid(), serviceName)) + << std::endl; exit(0); } + std::string serName; + while (std::cin >> serName) { + std::cout << GetErrStr(isHdf ? HdfGetServiceCheck(getpid(), serName.c_str()) + : g_service->GetServiceCheck(getpid(), serName)) + << std::endl; + } +} - testInput input; - SetOptions(argc, argv, options, input); - if (!input.isHdf) { - g_service = std::make_unique(false); +static void TestGetRemoteService(bool isHdf, const std::string &serviceName) +{ + if (!serviceName.empty()) { + std::cout << GetErrStr(isHdf ? SELINUX_PERMISSION_DENY + : g_service->GetRemoteServiceCheck(getpid(), serviceName)) + << std::endl; + exit(0); } std::string serName; - switch (input.cmd) { + while (std::cin >> serName) { + std::cout << GetErrStr(isHdf ? SELINUX_PERMISSION_DENY : g_service->GetRemoteServiceCheck(getpid(), serName)) + << std::endl; + } +} + +static void TestListService(bool isHdf) +{ + std::cout << GetErrStr(isHdf ? HdfListServiceCheck(getpid()) : g_service->ListServiceCheck(getpid())) << std::endl; +} + +static void Test(testInput &testCmd) +{ + switch (testCmd.cmd) { case 'a': { - while (std::cin >> serName) { - std::cout << GetErrStr(input.isHdf ? HdfAddServiceCheck(getpid(), serName.c_str()) - : g_service->AddServiceCheck(getpid(), serName)) - << std::endl; - } + TestAddService(testCmd.isHdf, testCmd.serviceName); exit(0); } case 'g': { - while (std::cin >> serName) { - std::cout << GetErrStr(input.isHdf ? HdfGetServiceCheck(getpid(), serName.c_str()) - : g_service->GetServiceCheck(getpid(), serName)) - << std::endl; - } + TestGetService(testCmd.isHdf, testCmd.serviceName); exit(0); } case 'r': { - while (std::cin >> serName) { - std::cout << GetErrStr(input.isHdf ? SELINUX_PERMISSION_DENY - : g_service->GetRemoteServiceCheck(getpid(), serName)) - << std::endl; - } + TestGetRemoteService(testCmd.isHdf, testCmd.serviceName); exit(0); } case 'l': { - std::cout << GetErrStr(input.isHdf ? HdfListServiceCheck(getpid()) : g_service->ListServiceCheck(getpid())) - << std::endl; + TestListService(testCmd.isHdf); exit(0); } default: exit(-1); } +} + +int main(int argc, char *argv[]) +{ + struct option options[] = { + {"help", no_argument, nullptr, 'h'}, {"add", no_argument, nullptr, 'a'}, + {"get", no_argument, nullptr, 'g'}, {"get_remote", no_argument, nullptr, 'r'}, + {"isHdf", no_argument, nullptr, 'd'}, {"list", no_argument, nullptr, 'l'}, + {"serviceName", required_argument, nullptr, 'n'}, {nullptr, no_argument, nullptr, 0}, + }; + + if (argc == 1) { + PrintUsage(); + exit(0); + } + + testInput input; + SetOptions(argc, argv, options, input); + if (!input.isHdf) { + g_service = std::make_unique(false); + } + Test(input); exit(0); } diff --git a/scripts/build_contexts.py b/scripts/build_contexts.py index a808be287..7d52d893d 100755 --- a/scripts/build_contexts.py +++ b/scripts/build_contexts.py @@ -159,6 +159,10 @@ def check_sehap_contexts(args, contexts_file, domain): continue match = pattern.match(line_) if match: + if match.group(1) == 'normal' and match.group(2) != None: + print(contexts_file + ":" + + str(line_index) + " name cannot be set while apl=normal") + err = 1 if domain: line = match.group(1) + " u:r:" + match.group(3) + ":s0\n" else: diff --git a/sepolicy/base/public/hdf_service.te b/sepolicy/base/public/hdf_service.te index 6e65725d8..7c634f10b 100644 --- a/sepolicy/base/public/hdf_service.te +++ b/sepolicy/base/public/hdf_service.te @@ -11,5 +11,6 @@ # See the License for the specific language governing permissions and # limitations under the License. +type default_hdf_service, hdf_devmgr_type; type hdf_usbd_service, hdf_devmgr_type; type hdf_wlan_hal_service, hdf_devmgr_type; diff --git a/sepolicy/base/public/service.te b/sepolicy/base/public/service.te index f2aab8368..8280de8b0 100644 --- a/sepolicy/base/public/service.te +++ b/sepolicy/base/public/service.te @@ -11,5 +11,6 @@ # See the License for the specific language governing permissions and # limitations under the License. +type default_service, samgr_type; type ams_service, samgr_type; type bms_service, samgr_type; diff --git a/test/BUILD.gn b/test/BUILD.gn index 3433407bb..3146c5f0f 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -27,20 +27,21 @@ ohos_unittest("selinux_unittest") { sources = [ "unittest/src/selinux_unit_test.cpp" ] - cflags_cc = [ "-DHILOG_ENABLE" ] - cflags = [ "-D_GNU_SOURCE", "-w", ] deps = [ - "//base/security/selinux:libhap_restorecon", "//third_party/selinux:libselinux", "//utils/native/base:utils", ] - external_deps = [ "selinux:libparaperm_checker" ] + external_deps = [ + "selinux:libhap_restorecon", + "selinux:libparaperm_checker", + "selinux:libservice_checker", + ] } group("unittest") { diff --git a/test/unittest/src/selinux_unit_test.cpp b/test/unittest/src/selinux_unit_test.cpp index db87bdcb3..8704e5bb8 100644 --- a/test/unittest/src/selinux_unit_test.cpp +++ b/test/unittest/src/selinux_unit_test.cpp @@ -20,6 +20,8 @@ #include #include "selinux_error.h" #include "selinux_parameter.h" +#include "service_checker.h" +#include "hdf_service_checker.h" using namespace testing::ext; using namespace OHOS::Security::Selinux; @@ -62,6 +64,10 @@ const static std::string DEFAULT_PARA_CONTEXT = "u:object_r:default_param:s0"; const static std::vector TEST_INVALID_PARA = {{".test"}, {"test."}, {"test..test"}, {""}, {"test+test"}}; +const static std::string TEST_SERVICE_NAME = "test_service"; +const static std::string DEFAULT_SERVICE = "default_service"; +const static std::string DEFAULT_HDF_SERVICE = "default_hdf_service"; + static bool CreateDirectory(const std::string &path) { std::string::size_type index = 0; @@ -858,3 +864,125 @@ HWTEST_F(SelinuxUnitTest, SetParamCheck002, TestSize.Level1) std::string cmdRes = RunCommand(cmd); ASSERT_TRUE(cmdRes.find(TEST_PARA_NAME) != std::string::npos); } + +/** + * @tc.name: HdfListServiceCheck001 + * @tc.desc: HdfListServiceCheck test. + * @tc.type: FUNC + * @tc.require:AR000GJSDS + */ +HWTEST_F(SelinuxUnitTest, HdfListServiceCheck001, TestSize.Level1) +{ + ASSERT_EQ(-SELINUX_GET_CONTEXT_ERROR, HdfListServiceCheck(-1)); + ASSERT_EQ(SELINUX_SUCC, HdfListServiceCheck(getpid())); + std::string cmd = + "dmesg | grep 'avc: denied { list } for service=hdf_devmgr_class pid=" + std::to_string(getpid()) + + "' | grep 'tclass=hdf_devmgr_class'"; + std::string cmdRes = RunCommand(cmd); + ASSERT_TRUE(cmdRes.find("hdf_devmgr_class") != std::string::npos); +} + +/** + * @tc.name: HdfGetServiceCheck001 + * @tc.desc: HdfGetServiceCheck test. + * @tc.type: FUNC + * @tc.require:AR000GJSDS + */ +HWTEST_F(SelinuxUnitTest, HdfGetServiceCheck001, TestSize.Level1) +{ + ASSERT_EQ(-SELINUX_GET_CONTEXT_ERROR, HdfGetServiceCheck(-1, TEST_SERVICE_NAME.c_str())); + ASSERT_EQ(-SELINUX_PTR_NULL, HdfGetServiceCheck(getpid(), nullptr)); + ASSERT_EQ(SELINUX_SUCC, HdfGetServiceCheck(getpid(), TEST_SERVICE_NAME.c_str())); + std::string cmd = "dmesg | grep 'avc: denied { get } for service=" + TEST_SERVICE_NAME + + " pid=" + std::to_string(getpid()) + "' | grep 'tclass=hdf_devmgr_class'"; + std::string cmdRes = RunCommand(cmd); + ASSERT_TRUE(cmdRes.find(TEST_SERVICE_NAME) != std::string::npos); +} + +/** + * @tc.name: HdfAddServiceCheck001 + * @tc.desc: HdfAddServiceCheck test. + * @tc.type: FUNC + * @tc.require:AR000GJSDS + */ +HWTEST_F(SelinuxUnitTest, HdfAddServiceCheck001, TestSize.Level1) +{ + ASSERT_EQ(-SELINUX_GET_CONTEXT_ERROR, HdfAddServiceCheck(-1, TEST_SERVICE_NAME.c_str())); + ASSERT_EQ(-SELINUX_PTR_NULL, HdfAddServiceCheck(getpid(), nullptr)); + ASSERT_EQ(SELINUX_SUCC, HdfAddServiceCheck(getpid(), TEST_SERVICE_NAME.c_str())); + std::string cmd = "dmesg | grep 'avc: denied { add } for service=" + TEST_SERVICE_NAME + + " pid=" + std::to_string(getpid()) + "' | grep 'tclass=hdf_devmgr_class'"; + std::string cmdRes = RunCommand(cmd); + ASSERT_TRUE(cmdRes.find(TEST_SERVICE_NAME) != std::string::npos); +} + +/** + * @tc.name: ListServiceCheck001 + * @tc.desc: ListServiceCheck test. + * @tc.type: FUNC + * @tc.require:AR000GJSDS + */ +HWTEST_F(SelinuxUnitTest, ListServiceCheck001, TestSize.Level1) +{ + ServiceChecker service(false); + ASSERT_EQ(-SELINUX_GET_CONTEXT_ERROR, service.ListServiceCheck(-1)); + ASSERT_EQ(SELINUX_SUCC, service.ListServiceCheck(getpid())); + std::string cmd = "dmesg | grep 'avc: denied { list } for service=samgr_class pid=" + std::to_string(getpid()) + + "' | grep 'tclass=samgr_class'"; + std::string cmdRes = RunCommand(cmd); + ASSERT_TRUE(cmdRes.find("samgr_class") != std::string::npos); +} + +/** + * @tc.name: GetServiceCheck001 + * @tc.desc: GetServiceCheck test. + * @tc.type: FUNC + * @tc.require:AR000GJSDS + */ +HWTEST_F(SelinuxUnitTest, GetServiceCheck001, TestSize.Level1) +{ + ServiceChecker service(false); + ASSERT_EQ(-SELINUX_GET_CONTEXT_ERROR, service.GetServiceCheck(-1, TEST_SERVICE_NAME)); + ASSERT_EQ(-SELINUX_ARG_INVALID, service.GetServiceCheck(getpid(), "")); + ASSERT_EQ(SELINUX_SUCC, service.GetServiceCheck(getpid(), TEST_SERVICE_NAME)); + std::string cmd = "dmesg | grep 'avc: denied { get } for service=" + TEST_SERVICE_NAME + + " pid=" + std::to_string(getpid()) + "' | grep 'tclass=samgr_class'"; + std::string cmdRes = RunCommand(cmd); + ASSERT_TRUE(cmdRes.find(TEST_SERVICE_NAME) != std::string::npos); +} + +/** + * @tc.name: GetRemoteServiceCheck001 + * @tc.desc: GetRemoteServiceCheck test. + * @tc.type: FUNC + * @tc.require:AR000GJSDS + */ +HWTEST_F(SelinuxUnitTest, GetRemoteServiceCheck001, TestSize.Level1) +{ + ServiceChecker service(false); + ASSERT_EQ(-SELINUX_GET_CONTEXT_ERROR, service.GetRemoteServiceCheck(-1, TEST_SERVICE_NAME)); + ASSERT_EQ(-SELINUX_ARG_INVALID, service.GetRemoteServiceCheck(getpid(), "")); + ASSERT_EQ(SELINUX_SUCC, service.GetRemoteServiceCheck(getpid(), TEST_SERVICE_NAME)); + std::string cmd = "dmesg | grep 'avc: denied { get_remote } for service=" + TEST_SERVICE_NAME + + " pid=" + std::to_string(getpid()) + "' | grep 'tclass=samgr_class'"; + std::string cmdRes = RunCommand(cmd); + ASSERT_TRUE(cmdRes.find(TEST_SERVICE_NAME) != std::string::npos); +} + +/** + * @tc.name: AddServiceCheck001 + * @tc.desc: AddServiceCheck test. + * @tc.type: FUNC + * @tc.require:AR000GJSDS + */ +HWTEST_F(SelinuxUnitTest, AddServiceCheck001, TestSize.Level1) +{ + ServiceChecker service(false); + ASSERT_EQ(-SELINUX_GET_CONTEXT_ERROR, service.AddServiceCheck(-1, TEST_SERVICE_NAME)); + ASSERT_EQ(-SELINUX_ARG_INVALID, service.AddServiceCheck(getpid(), "")); + ASSERT_EQ(SELINUX_SUCC, service.AddServiceCheck(getpid(), TEST_SERVICE_NAME)); + std::string cmd = "dmesg | grep 'avc: denied { add } for service=" + TEST_SERVICE_NAME + + " pid=" + std::to_string(getpid()) + "' | grep 'tclass=samgr_class'"; + std::string cmdRes = RunCommand(cmd); + ASSERT_TRUE(cmdRes.find(TEST_SERVICE_NAME) != std::string::npos); +} -- Gitee