代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/dim 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From 0e193ae62a67dd4141ec6089f515e651c7e6a515 Mon Sep 17 00:00:00 2001
From: Huaxin Lu <luhuaxin1@huawei.com>
Date: Sun, 11 Feb 2024 22:07:12 +0800
Subject: [PATCH 13/26] Refactor dim_core policy and support the action policy
1. Refactor the code for dim_core policy, separate policy text parsing
and policy management for expansion of other policy formats in future
2. Optimize the policy parsing, make it easier to extend the policy fields
3. Support to set "action=kill" in the policy line. If a process tamparing
is detected, kill the process (now only vaild for user process measurement)
---
src/Makefile | 7 +-
src/common/dim_utils.c | 44 ++-
src/common/dim_utils.h | 4 +-
src/core/dim_core_fs.c | 15 -
src/core/dim_core_main.c | 5 +
src/core/dim_core_measure.c | 17 -
src/core/dim_core_measure.h | 3 +-
src/core/dim_core_policy.c | 302 ------------------
src/core/dim_core_policy.h | 63 ----
src/core/dim_core_static_baseline.c | 4 +-
.../measure_task/dim_core_measure_module.c | 4 +-
src/core/measure_task/dim_core_measure_task.c | 8 +-
src/core/policy/dim_core_policy.c | 268 ++++++++++++++++
src/core/policy/dim_core_policy.h | 69 ++++
src/core/policy/dim_core_policy_complex.c | 190 +++++++++++
15 files changed, 583 insertions(+), 420 deletions(-)
delete mode 100644 src/core/dim_core_policy.c
delete mode 100644 src/core/dim_core_policy.h
create mode 100644 src/core/policy/dim_core_policy.c
create mode 100644 src/core/policy/dim_core_policy.h
create mode 100644 src/core/policy/dim_core_policy_complex.c
diff --git a/src/Makefile b/src/Makefile
index 1a3fac0..a17ce5b 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -6,7 +6,6 @@ obj-m += dim_monitor.o
dim_core-objs += core/dim_core_main.o
dim_core-objs += core/dim_core_fs.o
dim_core-objs += core/dim_core_mem_pool.o
-dim_core-objs += core/dim_core_policy.o
dim_core-objs += core/dim_core_static_baseline.o
dim_core-objs += core/dim_core_measure.o
dim_core-objs += core/dim_core_symbol.o
@@ -14,6 +13,8 @@ dim_core-objs += core/dim_core_sig.o
dim_core-objs += core/measure_task/dim_core_measure_kernel.o
dim_core-objs += core/measure_task/dim_core_measure_module.o
dim_core-objs += core/measure_task/dim_core_measure_task.o
+dim_core-objs += core/policy/dim_core_policy.o
+dim_core-objs += core/policy/dim_core_policy_complex.o
dim_core-objs += common/dim_entry.o
dim_core-objs += common/dim_utils.o
dim_core-objs += common/dim_baseline.o
@@ -46,9 +47,9 @@ dim_monitor-objs += measure/dim_measure_status.o
dim_monitor-objs += monitor/measure_task/dim_monitor_measure_data.o
dim_monitor-objs += monitor/measure_task/dim_monitor_measure_text.o
-# TODO
ccflags-y := -I$(src)/core
ccflags-y += -I$(src)/core/measure_task
+ccflags-y += -I$(src)/core/policy
ccflags-y += -I$(src)/monitor
ccflags-y += -I$(src)/monitor/measure_task
ccflags-y += -I$(src)/common
@@ -74,4 +75,4 @@ install:
insmod dim_monitor.ko
test:
- cd ../test && { sh test_dim_core.sh; sh test_dim_monitor.sh; }
\ No newline at end of file
+ cd ../test && { sh test_dim_core.sh; sh test_dim_monitor.sh; }
diff --git a/src/common/dim_utils.c b/src/common/dim_utils.c
index 75b58fc..4c99879 100644
--- a/src/common/dim_utils.c
+++ b/src/common/dim_utils.c
@@ -17,25 +17,47 @@ void *dim_kmalloc_gfp(size_t size)
void dim_kfree(void *data)
{
- kfree(data);
+ if (data != NULL)
+ kfree(data);
}
-const char *dim_absolute_path(const char *path, char *buf, int len)
+int dim_get_absolute_path(const char *path, const char **result)
{
- int ret;
+ int ret = 0;
struct path p;
+ char *buf = NULL;
char *apath = NULL;
- if (path == NULL || buf == NULL)
- return ERR_PTR(-EINVAL);
+ if (path == NULL)
+ return -EINVAL;
ret = kern_path(path, LOOKUP_FOLLOW, &p);
if (ret < 0)
- return ERR_PTR(ret);
+ return ret;
- apath = d_path(&p, buf, len);
+ buf = dim_kmalloc_gfp(PATH_MAX);
+ if (buf == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ apath = d_path(&p, buf, PATH_MAX);
+ if (IS_ERR(apath)) {
+ ret = PTR_ERR(apath);
+ goto out;
+ }
+
+ *result = kstrdup(apath, GFP_KERNEL);
+ if (*result == NULL) {
+ ret = -ENOMEM;
+ goto out;
+ }
+out:
path_put(&p);
- return apath;
+ if (buf != NULL)
+ dim_kfree(buf);
+
+ return ret;
}
bool dim_string_end_with(const char *str, const char *ext)
@@ -53,7 +75,7 @@ bool dim_string_end_with(const char *str, const char *ext)
return strcmp(str + name_len - ext_len, ext) == 0;
}
-int dim_parse_line_buf(char *buf, loff_t len, int (*line_parser)(char *, int))
+int dim_parse_line_buf(char *buf, loff_t len, int (*line_parser)(char *, int, void *), void *data)
{
int ret = 0;
int i = 0;
@@ -71,7 +93,7 @@ int dim_parse_line_buf(char *buf, loff_t len, int (*line_parser)(char *, int))
if (buf[i] == '\n') {
buf[i] = '\0';
- ret = line_parser(line, line_no);
+ ret = line_parser(line, line_no, data);
line = &buf[i + 1];
} else {
line_len = buf + i - line + 1;
@@ -80,7 +102,7 @@ int dim_parse_line_buf(char *buf, loff_t len, int (*line_parser)(char *, int))
return -ENOMEM;
memcpy(line_buf, line, line_len);
- ret = line_parser(line_buf, line_no);
+ ret = line_parser(line_buf, line_no, data);
}
if (ret < 0) {
diff --git a/src/common/dim_utils.h b/src/common/dim_utils.h
index 1db3ca1..5a9f132 100644
--- a/src/common/dim_utils.h
+++ b/src/common/dim_utils.h
@@ -19,8 +19,8 @@
void *dim_kmalloc_gfp(size_t size);
void dim_kfree(void *data);
-const char *dim_absolute_path(const char *path, char *buf, int len);
+int dim_get_absolute_path(const char *path, const char **result);
bool dim_string_end_with(const char *str, const char *ext);
-int dim_parse_line_buf(char *buf, loff_t len, int (*line_parser)(char *, int));
+int dim_parse_line_buf(char *buf, loff_t len, int (*line_parser)(char *, int, void *), void *data);
#endif
\ No newline at end of file
diff --git a/src/core/dim_core_fs.c b/src/core/dim_core_fs.c
index a76d622..4d6bdd4 100644
--- a/src/core/dim_core_fs.c
+++ b/src/core/dim_core_fs.c
@@ -53,18 +53,6 @@ dim_string_print_entry(dim_status, runtime_status, dim_core_status_print);
dim_uint_rw_entry(dim_interval, interval, dim_core_interval_get,
dim_core_interval_set);
-#ifdef DIM_CORE_TAMPERED_ACTION
-/*
- * tampered action set and read interface
- * dim_entry struct: dim_tampered_action_entry
- * file entry name: tampered_action
- * read function: dim_core_tampered_action_get
- * write function: dim_core_tampered_action_set
- */
-dim_uint_rw_entry(dim_tampered_action, tampered_action,
- dim_core_tampered_action_get, dim_core_tampered_action_set);
-#endif
-
/*
* dim directory
*/
@@ -81,9 +69,6 @@ static struct dim_entry *dim_core_files[] = {
&dim_measure_log_entry,
&dim_status_entry,
&dim_interval_entry,
-#ifdef DIM_CORE_TAMPERED_ACTION
- &dim_tampered_action_entry,
-#endif
};
void dim_core_destroy_fs(void)
diff --git a/src/core/dim_core_main.c b/src/core/dim_core_main.c
index 6a0ca41..ae34e81 100644
--- a/src/core/dim_core_main.c
+++ b/src/core/dim_core_main.c
@@ -4,6 +4,7 @@
#include <linux/module.h>
+#include "dim_core_policy.h"
#include "dim_core_symbol.h"
#include "dim_core_fs.h"
#include "dim_core_measure.h"
@@ -30,11 +31,15 @@ MODULE_PARM_DESC(measure_pcr, "TPM PCR index to extend measure log");
/* special measurement configuration for dim_core */
static unsigned int measure_interval = 0;
+bool dim_core_measure_action_enabled = 0;
static bool signature = false;
module_param(measure_interval, uint, 0);
MODULE_PARM_DESC(measure_interval, "Interval time (min) for automatic measurement");
+module_param_named(measure_action, dim_core_measure_action_enabled, bool, 0);
+MODULE_PARM_DESC(signature, "Enable actions when tampering detected");
+
module_param(signature, bool, 0);
MODULE_PARM_DESC(signature, "Require signature for policy and static baseline");
diff --git a/src/core/dim_core_measure.c b/src/core/dim_core_measure.c
index 0147735..3f1d6e4 100644
--- a/src/core/dim_core_measure.c
+++ b/src/core/dim_core_measure.c
@@ -30,7 +30,6 @@ static struct work_struct dim_baseline_work;
/* special measurement parameters for dim_core */
static atomic_t measure_interval = ATOMIC_INIT(0);
-static atomic_t tampered_action = ATOMIC_INIT(0);
/* interface to print measure status string */
const char *dim_core_status_print(void)
@@ -68,22 +67,6 @@ int dim_core_interval_set(unsigned int min)
return 0;
}
-/* interface to get tamper action flag */
-long dim_core_tampered_action_get(void)
-{
- return atomic_read(&tampered_action);
-}
-
-/* interface to set tamper action flag */
-int dim_core_tampered_action_set(unsigned int p)
-{
- if (p != 0 && p != 1)
- return -EINVAL;
-
- atomic_set(&tampered_action, p);
- return 0;
-}
-
static int baseline_prepare(struct dim_measure *m)
{
int ret = 0;
diff --git a/src/core/dim_core_measure.h b/src/core/dim_core_measure.h
index 699724a..3522ba0 100644
--- a/src/core/dim_core_measure.h
+++ b/src/core/dim_core_measure.h
@@ -16,6 +16,7 @@
#define DIM_MINUTE_TO_SEC (60UL)
#define DIM_MINUTE_TO_NSEC (60UL * 1000 * 1000 * 1000)
+extern bool dim_core_measure_action_enabled;
extern struct dim_measure dim_core_handle;
/* global init and destroy */
@@ -33,4 +34,4 @@ int dim_core_tampered_action_set(unsigned int p);
int dim_core_measure_blocking(void);
int dim_core_baseline_blocking(void);
-#endif
\ No newline at end of file
+#endif
diff --git a/src/core/dim_core_policy.c b/src/core/dim_core_policy.c
deleted file mode 100644
index 50ebcf7..0000000
--- a/src/core/dim_core_policy.c
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
- */
-
-#include <linux/fs.h>
-#include <linux/err.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/uaccess.h>
-#include <linux/vmalloc.h>
-#include <linux/namei.h>
-#include <linux/utsname.h>
-
-#include "dim_utils.h"
-#include "dim_rb.h"
-
-#include "dim_core_sig.h"
-#include "dim_core_policy.h"
-
-static const char *dim_policy_obj_str[DIM_POLICY_OBJ_LAST] = {
- [DIM_POLICY_OBJ_BPRM_TEXT] = "obj=BPRM_TEXT",
- [DIM_POLICY_OBJ_MODULE_TEXT] = "obj=MODULE_TEXT",
- [DIM_POLICY_OBJ_KERNEL_TEXT] = "obj=KERNEL_TEXT",
-};
-
-static const char *dim_policy_key_str[DIM_POLICY_KEY_LAST] = {
- [DIM_POLICY_KEY_NAME] = "name=",
- [DIM_POLICY_KEY_PATH] = "path=",
-};
-
-static struct rb_root policy_root = RB_ROOT;
-
-static int dim_policy_compare(struct dim_policy *x,
- struct dim_policy *y)
-{
- if (x->obj != y->obj)
- return x->obj - y->obj;
-
- if (x->key != y->key)
- return x->key - y->key;
-
- return strcmp(x->val, y->val);
-}
-
-/*
-static int dim_policy_rb_find(struct rb_root *root,
- struct dim_policy *data,
- struct dim_policy **find_data)
-*/
-dim_rb_find(dim_policy);
-/*
-static int dim_policy_rb_add(struct rb_root *root,
- struct dim_policy *data,
- struct dim_policy **find_data)
-*/
-dim_rb_add(dim_policy);
-
-static void policy_destroy(struct dim_policy *policy)
-{
- kfree(policy->val);
- kfree(policy);
-}
-
-static int policy_add(int obj, int key, const char *val, int action)
-{
- int ret = 0;
- struct dim_policy *policy = NULL;
-
- policy = dim_kmalloc_gfp(sizeof(struct dim_policy));
- if (policy == NULL)
- return -ENOMEM;
-
- policy->obj = obj;
- policy->key = key;
- policy->action = action;
- policy->val = kstrdup(val, GFP_KERNEL);
- if (policy->val == NULL) {
- kfree(policy);
- return -ENOMEM;
- }
-
- ret = dim_policy_rb_add(&policy_root, policy, NULL);
- if (ret < 0)
- policy_destroy(policy);
-
- return ret == -EEXIST ? 0 : ret;
-}
-
-static int policy_add_kernel(int action)
-{
- return policy_add(DIM_POLICY_OBJ_KERNEL_TEXT, DIM_POLICY_KEY_NAME,
- init_uts_ns.name.release, action);
-}
-
-static int policy_add_module(const char *name, int action)
-{
- return policy_add(DIM_POLICY_OBJ_MODULE_TEXT, DIM_POLICY_KEY_NAME,
- name, action);
-}
-
-static int policy_add_path(const char *path, int action)
-{
- int ret = 0;
- char *path_buf = NULL;
- const char *apath = NULL;
-
- /* This element is a filepath */
- ret = policy_add(DIM_POLICY_OBJ_BPRM_TEXT, DIM_POLICY_KEY_PATH,
- path, action);
- if (ret < 0)
- return ret;
-
- /* Try to get the absolute path */
- path_buf = dim_kmalloc_gfp(PATH_MAX);
- if (path_buf == NULL)
- return -ENOMEM;
-
- apath = dim_absolute_path(path, path_buf, PATH_MAX);
- if (IS_ERR(apath)) {
- dim_warn("failed to get absolute path of %s in policy: %ld\n",
- path, PTR_ERR(apath));
- kfree(path_buf);
- return 0;
- }
-
- if (strcmp(path, apath) != 0)
- ret = policy_add(DIM_POLICY_OBJ_BPRM_TEXT, DIM_POLICY_KEY_PATH,
- apath, action);
-
- kfree(path_buf);
- return ret;
-}
-
-static int policy_parse_key_value(const char *s, int *key, const char **val)
-{
- int i = 0;
- int len = 0;
-
- for (; i < DIM_POLICY_KEY_LAST; i++) {
- len = strlen(dim_policy_key_str[i]);
- if (strncmp(s, dim_policy_key_str[i], len) == 0) {
- *key = i;
- *val = s + len;
- return 0;
- }
- }
-
- return -EINVAL;
-}
-
-static int policy_parse_obj(const char *s, int *key)
-{
- int ret = match_string(dim_policy_obj_str, DIM_POLICY_OBJ_LAST, s);
- if (ret < 0)
- return ret;
-
- *key = ret;
- return 0;
-}
-
-static int policy_parse_line(char* line, int line_no)
-{
- int ret = 0;
- char *p = NULL;
- char *line_str = line;
- /* currently only support log action */
- int action = DIM_POLICY_LOG;
- int obj = 0;
- int key = 0;
- const char *val = NULL;
-
- if (line_no > DIM_POLICY_LINE_MAX) {
- dim_warn("more than %d policy items will be ignored\n",
- DIM_POLICY_LINE_MAX);
- return -E2BIG;
- }
-
- if (strlen(line) == 0 || line[0] == '#')
- return 0; /* ignore blank line and comment */
-
- if (strlen(line) > DIM_POLICY_MAX_LEN) {
- dim_err("overlength item at line %d\n", line_no);
- return -EINVAL;
- }
-
- if ((p = strsep(&line_str, " ")) == NULL ||
- strcmp(p, DIM_POLICY_MEASURE) != 0) {
- dim_err("invalid policy prefix at line %d\n", line_no);
- return -EINVAL;
- }
-
- if ((p = strsep(&line_str, " ")) == NULL ||
- (policy_parse_obj(p, &obj)) < 0) {
- dim_err("invalid policy object at line %d\n", line_no);
- return -EINVAL;
- }
-
- /* for kernel policy, ignore other parameters */
- if (obj == DIM_POLICY_OBJ_KERNEL_TEXT) {
- ret = policy_add_kernel(action);
- if (ret < 0)
- dim_err("failed to add measure policy line %d: %d\n",
- line_no, ret);
- return ret;
- }
-
- if ((p = strsep(&line_str, " ")) == NULL ||
- (policy_parse_key_value(p, &key, &val)) < 0) {
- dim_err("invalid policy key at line %d\n", line_no);
- return -EINVAL;
- }
-
- if ((obj == DIM_POLICY_OBJ_BPRM_TEXT && key != DIM_POLICY_KEY_PATH) ||
- (obj == DIM_POLICY_OBJ_MODULE_TEXT && key != DIM_POLICY_KEY_NAME)) {
- dim_err("mismatch policy object and key at line %d\n", line_no);
- return -EINVAL;
- }
-
- ret = obj == DIM_POLICY_OBJ_BPRM_TEXT ?
- policy_add_path(val, action) :
- policy_add_module(val, action);
- if (ret < 0)
- dim_err("failed to add measure policy line %d: %d\n",
- line_no, ret);
- return ret;
-}
-
-int dim_core_policy_load(void)
-{
- int ret = 0;
- void *buf = NULL;
- loff_t buf_len = 0;
-
- if (!RB_EMPTY_ROOT(&policy_root))
- dim_core_policy_destroy();
-
- ret = dim_read_verify_file(NULL, DIM_POLICY_PATH, &buf);
- if (ret < 0 || buf == NULL) {
- dim_err("failed to read policy file: %d\n", ret);
- return ret;
- }
-
- buf_len = ret;
- ret = dim_parse_line_buf(buf, buf_len, policy_parse_line);
- if (ret < 0) {
- dim_err("failed to parse policy: %d\n", ret);
- dim_core_policy_destroy();
- }
-
- vfree(buf);
- return ret;
-}
-
-void dim_core_policy_destroy(void)
-{
- struct dim_policy *pos = NULL;
- struct dim_policy *n = NULL;
-
- rbtree_postorder_for_each_entry_safe(pos, n, &policy_root, rb_node)
- policy_destroy(pos);
-
- policy_root = RB_ROOT;
-}
-
-bool dim_core_policy_match(int obj, int key, const char *val)
-{
- struct dim_policy policy = {
- .obj = obj,
- .key = key,
- .val = val,
- };
-
- if (obj < 0 || obj >= DIM_POLICY_OBJ_LAST ||
- key < 0 || key >= DIM_POLICY_KEY_LAST ||
- val == NULL)
- return false;
-
- return dim_policy_rb_find(&policy_root, &policy, NULL) == 0;
-}
-
-int dim_core_policy_get_action(int obj __always_unused,
- int key __always_unused,
- const char *val __always_unused)
-{
- return DIM_POLICY_LOG;
-}
-
-int dim_core_policy_walk(int (*f)(struct dim_policy *, void *), void *data)
-{
- int ret = 0;
- struct dim_policy *pos = NULL;
- struct dim_policy *n = NULL;
-
- rbtree_postorder_for_each_entry_safe(pos, n, &policy_root, rb_node) {
- ret = f(pos, data);
- if (ret < 0)
- return ret;
- }
-
- return 0;
-}
-
diff --git a/src/core/dim_core_policy.h b/src/core/dim_core_policy.h
deleted file mode 100644
index 2baab12..0000000
--- a/src/core/dim_core_policy.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
- */
-
-#ifndef __DIM_CORE_POLICY_H
-#define __DIM_CORE_POLICY_H
-
-#include <linux/rbtree.h>
-
-#define DIM_POLICY_PATH "/etc/dim/policy"
-#define DIM_POLICY_LINE_MAX 10000
-
-/* policy key */
-#define DIM_POLICY_MEASURE "measure"
-
-/* DIM_POLICY_OBJECT */
-enum dim_policy_obj {
- DIM_POLICY_OBJ_BPRM_TEXT,
- DIM_POLICY_OBJ_MODULE_TEXT,
- DIM_POLICY_OBJ_KERNEL_TEXT,
- DIM_POLICY_OBJ_LAST,
-};
-
-/* DIM_POLICY_KEY */
-enum dim_policy_key {
- DIM_POLICY_KEY_NAME,
- DIM_POLICY_KEY_PATH,
- DIM_POLICY_KEY_LAST,
-};
-
- /* measure obj=MODULE_TEXT path={PATH_MAX}\n*/
- #define DIM_POLICY_OBJ_MAX_LEN 15
- #define DIM_POLICY_KEY_MAX_LEN 5
- #define DIM_POLICY_MAX_LEN (strlen(DIM_POLICY_MEASURE) + 1 + \
- DIM_POLICY_OBJ_MAX_LEN + 1 + \
- DIM_POLICY_KEY_MAX_LEN + 1 + PATH_MAX + 1 + 1)
-
-struct dim_policy {
- struct rb_node rb_node;
- int obj; /* enum dim_policy_obj */
- int key; /* enum dim_policy_key */
- const char *val;
- int action; /* enum dim_policy_action */
-};
-
-/* funtion to walk dim policy nodes */
-typedef int (*dim_policy_visitor)(struct dim_policy *, void *);
-
-enum dim_policy_action {
- DIM_POLICY_LOG,
- DIM_POLICY_KILL,
- DIM_POLICY_LAST,
-};
-
-int dim_core_policy_load(void);
-void dim_core_policy_destroy(void);
-bool dim_core_policy_match(int obj, int key, const char *val);
-int dim_core_policy_walk(dim_policy_visitor f, void *data);
-int dim_core_policy_get_action(int obj __always_unused,
- int key __always_unused,
- const char *val __always_unused);
-
-#endif
diff --git a/src/core/dim_core_static_baseline.c b/src/core/dim_core_static_baseline.c
index f23dbce..1a87cfd 100644
--- a/src/core/dim_core_static_baseline.c
+++ b/src/core/dim_core_static_baseline.c
@@ -47,7 +47,7 @@ static bool match_policy(const char *name, int type)
DIM_POLICY_KEY_NAME, mod_name);
}
-static int parse_simple_baseline_line(char* line, int line_no)
+static int parse_simple_baseline_line(char* line, int line_no, void *data)
{
int ret = 0;
int type = 0;
@@ -149,7 +149,7 @@ static_baseline_load(struct dir_context *__ctx,
}
buf_len = ret;
- ret = dim_parse_line_buf(buf, buf_len, parse_simple_baseline_line);
+ ret = dim_parse_line_buf(buf, buf_len, parse_simple_baseline_line, NULL);
if (ret < 0)
dim_err("failed to parse baseline file %s: %d\n", name, ret);
out:
diff --git a/src/core/measure_task/dim_core_measure_module.c b/src/core/measure_task/dim_core_measure_module.c
index 497d3a4..aa3e2f3 100644
--- a/src/core/measure_task/dim_core_measure_module.c
+++ b/src/core/measure_task/dim_core_measure_module.c
@@ -64,11 +64,11 @@ static int measure_module(struct dim_policy *policy, void *data)
{
int ret = 0;
struct module_text_measure_ctx *ctx = data;
- const char *mod_name = policy->val;
+ const char *mod_name = policy->name;
struct dim_digest digest = { 0 };
if (policy == NULL || policy->obj != DIM_POLICY_OBJ_MODULE_TEXT ||
- policy->key != DIM_POLICY_KEY_NAME || mod_name == NULL)
+ mod_name == NULL)
return 0;
/* if module is not inserted in baseline_init stage, ignore it */
diff --git a/src/core/measure_task/dim_core_measure_task.c b/src/core/measure_task/dim_core_measure_task.c
index f240ddc..c9d21b1 100644
--- a/src/core/measure_task/dim_core_measure_task.c
+++ b/src/core/measure_task/dim_core_measure_task.c
@@ -293,13 +293,17 @@ static int check_user_digest(struct dim_digest *digest,
return ret;
}
- if (log_flag != LOG_TAMPERED || !dim_core_tampered_action_get())
+ if (log_flag != LOG_TAMPERED || !dim_core_measure_action_enabled)
return 0;
+ /* now the process is tampered, check if action need to be taken */
action = dim_core_policy_get_action(DIM_POLICY_OBJ_BPRM_TEXT,
DIM_POLICY_KEY_PATH, ctx->path);
- if (action == DIM_POLICY_KILL)
+ if (action == DIM_POLICY_ACTION_KILL) {
+ dim_warn("kill action is set, process %s will be killed\n",
+ ctx->path);
ctx->task_kill = true; /* this task need to be killed */
+ }
return 0;
}
diff --git a/src/core/policy/dim_core_policy.c b/src/core/policy/dim_core_policy.c
new file mode 100644
index 0000000..4d7bcc1
--- /dev/null
+++ b/src/core/policy/dim_core_policy.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#include <linux/fs.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+#include <linux/vmalloc.h>
+#include <linux/namei.h>
+#include <linux/utsname.h>
+
+#include "dim_utils.h"
+#include "dim_rb.h"
+
+#include "dim_core_sig.h"
+#include "dim_core_policy.h"
+
+static struct rb_root policy_root = RB_ROOT;
+
+static int dim_policy_compare(struct dim_policy *x, struct dim_policy *y)
+{
+ if (x->obj != y->obj)
+ return x->obj - y->obj;
+
+ switch (x->obj) {
+ case DIM_POLICY_OBJ_BPRM_TEXT:
+ if (x->path == NULL || y->path == NULL)
+ return -1;
+ return strcmp(x->path, y->path);
+ case DIM_POLICY_OBJ_MODULE_TEXT:
+ if (x->name == NULL || y->name == NULL)
+ return -1;
+ return strcmp(x->name, y->name);
+ case DIM_POLICY_OBJ_KERNEL_TEXT:
+ return 0;
+ default:
+ break;
+ }
+
+ return -1;
+}
+
+/*
+static int dim_policy_rb_find(struct rb_root *root,
+ struct dim_policy *data,
+ struct dim_policy **find_data)
+*/
+dim_rb_find(dim_policy);
+/*
+static int dim_policy_rb_add(struct rb_root *root,
+ struct dim_policy *data,
+ struct dim_policy **find_data)
+*/
+dim_rb_add(dim_policy);
+
+void policy_destroy(struct dim_policy *policy)
+{
+ if (policy == NULL)
+ return;
+
+ dim_kfree((char *)policy->name);
+ dim_kfree((char *)policy->path);
+ dim_kfree(policy);
+}
+
+static int policy_check_add_bprm_text(struct dim_policy *policy)
+{
+ int ret = 0;
+ const char *apath = NULL;
+ struct dim_policy *p = NULL;
+
+ /* check the policy is valid */
+ if (policy->path == NULL) {
+ pr_err("path must be set for BPRM_TEXT policy\n");
+ return -EINVAL;
+ }
+
+ if (strlen(policy->path) + 1 > PATH_MAX) {
+ pr_err("path must be shorter than %d\n", PATH_MAX);
+ return -ENAMETOOLONG;
+ }
+
+ if (policy->name != NULL)
+ pr_warn("name is ignored for BPRM_TEXT policy\n");
+
+ /* firstly, add the current node */
+ ret = dim_policy_rb_add(&policy_root, policy, NULL);
+ if (ret < 0)
+ return ret;
+
+ /* secondly, try to add another node with absolute path. beacuse
+ sometimes users may not sure whether to write /usr/bin/bash
+ or /bin/bash in policy */
+ ret = dim_get_absolute_path(policy->path, &apath);
+ if (ret < 0) {
+ dim_warn("failed to get absolute path of %s in policy: %d\n",
+ policy->path, ret);
+ return 0;
+ }
+
+ if (strcmp(apath, policy->path) == 0) {
+ /* the two paths are same, no need to add another policy */
+ dim_kfree((char *)apath);
+ return 0;
+ }
+
+ p = kmemdup(policy, sizeof(struct dim_policy), GFP_KERNEL);
+ if (p == NULL) {
+ dim_kfree((char *)apath);
+ return -ENOMEM;
+ }
+
+ /* set the absolute path and add the policy node */
+ p->path = apath;
+ ret = dim_policy_rb_add(&policy_root, p, NULL);
+ if (ret < 0)
+ policy_destroy(p);
+
+ /* the EEXIST error must be processed here */
+ return ret == -EEXIST ? 0 : ret;
+}
+
+static int policy_check_add_module_text(struct dim_policy *policy)
+{
+ if (policy->name == NULL) {
+ pr_err("name must be set for MODULE_TEXT policy\n");
+ return -EINVAL;
+ }
+
+ if (strlen(policy->name) + 1 > NAME_MAX) {
+ pr_err("name must be shorter than %d\n", NAME_MAX);
+ return -ENAMETOOLONG;
+ }
+
+ if (policy->path != NULL)
+ pr_warn("path is ignored for BPRM_TEXT policy\n");
+
+ if (policy->action != DIM_POLICY_ACTION_LOG)
+ pr_warn("action is ignored for MODULE_TEXT policy\n");
+
+ return dim_policy_rb_add(&policy_root, policy, NULL);
+}
+
+static int policy_check_add_kernel_text(struct dim_policy *policy)
+{
+ if (policy->name != NULL || policy->path != NULL ||
+ policy->action != DIM_POLICY_ACTION_LOG)
+ pr_warn("all parameters are ignored for KERNEL_TEXT policy\n");
+
+ return dim_policy_rb_add(&policy_root, policy, NULL);
+}
+
+static int policy_check_add(struct dim_policy *policy)
+{
+ switch (policy->obj)
+ {
+ case DIM_POLICY_OBJ_BPRM_TEXT:
+ return policy_check_add_bprm_text(policy);
+ case DIM_POLICY_OBJ_MODULE_TEXT:
+ return policy_check_add_module_text(policy);
+ case DIM_POLICY_OBJ_KERNEL_TEXT:
+ return policy_check_add_kernel_text(policy);
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+int dim_core_policy_load(void)
+{
+ int ret = 0;
+ void *buf = NULL;
+ loff_t buf_len = 0;
+
+ if (!RB_EMPTY_ROOT(&policy_root))
+ dim_core_policy_destroy();
+
+ ret = dim_read_verify_file(NULL, DIM_POLICY_PATH, &buf);
+ if (ret < 0 || buf == NULL) {
+ dim_err("failed to read policy file: %d\n", ret);
+ return ret;
+ }
+
+ buf_len = ret;
+ ret = dim_policy_parse(buf, buf_len, policy_check_add);
+ if (ret < 0) {
+ dim_err("failed to parse policy: %d\n", ret);
+ dim_core_policy_destroy();
+ }
+
+ vfree(buf);
+ return ret;
+}
+
+void dim_core_policy_destroy(void)
+{
+ struct dim_policy *pos = NULL;
+ struct dim_policy *n = NULL;
+
+ rbtree_postorder_for_each_entry_safe(pos, n, &policy_root, rb_node)
+ policy_destroy(pos);
+
+ policy_root = RB_ROOT;
+}
+
+static int policy_find(int obj, int key __always_unused, const char *val,
+ struct dim_policy **find)
+{
+ struct dim_policy policy = { 0 };
+
+ /* now the key parameter is unused */
+ switch (obj) {
+ case DIM_POLICY_OBJ_BPRM_TEXT:
+ policy.path = val;
+ break;
+ case DIM_POLICY_OBJ_MODULE_TEXT:
+ policy.name = val;
+ break;
+ case DIM_POLICY_OBJ_KERNEL_TEXT:
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ policy.obj = obj;
+ return dim_policy_rb_find(&policy_root, &policy, find);
+}
+
+bool dim_core_policy_match(int obj, int key, const char *val)
+{
+ if (val == NULL)
+ return false;
+
+ return policy_find(obj, key, val, NULL) == 0;
+}
+
+int dim_core_policy_get_action(int obj, int key, const char *val)
+{
+ int ret = 0;
+ struct dim_policy *find = NULL;
+
+ if (val == NULL)
+ return DIM_POLICY_ACTION_LAST;
+
+ ret = policy_find(obj, key, val, &find);
+ if (ret < 0)
+ return DIM_POLICY_ACTION_LAST;
+
+ return find->action;
+}
+
+int dim_core_policy_walk(int (*f)(struct dim_policy *, void *), void *data)
+{
+ int ret = 0;
+ struct dim_policy *pos = NULL;
+ struct dim_policy *n = NULL;
+
+ rbtree_postorder_for_each_entry_safe(pos, n, &policy_root, rb_node) {
+ ret = f(pos, data);
+ if (ret < 0)
+ return ret;
+ }
+
+ return 0;
+}
diff --git a/src/core/policy/dim_core_policy.h b/src/core/policy/dim_core_policy.h
new file mode 100644
index 0000000..7f2c756
--- /dev/null
+++ b/src/core/policy/dim_core_policy.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#ifndef __DIM_CORE_POLICY_H
+#define __DIM_CORE_POLICY_H
+
+#include <linux/rbtree.h>
+
+/* the policy filepath */
+#define DIM_POLICY_PATH "/etc/dim/policy"
+/* max number of lines for parsing */
+#define DIM_POLICY_LINE_MAX 10000
+
+/* measurement object of policy */
+enum dim_policy_obj {
+ DIM_POLICY_OBJ_BPRM_TEXT,
+ DIM_POLICY_OBJ_MODULE_TEXT,
+ DIM_POLICY_OBJ_KERNEL_TEXT,
+ DIM_POLICY_OBJ_LAST,
+};
+
+/* key of measurement condition */
+enum dim_policy_key {
+ DIM_POLICY_KEY_OBJ,
+ DIM_POLICY_KEY_NAME,
+ DIM_POLICY_KEY_PATH,
+ DIM_POLICY_KEY_ACTION,
+ DIM_POLICY_KEY_LAST,
+};
+
+/* action to perform when dim detected a tampering */
+enum dim_policy_action {
+ /* add to measure log (default) */
+ DIM_POLICY_ACTION_LOG,
+ /* kill the tampered user process */
+ DIM_POLICY_ACTION_KILL,
+ DIM_POLICY_ACTION_LAST,
+};
+
+struct dim_policy {
+ struct rb_node rb_node;
+ int obj; /* enum dim_policy_obj */
+ const char *path; /* user process path */
+ const char *name; /* module name */
+ int action; /* enum dim_policy_action */
+};
+
+/* callback funtion to walk dim policy nodes */
+typedef int (*dim_policy_visitor)(struct dim_policy *, void *);
+
+/* callback funtion to add a policy item when parsing policy file */
+typedef int (*policy_add_func)(struct dim_policy *);
+
+/* parse dim policy in complex format */
+int policy_parse_complex_format(char *buf, size_t buf_len,
+ policy_add_func policy_add);
+#define dim_policy_parse policy_parse_complex_format
+
+/* export for implementing the policy parser */
+void policy_destroy(struct dim_policy *policy);
+
+int dim_core_policy_load(void);
+void dim_core_policy_destroy(void);
+bool dim_core_policy_match(int obj, int key, const char *val);
+int dim_core_policy_walk(dim_policy_visitor f, void *data);
+int dim_core_policy_get_action(int obj, int key, const char *val);
+
+#endif
diff --git a/src/core/policy/dim_core_policy_complex.c b/src/core/policy/dim_core_policy_complex.c
new file mode 100644
index 0000000..b29483d
--- /dev/null
+++ b/src/core/policy/dim_core_policy_complex.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#include <linux/slab.h>
+
+#include "dim_utils.h"
+
+#include "dim_core_policy.h"
+
+/* policy key */
+#define DIM_POLICY_MEASURE "measure"
+
+/* measure obj=MODULE_TEXT path={PATH_MAX} action=kill\n */
+#define DIM_POLICY_MAX_KEY_FIELDS 3
+#define DIM_POLICY_OBJ_MAX_LEN 15
+#define DIM_POLICY_KEY_MAX_LEN 5
+#define DIM_POLICY_ACTION_MAX_LEN 11
+#define DIM_POLICY_MAX_LEN (strlen(DIM_POLICY_MEASURE) + 1 + \
+ DIM_POLICY_OBJ_MAX_LEN + 1 + \
+ DIM_POLICY_KEY_MAX_LEN + 1 + PATH_MAX + 1 + \
+ DIM_POLICY_ACTION_MAX_LEN + 1)
+
+static const char *dim_policy_key_str[DIM_POLICY_KEY_LAST] = {
+ [DIM_POLICY_KEY_OBJ] = "obj=",
+ [DIM_POLICY_KEY_NAME] = "name=",
+ [DIM_POLICY_KEY_PATH] = "path=",
+ [DIM_POLICY_KEY_ACTION] = "action=",
+};
+
+static const char *dim_policy_obj_str[DIM_POLICY_OBJ_LAST] = {
+ [DIM_POLICY_OBJ_BPRM_TEXT] = "BPRM_TEXT",
+ [DIM_POLICY_OBJ_MODULE_TEXT] = "MODULE_TEXT",
+ [DIM_POLICY_OBJ_KERNEL_TEXT] = "KERNEL_TEXT",
+};
+
+static const char *dim_policy_action_str[DIM_POLICY_KEY_LAST] = {
+ [DIM_POLICY_ACTION_LOG] = "log",
+ [DIM_POLICY_ACTION_KILL] = "kill",
+};
+
+static const char *policy_get_string_value(const char *s)
+{
+ return kstrdup(s, GFP_KERNEL);
+}
+
+static int policy_get_action(const char *s)
+{
+ return match_string(dim_policy_action_str, DIM_POLICY_ACTION_LAST, s);
+}
+
+static int policy_get_obj(const char *s)
+{
+ return match_string(dim_policy_obj_str, DIM_POLICY_OBJ_LAST, s);
+}
+
+static int policy_get_key(const char *s, const char **val)
+{
+ unsigned int i = 0;
+ unsigned int len = 0;
+
+ for (; i < DIM_POLICY_KEY_LAST; i++) {
+ len = strlen(dim_policy_key_str[i]);
+ if (strncmp(s, dim_policy_key_str[i], len) == 0) {
+ *val = s + len;
+ return i;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int policy_parse_key_value(char *s, struct dim_policy *policy)
+{
+ char *p = NULL;
+ int key = 0;
+ int filed_num = 0;
+ const char *val = NULL;
+
+ while ((p = strsep(&s, " ")) != NULL) {
+ key = policy_get_key(p, &val);
+ if (key < 0 || val == NULL)
+ return -EINVAL;
+
+ if (++filed_num > DIM_POLICY_MAX_KEY_FIELDS)
+ return -EINVAL;
+
+ switch (key)
+ {
+ case DIM_POLICY_KEY_OBJ:
+ policy->obj = policy_get_obj(val);
+ if (policy->obj < 0)
+ return -EINVAL;
+ break;
+ case DIM_POLICY_KEY_NAME:
+ policy->name = policy_get_string_value(val);
+ if (policy->name == NULL)
+ return -ENOMEM;
+ break;
+ case DIM_POLICY_KEY_PATH:
+ policy->path = policy_get_string_value(val);
+ if (policy->path == NULL)
+ return -ENOMEM;
+ break;
+ case DIM_POLICY_KEY_ACTION:
+ policy->action = policy_get_action(val);
+ if (policy->action < 0)
+ return -EINVAL;
+ break;
+ default:
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+static int parse_line(char *line_str, struct dim_policy *policy)
+{
+ int ret = 0;
+ char *p = NULL;
+
+ if ((p = strsep(&line_str, " ")) == NULL ||
+ strcmp(p, DIM_POLICY_MEASURE) != 0) {
+ dim_err("invalid policy prefix, must start with %s\n",
+ DIM_POLICY_MEASURE);
+ return -EINVAL;
+ }
+
+ ret = policy_parse_key_value(line_str, policy);
+ if (ret < 0) {
+ dim_err("fail to parse policy key and value: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int policy_parse_line(char* line, int line_no, void *data)
+{
+ int ret = 0;
+ struct dim_policy *policy = NULL;
+ policy_add_func policy_add = data;
+
+ if (line_no > DIM_POLICY_LINE_MAX) {
+ dim_warn("more than %d policy items will be ignored\n",
+ DIM_POLICY_LINE_MAX);
+ return -E2BIG;
+ }
+
+ if (strlen(line) == 0 || line[0] == '#')
+ return 0; /* ignore blank line and comment */
+
+ if (strlen(line) > DIM_POLICY_MAX_LEN) {
+ dim_err("overlength line %d\n", line_no);
+ return -EINVAL;
+ }
+
+ policy = dim_kmalloc_gfp(sizeof(struct dim_policy));
+ if (policy == NULL)
+ return -ENOMEM;
+
+ memset(policy, 0, sizeof(struct dim_policy));
+
+ ret = parse_line(line, policy);
+ if (ret < 0) {
+ dim_err("fail to parse policy at line %d: %d\n", line_no, ret);
+ return ret;
+ }
+
+ ret = policy_add(policy);
+ if (ret < 0) {
+ policy_destroy(policy);
+ /* ignore the repeat add */
+ if (ret != -EEXIST)
+ dim_err("fail to add policy at line %d: %d\n", line_no, ret);
+ return ret == -EEXIST ? 0 : ret;
+ }
+
+ return 0;
+}
+
+int policy_parse_complex_format(char *buf, size_t buf_len,
+ policy_add_func policy_add)
+{
+ if (buf == NULL || buf_len == 0 || policy_add == NULL)
+ return -EINVAL;
+
+ return dim_parse_line_buf(buf, buf_len, policy_parse_line, policy_add);
+}
\ No newline at end of file
--
2.33.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。