From 4419ee786e29c177db0e9c303fa8a0c279093b26 Mon Sep 17 00:00:00 2001 From: renwei Date: Tue, 18 Jan 2022 16:30:59 +0800 Subject: [PATCH 1/3] policy update Signed-off-by: renwei Change-Id: I38eddb28e8311c05978e48dd0e35f2f21d88508d --- sepolicy/base/public/domain.te | 8 ++++---- sepolicy/base/system/file.te | 3 +-- sepolicy/base/system/virtfs_contexts | 5 +++-- sepolicy/ohos_policy/startup/init/system/init.te | 2 +- sepolicy/ohos_policy/startup/init/system/ueventd.te | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/sepolicy/base/public/domain.te b/sepolicy/base/public/domain.te index 8119b3ecd..f5587b77d 100644 --- a/sepolicy/base/public/domain.te +++ b/sepolicy/base/public/domain.te @@ -39,8 +39,8 @@ allow domain domain:{ file lnk_file } read_file_perms; allow domain domain:{ fifo_file file } rw_file_perms; allow domain domain:unix_dgram_socket { create_socket_perms sendto }; -allow domain proc:dir read_dir_perms; -allow domain proc:lnk_file { getattr read }; +allow domain proc_file:dir read_dir_perms; +allow domain proc_file:lnk_file { getattr read }; allow domain tmpfs:dir { getattr search }; allow domain tmpfs:chr_file { read write open getattr setattr ioctl map }; @@ -75,8 +75,8 @@ allow domain { allow domain system_lib_file:file { execute read open getattr map }; -allow domain sysfs:dir search; -allow domain sysfs:{ lnk_file file } { getattr read }; +allow domain sys_file:dir search; +allow domain sys_file:{ lnk_file file } { getattr read }; allow domain system_data_file:dir search; diff --git a/sepolicy/base/system/file.te b/sepolicy/base/system/file.te index 3972e157e..b980b5615 100644 --- a/sepolicy/base/system/file.te +++ b/sepolicy/base/system/file.te @@ -16,7 +16,7 @@ type labeledfs, fs_type; type pipefs, fs_type; type sockfs, fs_type; type rootfs, fs_type; -type proc, fs_type, proc_type; +type proc_file, fs_type, proc_type; type proc_panic, fs_type, proc_type; type unlabeled, fs_type; @@ -27,7 +27,6 @@ type mqueue, fs_type; type sys_file, fs_type; type selinuxfs, fs_type; type cgroup, fs_type; -type sysfs, fs_type; type inotify, fs_type; type debugfs, fs_type; type config_file, fs_type; diff --git a/sepolicy/base/system/virtfs_contexts b/sepolicy/base/system/virtfs_contexts index af7c8cf13..f80b74174 100644 --- a/sepolicy/base/system/virtfs_contexts +++ b/sepolicy/base/system/virtfs_contexts @@ -1,13 +1,14 @@ # please put longer path ahead. # use relative path to mount point. genfscon rootfs / u:object_r:rootfs:s0 -genfscon proc / u:object_r:proc:s0 +genfscon proc / u:object_r:proc_file:s0 genfscon selinuxfs / u:object_r:selinuxfs:s0 genfscon sysfs /block u:object_r:sysfs_block_file:s0 genfscon sysfs /hisys u:object_r:sysfs_hisys_file:s0 -genfscon sysfs / u:object_r:sysfs:s0 +genfscon sysfs / u:object_r:sys_file:s0 genfscon configfs / u:object_r:config_file:s0 genfscon debugfs / u:object_r:debugfs:s0 +genfscon cgroup / u:object_r:cgroup:s0 \ No newline at end of file diff --git a/sepolicy/ohos_policy/startup/init/system/init.te b/sepolicy/ohos_policy/startup/init/system/init.te index 3332d2398..9bd90a858 100644 --- a/sepolicy/ohos_policy/startup/init/system/init.te +++ b/sepolicy/ohos_policy/startup/init/system/init.te @@ -47,7 +47,7 @@ allow init system_file:file execute_no_trans; allow init device:sock_file { create setattr }; -allow init sysfs:file setattr; +allow init sys_file:file setattr; allow init shell_exec:file { execute_no_trans }; allow init logserver_exec:file { execute_no_trans }; diff --git a/sepolicy/ohos_policy/startup/init/system/ueventd.te b/sepolicy/ohos_policy/startup/init/system/ueventd.te index ec05c4e40..8d840e604 100644 --- a/sepolicy/ohos_policy/startup/init/system/ueventd.te +++ b/sepolicy/ohos_policy/startup/init/system/ueventd.te @@ -18,7 +18,7 @@ init_daemon_domain(ueventd); allow ueventd kernel:fd use; -allow ueventd sysfs:file write_file_perms; +allow ueventd sys_file:file write_file_perms; allow ueventd tmpfs:chr_file { create setattr unlink rw_file_perms }; allow ueventd tmpfs:dir create_dir_perms; allow ueventd tmpfs:blk_file { create setattr unlink rw_file_perms }; -- Gitee From 1cd1d44680da60fca2de74e01af536226cdea729 Mon Sep 17 00:00:00 2001 From: renwei Date: Tue, 18 Jan 2022 20:08:55 +0800 Subject: [PATCH 2/3] add rom and ram info Signed-off-by: renwei Change-Id: If988c7ea656a59059bd4949b7545759b4fcdb74b --- bundle.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bundle.json b/bundle.json index b26af929e..bebbd88a6 100755 --- a/bundle.json +++ b/bundle.json @@ -13,6 +13,8 @@ "name": "selinux", "subsystem": "security", "adapted_system_type": [ "standard" ], + "rom": "3072KB", + "ram": "3072KB", "deps": { "components": [], "third_party": [ -- Gitee From 01f620b70090b5fd7201a369cc49b5817dc36872 Mon Sep 17 00:00:00 2001 From: steven_q Date: Tue, 18 Jan 2022 22:13:02 +0800 Subject: [PATCH 3/3] add restorecon and setcon for hap Signed-off-by: steven_q --- BUILD.gn | 57 +++ .../policycoreutils/include/hap_restorecon.h | 61 +++ .../policycoreutils/include/selinux_error.h | 38 ++ .../policycoreutils/include/selinux_log.h | 63 +++ .../policycoreutils/src/hap_restorecon.cpp | 404 ++++++++++++++++++ interfaces/tools/hap_restorecon/test.cpp | 53 +++ sepolicy/base/public/test.te | 36 ++ sepolicy/sehap_contexts | 29 ++ 8 files changed, 741 insertions(+) create mode 100644 interfaces/policycoreutils/include/hap_restorecon.h create mode 100644 interfaces/policycoreutils/include/selinux_error.h create mode 100644 interfaces/policycoreutils/include/selinux_log.h create mode 100644 interfaces/policycoreutils/src/hap_restorecon.cpp create mode 100644 interfaces/tools/hap_restorecon/test.cpp create mode 100644 sepolicy/base/public/test.te create mode 100644 sepolicy/sehap_contexts diff --git a/BUILD.gn b/BUILD.gn index f8a9f84bc..6f7a5ff2c 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -96,6 +96,36 @@ ohos_shared_library("librestorecon") { subsystem_name = "security" } +ohos_shared_library("libhap_restorecon") { + output_name = "libhap_restorecon" + sources = + [ "$SELINUX_ROOT_DIR/interfaces/policycoreutils/src/hap_restorecon.cpp" ] + include_dirs = [ + "$SELINUX_ROOT_DIR/interfaces/policycoreutils/include", + "$LIBSELINUX_ROOT_DIR/include", + "$LIBSELINUX_ROOT_DIR/src", + "//third_party/FreeBSD", + "//utils/native/base/include", + ] + deps = [ + "$THIRD_PARTY_SELINUX_DIR:libselinux", + "//utils/native/base:utils", + ] + + external_deps = [ "hiviewdfx_hilog_native:libhilog" ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + cflags = [ + "-D_GNU_SOURCE", + "-w", + ] + install_enable = true + license_file = "$SELINUX_ROOT_DIR/LICENSE" + part_name = "selinux" + subsystem_name = "security" +} + ohos_executable("load_policy") { install_enable = true sources = [ "$SELINUX_ROOT_DIR/interfaces/tools/load_policy/load_policy.c" ] @@ -140,6 +170,24 @@ ohos_executable("restorecon") { subsystem_name = "security" } +ohos_executable("hap_restorecon") { + install_enable = true + sources = [ "$SELINUX_ROOT_DIR/interfaces/tools/hap_restorecon/test.cpp" ] + include_dirs = [ + "$SELINUX_ROOT_DIR/interfaces/policycoreutils/include", + "$LIBSELINUX_ROOT_DIR/include", + ] + deps = [ ":libhap_restorecon" ] + + cflags = [ + "-D_GNU_SOURCE", + "-w", + ] + license_file = "$SELINUX_ROOT_DIR/LICENSE" + part_name = "selinux" + subsystem_name = "security" +} + ohos_executable("selinux_test") { install_enable = true sources = [ "$SELINUX_ROOT_DIR/test/selinux_test.c" ] @@ -221,6 +269,13 @@ ohos_prebuilt_etc("config") { relative_install_dir = "selinux/" } +ohos_prebuilt_etc("sehap_contexts") { + source = "$SELINUX_ROOT_DIR/sepolicy/sehap_contexts" + license_file = "$SELINUX_ROOT_DIR/LICENSE" + part_name = "selinux" + relative_install_dir = "selinux/targeted/contexts/" +} + ohos_prebuilt_etc("file_contexts") { deps = [ ":build_file_contexts_bin" ] source = target_out_dir + "/file_contexts" @@ -241,8 +296,10 @@ group("selinux_group") { "//base/security/selinux:build_sepolicy", "//base/security/selinux:config", "//base/security/selinux:file_contexts", + "//base/security/selinux:hap_restorecon", "//base/security/selinux:load_policy", "//base/security/selinux:restorecon", + "//base/security/selinux:sehap_contexts", "//base/security/selinux:selinux_test", "//third_party/selinux:checkpolicy($host_toolchain)", "//third_party/selinux:chkcon", diff --git a/interfaces/policycoreutils/include/hap_restorecon.h b/interfaces/policycoreutils/include/hap_restorecon.h new file mode 100644 index 000000000..3e50249db --- /dev/null +++ b/interfaces/policycoreutils/include/hap_restorecon.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 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 HAP_RESTORECON_H +#define HAP_RESTORECON_H + +#include +#include +#include +#include +#include +#include + +#define SELINUX_HAP_RESTORECON_RECURSE 1 + +// parameters of each SehapContext in file sehap_contexts +struct SehapContext { + std::string apl = ""; + std::string name = ""; + std::string domain = ""; + std::string type = ""; +}; + +class HapContext { +public: + HapContext(); + ~HapContext(); + int HapFileRestorecon(std::vector &pathNameOrig, const std::string &apl, + const std::string &packageName, unsigned int flags); + int HapFileRestorecon(const std::string &pathNameOrig, const std::string &apl, const std::string &packageName, + unsigned int flags); + int HapDomainSetcontext(const std::string &apl, const std::string &packageName); + +protected: + static std::unordered_map sehapContextsBuff; + static struct selabel_handle *fileContextsHandle; + +private: + 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); + int HapLabelLookup(const std::string &apl, const std::string &packageName, char **secontextPtr); + + static void RestoreconInit(); + static bool HapContextsLoad(); + static void HapContextsClear(); +}; + +#endif // HAP_RESTORECON_H diff --git a/interfaces/policycoreutils/include/selinux_error.h b/interfaces/policycoreutils/include/selinux_error.h new file mode 100644 index 000000000..425219f41 --- /dev/null +++ b/interfaces/policycoreutils/include/selinux_error.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 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_ERROE_H +#define SELINUX_ERROE_H + +namespace Selinux { +enum Errno { + SELINUX_SUCC, + SELINUX_ARG_INVALID, + SELINUX_TYPE_SET_ERR, + SELINUX_TYPE_INVALID, + SELINUX_KEY_NOT_FOUND, + SELINUX_CONTEXTS_NOT_FOUND, + SELINUX_CONTEXTS_LOAD_ERR, + SELINUX_PTR_NULL, + SELINUX_PATH_INVAILD, + SELINUX_FILE_INVAILD, + SELINUX_FILE_ERR, + SELINUX_FTS_ELOOP, + SELINUX_SETCON_ERR, + SELINUX_GETCON_ERR, +}; +} // namespace Selinux + +#endif // SELINUX_ERROE_H diff --git a/interfaces/policycoreutils/include/selinux_log.h b/interfaces/policycoreutils/include/selinux_log.h new file mode 100644 index 000000000..6023638ea --- /dev/null +++ b/interfaces/policycoreutils/include/selinux_log.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2021 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 new file mode 100644 index 000000000..16bdb4c19 --- /dev/null +++ b/interfaces/policycoreutils/src/hap_restorecon.cpp @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "hap_restorecon.h" +#include "callbacks.h" +#include "selinux_error.h" +#include "selinux_log.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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="; +static const std::string DOMAIN_PREFIX = "domain="; +static const std::string TYPE_PREFIX = "type="; +static const std::string PATH_PREFIX = "/data/app"; + +static pthread_once_t FC_ONCE = PTHREAD_ONCE_INIT; +} // namespace + +struct selabel_handle *HapContext::fileContextsHandle = nullptr; +std::unordered_map HapContext::sehapContextsBuff; + +HapContext::HapContext() {} + +HapContext::~HapContext() {} + +struct selabel_handle *SelinuxRestoreconHandle() +{ + struct selinux_opt selinuxOpts[] = { + {SELABEL_OPT_VALIDATE, NULL}, + {SELABEL_OPT_PATH, NULL}, + {SELABEL_OPT_DIGEST, NULL}, + }; + + return selabel_open(SELABEL_CTX_FILE, selinuxOpts, 1); +} + +static bool CouldSkip(const std::string &line) +{ + if (line.size() <= 10) { + return true; + } + int i = 0; + while (isspace(line[i++])) + ; + if (line[i] == '#') { + return true; + } + if (line.find(APL_PREFIX) == line.npos) { + return true; + } + return false; +} + +static struct SehapContext DecodeString(std::string &line) +{ + std::stringstream input(line); + std::string tmp; + struct SehapContext contextBuff; + bool aplVisit = false; + bool nameVisit = false; + bool domainVisit = false; + bool typeVisit = false; + + while (input >> tmp) { + if (!aplVisit && (tmp.find(APL_PREFIX) != tmp.npos)) { + contextBuff.apl = tmp.substr(tmp.find(APL_PREFIX) + APL_PREFIX.size()); + aplVisit = true; + } else if (!nameVisit && (tmp.find(NAME_PREFIX) != tmp.npos)) { + contextBuff.name = tmp.substr(tmp.find(NAME_PREFIX) + NAME_PREFIX.size()); + nameVisit = true; + } else if (!domainVisit && (tmp.find(DOMAIN_PREFIX) != tmp.npos)) { + contextBuff.domain = tmp.substr(tmp.find(DOMAIN_PREFIX) + DOMAIN_PREFIX.size()); + domainVisit = true; + } else if (!typeVisit && (tmp.find(TYPE_PREFIX) != tmp.npos)) { + contextBuff.type = tmp.substr(tmp.find(TYPE_PREFIX) + TYPE_PREFIX.size()); + typeVisit = true; + } + } + + return contextBuff; +} + +void HapContext::RestoreconInit() +{ + if (fileContextsHandle == nullptr) { + fileContextsHandle = SelinuxRestoreconHandle(); + } +} + +void HapContext::HapContextsClear() +{ + if (!sehapContextsBuff.empty()) { + sehapContextsBuff.clear(); + } +} + +bool HapContext::HapContextsLoad() +{ + // load sehap_contexts file + std::ifstream contextsFile(SEHAP_CONTEXTS_FILE); + if (contextsFile) { + int lineNum = 0; + std::string line; + while (getline(contextsFile, line)) { + lineNum++; + if (CouldSkip(line)) + continue; + struct SehapContext tmpContext = DecodeString(line); + if (!tmpContext.apl.empty()) { + sehapContextsBuff.emplace(tmpContext.apl + tmpContext.name, tmpContext); + } else { + SELINUX_LOG_INFO(LABEL, "hap_contexts read fail in line %{public}d", lineNum); + } + } + } else { + SELINUX_LOG_ERROR(LABEL, "Load hap_contexts fail, no such file: %{public}s", SEHAP_CONTEXTS_FILE.c_str()); + return false; + } + SELINUX_LOG_INFO(LABEL, "Load hap_contexts succes: %{public}s", SEHAP_CONTEXTS_FILE.c_str()); + contextsFile.close(); + return true; +} + +int HapContext::HapContextsLookup(bool isDomain, const std::string &apl, const std::string &packageName, context_t con) +{ + if (sehapContextsBuff.empty()) { + if (!HapContextsLoad()) { + return -SELINUX_CONTEXTS_LOAD_ERR; + } + } + + auto iter = sehapContextsBuff.find(std::string(apl) + std::string(packageName)); + if (iter != sehapContextsBuff.end()) { + std::string type = ""; + if (isDomain) { + type = iter->second.domain; + } else { + type = iter->second.type; + } + if (context_type_set(con, type.c_str())) { + SELINUX_LOG_ERROR(LABEL, "Set type for %{public}s fail", type.c_str()); + return -SELINUX_TYPE_SET_ERR; + } + return SELINUX_SUCC; + } + return -SELINUX_KEY_NOT_FOUND; +} + +int HapContext::HapLabelLookup(const std::string &apl, const std::string &packageName, char **secontextPtr) +{ + if (apl.size() == 0 || secontextPtr == nullptr) { + return -SELINUX_ARG_INVALID; + } + char *secontext = *secontextPtr; + context_t con = context_new(secontext); + if (con == nullptr) { + return -SELINUX_PTR_NULL; + } + + int res = HapContextsLookup(false, apl, packageName, con); + if (res < 0) { + context_free(con); + return res; + } + + secontext = context_str(con); + if (secontext == nullptr) { + context_free(con); + return -SELINUX_PTR_NULL; + } + + // if new contexts is same as old + if (!strcmp(secontext, *secontextPtr)) { + context_free(con); + return SELINUX_SUCC; + } + + // check whether the context is valid + if (security_check_context(secontext) < 0) { + context_free(con); + return -SELINUX_TYPE_INVALID; + } + + freecon(*secontextPtr); + *secontextPtr = strdup(secontext); + if (!(*secontextPtr)) { + context_free(con); + return -SELINUX_PTR_NULL; + } + + context_free(con); + return SELINUX_SUCC; +} + +int HapContext::RestoreconSb(const std::string &pathname, const struct stat *sb, const std::string &apl, + const std::string &packageName) +{ + char *secontext = nullptr; + char *oldSecontext = nullptr; + + if (selabel_lookup(fileContextsHandle, &secontext, pathname.c_str(), sb->st_mode) < 0) { + return SELINUX_SUCC; + } + + if (lgetfilecon(pathname.c_str(), &oldSecontext) < 0) { + freecon(secontext); + freecon(oldSecontext); + return -SELINUX_CONTEXTS_NOT_FOUND; + } + + int res = HapLabelLookup(apl, packageName, &secontext); + if (res < 0) { + freecon(secontext); + freecon(oldSecontext); + return res; + } + + if (strcmp(oldSecontext, secontext)) { + if (lsetfilecon(pathname.c_str(), secontext) < 0) { + freecon(secontext); + freecon(oldSecontext); + return -SELINUX_CONTEXTS_NOT_FOUND; + } + } + + freecon(secontext); + freecon(oldSecontext); + return SELINUX_SUCC; +} + +int HapContext::HapFileRestorecon(std::vector &pathNameOrig, const std::string &apl, + const std::string &packageName, unsigned int flags) +{ + if (pathNameOrig.empty()) { + return -SELINUX_PATH_INVAILD; + } + int res = SELINUX_SUCC; + for (auto pathname : pathNameOrig) { + res |= HapFileRestorecon(pathname.c_str(), apl, packageName, flags); + } + return res; +} + +int HapContext::HapFileRestorecon(const std::string &pathNameOrig, const std::string &apl, + const std::string &packageName, unsigned int flags) +{ + if (is_selinux_enabled() < 1) { + SELINUX_LOG_INFO(LABEL, "Selinux not enbaled"); + return SELINUX_SUCC; + } + + if (std::string(pathNameOrig).compare(0, PATH_PREFIX.size(), PATH_PREFIX) != 0) { + return -SELINUX_PATH_INVAILD; + } + + // 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)); + return -SELINUX_PTR_NULL; + } + + struct stat sb; + char realPath[PATH_MAX]; + if (realpath(pathNameOrig.c_str(), realPath) == nullptr) { + return -SELINUX_PATH_INVAILD; + } + + bool recurse = (flags & SELINUX_HAP_RESTORECON_RECURSE) ? true : false; + if (!recurse) { + if (lstat(realPath, &sb) < 0) { + return -SELINUX_FILE_INVAILD; + } + + int res = RestoreconSb(realPath, &sb, apl, packageName); + if (res < 0) { + SELINUX_LOG_ERROR(LABEL, "RestoreconSb failed"); + } + return res; + } + + char *paths[2] = {NULL, NULL}; + paths[0] = (char *)realPath; + int ftsFlags = FTS_PHYSICAL | FTS_NOCHDIR; + FTS *fts = fts_open(paths, ftsFlags, NULL); + if (fts == nullptr) { + return -SELINUX_FILE_ERR; + } + + FTSENT *ftsent = nullptr; + int error = 0; + while ((ftsent = fts_read(fts)) != NULL) { + switch (ftsent->fts_info) { + case FTS_DC: + SELINUX_LOG_ERROR(LABEL, "Cycle on %{public}s", 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, + 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)); + 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, + strerror(errno)); + fts_set(fts, ftsent, FTS_SKIP); + continue; + case FTS_D: + default: + error |= RestoreconSb(ftsent->fts_path, ftsent->fts_statp, apl, packageName); + break; + } + } + (void)fts_close(fts); + return error; +} + +int HapContext::HapDomainSetcontext(const std::string &apl, const std::string &packageName) +{ + if (is_selinux_enabled() < 1) { + SELINUX_LOG_INFO(LABEL, "Selinux not enbaled"); + return SELINUX_SUCC; + } + + char *typeContext = nullptr; + if (getcon(&typeContext)) { + return -SELINUX_GETCON_ERR; + } + + context_t con = nullptr; + con = context_new(typeContext); + if (con == nullptr) { + return -SELINUX_PTR_NULL; + } + char *oldTypeContext = typeContext; + + int res = HapContextsLookup(true, apl, packageName, con); + if (res < 0) { + freecon(oldTypeContext); + context_free(con); + return res; + } + + typeContext = context_str(con); + if (typeContext == nullptr) { + freecon(oldTypeContext); + context_free(con); + return -SELINUX_PTR_NULL; + } + + SELINUX_LOG_INFO(LABEL, "Hap type for %{public}s is changing from %{public}s to %{public}s", packageName.c_str(), + oldTypeContext, typeContext); + + if (security_check_context(typeContext) < 0) { + freecon(oldTypeContext); + context_free(con); + return -SELINUX_TYPE_INVALID; + } + + if (strcmp(typeContext, oldTypeContext)) { + if (setcon(typeContext) < 0) { + freecon(oldTypeContext); + context_free(con); + return -SELINUX_SETCON_ERR; + } + } + SELINUX_LOG_INFO(LABEL, "Hap setcon finish for %{public}s", packageName.c_str()); + + freecon(oldTypeContext); + context_free(con); + return SELINUX_SUCC; +} diff --git a/interfaces/tools/hap_restorecon/test.cpp b/interfaces/tools/hap_restorecon/test.cpp new file mode 100644 index 000000000..015502c00 --- /dev/null +++ b/interfaces/tools/hap_restorecon/test.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 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. + */ + +#include "hap_restorecon.h" + +#include + +int main(int argc, char **argv) +{ + int res; + HapContext test; + std::cout << "test 1: invalid path not with /data/app" << std::endl; + res = test.HapFileRestorecon("/data/data/com.hap.selftest", "system_core", "com.hap.selftest", + SELINUX_HAP_RESTORECON_RECURSE); + std::cout << "res: " << res << std::endl; + + std::cout << "test 2: single path" << std::endl; + res = test.HapFileRestorecon("/data/app/com.hap.selftest", "system_core", "com.hap.selftest", + SELINUX_HAP_RESTORECON_RECURSE); + std::cout << "res: " << res << std::endl; + + std::cout << "test 3: single path no recurse" << std::endl; + res = test.HapFileRestorecon("/data/app/com.hap.selftest1", "system_core", "com.hap.selftest1", 0); + std::cout << "res: " << res << std::endl; + + std::cout << "test 4: multi path" << std::endl; + std::vector tmp; + tmp.emplace_back("/data/app/test1"); + tmp.emplace_back("/data/app/test2"); + tmp.emplace_back("/data/app/test3"); + + res = test.HapFileRestorecon(tmp, "system_core", "com.hap.selftest", SELINUX_HAP_RESTORECON_RECURSE); + std::cout << "res: " << res << std::endl; + + std::cout << "test 5" << std::endl; + res = test.HapDomainSetcontext("system_core", "com.hap.selftest"); + std::cout << "res: " << res << std::endl; + + while(1); + return 0; +} \ No newline at end of file diff --git a/sepolicy/base/public/test.te b/sepolicy/base/public/test.te new file mode 100644 index 000000000..8304e5337 --- /dev/null +++ b/sepolicy/base/public/test.te @@ -0,0 +1,36 @@ +# Copyright (c) 2021 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. + +# for test +type selftest, domain; +type selftest_hap_data_file, file_type; +type selftest1, domain; +type selftest_hap_data_file1, file_type; + + + +type launcher, domain; +type settingsdata, domain; +type systemui, domain; +type mms, domain; +type telephonydataability, domain; +type contactsdataability, domain; +type contacts, domain; + +type launcher_hap_data_file, file_type; +type settingsdata_hap_data_file, file_type; +type systemui_hap_data_file, file_type; +type telephonydataability_hap_data_file, file_type; +type mms_hap_data_file, file_type; +type contactsdataability_hap_data_file, file_type; +type contacts_hap_data_file, file_type; diff --git a/sepolicy/sehap_contexts b/sepolicy/sehap_contexts new file mode 100644 index 000000000..009603f8e --- /dev/null +++ b/sepolicy/sehap_contexts @@ -0,0 +1,29 @@ +# Copyright (c) 2021 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. + +apl=system_core domain=platform_hap_domain type=platform_hap_data_file +apl=system_basic domain=priv_hap_domain type=priv_hap_data_file +apl=normal domain=normal_hap_domain type=normal_hap_data_file + +# for test +apl=system_core name=com.hap.selftest domain=selftest type=selftest_hap_data_file +apl=system_core name=com.hap.selftest1 domain=selftest1 type=selftest_hap_data_file1 + +apl=system_core name=com.ohos.launcher domain=launcher type=launcher_hap_data_file +apl=system_core name=com.ohos.settingsdata domain=settingsdata type=settingsdata_hap_data_file +apl=system_core name=com.ohos.systemui domain=systemui type=systemui_hap_data_file +apl=system_core name=com.ohos.contacts domain=contacts type=contacts_hap_data_file +apl=system_core name=com.ohos.telephonydataability domain=telephonydataability type=telephonydataability_hap_data_file +apl=system_core name=com.ohos.contactsdataability domain=contactsdataability type=contactsdataability_hap_data_file +apl=system_core name=com.ohos.mms domain=mms type=mms_hap_data_file + -- Gitee