diff --git a/LICENSE b/LICENSE
index 8eddf19d0568ff3af1bcd1ca9163e875da8cbc0d..21795c929b88afa5e7b1a2a84e620d9cf123b910 100644
--- a/LICENSE
+++ b/LICENSE
@@ -9,5 +9,6 @@
./container_escape_detection
./module_sample
./pac/
+ ./dec
As for the specific use of the licenses, please refer to the relevant description in the documents.
diff --git a/OAT.xml b/OAT.xml
index f4ef13823b6d0d5a44d2d5a611e565e8231992e8..dfa276cdb30319b153acd22e192be2350b397128 100644
--- a/OAT.xml
+++ b/OAT.xml
@@ -66,7 +66,9 @@ Note:If the text contains special characters, please escape them according to th
-
+
+
+
@@ -76,7 +78,9 @@ Note:If the text contains special characters, please escape them according to th
-
+
+
+
@@ -99,7 +103,8 @@ Note:If the text contains special characters, please escape them according to th
-
+
+
diff --git a/code_sign/code_sign_elf.c b/code_sign/code_sign_elf.c
index 9c9a3dccffd6692d261c26a639eecffe4c093492..0745061b11aea5ef4086549b35e9ba362d20f3a0 100644
--- a/code_sign/code_sign_elf.c
+++ b/code_sign/code_sign_elf.c
@@ -4,14 +4,22 @@
*/
#include
+#include
#include
#include
-#include "dsmm_developer.h"
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 6, 0)
+#include
+#endif
+
#include "code_sign_elf.h"
#include "code_sign_log.h"
#include "verify_cert_chain.h"
+#ifdef CONFIG_SECURITY_XPM
+#include "dsmm_developer.h"
+#endif
+
#define SIGN_HEAD_SIZE (sizeof(sign_head_t))
static void parse_sign_head(sign_head_t *out, char *ptr)
@@ -197,12 +205,20 @@ out:
int elf_file_enable_fs_verity(struct file *file)
{
+#ifdef CONFIG_SECURITY_XPM
/* developer mode */
if (get_developer_mode_state() != STATE_ON) {
code_sign_log_info("developer mode off, elf not allowed to execute");
return -EINVAL;
}
+#else
+ code_sign_log_info("developer mode off, elf not allowed to execute");
+ return -EINVAL;
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
mm_segment_t fs;
+#endif
char *path_buf = kzalloc(PATH_MAX, GFP_KERNEL);
if (!path_buf) {
code_sign_log_error("alloc mem for path_buf failed");
@@ -245,10 +261,10 @@ int elf_file_enable_fs_verity(struct file *file)
err = -ENOMEM;
goto filp_close_out;
}
-
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
fs = get_fs();
set_fs(KERNEL_DS);
-
+#endif
ssize_t cnt = vfs_read(fp, sign_head_ptr, SIGN_HEAD_SIZE, &pos);
if (cnt != SIGN_HEAD_SIZE) {
code_sign_log_error("read sign head from file failed: return value %lu, expect %u bytes",
@@ -278,7 +294,9 @@ int elf_file_enable_fs_verity(struct file *file)
release_sign_head_out:
kfree(sign_head_ptr);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
set_fs(fs);
+#endif
filp_close_out:
filp_close(fp, NULL);
release_path_buf_out:
diff --git a/code_sign/code_sign_ext.c b/code_sign/code_sign_ext.c
index afe042278473faa5d1b794d8c8ec62856332e1be..16abbaf803ceb3eb8429e090f4e0c99f35ceaf34 100644
--- a/code_sign/code_sign_ext.c
+++ b/code_sign/code_sign_ext.c
@@ -24,10 +24,14 @@ static inline int check_code_sign_descriptor(const struct inode *inode,
if (!desc->cs_version)
return 0;
-
- if (desc->__reserved1 ||
- memchr_inv(desc->__reserved2, 0, sizeof(desc->__reserved2)))
+
+ // when calc pgtypeinfo_size, trans bit size to byte size
+ u32 pgtypeinfo_size_bytes = le32_to_cpu(desc->pgtypeinfo_size) / 8;
+ if (le64_to_cpu(desc->pgtypeinfo_off) > le64_to_cpu(desc->data_size) - pgtypeinfo_size_bytes) {
+ code_sign_log_error("Wrong offset: %llu (pgtypeinfo_off) > %llu (data_size) - %u (pgtypeinfo_size)",
+ le64_to_cpu(desc->pgtypeinfo_off), le64_to_cpu(desc->data_size), pgtypeinfo_size_bytes);
return -EINVAL;
+ }
if (le64_to_cpu(desc->data_size) > inode->i_size) {
code_sign_log_error("Wrong data_size: %llu (desc) > %lld (inode)",
@@ -67,11 +71,11 @@ void code_sign_before_measurement(void *_desc, int *ret)
{
struct code_sign_descriptor *desc = CAST_CODE_SIGN_DESC(_desc);
- if (desc->cs_version) {
- // replace version with cs_version
- desc->version = desc->cs_version;
+ if (desc->cs_version == 1) {
+ *ret = desc->cs_version;
desc->cs_version = 0;
- *ret = desc->version;
+ } else {
+ *ret = desc->cs_version;
}
}
@@ -79,7 +83,7 @@ void code_sign_after_measurement(void *_desc, int version)
{
struct code_sign_descriptor *desc = CAST_CODE_SIGN_DESC(_desc);
- if (version) {
+ if (version == 1) {
// restore cs_version
desc->cs_version = desc->version;
desc->version = version;
diff --git a/code_sign/code_sign_ioctl.c b/code_sign/code_sign_ioctl.c
index 16e640c6a648268ab8af7a35d9f7ed10254cac24..8e2efdd221ac4fbb699d02792cedfeb551f1a12a 100644
--- a/code_sign/code_sign_ioctl.c
+++ b/code_sign/code_sign_ioctl.c
@@ -8,11 +8,12 @@
#include
#include
#include
+#include
#include "avc.h"
#include "objsec.h"
-#include "dsmm_developer.h"
#include "code_sign_ioctl.h"
#include "code_sign_log.h"
+#define MAX_SIGNING_LENGTH 2048
DEFINE_SPINLOCK(cert_chain_tree_lock);
struct rb_root cert_chain_tree = RB_ROOT;
@@ -71,8 +72,11 @@ int code_sign_check_caller(char *caller)
u32 sid = current_sid(), context_len;
char *context = NULL;
int rc;
-
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
rc = security_sid_to_context(&selinux_state, sid, &context, &context_len);
+#else
+ rc = security_sid_to_context(sid, &context, &context_len);
+#endif
if (rc)
return -EINVAL;
@@ -180,11 +184,17 @@ int code_sign_avc_has_perm(u16 tclass, u32 requested)
struct av_decision avd;
u32 sid = current_sid();
int rc, rc2;
-
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0)
rc = avc_has_perm_noaudit(&selinux_state, sid, sid, tclass, requested,
AVC_STRICT, &avd);
rc2 = avc_audit(&selinux_state, sid, sid, tclass, requested, &avd, rc,
NULL, AVC_STRICT);
+#else
+ rc = avc_has_perm_noaudit(sid, sid, tclass, requested,
+ AVC_STRICT, &avd);
+ rc2 = avc_audit(sid, sid, tclass, requested, &avd, rc,
+ NULL);
+#endif
if (rc2)
return rc2;
@@ -207,13 +217,14 @@ int parse_cert_source(unsigned long args, struct cert_source **_source)
goto copy_source_failed;
}
- if (info.path_len > CERT_CHAIN_PATH_LEN_MAX || info.issuer_length == 0 || info.signing_length == 0) {
+ if (info.path_len > CERT_CHAIN_PATH_LEN_MAX || info.issuer_length == 0 || info.signing_length == 0
+ || info.issuer_length > MAX_SIGNING_LENGTH || info.signing_length > MAX_SIGNING_LENGTH) {
code_sign_log_error("invalid path len or subject or issuer");
ret = -EINVAL;
goto copy_source_failed;
}
- source->subject = kzalloc(info.signing_length, GFP_KERNEL);
+ source->subject = kzalloc(info.signing_length + 1, GFP_KERNEL);
if (!source->subject) {
ret = -ENOMEM;
goto copy_source_failed;
@@ -225,7 +236,7 @@ int parse_cert_source(unsigned long args, struct cert_source **_source)
goto copy_subject_failed;
}
- source->issuer = kzalloc(info.issuer_length, GFP_KERNEL);
+ source->issuer = kzalloc(info.issuer_length + 1, GFP_KERNEL);
if (!source->issuer) {
ret = -ENOMEM;
goto copy_subject_failed;
@@ -288,10 +299,8 @@ long code_sign_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
if (ret == 1) {
// developer cert
- if (get_developer_mode_state() == STATE_ON) {
- code_sign_log_debug("add developer cert");
- ret = cert_chain_insert(&dev_cert_chain_tree, source);
- }
+ code_sign_log_debug("add developer cert");
+ ret = cert_chain_insert(&dev_cert_chain_tree, source);
} else {
code_sign_log_debug("add release cert");
ret = cert_chain_insert(&cert_chain_tree, source);
@@ -314,10 +323,8 @@ long code_sign_ioctl(struct file *filp, unsigned int cmd, unsigned long args)
if (ret == 1) {
// developer cert
- if (get_developer_mode_state() == STATE_ON) {
- code_sign_log_debug("remove developer cert");
- ret = cert_chain_remove(&dev_cert_chain_tree, source);
- }
+ code_sign_log_debug("remove developer cert");
+ ret = cert_chain_remove(&dev_cert_chain_tree, source);
} else {
code_sign_log_debug("remove release cert");
ret = cert_chain_remove(&cert_chain_tree, source);
diff --git a/code_sign/verify_cert_chain.c b/code_sign/verify_cert_chain.c
index 908dd6babb36cd9abf191993ad4dd1757a64498c..3e9d096777bcc22300d4d8b679475df8703548a9 100644
--- a/code_sign/verify_cert_chain.c
+++ b/code_sign/verify_cert_chain.c
@@ -6,15 +6,19 @@
#include
#include
#include
+#include
#include
#include
#include "objsec.h"
-#include "dsmm_developer.h"
#include "code_sign_ext.h"
#include "code_sign_ioctl.h"
#include "code_sign_log.h"
#include "verify_cert_chain.h"
+#ifdef CONFIG_SECURITY_XPM
+#include "dsmm_developer.h"
+#endif
+
/*
* Find the key (X.509 certificate) to use to verify a PKCS#7 message. PKCS#7
* uses the issuer's name and the issuing certificate serial number for
@@ -144,11 +148,13 @@ void code_sign_verify_certchain(const void *raw_pkcs7, size_t pkcs7_len,
bool is_dev_mode = false;
+#ifdef CONFIG_SECURITY_XPM
// developer mode && developer proc
if (get_developer_mode_state() == STATE_ON) {
code_sign_log_info("developer mode on");
is_dev_mode = true;
}
+#endif
for (sinfo = pkcs7->signed_infos; sinfo; sinfo = sinfo->next) {
/* Find the key for the signature if there is one */
diff --git a/container_escape_detection/core/ced_detection.c b/container_escape_detection/core/ced_detection.c
index 3f0ff8c6d20d42299720bedc7df80204cbdc49c1..b8f291715ca41979e2459e5e65760144ac2a8b62 100644
--- a/container_escape_detection/core/ced_detection.c
+++ b/container_escape_detection/core/ced_detection.c
@@ -9,6 +9,7 @@
#include "objsec.h"
#include "ced_detection.h"
#include "ced_detection_points.h"
+#include
enum ced_event_type {
EVENT_OK,
@@ -40,13 +41,21 @@ static int ced_avc_has_perm(u16 tclass, u32 requested)
struct av_decision avd;
int rc;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
if (!selinux_initialized(&selinux_state))
return 1;
-
+#else
+ if (!selinux_initialized())
+ return 1;
+#endif
u32 sid = current_sid();
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
rc = avc_has_perm_noaudit(&selinux_state, sid, sid, tclass, requested,
AVC_STRICT, &avd);
-
+#else
+ rc = avc_has_perm_noaudit(sid, sid, tclass, requested,
+ AVC_STRICT, &avd);
+#endif
return rc;
}
diff --git a/container_escape_detection/include/ced_detection_points.h b/container_escape_detection/include/ced_detection_points.h
index 45eb2babca36f19bb75c7d1c26ec652528e9314d..cf62cb285b8296df7dab88c3866c9ce7ef8f137d 100644
--- a/container_escape_detection/include/ced_detection_points.h
+++ b/container_escape_detection/include/ced_detection_points.h
@@ -29,7 +29,7 @@ static inline void cred_info_record(struct cred_info *info, const struct cred *c
info->egid = cred->egid.val;
info->fsuid = cred->fsuid.val;
- memcpy(&info->cap_effective.cap[0], &cred->cap_effective.cap[0], sizeof(info->cap_effective.cap));
+ memcpy(&info->cap_effective, &cred->cap_effective, sizeof(kernel_cap_t));
}
struct ns_info {
diff --git a/dec/Kconfig b/dec/Kconfig
new file mode 100644
index 0000000000000000000000000000000000000000..9f9cbda17d8db0c87fcb90434d4a5b9d82705277
--- /dev/null
+++ b/dec/Kconfig
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2024 Huawei Device Co., Ltd.
+#
+config SECURITY_DEC
+ bool "Data enhance control features"
+
+ default y
+ help
+ This option enables file operation permission verification
+ at VFS layer.
+
+ If unsure, say N.
diff --git a/dec/Makefile b/dec/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..efd9cfef5993875569cbca81e83f99d476f471b7
--- /dev/null
+++ b/dec/Makefile
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2024 Huawei Device Co., Ltd.
+#
+obj-$(CONFIG_SECURITY_DEC) += \
+ dec_misc.o
+
+ccflags-$(CONFIG_SECURITY_DEC) += \
+ -I$(srctree)/fs/dec
+
+$(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)
diff --git a/dec/apply_dec.sh b/dec/apply_dec.sh
new file mode 100644
index 0000000000000000000000000000000000000000..6f63fb5e8d525b0bec012df1732819a53e08cdfc
--- /dev/null
+++ b/dec/apply_dec.sh
@@ -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
+DEC_SOURCE_ROOT=$OHOS_SOURCE_ROOT/kernel/linux/common_modules/dec
+
+function main()
+{
+ pushd .
+
+ if [ ! -d "$KERNEL_BUILD_ROOT/fs/dec" ]; then
+ mkdir $KERNEL_BUILD_ROOT/fs/dec
+ fi
+
+ cd $KERNEL_BUILD_ROOT/fs/dec
+ ln -s -f $(realpath --relative-to=$KERNEL_BUILD_ROOT/fs/dec $DEC_SOURCE_ROOT)/* ./
+
+ popd
+}
+
+main
diff --git a/dec/dec_misc.c b/dec/dec_misc.c
new file mode 100644
index 0000000000000000000000000000000000000000..534ce5ce622bf8c82e28feefafbad0c13945fd12
--- /dev/null
+++ b/dec/dec_misc.c
@@ -0,0 +1,122 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2024 Huawei Device Co., Ltd.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "dec_misc.h"
+
+static int vfs_deal_policy_cmd(unsigned int cmd, void __user *arg)
+{
+ pr_info("vfs dec deal policy cmd:%u\n", cmd);
+ int ret = 0;
+ struct dec_policy_info info = { 0 };
+
+ ret = copy_from_user(&info, arg, sizeof(info));
+ if (ret != 0) {
+ pr_err("copy from user failed\n");
+ return -EFAULT;
+ }
+
+ pr_info("tokenid:%lu path_num:%u persist_flag:%d\n", info.tokenid, info.path_num, info.persist_flag);
+
+ return ret;
+}
+
+static int vfs_destroy_dec_policy(void __user *arg)
+{
+ int ret = 0;
+ uint64_t tokenid;
+
+ ret = copy_from_user(&tokenid, arg, sizeof(tokenid));
+ if (ret != 0) {
+ pr_err("destroy dec policy copy from caller failed\n");
+ return -EFAULT;
+ }
+
+ pr_info("destroy dec policy tokenid:%ld\n", tokenid);
+ return 0;
+}
+
+static long dec_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ pr_info("dec ioctl cmd:%u\n", cmd);
+ int ret = 0;
+
+ switch (cmd) {
+ case SET_DEC_POLICY_CMD:
+ case DEL_DEC_POLICY_CMD:
+ case QUERY_DEC_POLICY_CMD:
+ case CHECK_DEC_POLICY_CMD:
+ case CONSTRAINT_DEC_POLICY_CMD:
+ case DENY_DEC_POLICY_CMD:
+ ret = vfs_deal_policy_cmd(cmd, (void __user *)arg);
+ break;
+ case DESTROY_DEC_POLICY_CMD:
+ ret = vfs_destroy_dec_policy((void __user *)arg);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return 0;
+}
+
+static int dec_open(struct inode *inode, struct file *filp)
+{
+ pr_info("dec open\n");
+ return 0;
+}
+
+static int dec_release(struct inode *inode, struct file *filp)
+{
+ pr_info("dec close\n");
+ return 0;
+}
+
+static const struct file_operations dec_fops = {
+ .owner = THIS_MODULE,
+ .open = dec_open,
+ .release = dec_release,
+ .unlocked_ioctl = dec_ioctl,
+ .compat_ioctl = dec_ioctl,
+};
+
+static struct miscdevice dec_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "dec",
+ .fops = &dec_fops,
+};
+
+static int __init dec_init(void)
+{
+ int err = 0;
+
+ err = misc_register(&dec_misc);
+ if (err < 0) {
+ pr_err("dec device init failed\n");
+ return err;
+ }
+
+ pr_err("dec device init success\n");
+ return 0;
+}
+
+static void __exit dec_exit(void)
+{
+ misc_deregister(&dec_misc);
+ pr_info("dec exited");
+}
+
+/* module entry points */
+module_init(dec_init);
+module_exit(dec_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/dec/dec_misc.h b/dec/dec_misc.h
new file mode 100644
index 0000000000000000000000000000000000000000..1154ece0904126309605e2195957acd9689e8a0e
--- /dev/null
+++ b/dec/dec_misc.h
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2024 Huawei Device Co., Ltd.
+ */
+
+#ifndef _DEC_MISC_H
+#define _DEC_MISC_H
+
+#include
+#include
+#include
+
+#define MAX_PATH_NUM 8
+
+#define DEV_DEC_MINOR 0x25
+#define DEC_IOCTL_BASE 's'
+#define SET_POLICY_ID 1
+#define DEL_POLICY_ID 2
+#define QUERY_POLICY_ID 3
+#define CHECK_POLICY_ID 4
+#define DESTROY_POLICY_ID 5
+#define CONSTRAINT_POLICY_ID 6
+#define DENY_POLICY_ID 7
+
+struct path_info {
+ char* path;
+ uint32_t path_len;
+ uint32_t mode;
+ bool ret_flag;
+};
+
+struct dec_policy_info {
+ uint64_t tokenid;
+ struct path_info path[MAX_PATH_NUM];
+ uint32_t path_num;
+ bool persist_flag;
+};
+
+#define SET_DEC_POLICY_CMD \
+ _IOWR(DEC_IOCTL_BASE, SET_POLICY_ID, struct dec_policy_info)
+#define DEL_DEC_POLICY_CMD \
+ _IOWR(DEC_IOCTL_BASE, DEL_POLICY_ID, struct dec_policy_info)
+#define QUERY_DEC_POLICY_CMD \
+ _IOWR(DEC_IOCTL_BASE, QUERY_POLICY_ID, struct dec_policy_info)
+#define CHECK_DEC_POLICY_CMD \
+ _IOWR(DEC_IOCTL_BASE, CHECK_POLICY_ID, struct dec_policy_info)
+#define CONSTRAINT_DEC_POLICY_CMD \
+ _IOW(DEC_IOCTL_BASE, CONSTRAINT_POLICY_ID, struct dec_policy_info)
+#define DENY_DEC_POLICY_CMD \
+ _IOWR(DEC_IOCTL_BASE, DENY_POLICY_ID, struct dec_policy_info)
+#define DESTROY_DEC_POLICY_CMD \
+ _IOW(DEC_IOCTL_BASE, DESTROY_POLICY_ID, uint64_t)
+
+#endif /* _DEC_MISC_H */
\ No newline at end of file
diff --git a/memory_security/src/hideaddr.c b/memory_security/src/hideaddr.c
index c34bbcd38f4632eeb78c6db0e6a5373f7a948128..5d77c4e9e40a11f5454b22b0f0e984425d1fb215 100644
--- a/memory_security/src/hideaddr.c
+++ b/memory_security/src/hideaddr.c
@@ -17,6 +17,7 @@
#include "avc.h"
#include "objsec.h"
#include "hideaddr.h"
+#include
static bool is_anon_exec(struct vm_area_struct *vma)
{
@@ -44,8 +45,13 @@ static int hideaddr_avc_has_perm(u16 tclass, u32 requested, struct seq_file *m)
u32 secid;
security_cred_getsecid(task->cred, &secid);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
return avc_has_perm_noaudit(&selinux_state, secid, secid, tclass, requested,
AVC_STRICT, &avd);
+#else
+ return avc_has_perm_noaudit(secid, secid, tclass, requested,
+ AVC_STRICT, &avd);
+#endif
}
static void hideaddr_header_prefix(unsigned long *start, unsigned long *end,
diff --git a/memory_security/src/jit_memory.c b/memory_security/src/jit_memory.c
index 0fc0bee268878a5715dfadaf1db3af6386f595a8..e34b6ab0cbe380bf5841bdb76be3d6e1d3339a84 100644
--- a/memory_security/src/jit_memory.c
+++ b/memory_security/src/jit_memory.c
@@ -11,6 +11,7 @@
#include "jit_space_list.h"
#include "avc.h"
#include "objsec.h"
+#include
DEFINE_SPINLOCK(list_lock);
@@ -25,8 +26,13 @@ static bool jit_avc_has_perm(u16 tclass, u32 requested, struct task_struct *task
u32 secid;
security_cred_getsecid(task->cred, &secid);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
return (avc_has_perm_noaudit(&selinux_state, secid, secid, tclass, requested,
AVC_STRICT, &avd) == 0);
+#else
+ return (avc_has_perm_noaudit(secid, secid, tclass, requested,
+ AVC_STRICT, &avd) == 0);
+#endif
}
void find_jit_memory(struct task_struct *task, unsigned long start, unsigned long size, int *err)
diff --git a/qos_auth/include/auth_ctrl.h b/qos_auth/include/auth_ctrl.h
index 3fa0be5586e768e4ca9d32631be970bad509378a..f2e04ee959666450efe3eece4a1e547df9c29178 100644
--- a/qos_auth/include/auth_ctrl.h
+++ b/qos_auth/include/auth_ctrl.h
@@ -14,7 +14,8 @@
#define SYSTEM_UID 1000
#define SUPER_UID SYSTEM_UID
-#define super_uid(uid) (uid == ROOT_UID || uid == SYSTEM_UID)
+#define RESOURCE_SCHEDULE_SERVICE_UID 1096
+#define super_uid(uid) (uid == ROOT_UID || uid == SYSTEM_UID || uid == RESOURCE_SCHEDULE_SERVICE_UID)
enum ioctl_abi_format_auth{
AUTH_IOCTL_ABI_ARM32,
diff --git a/ucollection/ucollection_process_cpu.c b/ucollection/ucollection_process_cpu.c
index db12fbe786b4627622463bb0b63142bdc9617c9e..79d0cf8d41eaf54a857739c803ced1e1c4da9b42 100644
--- a/ucollection/ucollection_process_cpu.c
+++ b/ucollection/ucollection_process_cpu.c
@@ -96,6 +96,7 @@ static void get_thread_load(struct task_struct *task, int cur_count,
do_div(utime, NS_TO_MS);
do_div(stime, NS_TO_MS);
thread_cpu_item.tid = task->pid;
+ strcpy(thread_cpu_item.name, task->comm);
thread_cpu_item.cpu_usage_utime = utime;
thread_cpu_item.cpu_usage_stime = stime;
thread_cpu_item.cpu_load_time = 0;
diff --git a/ucollection/unified_collection_data.h b/ucollection/unified_collection_data.h
index 67e270fa488152d668575677652ddd18150e8669..e261dd9cf4bceafd66ffeb7434b19da4e69ebe73 100644
--- a/ucollection/unified_collection_data.h
+++ b/ucollection/unified_collection_data.h
@@ -39,6 +39,7 @@ struct ucollection_process_thread_count {
struct ucollection_thread_cpu_item {
int tid;
+ char name[16]; // 16 : max length of thread name
unsigned long long cpu_usage_utime;
unsigned long long cpu_usage_stime;
unsigned long long cpu_load_time;
diff --git a/xpm/core/xpm_security_hooks.c b/xpm/core/xpm_security_hooks.c
index 5fe5b37757acce3295cc8190221bfc48bbba040c..bb60507f46ea969d8995823632173fce1cc5fee9 100644
--- a/xpm/core/xpm_security_hooks.c
+++ b/xpm/core/xpm_security_hooks.c
@@ -5,6 +5,7 @@
#include
#include
+#include
#include "avc.h"
#include "objsec.h"
@@ -182,8 +183,13 @@ static int xpm_avc_has_perm(u16 tclass, u32 requested)
struct av_decision avd;
u32 sid = current_sid();
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
return avc_has_perm_noaudit(&selinux_state, sid, sid, tclass, requested,
AVC_STRICT, &avd);
+#else
+ return avc_has_perm_noaudit(sid, sid, tclass, requested,
+ AVC_STRICT, &avd);
+#endif
}
static int xpm_validate_signature(struct vm_area_struct *vma,
@@ -361,7 +367,7 @@ static int xpm_mprotect_check(struct vm_area_struct *vma,
return xpm_common_check(vma, prot);
}
-static struct security_hook_list xpm_hooks[] __lsm_ro_after_init = {
+static struct security_hook_list xpm_hooks[] __ro_after_init = {
LSM_HOOK_INIT(mmap_region, xpm_mmap_check),
LSM_HOOK_INIT(file_mprotect, xpm_mprotect_check),
};
diff --git a/xpm/validator/elf_code_segment_info.c b/xpm/validator/elf_code_segment_info.c
index dbbb1a0f95cbe39ff57681071be2f61237a477ea..385ad3c863fab2707fc29676e836d1a36966b3aa 100644
--- a/xpm/validator/elf_code_segment_info.c
+++ b/xpm/validator/elf_code_segment_info.c
@@ -225,7 +225,7 @@ static int get_elf64_info(struct elfhdr *elf_ehdr, struct elf_info *elf_info)
return 0;
}
-static int elf_check_and_get_code_segment_offset(struct file *file, struct elf_info *elf_info)
+static int elf_check_and_get_code_segment_offset(struct file *file, struct elf_info *elf_info, bool *skip)
{
uint16_t type;
struct elfhdr *elf_ehdr = &elf_info->elf_ehdr;
@@ -235,8 +235,11 @@ static int elf_check_and_get_code_segment_offset(struct file *file, struct elf_i
if (ret < 0)
return ret;
- if (memcmp(elf_ehdr->e_ident, ELFMAG, SELFMAG) != 0)
- return -ENOEXEC;
+ if (memcmp(elf_ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
+ // when the file is not an ELF file, skip checking
+ *skip = true;
+ return 0;
+ }
type = elf16_get_value(elf_ehdr, elf_ehdr->e_type);
if (type != ET_EXEC && type != ET_DYN)
@@ -287,16 +290,52 @@ static int find_elf_code_segment_info(const char *phdr_info, struct elf_info *el
return 0;
}
+static int handle_skip_case(struct file *file, struct exec_file_signature_info **code_segment_info) {
+ struct exec_file_signature_info *tmp_info = NULL;
+ if (*code_segment_info == NULL) {
+ tmp_info = kzalloc(sizeof(struct exec_file_signature_info), GFP_KERNEL);
+ if (tmp_info == NULL) {
+ return -ENOMEM;
+ }
+ } else {
+ tmp_info = *code_segment_info;
+ }
+
+ if (tmp_info->code_segments == NULL) {
+ tmp_info->code_segments = kzalloc(sizeof(struct exec_segment_info), GFP_KERNEL);
+ if (tmp_info->code_segments == NULL) {
+ if (*code_segment_info == NULL) {
+ kfree(tmp_info);
+ tmp_info = NULL;
+ }
+ return -ENOMEM;
+ }
+ tmp_info->code_segment_count = 1;
+ }
+
+ tmp_info->code_segments[0].file_offset = 0;
+ tmp_info->code_segments[0].size = file_inode(file)->i_size;
+
+ if (*code_segment_info == NULL) {
+ *code_segment_info = tmp_info;
+ }
+ return 0;
+}
+
int parse_elf_code_segment_info(struct file *file,
struct exec_file_signature_info **code_segment_info)
{
const char *phdr_info;
struct elf_info elf_info = {0};
int ret;
-
- ret = elf_check_and_get_code_segment_offset(file, &elf_info);
+ bool skip = false;
+ ret = elf_check_and_get_code_segment_offset(file, &elf_info, &skip);
if (ret < 0)
return ret;
+
+ if (skip) {
+ return handle_skip_case(file, code_segment_info);
+ }
phdr_info = kzalloc(elf_info.e_phsize, GFP_KERNEL);
if (phdr_info == NULL)
diff --git a/xpm/validator/exec_signature_info.c b/xpm/validator/exec_signature_info.c
index 9c02c4ffaf60bb70b26367b4ac2e1c0644e99609..2d0f02e2462ce53c7a7cf9e60e15b7b29b9a4a0b 100644
--- a/xpm/validator/exec_signature_info.c
+++ b/xpm/validator/exec_signature_info.c
@@ -486,13 +486,15 @@ static void insert_new_signature_info(struct inode *file_node, int type,
RB_CLEAR_NODE(&new_info->rb_node);
if ((*old_info) != NULL) {
write_lock(verity->lock);
- rb_erase_node(verity->root, verity->node_count, *old_info);
- (*old_info)->type |= FILE_SIGNATURE_DELETE;
- write_unlock(verity->lock);
- if (atomic_sub_return(1, &(*old_info)->reference) <= 0) {
- kfree(*old_info);
- *old_info = NULL;
+ if ((*old_info) != NULL) {
+ if (atomic_sub_return(1, &(*old_info)->reference) <= 0) {
+ rb_erase_node(verity->root, verity->node_count, *old_info);
+ (*old_info)->type |= FILE_SIGNATURE_DELETE;
+ kfree(*old_info);
+ *old_info = NULL;
+ }
}
+ write_unlock(verity->lock);
}
write_lock(verity->lock);