mirror of
https://gitee.com/openharmony/security_selinux
synced 2024-11-27 07:10:25 +00:00
!25 add restorecon and setcon for hap
Merge pull request !25 from steven_Q/master
This commit is contained in:
commit
2ef38b7e07
57
BUILD.gn
57
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",
|
||||
|
61
interfaces/policycoreutils/include/hap_restorecon.h
Normal file
61
interfaces/policycoreutils/include/hap_restorecon.h
Normal file
@ -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 <iostream>
|
||||
#include <selinux/context.h>
|
||||
#include <string>
|
||||
#include <sys/stat.h>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#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<std::string> &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<std::string, struct SehapContext> 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
|
38
interfaces/policycoreutils/include/selinux_error.h
Normal file
38
interfaces/policycoreutils/include/selinux_error.h
Normal file
@ -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
|
63
interfaces/policycoreutils/include/selinux_log.h
Normal file
63
interfaces/policycoreutils/include/selinux_log.h
Normal file
@ -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 <stdarg.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/* 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
|
404
interfaces/policycoreutils/src/hap_restorecon.cpp
Normal file
404
interfaces/policycoreutils/src/hap_restorecon.cpp
Normal file
@ -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 <fstream>
|
||||
#include <include/fts.h>
|
||||
#include <iostream>
|
||||
#include <selinux/label.h>
|
||||
#include <selinux/restorecon.h>
|
||||
#include <selinux_internal.h>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
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<std::string, struct SehapContext> 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<std::string> &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;
|
||||
}
|
53
interfaces/tools/hap_restorecon/test.cpp
Normal file
53
interfaces/tools/hap_restorecon/test.cpp
Normal file
@ -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 <unistd.h>
|
||||
|
||||
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<std::string> 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;
|
||||
}
|
36
sepolicy/base/public/test.te
Normal file
36
sepolicy/base/public/test.te
Normal file
@ -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;
|
29
sepolicy/sehap_contexts
Normal file
29
sepolicy/sehap_contexts
Normal file
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user