mirror of
https://github.com/openharmony/kernel_linux_common_modules.git
synced 2026-08-26 17:16:37 -04:00
新增容器逃逸检测模块
Signed-off-by: xiacong <xiacong4@huawei.com> Change-Id: Ib9a158b9bf965bcf1cd28786c25a50fe718a6690 Signed-off-by: xiacong <xiacong4@huawei.com>
This commit is contained in:
@@ -5,5 +5,6 @@
|
||||
./ucollection/
|
||||
./memory_security/
|
||||
./code_sign
|
||||
./container_escape_detection
|
||||
|
||||
As for the specific use of the licenses, please refer to the relevant description in the documents.
|
||||
|
||||
@@ -63,12 +63,14 @@ Note:If the text contains special characters, please escape them according to th
|
||||
<policyitem type="compatibility" name="GPL" path="qos_auth/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="compatibility" name="GPL" path="ucollection/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="compatibility" name="GPL" path="code_sign/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="compatibility" name="GPL" path="container_escape_detection/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="license" name="GPL" path="newip/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="license" name="GPL" path="xpm/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="license" name="GPL" path="memory_security/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="license" name="GPL" path="qos_auth/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="license" name="GPL" path="ucollection/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="license" name="GPL" path="code_sign/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
<policyitem type="license" name="GPL" path="container_escape_detection/.*" rule="may" group="defaultGroup" filefilter="defaultPolicyFilter"/>
|
||||
</policy>
|
||||
</policylist>
|
||||
<filefilterlist>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
#
|
||||
config SECURITY_CONTAINER_ESCAPE_DETECTION
|
||||
bool "Enable container escape detection"
|
||||
default n
|
||||
depends on SECURITY_SELINUX
|
||||
help
|
||||
Build support for container escape detection.
|
||||
@@ -0,0 +1,18 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
#
|
||||
obj-$(CONFIG_SECURITY_CONTAINER_ESCAPE_DETECTION) += core/ced_detection.o
|
||||
obj-$(CONFIG_SECURITY_CONTAINER_ESCAPE_DETECTION) += core/ced_module.o
|
||||
|
||||
ccflags-$(CONFIG_SECURITY_CONTAINER_ESCAPE_DETECTION) := \
|
||||
-I$(srctree)/security/container_escape_detection/include \
|
||||
-I$(srctree)/security/selinux/include
|
||||
|
||||
$(addprefix $(obj)/,$(obj-y)): $(obj)/flask.h
|
||||
|
||||
quiet_cmd_flask = GEN $(obj)/flask.h $(obj)/av_permissions.h
|
||||
cmd_flask = scripts/selinux/genheaders/genheaders $(obj)/flask.h $(obj)/av_permissions.h
|
||||
|
||||
targets += flask.h av_permissions.h
|
||||
$(obj)/flask.h: $(srctree)/security/selinux/include/classmap.h FORCE
|
||||
$(call if_changed,flask)
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
OHOS_SOURCE_ROOT=$1
|
||||
KERNEL_BUILD_ROOT=$2
|
||||
PRODUCT_NAME=$3
|
||||
KERNEL_VERSION=$4
|
||||
CED_SOURCE_ROOT=$OHOS_SOURCE_ROOT/kernel/linux/common_modules/container_escape_detection
|
||||
|
||||
function main()
|
||||
{
|
||||
pushd .
|
||||
|
||||
if [ ! -d " $KERNEL_BUILD_ROOT/security/container_escape_detection" ]; then
|
||||
mkdir $KERNEL_BUILD_ROOT/security/container_escape_detection
|
||||
fi
|
||||
|
||||
cd $KERNEL_BUILD_ROOT/security/container_escape_detection
|
||||
ln -s -f $(realpath --relative-to=$KERNEL_BUILD_ROOT/security/container_escape_detection/ $CED_SOURCE_ROOT)/* ./
|
||||
|
||||
popd
|
||||
}
|
||||
|
||||
main
|
||||
@@ -0,0 +1,128 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/fs_struct.h>
|
||||
#include "ced_log.h"
|
||||
#include "avc.h"
|
||||
#include "objsec.h"
|
||||
#include "ced_detection.h"
|
||||
|
||||
enum ced_event_type {
|
||||
EVENT_CRED_ROOT,
|
||||
EVENT_NSPROXY_ROOT,
|
||||
EVENT_HAS_ROOT,
|
||||
EVENT_NUM
|
||||
};
|
||||
|
||||
extern struct task_struct init_task;
|
||||
|
||||
static const char *gEventContent[EVENT_NUM] = {
|
||||
"cred has been changed to root.",
|
||||
"nsproxy has been changed to init.",
|
||||
"process has been rooted."
|
||||
};
|
||||
|
||||
static inline void print_container_escape_detection(enum ced_event_type type)
|
||||
{
|
||||
if (type < EVENT_NUM) {
|
||||
ced_log_error("tgid is %d, %s container escape is detected!!!!", current->tgid, gEventContent[type]);
|
||||
}
|
||||
}
|
||||
|
||||
static int ced_avc_has_perm(u16 tclass, u32 requested)
|
||||
{
|
||||
struct av_decision avd;
|
||||
u32 sid = current_sid();
|
||||
int rc;
|
||||
|
||||
rc = avc_has_perm_noaudit(&selinux_state, sid, sid, tclass, requested,
|
||||
AVC_STRICT, &avd);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool ced_has_check_perm(void)
|
||||
{
|
||||
// use selinux label to tell the process is hap process
|
||||
int rc = ced_avc_has_perm(SECCLASS_CED, CED__CONTAINER_ESCAPE_CHECK);
|
||||
if (rc) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint64_t process_ns_pac_hash(const struct nsproxy *nsproxy)
|
||||
{
|
||||
uint64_t pac_hash = 0;
|
||||
uintptr_t ns_ptr = (uintptr_t)nsproxy->mnt_ns;
|
||||
pac_hash ^= ns_ptr;
|
||||
ns_ptr = (uintptr_t)nsproxy->pid_ns_for_children;
|
||||
pac_hash ^= ns_ptr;
|
||||
ns_ptr = (uintptr_t)nsproxy->net_ns;
|
||||
pac_hash ^= ns_ptr;
|
||||
return pac_hash;
|
||||
}
|
||||
|
||||
static bool is_container_process(const struct nsproxy *new)
|
||||
{
|
||||
uint64_t current_pac_hash = process_ns_pac_hash(new);
|
||||
uint64_t init_task_ns_pac = process_ns_pac_hash(init_task.nsproxy);
|
||||
if (current_pac_hash == init_task_ns_pac) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static bool detection_promotion_privilege(const struct cred *new)
|
||||
{
|
||||
const struct cred *init_cred = get_task_cred(&init_task);
|
||||
bool flag = false;
|
||||
if (new->euid.val == 0 || new->egid.val == 0 || new->fsuid.val == 0
|
||||
|| !memcmp(&new->cap_effective, &init_cred->cap_effective, sizeof(kernel_cap_t))) {
|
||||
flag = true;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
void switch_task_namespaces_hook(const struct nsproxy *new)
|
||||
{
|
||||
if (!ced_has_check_perm()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (new == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_container_process(new)) {
|
||||
print_container_escape_detection(EVENT_NSPROXY_ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
void commit_creds_hook(const struct cred *new)
|
||||
{
|
||||
if (!ced_has_check_perm()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (detection_promotion_privilege(new)) {
|
||||
print_container_escape_detection(EVENT_CRED_ROOT);
|
||||
}
|
||||
}
|
||||
|
||||
void detection_hook(struct task_struct *task)
|
||||
{
|
||||
if (!ced_has_check_perm()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const struct cred *cred = get_task_cred(task);
|
||||
|
||||
if ((!is_container_process(task->nsproxy) || (detection_promotion_privilege(cred)))) {
|
||||
print_container_escape_detection(EVENT_HAS_ROOT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/hck/lite_hck_ced.h>
|
||||
#include "ced_detection.h"
|
||||
#include "ced_log.h"
|
||||
|
||||
void ced_register_ced_hooks(void)
|
||||
{
|
||||
REGISTER_HCK_LITE_HOOK(ced_detection_lhck, detection_hook);
|
||||
REGISTER_HCK_LITE_HOOK(ced_switch_task_namespaces_lhck, switch_task_namespaces_hook);
|
||||
REGISTER_HCK_LITE_HOOK(ced_commit_creds_lhck, commit_creds_hook);
|
||||
ced_log_info("ced_register_ced_hooks");
|
||||
}
|
||||
|
||||
static int __init ced_module_init(void)
|
||||
{
|
||||
ced_register_ced_hooks();
|
||||
return 0;
|
||||
}
|
||||
|
||||
module_init(ced_module_init);
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -0,0 +1,16 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef _CED_DETECTION_H
|
||||
#define _CED_DETECTION_H
|
||||
|
||||
#include <linux/cred.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
void detection_hook(struct task_struct *task);
|
||||
void switch_task_namespaces_hook(const struct nsproxy *new);
|
||||
void commit_creds_hook(const struct cred *new);
|
||||
|
||||
#endif /* _CED_DETECTION_H */
|
||||
@@ -0,0 +1,22 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
||||
*/
|
||||
|
||||
#ifndef _CED_LOG_H
|
||||
#define _CED_LOG_H
|
||||
|
||||
#define CED_CHECK_FAILED (-1024)
|
||||
|
||||
#define CED_TAG "ced_kernel"
|
||||
#define CED_INFO_TAG "I"
|
||||
#define CED_ERROR_TAG "E"
|
||||
#define CED_DEBUG_TAG "D"
|
||||
|
||||
#define ced_log_info(fmt, args...) pr_info("[%s/%s]%s: " fmt "\n", \
|
||||
CED_INFO_TAG, CED_TAG, __func__, ##args)
|
||||
|
||||
#define ced_log_error(fmt, args...) pr_err("[%s/%s]%s: " fmt "\n", \
|
||||
CED_ERROR_TAG, CED_TAG, __func__, ##args)
|
||||
|
||||
#endif /* _CED_LOG_H */
|
||||
Reference in New Issue
Block a user