代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/dim 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From f1751e2438811f861e24e7be285a333942132b47 Mon Sep 17 00:00:00 2001
From: Huaxin Lu <luhuaxin1@huawei.com>
Date: Sun, 11 Feb 2024 14:36:27 +0800
Subject: [PATCH 12/26] Refactor the measurement code
Refactor the measurement function code, extract a measurement
framework layer to implement the common measurement logic.
---
src/Makefile | 30 +-
src/common/dim_baseline.c | 10 +-
src/common/dim_entry.h | 11 +-
src/common/dim_hash.c | 2 +-
src/common/dim_status.c | 39 ---
src/common/dim_status.h | 23 --
src/common/dim_utils.h | 8 +-
src/core/dim_core.h | 13 -
src/core/dim_core_baseline.c | 115 -------
src/core/dim_core_baseline.h | 25 --
src/core/dim_core_fs.c | 33 +-
src/core/dim_core_main.c | 37 +-
src/core/dim_core_measure.c | 315 ++++++++----------
src/core/dim_core_measure.h | 73 +---
src/core/dim_core_measure_common.c | 87 -----
src/core/dim_core_mem_pool.c | 3 +-
src/core/dim_core_policy.c | 5 +-
src/core/dim_core_policy.h | 2 +
src/core/dim_core_sig.c | 3 +-
src/core/dim_core_static_baseline.c | 16 +-
src/core/dim_core_static_baseline.h | 2 +
src/core/dim_core_status.c | 42 ---
src/core/dim_core_status.h | 24 --
src/core/dim_core_symbol.c | 2 +-
.../dim_core_measure_kernel.c | 40 ++-
.../dim_core_measure_module.c | 48 ++-
.../dim_core_measure_task.c | 83 +++--
src/core/measure_task/dim_core_measure_task.h | 8 +
src/measure/dim_measure.c | 100 ++++++
src/measure/dim_measure.h | 117 +++++++
src/measure/dim_measure_baseline.c | 235 +++++++++++++
src/measure/dim_measure_status.c | 34 ++
src/measure/dim_measure_task.c | 91 +++++
src/measure/dim_measure_utils.c | 13 +
src/monitor/dim_monitor.h | 33 +-
src/monitor/dim_monitor_fs.c | 22 +-
src/monitor/dim_monitor_main.c | 23 +-
src/monitor/dim_monitor_measure.c | 245 +++-----------
src/monitor/dim_monitor_symbol.c | 2 +-
.../measure_task/dim_monitor_measure_data.c | 56 ++++
.../measure_task/dim_monitor_measure_task.h | 11 +
.../measure_task/dim_monitor_measure_text.c | 64 ++++
42 files changed, 1171 insertions(+), 974 deletions(-)
delete mode 100644 src/common/dim_status.c
delete mode 100644 src/common/dim_status.h
delete mode 100644 src/core/dim_core.h
delete mode 100644 src/core/dim_core_baseline.c
delete mode 100644 src/core/dim_core_baseline.h
delete mode 100644 src/core/dim_core_measure_common.c
delete mode 100644 src/core/dim_core_status.c
delete mode 100644 src/core/dim_core_status.h
rename src/core/{ => measure_task}/dim_core_measure_kernel.c (79%)
rename src/core/{ => measure_task}/dim_core_measure_module.c (64%)
rename src/core/{ => measure_task}/dim_core_measure_task.c (88%)
create mode 100644 src/core/measure_task/dim_core_measure_task.h
create mode 100644 src/measure/dim_measure.c
create mode 100644 src/measure/dim_measure.h
create mode 100644 src/measure/dim_measure_baseline.c
create mode 100644 src/measure/dim_measure_status.c
create mode 100644 src/measure/dim_measure_task.c
create mode 100644 src/measure/dim_measure_utils.c
create mode 100644 src/monitor/measure_task/dim_monitor_measure_data.c
create mode 100644 src/monitor/measure_task/dim_monitor_measure_task.h
create mode 100644 src/monitor/measure_task/dim_monitor_measure_text.c
diff --git a/src/Makefile b/src/Makefile
index fe22112..1a3fac0 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -8,23 +8,24 @@ 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_baseline.o
dim_core-objs += core/dim_core_measure.o
-dim_core-objs += core/dim_core_measure_task.o
-dim_core-objs += core/dim_core_measure_module.o
-dim_core-objs += core/dim_core_measure_kernel.o
-dim_core-objs += core/dim_core_measure_common.o
-dim_core-objs += core/dim_core_status.o
dim_core-objs += core/dim_core_symbol.o
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 += common/dim_entry.o
dim_core-objs += common/dim_utils.o
dim_core-objs += common/dim_baseline.o
dim_core-objs += common/dim_hash.o
dim_core-objs += common/dim_measure_log.o
-dim_core-objs += common/dim_status.o
dim_core-objs += common/dim_tpm.o
dim_core-objs += common/dim_symbol.o
+dim_core-objs += measure/dim_measure.o
+dim_core-objs += measure/dim_measure_baseline.o
+dim_core-objs += measure/dim_measure_task.o
+dim_core-objs += measure/dim_measure_utils.o
+dim_core-objs += measure/dim_measure_status.o
dim_monitor-objs += monitor/dim_monitor_main.o
dim_monitor-objs += monitor/dim_monitor_fs.o
@@ -32,16 +33,26 @@ dim_monitor-objs += monitor/dim_monitor_measure.o
dim_monitor-objs += monitor/dim_monitor_symbol.o
dim_monitor-objs += common/dim_entry.o
dim_monitor-objs += common/dim_hash.o
-dim_monitor-objs += common/dim_status.o
dim_monitor-objs += common/dim_utils.o
dim_monitor-objs += common/dim_measure_log.o
dim_monitor-objs += common/dim_baseline.o
dim_monitor-objs += common/dim_tpm.o
dim_monitor-objs += common/dim_symbol.o
+dim_monitor-objs += measure/dim_measure.o
+dim_monitor-objs += measure/dim_measure_baseline.o
+dim_monitor-objs += measure/dim_measure_task.o
+dim_monitor-objs += measure/dim_measure_utils.o
+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)/monitor
+ccflags-y += -I$(src)/monitor/measure_task
ccflags-y += -I$(src)/common
+ccflags-y += -I$(src)/measure
EXTRA_CFLAGS += -Wall -Werror -D_FORTIFY_SOURCE=2 -O2 -fstack-protector-strong
@@ -61,3 +72,6 @@ install:
rmmod -f dim_core || :
insmod dim_core.ko
insmod dim_monitor.ko
+
+test:
+ cd ../test && { sh test_dim_core.sh; sh test_dim_monitor.sh; }
\ No newline at end of file
diff --git a/src/common/dim_baseline.c b/src/common/dim_baseline.c
index 09a2780..ec53b1c 100644
--- a/src/common/dim_baseline.c
+++ b/src/common/dim_baseline.c
@@ -4,6 +4,7 @@
#include "dim_rb.h"
#include "dim_baseline.h"
+#include "dim_utils.h"
static int dim_baseline_compare(struct dim_baseline *x,
struct dim_baseline *y)
@@ -104,7 +105,7 @@ int dim_baseline_add(struct dim_baseline_tree *root, const char *name,
if (ret < 0)
goto err;
- strncpy((char *)baseline->name, name, buf_len - 1);
+ strncpy((char *)baseline->name, name, buf_len - 1);
((char *)baseline->name)[buf_len - 1] = '\0';
write_lock(&root->lock);
@@ -143,12 +144,13 @@ void dim_baseline_destroy_tree(struct dim_baseline_tree *root)
int dim_baseline_init_tree(malloc_func malloc, free_func free,
struct dim_baseline_tree *root)
{
- if (malloc == NULL || free == NULL || root == NULL)
+ if (root == NULL)
return -EINVAL;
rwlock_init(&root->lock);
root->rb_root = RB_ROOT;
- root->malloc = malloc;
- root->free = free;
+ /* use kmalloc by default */
+ root->malloc = malloc == NULL ? dim_kmalloc_gfp : malloc;
+ root->free = free == NULL ? dim_kfree : free;
return 0;
}
diff --git a/src/common/dim_entry.h b/src/common/dim_entry.h
index acfc3a0..1c557b8 100644
--- a/src/common/dim_entry.h
+++ b/src/common/dim_entry.h
@@ -10,7 +10,6 @@
#include <linux/seq_file.h>
#include "dim_measure_log.h"
-#include "dim_status.h"
#define DIM_ENTRY_DIR_MASK (S_IFDIR | S_IRWXU | S_IRUSR)
#define DIM_ENTRY_RW_MASK (S_IWUSR | S_IRUSR)
@@ -26,7 +25,7 @@ struct dim_entry {
};
/* the file interface for trigger by 'echo 1 > file_path' */
-#define dim_trigger_entry(sname, fname, function, param) \
+#define dim_trigger_entry(sname, fname, function) \
static ssize_t sname##_trigger(struct file *file, \
const char __user *buf, \
size_t count, loff_t *ppos) \
@@ -41,7 +40,7 @@ static ssize_t sname##_trigger(struct file *file, \
if (ret < 0 || val != 1) \
return ret < 0 ? ret : -EINVAL; \
\
- ret = function(param); \
+ ret = function(); \
if (ret < 0) \
return ret; \
\
@@ -113,8 +112,8 @@ static struct dim_entry sname##_entry = { \
.fops = &sname##_ops, \
};
-/* the file interface for reading dim status */
-#define dim_status_entry(sname, fname, status_ptr) \
+/* the file interface for print string */
+#define dim_string_print_entry(sname, fname, function) \
static ssize_t sname##_read(struct file *file, \
char __user *buf, \
size_t count, loff_t *ppos) \
@@ -125,7 +124,7 @@ static ssize_t sname##_read(struct file *file, \
len = scnprintf(tmpbuf, \
DIM_FS_TMP_BUF_SIZE, \
"%s\n", \
- dim_status_get_name(status_ptr)); \
+ function()); \
\
return simple_read_from_buffer(buf, count, ppos, tmpbuf, len); \
} \
diff --git a/src/common/dim_hash.c b/src/common/dim_hash.c
index 38464df..9f73320 100644
--- a/src/common/dim_hash.c
+++ b/src/common/dim_hash.c
@@ -49,7 +49,7 @@ int dim_hash_calculate(const void *data, unsigned int len,
int ret = 0;
SHASH_DESC_ON_STACK(shash, alg->tfm);
- if (data == NULL || alg == NULL || digest == NULL)
+ if (data == NULL || alg == NULL || digest == NULL || alg->tfm == NULL)
return -EINVAL;
digest->algo = alg->algo;
diff --git a/src/common/dim_status.c b/src/common/dim_status.c
deleted file mode 100644
index 411430a..0000000
--- a/src/common/dim_status.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
- */
-
-#include <linux/err.h>
-
-#include "dim_status.h"
-
-int dim_status_init(struct dim_status *status,
- const char **table,
- unsigned int len)
-{
- if (status == NULL || table == NULL || len == 0)
- return -EINVAL;
-
- status->table = table;
- status->table_len = len;
- atomic_set(&status->status_cur, 0);
- return 0;
-}
-
-int dim_status_get(struct dim_status *status)
-{
- return status == NULL ? 0 : atomic_read(&status->status_cur);
-}
-
-const char *dim_status_get_name(struct dim_status *status)
-{
- return status == NULL ? NULL :
- status->table[atomic_read(&status->status_cur)];
-}
-
-void dim_status_set(struct dim_status *status, unsigned int s)
-{
- if (status == NULL || s >= status->table_len)
- return;
-
- atomic_set(&status->status_cur, s);
-}
\ No newline at end of file
diff --git a/src/common/dim_status.h b/src/common/dim_status.h
deleted file mode 100644
index 741bcda..0000000
--- a/src/common/dim_status.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
- */
-
-#ifndef __DIM_STATUS_H
-#define __DIM_STATUS_H
-
-#include <linux/atomic.h>
-
-struct dim_status {
- const char **table;
- int table_len;
- atomic_t status_cur;
-};
-
-int dim_status_init(struct dim_status *status,
- const char **table,
- unsigned int len);
-int dim_status_get(struct dim_status *status);
-const char *dim_status_get_name(struct dim_status *status);
-void dim_status_set(struct dim_status *status, unsigned int s);
-
-#endif
\ No newline at end of file
diff --git a/src/common/dim_utils.h b/src/common/dim_utils.h
index 382721b..1db3ca1 100644
--- a/src/common/dim_utils.h
+++ b/src/common/dim_utils.h
@@ -10,11 +10,11 @@
#define DIM_ARRAY_LEN(ARR) (sizeof(ARR) / sizeof(ARR[0]))
-#define dim_fmt(fmt) DIM_MODULE ": " fmt
+#define dim_fmt(fmt) "%s: " fmt
-#define dim_err(fmt, ...) pr_err(dim_fmt(fmt), ##__VA_ARGS__)
-#define dim_warn(fmt, ...) pr_warn(dim_fmt(fmt), ##__VA_ARGS__)
-#define dim_info(fmt, ...) pr_info(dim_fmt(fmt), ##__VA_ARGS__)
+#define dim_err(fmt, ...) pr_err(dim_fmt(fmt), THIS_MODULE->name, ##__VA_ARGS__)
+#define dim_warn(fmt, ...) pr_warn(dim_fmt(fmt), THIS_MODULE->name, ##__VA_ARGS__)
+#define dim_info(fmt, ...) pr_info(dim_fmt(fmt), THIS_MODULE->name, ##__VA_ARGS__)
#define dim_devel(fmt, ...)
void *dim_kmalloc_gfp(size_t size);
diff --git a/src/core/dim_core.h b/src/core/dim_core.h
deleted file mode 100644
index c210c66..0000000
--- a/src/core/dim_core.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
- */
-
-#ifndef __DIM_CORE_H
-#define __DIM_CORE_H
-
-#include "dim_utils.h"
-
-#define DIM_MODULE "dim_core"
-#define DIM_CORE_HASH_DEFAULT "sha256"
-
-#endif
diff --git a/src/core/dim_core_baseline.c b/src/core/dim_core_baseline.c
deleted file mode 100644
index 27a8114..0000000
--- a/src/core/dim_core_baseline.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
- */
-
-#include <linux/atomic.h>
-#include <linux/utsname.h>
-
-#include "dim_baseline.h"
-#include "dim_hash.h"
-#include "dim_utils.h"
-
-#include "dim_core.h"
-#include "dim_core_mem_pool.h"
-
-static struct dim_baseline_tree static_baseline = { 0 };
-static struct dim_baseline_tree dynamic_baseline = { 0 };
-
-static const char *process_static_name(const char *name, int type,
- char *buf, int buf_len)
-{
- const char *kr = init_uts_ns.name.release;
-
- if (type != DIM_BASELINE_KERNEL || strcmp(name, kr) == 0)
- return name;
-
- /* name of kernel module has a kernel prefix in static baseline */
- if (sprintf(buf, "%s/%s", kr, name) < 0)
- return NULL;
-
- return buf;
-}
-
-int dim_core_add_static_baseline(const char *name, int type,
- struct dim_digest *digest)
-{
- int ret = dim_baseline_add(&static_baseline, name, type, digest);
- if (ret < 0 && ret != -EEXIST) {
- dim_err("failed to add static baseline of %s\n", name);
- return ret;
- }
-
- return 0;
-}
-
-int dim_core_add_dynamic_baseline(const char *name, int type,
- struct dim_digest *digest)
-{
- int ret = dim_baseline_add(&dynamic_baseline, name, type, digest);
- if (ret < 0 && ret != -EEXIST) {
- dim_err("failed to add dynamic baseline of %s\n", name);
- return ret;
- }
-
- return 0;
-}
-
-bool dim_core_match_static_baseline(const char *name, int type,
- struct dim_digest *digest)
-{
- char buf[NAME_MAX + NAME_MAX + 1 + 1] = { 0 };
- return dim_baseline_match(&static_baseline,
- process_static_name(name, type, buf, sizeof(buf)),
- type, digest);
-}
-
-bool dim_core_match_dynamic_baseline(const char *name, int type,
- struct dim_digest *digest)
-{
- return dim_baseline_match(&dynamic_baseline, name, type, digest);
-}
-
-int dim_core_search_static_baseline(const char *name, int type,
- struct dim_digest *digest)
-{
- char buf[NAME_MAX + NAME_MAX + 1 + 1] = { 0 };
- return dim_baseline_search_digest(&static_baseline,
- process_static_name(name, type, buf, sizeof(buf)),
- type, digest);
-}
-
-int dim_core_search_dynamic_baseline(const char *name, int type,
- struct dim_digest *digest)
-{
- return dim_baseline_search_digest(&dynamic_baseline, name,
- type, digest);
-}
-
-int dim_core_baseline_init(void)
-{
- int ret;
-
- ret = dim_baseline_init_tree(dim_kmalloc_gfp,
- dim_kfree,
- &static_baseline);
- if (ret < 0) {
- dim_err("failed to initialize static baseline root: %d\n", ret);
- return ret;
- }
-
- ret = dim_baseline_init_tree(dim_mem_pool_alloc,
- dim_mem_pool_free,
- &dynamic_baseline);
- if (ret < 0) {
- dim_err("failed to initialize dynamic baseline root: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
-
-void dim_core_baseline_destroy(void)
-{
- dim_baseline_destroy_tree(&static_baseline);
- dim_baseline_destroy_tree(&dynamic_baseline);
-}
diff --git a/src/core/dim_core_baseline.h b/src/core/dim_core_baseline.h
deleted file mode 100644
index e4c7282..0000000
--- a/src/core/dim_core_baseline.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
- */
-
-#ifndef __DIM_CORE_BASELINE_H
-#define __DIM_CORE_BASELINE_H
-
-#include "dim_hash.h"
-
-int dim_core_baseline_init(void);
-void dim_core_baseline_destroy(void);
-int dim_core_add_static_baseline(const char *name, int type,
- struct dim_digest *digest);
-int dim_core_add_dynamic_baseline(const char *name, int type,
- struct dim_digest *digest);
-bool dim_core_match_static_baseline(const char *name, int type,
- struct dim_digest *digest);
-bool dim_core_match_dynamic_baseline(const char *name, int type,
- struct dim_digest *digest);
-int dim_core_search_static_baseline(const char *name, int type,
- struct dim_digest *digest);
-int dim_core_search_dynamic_baseline(const char *name, int type,
- struct dim_digest *digest);
-
-#endif
diff --git a/src/core/dim_core_fs.c b/src/core/dim_core_fs.c
index e050a19..a76d622 100644
--- a/src/core/dim_core_fs.c
+++ b/src/core/dim_core_fs.c
@@ -6,26 +6,25 @@
#include "dim_utils.h"
-#include "dim_core.h"
#include "dim_core_measure.h"
-#include "dim_core_status.h"
#include "dim_core_fs.h"
/*
* measure trigger interface
* dim_entry struct: dim_measure_entry
* file entry name: measure
- * function: dim_core_measure(0)
+ * function: dim_core_measure_blocking()
*/
-dim_trigger_entry(dim_measure, measure, dim_core_measure, 0);
+dim_trigger_entry(dim_measure, measure, dim_core_measure_blocking);
/*
* baseline_init trigger interface
* dim_entry struct: dim_baseline_init_entry
* file entry name: baseline_init
- * function: dim_core_measure(1)
+ * function: dim_core_baseline_blocking(0)
*/
-dim_trigger_entry(dim_baseline_init, baseline_init, dim_core_measure, 1);
+dim_trigger_entry(dim_baseline_init, baseline_init,
+ dim_core_baseline_blocking);
/*
* measure log read interface
@@ -33,17 +32,16 @@ dim_trigger_entry(dim_baseline_init, baseline_init, dim_core_measure, 1);
* file entry name: runtime_status
* status to read: dim_measure_log_tree
*/
-dim_measure_log_entry(dim_measure_log,
- ascii_runtime_measurements,
- &dim_core_log);
+dim_measure_log_entry(dim_measure_log, ascii_runtime_measurements,
+ &dim_core_handle.log);
/*
- * status read interface
+ * status print interface
* dim_entry struct: dim_status_entry
- * file entry name: ascii_runtime_measurements
- * data to read: dim_core_status
+ * file entry name: runtime_status
+ * print function: dim_core_status_print
*/
-dim_status_entry(dim_status, runtime_status, &dim_core_status);
+dim_string_print_entry(dim_status, runtime_status, dim_core_status_print);
/*
* measure interval set and read interface
@@ -52,8 +50,7 @@ dim_status_entry(dim_status, runtime_status, &dim_core_status);
* read function: dim_core_interval_get
* write function: dim_core_interval_set
*/
-dim_uint_rw_entry(dim_interval, interval,
- dim_core_interval_get,
+dim_uint_rw_entry(dim_interval, interval, dim_core_interval_get,
dim_core_interval_set);
#ifdef DIM_CORE_TAMPERED_ACTION
@@ -64,10 +61,8 @@ dim_uint_rw_entry(dim_interval, interval,
* 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);
+dim_uint_rw_entry(dim_tampered_action, tampered_action,
+ dim_core_tampered_action_get, dim_core_tampered_action_set);
#endif
/*
diff --git a/src/core/dim_core_main.c b/src/core/dim_core_main.c
index 6de0c2a..6a0ca41 100644
--- a/src/core/dim_core_main.c
+++ b/src/core/dim_core_main.c
@@ -4,31 +4,37 @@
#include <linux/module.h>
-#include "dim_core.h"
#include "dim_core_symbol.h"
#include "dim_core_fs.h"
#include "dim_core_measure.h"
#include "dim_core_mem_pool.h"
#include "dim_core_sig.h"
-static char *measure_hash = NULL;
-bool signature = false;
+/* common measurement configuration */
+static struct dim_measure_cfg cfg = {
+ .alg_name = DIM_CORE_HASH_DEFAULT,
+ .log_cap = DIM_CORE_LOG_CAP_DEFAULT,
+};
-module_param(measure_log_capacity, uint, 0);
+module_param_named(measure_log_capacity, cfg.log_cap, uint, 0);
MODULE_PARM_DESC(measure_log_capacity, "Max number of measure log");
-module_param(measure_schedule, uint, 0);
+module_param_named(measure_schedule, cfg.schedule_ms, uint, 0);
MODULE_PARM_DESC(measure_schedule, "Schedule time (ms) for each measure object");
-module_param(measure_interval, uint, 0);
-MODULE_PARM_DESC(measure_interval, "Interval time (min) for automatic measurement");
-
-module_param(measure_hash, charp, 0);
+module_param_named(measure_hash, cfg.alg_name, charp, 0);
MODULE_PARM_DESC(measure_hash, "Hash algorithm for measurement");
-module_param(measure_pcr, uint, 0);
+module_param_named(measure_pcr, cfg.pcr, uint, 0);
MODULE_PARM_DESC(measure_pcr, "TPM PCR index to extend measure log");
+/* special measurement configuration for dim_core */
+static unsigned int measure_interval = 0;
+static bool signature = false;
+
+module_param(measure_interval, uint, 0);
+MODULE_PARM_DESC(measure_interval, "Interval time (min) for automatic measurement");
+
module_param(signature, bool, 0);
MODULE_PARM_DESC(signature, "Require signature for policy and static baseline");
@@ -56,8 +62,7 @@ static int __init dim_core_init(void)
}
}
- ret = dim_core_measure_init(measure_hash == NULL ?
- DIM_CORE_HASH_DEFAULT : measure_hash);
+ ret = dim_core_measure_init(&cfg, measure_interval);
if (ret < 0) {
dim_err("failed to initialize dim measurement: %d\n", ret);
goto err;
@@ -72,14 +77,18 @@ static int __init dim_core_init(void)
return 0;
err:
dim_core_destroy_fs();
- dim_core_destroy_measure();
+ dim_core_measure_destroy();
dim_mem_pool_destroy();
+
+ if (signature)
+ dim_core_sig_destroy();
+
return ret;
}
static void __exit dim_core_exit(void)
{
- dim_core_destroy_measure();
+ dim_core_measure_destroy();
dim_core_destroy_fs();
dim_mem_pool_destroy();
diff --git a/src/core/dim_core_measure.c b/src/core/dim_core_measure.c
index ed4a464..0147735 100644
--- a/src/core/dim_core_measure.c
+++ b/src/core/dim_core_measure.c
@@ -2,153 +2,107 @@
* Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
*/
-#include <linux/highmem.h>
-#include <linux/seq_file.h>
-#include <linux/vmalloc.h>
+#include <linux/workqueue.h>
-#include "dim_measure_log.h"
-#include "dim_tpm.h"
-
-#include "dim_core.h"
-#include "dim_core_status.h"
#include "dim_core_policy.h"
+#include "dim_core_mem_pool.h"
#include "dim_core_static_baseline.h"
-#include "dim_core_baseline.h"
+#include "dim_core_measure_task.h"
#include "dim_core_measure.h"
-/* lock to prevent concurrent measurement */
+/* measurement tasks */
+static struct dim_measure_task *dim_core_tasks[] = {
+ &dim_core_measure_task_user_text,
+ &dim_core_measure_task_kernel_text,
+ &dim_core_measure_task_module_text,
+};
+
+/* the global measurement handle */
+struct dim_measure dim_core_handle = { 0 };
+
+/* lock to prevent trigger multiple measurement */
DEFINE_MUTEX(dim_core_measure_lock);
-/* lock to prevent concurrent baseline_init */
-DEFINE_MUTEX(dim_core_baseline_lock);
-/* lock to prevent concurrent setting interval */
-DEFINE_MUTEX(dim_core_interval_lock);
-/* lock to prevent concurrent setting tampered_action */
-DEFINE_MUTEX(dim_core_tampered_action_lock);
-/* dim work quee */
+
+/* dim measurement work */
static struct workqueue_struct *dim_work_queue = NULL;
static struct delayed_work dim_measure_work;
-/* parameters set by module commandline */
-unsigned int measure_log_capacity = 100000;
-unsigned int measure_schedule = 0;
-unsigned int measure_interval = 0;
-unsigned int measure_pcr = 0;
-bool tampered_action = false;
-
-/* time (jiffies) to set */
-unsigned long measure_schedule_jiffies = 0;
-static unsigned long measure_interval_jiffies = 0;
+static struct work_struct dim_baseline_work;
-struct dim_tpm dim_core_tpm = { 0 };
-struct dim_hash dim_core_hash = { 0 };
-struct dim_measure_log_tree dim_core_log = { 0 };
+/* special measurement parameters for dim_core */
+static atomic_t measure_interval = ATOMIC_INIT(0);
+static atomic_t tampered_action = ATOMIC_INIT(0);
-long dim_core_interval_get(void)
+/* interface to print measure status string */
+const char *dim_core_status_print(void)
{
- long p = 0;
-
- mutex_lock(&dim_core_interval_lock);
- p = measure_interval;
- mutex_unlock(&dim_core_interval_lock);
- return p;
+ return dim_measure_status_print(&dim_core_handle);
}
-unsigned long dim_core_interval_jiffies_get(void)
+/* interface to get measure interval */
+long dim_core_interval_get(void)
{
- unsigned long p = 0;
-
- mutex_lock(&dim_core_interval_lock);
- p = measure_interval_jiffies;
- mutex_unlock(&dim_core_interval_lock);
- return p;
+ return atomic_read(&measure_interval);
}
+/* interface to set measure interval */
int dim_core_interval_set(unsigned int min)
{
- unsigned long min_jiffies = 0;
+ unsigned long jiffies = 0;
if (min > DIM_INTERVAL_MAX ||
(unsigned long)min * DIM_MINUTE_TO_SEC > MAX_SEC_IN_JIFFIES)
return -ERANGE;
- min_jiffies = (min == 0) ? 0 :
- nsecs_to_jiffies64((unsigned long)min * DIM_MINUTE_TO_NSEC);
-
- mutex_lock(&dim_core_interval_lock);
- measure_interval = min;
- measure_interval_jiffies = min_jiffies;
- if (measure_interval == 0) {
+ atomic_set(&measure_interval, min);
+ if (min == 0) {
dim_info("cancel dim timed measure work");
cancel_delayed_work_sync(&dim_measure_work);
} else {
+ jiffies = nsecs_to_jiffies64((unsigned long)min *
+ DIM_MINUTE_TO_NSEC);
dim_info("modify dim measure interval to %u min "
- "(jittfies = 0x%lx)", min, min_jiffies);
- mod_delayed_work(dim_work_queue, &dim_measure_work,
- min_jiffies);
+ "(jittfies = 0x%lx)", min, jiffies);
+ mod_delayed_work(dim_work_queue, &dim_measure_work, jiffies);
}
- mutex_unlock(&dim_core_interval_lock);
return 0;
}
+/* interface to get tamper action flag */
long dim_core_tampered_action_get(void)
{
- long p = 0;
-
- mutex_lock(&dim_core_tampered_action_lock);
- p = tampered_action ? 1 : 0;
- mutex_unlock(&dim_core_tampered_action_lock);
- return p;
+ 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;
- mutex_lock(&dim_core_tampered_action_lock);
- tampered_action = !!p;
- mutex_unlock(&dim_core_tampered_action_lock);
+ atomic_set(&tampered_action, p);
return 0;
}
-static void do_measure(void)
+static int baseline_prepare(struct dim_measure *m)
{
int ret = 0;
- int bi = 0;
-
- /* dont do measure when doing baseline_init */
- if (!mutex_trylock(&dim_core_baseline_lock))
- return;
-
- bi = (dim_core_status_get() == DIM_BASELINE_RUNNING ? 1 : 0);
- dim_info("start dim measure work, baseline_init = %d\n", bi);
-
- ret = dim_core_measure_task(bi);
- if (ret < 0)
- dim_err("failed to measure user process: %d\n", ret);
-
- ret = dim_core_measure_module(bi);
- if (ret < 0)
- dim_err("failed to measure kernel modules: %d\n", ret);
-
- ret = dim_core_measure_kernel(bi);
- if (ret < 0)
- dim_err("failed to measure kernel: %d\n", ret);
-
- mutex_unlock(&dim_core_baseline_lock);
-}
-static int do_baseline(void)
-{
- int ret = 0;
+ if (m == NULL)
+ return -EINVAL;
+ /* 1. reload dim policy */
ret = dim_core_policy_load();
if (ret < 0) {
dim_err("failed to load dim core policy: %d\n", ret);
return ret;
}
- dim_core_baseline_destroy();
+ /* 2. clear dim baseline */
+ dim_baseline_destroy_tree(&m->static_baseline);
+ dim_baseline_destroy_tree(&m->dynamic_baseline);
+
+ /* 3. reload dim baseline */
ret = dim_core_static_baseline_load();
if (ret < 0) {
dim_err("failed to load dim static baseline: %d\n", ret);
@@ -156,21 +110,38 @@ static int do_baseline(void)
return ret;
}
- dim_measure_log_refresh(&dim_core_log);
+ /* 4. refresh measure log */
+ dim_measure_log_refresh(&m->log);
return 0;
}
-static void dim_worker_work_cb(struct work_struct *work)
+static void queue_delayed_measure_work(void)
{
- unsigned long p;
+ unsigned long jiffies = 0;
+ unsigned int interval = atomic_read(&measure_interval);
+
+ if (interval == 0)
+ return;
- do_measure();
- p = dim_core_interval_jiffies_get();
- if (p != 0)
- queue_delayed_work(dim_work_queue, &dim_measure_work, p);
+ jiffies = nsecs_to_jiffies64((unsigned long)interval *
+ DIM_MINUTE_TO_NSEC);
+ queue_delayed_work(dim_work_queue, &dim_measure_work, jiffies);
}
-int dim_core_measure(int baseline_init)
+static void measure_work_cb(struct work_struct *work)
+{
+ dim_measure_task_measure(DIM_MEASURE, &dim_core_handle);
+ queue_delayed_measure_work();
+}
+
+static void baseline_work_cb(struct work_struct *work)
+{
+ dim_measure_task_measure(DIM_BASELINE, &dim_core_handle);
+ queue_delayed_measure_work();
+}
+
+/* trigger a measurement and wait for it to complete */
+int dim_core_measure_blocking(void)
{
int ret = 0;
@@ -180,125 +151,103 @@ int dim_core_measure(int baseline_init)
/* clean the running work */
flush_delayed_work(&dim_measure_work);
cancel_delayed_work_sync(&dim_measure_work);
-
- if (dim_core_status_get() == DIM_NO_BASELINE)
- baseline_init = 1;
-
- if (baseline_init) {
- mutex_lock(&dim_core_baseline_lock);
- dim_core_status_set(DIM_BASELINE_RUNNING);
- ret = do_baseline();
- mutex_unlock(&dim_core_baseline_lock);
- if (ret < 0)
- goto out;
- } else {
- dim_core_status_set(DIM_MEASURE_RUNNING);
- }
-
+ /* queue and flush measure work */
queue_delayed_work(dim_work_queue, &dim_measure_work, 0);
flush_delayed_work(&dim_measure_work);
-out:
- dim_core_status_set(ret < 0 ? DIM_ERROR : DIM_PROTECTED);
+
+ /* check error status */
+ if (dim_measure_status_error(&dim_core_handle))
+ ret = -EFAULT;
+
mutex_unlock(&dim_core_measure_lock);
return ret;
}
-int dim_core_measure_init(const char *alg_name)
+/* trigger a dynamic baseline and wait for it to complete */
+int dim_core_baseline_blocking(void)
{
int ret = 0;
- /* 1. check the measure parameter */
- if (measure_log_capacity < MEASURE_LOG_CAP_MIN ||
- measure_log_capacity > MEASURE_LOG_CAP_MAX) {
- dim_err("invalid measure_log_capacity parameter\n");
- return -ERANGE;
- }
+ if (!mutex_trylock(&dim_core_measure_lock))
+ return -EBUSY;
- if (measure_schedule > MEASURE_SCHEDULE_MAX) {
- dim_err("invalid measure_schedule parameter\n");
- return -ERANGE;
- }
+ /* clean the running work */
+ flush_delayed_work(&dim_measure_work);
+ cancel_delayed_work_sync(&dim_measure_work);
- if (measure_interval > DIM_INTERVAL_MAX) {
- dim_err("invalid measure_interval parameter\n");
- return -ERANGE;
- }
+ /* queue and flush baseline work */
+ queue_work(dim_work_queue, &dim_baseline_work);
+ flush_work(&dim_baseline_work);
- if (measure_pcr > DIM_PCR_MAX) {
- dim_err("invalid measure_pcr parameter\n");
- return -ERANGE;
- }
+ /* check error status */
+ if (dim_measure_status_error(&dim_core_handle))
+ ret = -EFAULT;
- /* 2. init measure hash algorithm */
- ret = dim_hash_init(alg_name, &dim_core_hash);
- if (ret < 0) {
- dim_err("failed to initialize hash algorithm: %d\n", ret);
- goto err;
- }
+ mutex_unlock(&dim_core_measure_lock);
+ return ret;
+}
- /* 3. init TPM, dont break if init fail */
- if (measure_pcr > 0) {
- ret = dim_tpm_init(&dim_core_tpm, HASH_ALGO_SHA256);
- if (ret < 0)
- dim_warn("failed to initialize tpm chip: %d\n", ret);
- }
+int dim_core_measure_init(struct dim_measure_cfg *cfg, unsigned int interval)
+{
+ int ret = 0;
- /* 4. init measurement status */
- ret = dim_core_status_init();
- if (ret < 0) {
- dim_err("failed to initialize dim status: %d\n", ret);
- goto err;
- }
+ /* set the special baseline memory functions */
+ cfg->dyn_malloc = dim_mem_pool_alloc;
+ cfg->dyn_free = dim_mem_pool_free;
- /* 5. init baseline data (static and dynamic) */
- ret = dim_core_baseline_init();
+ /* init the measurement handle */
+ ret = dim_measure_init(&dim_core_handle, cfg);
if (ret < 0) {
- dim_err("failed to initialize dim baseline: %d\n", ret);
- goto err;
+ dim_err("failed to init measurement handle\n");
+ return ret;
}
- /* 6. init measure log */
- ret = dim_measure_log_init_tree(&dim_core_log,
- &dim_core_hash, &dim_core_tpm,
- measure_log_capacity, measure_pcr);
+ /* set the baseline prepare function */
+ dim_core_handle.baseline_prepare = baseline_prepare;
+
+ /* register all measurement tasks */
+ ret = dim_measure_tasks_register(&dim_core_handle, dim_core_tasks,
+ DIM_ARRAY_LEN(dim_core_tasks));
if (ret < 0) {
- dim_err("failed to initialize measure log root: %d\n", ret);
+ dim_err("failed to register measure tasks: %d\n", ret);
goto err;
}
- /* 7. init measure work thread */
- INIT_DELAYED_WORK(&dim_measure_work, dim_worker_work_cb);
+ /* init the measurement working thread */
dim_work_queue = create_singlethread_workqueue("dim_core");
if (dim_work_queue == NULL) {
ret = -ENOMEM;
dim_err("failed to create dim work queue: %d\n", ret);
goto err;
}
-
- /* 8. if the interval is set, start to do baseline and measure */
- if (measure_interval) {
- ret = dim_core_measure(1);
+
+ /* init the measurement work */
+ INIT_WORK(&dim_baseline_work, baseline_work_cb);
+ INIT_DELAYED_WORK(&dim_measure_work, measure_work_cb);
+
+ /* if the interval is set, start to do baseline and measure */
+ if (interval) {
+ ret = dim_core_baseline_blocking();
if (ret < 0) {
dim_err("failed to do baseline init: %d\n", ret);
goto err;
}
- dim_core_interval_set(measure_interval);
+ ret = dim_core_interval_set(interval);
+ if (ret < 0)
+ dim_warn("failed to set measure interval: %d\n", ret);
}
- if (measure_schedule)
- measure_schedule_jiffies = msecs_to_jiffies(measure_schedule);
-
return 0;
err:
- dim_hash_destroy(&dim_core_hash);
- dim_tpm_destroy(&dim_core_tpm);
- dim_core_baseline_destroy();
- dim_measure_log_destroy_tree(&dim_core_log);
+ dim_measure_destroy(&dim_core_handle);
+ if (dim_work_queue != NULL)
+ destroy_workqueue(dim_work_queue);
+
return ret;
}
-void dim_core_destroy_measure(void)
+void dim_core_measure_destroy(void)
{
mutex_lock(&dim_core_measure_lock);
if (dim_work_queue != NULL) {
@@ -309,9 +258,7 @@ void dim_core_destroy_measure(void)
destroy_workqueue(dim_work_queue);
}
- dim_measure_log_destroy_tree(&dim_core_log);
- dim_core_baseline_destroy();
+ dim_measure_destroy(&dim_core_handle);
dim_core_policy_destroy();
- dim_tpm_destroy(&dim_core_tpm);
- dim_hash_destroy(&dim_core_hash);
-}
+ mutex_unlock(&dim_core_measure_lock);
+}
\ No newline at end of file
diff --git a/src/core/dim_core_measure.h b/src/core/dim_core_measure.h
index a379cf6..699724a 100644
--- a/src/core/dim_core_measure.h
+++ b/src/core/dim_core_measure.h
@@ -5,75 +5,32 @@
#ifndef __DIM_CORE_MEASURE_H
#define __DIM_CORE_MEASURE_H
-#include "dim_hash.h"
+#include "dim_measure.h"
+
+/* default configuration */
+#define DIM_CORE_HASH_DEFAULT "sha256"
+#define DIM_CORE_LOG_CAP_DEFAULT 100000
/* max measure interval = 1 year */
#define DIM_INTERVAL_MAX (365 * 24 * 60)
#define DIM_MINUTE_TO_SEC (60UL)
#define DIM_MINUTE_TO_NSEC (60UL * 1000 * 1000 * 1000)
-/* max number of kill tasks */
-#define DIM_KILL_TASKS_MAX (1024)
-/* limit of measure parameter */
-#define MEASURE_LOG_CAP_MAX (UINT_MAX)
-#define MEASURE_LOG_CAP_MIN (100)
-#define MEASURE_SCHEDULE_MAX (1000)
-/* max size of x86 */
-#define DIM_JUMP_LABEL_NOP_SIZE_MAX 5
-
-struct vm_text_area {
- struct mm_struct *mm;
- struct vm_area_struct *vma_start;
- struct vm_area_struct *vma_end;
-};
-
-struct task_measure_ctx {
- int baseline; /* measure or baseline init */
- char path_buf[PATH_MAX];
- const char *path;
- struct task_struct *task; /* current measured task */
- bool task_kill;
- bool task_measure;
-};
-struct task_kill_ctx {
- struct task_struct **buf;
- int len;
- int size;
- int ret;
-};
+extern struct dim_measure dim_core_handle;
-typedef int (*task_measurer)(struct task_struct *, struct task_measure_ctx *);
+/* global init and destroy */
+int dim_core_measure_init(struct dim_measure_cfg *cfg, unsigned int interval);
+void dim_core_measure_destroy(void);
-extern struct dim_hash dim_core_hash;
-extern struct dim_measure_log_tree dim_core_log;
-extern struct dim_tpm dim_core_tpm;
-extern unsigned int measure_log_capacity;
-extern unsigned int measure_schedule;
-extern unsigned int measure_interval;
-extern unsigned int measure_pcr;
-extern unsigned long measure_schedule_jiffies;
-
-int dim_core_measure_init(const char *alg_name);
-void dim_core_destroy_measure(void);
-int dim_core_measure(int baseline_init);
+/* control function for measurement parameters */
+const char *dim_core_status_print(void);
long dim_core_interval_get(void);
int dim_core_interval_set(unsigned int p);
long dim_core_tampered_action_get(void);
int dim_core_tampered_action_set(unsigned int p);
-int dim_core_measure_kernel(int baseline_init);
-int dim_core_measure_module(int baseline_init);
-int dim_core_measure_task(int baseline_init);
-
-int dim_core_add_measure_log(const char *name,
- struct dim_digest *digest,
- int flag);
-int dim_core_check_kernel_digest(int baseline_init,
- const char *name,
- struct dim_digest *digest);
-int dim_core_check_user_digest(int baseline_init,
- const char *name,
- struct dim_digest *digest,
- int *log_flag);
+/* measurement trigger functions */
+int dim_core_measure_blocking(void);
+int dim_core_baseline_blocking(void);
-#endif
+#endif
\ No newline at end of file
diff --git a/src/core/dim_core_measure_common.c b/src/core/dim_core_measure_common.c
deleted file mode 100644
index 406ed3f..0000000
--- a/src/core/dim_core_measure_common.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
- */
-
-#include "dim_hash.h"
-#include "dim_tpm.h"
-#include "dim_measure_log.h"
-#include "dim_baseline.h"
-
-#include "dim_core.h"
-#include "dim_core_measure.h"
-#include "dim_core_baseline.h"
-
-int dim_core_add_measure_log(const char *name, struct dim_digest *digest, int flag)
-{
- int ret = dim_measure_log_add(&dim_core_log, name, digest, flag);
- if (ret < 0 && ret != -EEXIST) {
- dim_err("failed to add measure log of %s: %d\n", name, ret);
- return ret;
- }
-
- return 0;
-}
-
-int dim_core_check_kernel_digest(int baseline_init,
- const char *name,
- struct dim_digest *digest)
-{
- int ret = 0;
- struct dim_digest digest_static = { 0 };
-
- /* in the measure stage, do nothing if baseline matched */
- if (!baseline_init &&
- !dim_core_match_dynamic_baseline(name, DIM_BASELINE_KERNEL, digest)) {
- dim_err("mismatch dynamic baseline of kernel %s\n", name);
- return dim_core_add_measure_log(name, digest, LOG_TAMPERED);
- }
-
- /* in the baseline init stage */
- /* 1. add digest to dynamic baseline */
- ret = dim_core_add_dynamic_baseline(name, DIM_BASELINE_KERNEL, digest);
- if (ret < 0)
- return ret;
-
- /* 2. search digest from static baseline */
- ret = dim_core_search_static_baseline(name, DIM_BASELINE_KERNEL, &digest_static);
- if (ret < 0)
- /* 2.1. if not find, log the dynamic baseline */
- return dim_core_add_measure_log(name, digest, LOG_NO_SATIC_BASELINE);
-
- /* 2.2. if find, log the static baseline */
- return dim_core_add_measure_log(name, &digest_static, LOG_STATIC_BASELINE);
-}
-
-int dim_core_check_user_digest(int baseline_init,
- const char *name,
- struct dim_digest *digest,
- int *log_flag)
-{
- int ret = 0;
- struct dim_digest digest_static = { 0 };
-
- /* in the measure stage, do nothing if baseline matched */
- if (!baseline_init &&
- !dim_core_match_dynamic_baseline(name, DIM_BASELINE_USER, digest)) {
- dim_warn("mismatch dynamic baseline of user process %s\n", name);
- return dim_core_add_measure_log(name, digest, LOG_TAMPERED);
- }
-
- /* in the baseline init stage */
- /* 1. add digest to dynamic baseline */
- ret = dim_core_add_dynamic_baseline(name, DIM_BASELINE_USER, digest);
- if (ret < 0)
- return ret;
-
- /* 2. search digest from static baseline */
- ret = dim_core_search_static_baseline(name, DIM_BASELINE_USER, &digest_static);
- if (ret < 0) /* 2.1. if not find, log the dynamic baseline */
- return dim_core_add_measure_log(name, digest, LOG_NO_SATIC_BASELINE);
-
- /* 2.2. if find, compare with the static baseline */
- if (dim_core_match_static_baseline(name, DIM_BASELINE_USER, digest))
- return dim_core_add_measure_log(name, digest, LOG_STATIC_BASELINE);
-
- dim_warn("mismatch static baseline of user process %s\n", name);
- return dim_core_add_measure_log(name, digest, LOG_TAMPERED);
-}
diff --git a/src/core/dim_core_mem_pool.c b/src/core/dim_core_mem_pool.c
index a16b7bb..160f819 100644
--- a/src/core/dim_core_mem_pool.c
+++ b/src/core/dim_core_mem_pool.c
@@ -4,7 +4,8 @@
#include <linux/mm.h>
-#include "dim_core.h"
+#include "dim_utils.h"
+
#include "dim_core_mem_pool.h"
static struct gen_pool *dim_pool = NULL;
diff --git a/src/core/dim_core_policy.c b/src/core/dim_core_policy.c
index 0e7fbf3..50ebcf7 100644
--- a/src/core/dim_core_policy.c
+++ b/src/core/dim_core_policy.c
@@ -14,7 +14,6 @@
#include "dim_utils.h"
#include "dim_rb.h"
-#include "dim_core.h"
#include "dim_core_sig.h"
#include "dim_core_policy.h"
@@ -67,7 +66,7 @@ static int policy_add(int obj, int key, const char *val, int action)
int ret = 0;
struct dim_policy *policy = NULL;
- policy = kmalloc(sizeof(struct dim_policy), GFP_KERNEL);
+ policy = dim_kmalloc_gfp(sizeof(struct dim_policy));
if (policy == NULL)
return -ENOMEM;
@@ -112,7 +111,7 @@ static int policy_add_path(const char *path, int action)
return ret;
/* Try to get the absolute path */
- path_buf = kmalloc(PATH_MAX, GFP_KERNEL);
+ path_buf = dim_kmalloc_gfp(PATH_MAX);
if (path_buf == NULL)
return -ENOMEM;
diff --git a/src/core/dim_core_policy.h b/src/core/dim_core_policy.h
index 48c6f41..2baab12 100644
--- a/src/core/dim_core_policy.h
+++ b/src/core/dim_core_policy.h
@@ -5,6 +5,8 @@
#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
diff --git a/src/core/dim_core_sig.c b/src/core/dim_core_sig.c
index aae323c..70a3469 100644
--- a/src/core/dim_core_sig.c
+++ b/src/core/dim_core_sig.c
@@ -14,7 +14,6 @@
#include "dim_hash.h"
#include "dim_utils.h"
-#include "dim_core.h"
#include "dim_core_sig.h"
static struct key *dim_core_keyring = NULL;
@@ -27,7 +26,7 @@ static char *add_suffix(const char *str, const char *suffix)
char *buf = NULL;
len = strlen(str) + strlen(suffix) + 1;
- buf = kmalloc(len, GFP_KERNEL);
+ buf = dim_kmalloc_gfp(len);
if (buf == NULL)
return NULL;
diff --git a/src/core/dim_core_static_baseline.c b/src/core/dim_core_static_baseline.c
index 0d99f7b..f23dbce 100644
--- a/src/core/dim_core_static_baseline.c
+++ b/src/core/dim_core_static_baseline.c
@@ -17,10 +17,9 @@
#include "dim_hash.h"
#include "dim_baseline.h"
-#include "dim_core.h"
#include "dim_core_sig.h"
#include "dim_core_policy.h"
-#include "dim_core_baseline.h"
+#include "dim_core_measure.h"
#include "dim_core_static_baseline.h"
static bool match_policy(const char *name, int type)
@@ -110,7 +109,8 @@ static int parse_simple_baseline_line(char* line, int line_no)
if (!match_policy(line_str, type))
return 0;
- ret = dim_core_add_static_baseline(line_str, type, &digest);
+ ret = dim_measure_static_baseline_add(&dim_core_handle, line_str,
+ type, &digest);
if (ret < 0)
dim_warn("failed to add static baseline at line %d: %d\n",
line_no, ret);
@@ -128,11 +128,11 @@ static int
static bool
#endif
static_baseline_load(struct dir_context *__ctx,
- const char *name,
- int name_len,
- loff_t offset,
- unsigned long long ino,
- unsigned d_type)
+ const char *name,
+ int name_len,
+ loff_t offset,
+ unsigned long long ino,
+ unsigned d_type)
{
struct readdir_ctx *ctx = container_of(__ctx, typeof(*ctx), ctx);
int ret;
diff --git a/src/core/dim_core_static_baseline.h b/src/core/dim_core_static_baseline.h
index bec37d6..af4d1f9 100644
--- a/src/core/dim_core_static_baseline.h
+++ b/src/core/dim_core_static_baseline.h
@@ -5,6 +5,8 @@
#ifndef __DIM_CORE_STATIC_BASELINE_H
#define __DIM_CORE_STATIC_BASELINE_H
+#include "dim_measure.h"
+
#define DIM_STATIC_BASELINE_ROOT "/etc/dim/digest_list"
#define DIM_STATIC_BASELINE_LINE_MAX 10000
diff --git a/src/core/dim_core_status.c b/src/core/dim_core_status.c
deleted file mode 100644
index 3b8c08a..0000000
--- a/src/core/dim_core_status.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
- */
-
-#include "dim_status.h"
-
-#include "dim_core.h"
-#include "dim_core_status.h"
-
-static const char* dim_core_status_name[DIM_STATUS_LAST] = {
- [DIM_OFF] = "DIM_OFF",
- [DIM_NO_BASELINE] = "DIM_NO_BASELINE",
- [DIM_BASELINE_RUNNING] = "DIM_BASELINE_RUNNING",
- [DIM_MEASURE_RUNNING] = "DIM_MEASURE_RUNNING",
- [DIM_PROTECTED] = "DIM_PROTECTED",
- [DIM_ERROR] = "DIM_ERROR",
-};
-
-struct dim_status dim_core_status = { 0 };
-
-int dim_core_status_init(void)
-{
- int ret = 0;
-
- ret = dim_status_init(&dim_core_status, dim_core_status_name,
- DIM_STATUS_LAST);
- if (ret < 0)
- return ret;
-
- dim_status_set(&dim_core_status, DIM_NO_BASELINE);
- return 0;
-}
-
-void dim_core_status_set(unsigned int status)
-{
- dim_status_set(&dim_core_status, status);
-}
-
-int dim_core_status_get(void)
-{
- return dim_status_get(&dim_core_status);
-}
diff --git a/src/core/dim_core_status.h b/src/core/dim_core_status.h
deleted file mode 100644
index 64b1e94..0000000
--- a/src/core/dim_core_status.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
- */
-
-#ifndef __DIM_CORE_STATUS_H
-#define __DIM_CORE_STATUS_H
-
-enum dim_core_status {
- DIM_OFF,
- DIM_NO_BASELINE,
- DIM_BASELINE_RUNNING,
- DIM_MEASURE_RUNNING,
- DIM_PROTECTED,
- DIM_ERROR,
- DIM_STATUS_LAST,
-};
-
-extern struct dim_status dim_core_status;
-
-int dim_core_status_init(void);
-void dim_core_status_set(unsigned int status);
-int dim_core_status_get(void);
-
-#endif
diff --git a/src/core/dim_core_symbol.c b/src/core/dim_core_symbol.c
index 3da3df2..eeb9240 100644
--- a/src/core/dim_core_symbol.c
+++ b/src/core/dim_core_symbol.c
@@ -6,8 +6,8 @@
#include <linux/jump_label.h>
#include "dim_symbol.h"
+#include "dim_utils.h"
-#include "dim_core.h"
#include "dim_core_symbol.h"
struct dim_core_kallsyms dim_core_kernel_symbol;
diff --git a/src/core/dim_core_measure_kernel.c b/src/core/measure_task/dim_core_measure_kernel.c
similarity index 79%
rename from src/core/dim_core_measure_kernel.c
rename to src/core/measure_task/dim_core_measure_kernel.c
index 3724501..e13e177 100644
--- a/src/core/dim_core_measure_kernel.c
+++ b/src/core/measure_task/dim_core_measure_kernel.c
@@ -8,14 +8,17 @@
#include <linux/vmalloc.h>
#include <linux/utsname.h>
-#include "dim_hash.h"
-#include "dim_measure_log.h"
+#include "dim_measure.h"
-#include "dim_core.h"
#include "dim_core_symbol.h"
#include "dim_core_measure.h"
#include "dim_core_policy.h"
+#include "dim_core_measure_task.h"
+
+/* max size of x86 */
+#define DIM_JUMP_LABEL_NOP_SIZE_MAX 5
+
static int code_cmp(const void *a, const void *b)
{
return *(unsigned long *)a - *(unsigned long *)b;
@@ -46,15 +49,19 @@ static int do_calc_kernel_digest(uintptr_t saddr,
uintptr_t eaddr,
uintptr_t *jcode_sort,
unsigned int jcode_cnt,
+ struct dim_hash *hash,
struct dim_digest *digest)
{
int ret = 0;
unsigned int i;
uintptr_t jump_code;
uintptr_t cur_addr = saddr;
- SHASH_DESC_ON_STACK(shash, dim_core_hash.tfm);
+ SHASH_DESC_ON_STACK(shash, hash->tfm);
+
+ shash->tfm = hash->tfm;
+ if (shash->tfm == NULL)
+ return -EINVAL;
- shash->tfm = dim_core_hash.tfm;
ret = crypto_shash_init(shash);
if (ret < 0)
return ret;
@@ -92,7 +99,7 @@ static int do_calc_kernel_digest(uintptr_t saddr,
return crypto_shash_final(shash, digest->data);
}
-static int calc_kernel_digest(struct dim_digest *digest)
+static int calc_kernel_digest(struct dim_hash *hash, struct dim_digest *digest)
{
int ret = 0;
uintptr_t stext = 0;
@@ -119,7 +126,8 @@ static int calc_kernel_digest(struct dim_digest *digest)
jcode_cnt = 0;
}
- ret = do_calc_kernel_digest(stext, etext, jcode_sort, jcode_cnt, digest);
+ ret = do_calc_kernel_digest(stext, etext, jcode_sort,
+ jcode_cnt, hash, digest);
if (ret < 0)
dim_err("failed to calculate kernel digest: %d\n", ret);
@@ -127,25 +135,35 @@ static int calc_kernel_digest(struct dim_digest *digest)
return ret;
}
-int dim_core_measure_kernel(int baseline_init)
+static int kernel_text_measure(int mode, struct dim_measure *m)
{
int ret = 0;
const char *kr = init_uts_ns.name.release;
- struct dim_digest digest = { .algo = dim_core_hash.algo };
+ struct dim_digest digest = {
+ .algo = m->hash.algo,
+ };
+
+ if (m == NULL)
+ return -EINVAL;
if (!dim_core_policy_match(DIM_POLICY_OBJ_KERNEL_TEXT,
DIM_POLICY_KEY_NAME, kr))
return 0;
- ret = calc_kernel_digest(&digest);
+ ret = calc_kernel_digest(&m->hash, &digest);
if (ret < 0) {
dim_err("failed to calculate kernel digest: %d\n", ret);
return ret;
}
- ret = dim_core_check_kernel_digest(baseline_init, kr, &digest);
+ ret = dim_measure_process_dynamic_result(m, mode, kr, &digest, NULL);
if (ret < 0)
dim_err("failed to check kernel digest: %d\n", ret);
return ret;
}
+
+struct dim_measure_task dim_core_measure_task_kernel_text = {
+ .name = "dim_core_measure_task_kernel_text",
+ .measure = kernel_text_measure,
+};
diff --git a/src/core/dim_core_measure_module.c b/src/core/measure_task/dim_core_measure_module.c
similarity index 64%
rename from src/core/dim_core_measure_module.c
rename to src/core/measure_task/dim_core_measure_module.c
index 4c4726e..497d3a4 100644
--- a/src/core/dim_core_measure_module.c
+++ b/src/core/measure_task/dim_core_measure_module.c
@@ -10,13 +10,19 @@
#include "dim_baseline.h"
#include "dim_measure_log.h"
-#include "dim_core.h"
#include "dim_core_measure.h"
-#include "dim_core_baseline.h"
#include "dim_core_policy.h"
#include "dim_core_symbol.h"
+#include "dim_core_measure_task.h"
+
+struct module_text_measure_ctx {
+ struct dim_measure *m;
+ int mode;
+};
+
static int calculate_module_digest(const char *name,
+ struct dim_hash *hash,
struct dim_digest *digest)
{
int ret = 0;
@@ -44,11 +50,11 @@ static int calculate_module_digest(const char *name,
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
ret = dim_hash_calculate(mod->core_layout.base,
mod->core_layout.text_size,
- &dim_core_hash, digest);
+ hash, digest);
#else
ret = dim_hash_calculate(mod->mem[MOD_TEXT].base,
mod->mem[MOD_TEXT].size,
- &dim_core_hash, digest);
+ hash, digest);
#endif
module_put(mod);
return ret;
@@ -57,7 +63,7 @@ static int calculate_module_digest(const char *name,
static int measure_module(struct dim_policy *policy, void *data)
{
int ret = 0;
- int baseline_init = *(int *)data;
+ struct module_text_measure_ctx *ctx = data;
const char *mod_name = policy->val;
struct dim_digest digest = { 0 };
@@ -66,27 +72,41 @@ static int measure_module(struct dim_policy *policy, void *data)
return 0;
/* if module is not inserted in baseline_init stage, ignore it */
- if (!baseline_init &&
- dim_core_search_dynamic_baseline(mod_name, DIM_BASELINE_KERNEL,
- &digest) < 0)
+ if (ctx->mode == DIM_MEASURE &&
+ dim_measure_dynamic_baseline_search(ctx->m, mod_name,
+ DIM_BASELINE_KERNEL, &digest) < 0)
return 0;
- digest.algo = dim_core_hash.algo;
- ret = calculate_module_digest(mod_name, &digest);
+ digest.algo = ctx->m->hash.algo;
+ ret = calculate_module_digest(mod_name, &ctx->m->hash, &digest);
if (ret < 0) {
dim_err("fail to calculate digest of module %s: %d\n",
mod_name, ret);
return ret == -ENOENT ? 0 : ret;
}
- ret = dim_core_check_kernel_digest(baseline_init, mod_name, &digest);
+ ret = dim_measure_process_dynamic_result(ctx->m, ctx->mode,
+ mod_name, &digest, NULL);
if (ret < 0)
- dim_err("fail to check kernel digest: %d\n", ret);
+ dim_err("failed to check module digest: %d\n", ret);
return 0;
}
-int dim_core_measure_module(int baseline_init)
+static int module_text_measure(int mode, struct dim_measure *m)
{
- return dim_core_policy_walk(measure_module, &baseline_init);
+ struct module_text_measure_ctx ctx = {
+ .m = m,
+ .mode = mode,
+ };
+
+ if (m == NULL)
+ return -EINVAL;
+
+ return dim_core_policy_walk(measure_module, &ctx);
}
+
+struct dim_measure_task dim_core_measure_task_module_text = {
+ .name = "dim_core_measure_task_module_text",
+ .measure = module_text_measure,
+};
diff --git a/src/core/dim_core_measure_task.c b/src/core/measure_task/dim_core_measure_task.c
similarity index 88%
rename from src/core/dim_core_measure_task.c
rename to src/core/measure_task/dim_core_measure_task.c
index 6ab60d1..f240ddc 100644
--- a/src/core/dim_core_measure_task.c
+++ b/src/core/measure_task/dim_core_measure_task.c
@@ -16,11 +16,39 @@
#include "dim_measure_log.h"
#include "dim_baseline.h"
-#include "dim_core.h"
#include "dim_core_symbol.h"
#include "dim_core_policy.h"
#include "dim_core_measure.h"
-#include "dim_core_baseline.h"
+
+#include "dim_core_measure_task.h"
+
+/* max number of kill tasks */
+#define DIM_KILL_TASKS_MAX (1024)
+
+struct vm_text_area {
+ struct mm_struct *mm;
+ struct vm_area_struct *vma_start;
+ struct vm_area_struct *vma_end;
+};
+
+struct task_measure_ctx {
+ struct dim_measure *m;
+ int mode;
+ char path_buf[PATH_MAX];
+ const char *path;
+ struct task_struct *task; /* current measured task */
+ bool task_kill;
+ bool task_measure;
+};
+
+struct task_kill_ctx {
+ struct task_struct **buf;
+ int len;
+ int size;
+ int ret;
+};
+
+typedef int (*task_measurer)(struct task_struct *, struct task_measure_ctx *);
static struct file *get_vm_file(struct vm_area_struct *vma)
{
@@ -167,7 +195,7 @@ static int kill_task_tree(struct task_struct *tsk)
const int def_size = 32;
struct task_kill_ctx ctx = { .size = def_size };
- ctx.buf = kmalloc(def_size * sizeof(struct task_struct *), GFP_KERNEL);
+ ctx.buf = dim_kmalloc_gfp(def_size * sizeof(struct task_struct *));
if (ctx.buf == NULL)
return -ENOMEM;
@@ -197,12 +225,12 @@ static bool vm_file_match_policy(struct file *vm_file,
return false;
}
- if (ctx->baseline)
+ if (ctx->mode == DIM_BASELINE)
return dim_core_policy_match(DIM_POLICY_OBJ_BPRM_TEXT,
DIM_POLICY_KEY_PATH, ctx->path);
- return dim_core_search_dynamic_baseline(ctx->path, DIM_BASELINE_USER,
- &dig) == 0;
+ return dim_measure_dynamic_baseline_search(ctx->m, ctx->path,
+ DIM_BASELINE_USER, &dig) == 0;
}
static int update_vma_digest(struct vm_area_struct *vma_start,
@@ -258,8 +286,8 @@ static int check_user_digest(struct dim_digest *digest,
int log_flag = 0;
int action = 0;
- ret = dim_core_check_user_digest(ctx->baseline, ctx->path,
- digest, &log_flag);
+ ret = dim_measure_process_static_result(ctx->m, ctx->mode, ctx->path,
+ digest, &log_flag);
if (ret < 0) {
dim_err("failed to check user digest: %d\n", ret);
return ret;
@@ -281,10 +309,12 @@ static int measure_anon_text_vma(struct vm_area_struct *vma,
struct task_measure_ctx *ctx)
{
int ret = 0;
- struct dim_digest digest = { .algo = dim_core_hash.algo };
- SHASH_DESC_ON_STACK(shash, dim_core_hash.tfm);
+ struct dim_digest digest = {
+ .algo = ctx->m->hash.algo,
+ };
+ SHASH_DESC_ON_STACK(shash, ctx->hash.tfm);
- shash->tfm = dim_core_hash.tfm;
+ shash->tfm = ctx->hash.tfm;
ret = crypto_shash_init(shash);
if (ret < 0)
return ret;
@@ -333,10 +363,12 @@ static int measure_task_module_file_text(struct vm_area_struct *vma,
int ret = 0;
struct vm_area_struct *v = vma;
struct vm_area_struct *v_end = NULL;
- struct dim_digest digest = { .algo = dim_core_hash.algo };
- SHASH_DESC_ON_STACK(shash, dim_core_hash.tfm);
+ struct dim_digest digest = {
+ .algo = ctx->m->hash.algo
+ };
+ SHASH_DESC_ON_STACK(shash, ctx->m->hash.tfm);
- shash->tfm = dim_core_hash.tfm;
+ shash->tfm = ctx->m->hash.tfm;
ret = crypto_shash_init(shash);
if (ret < 0)
return ret;
@@ -434,8 +466,8 @@ out:
}
/* do schedule if this task is measured */
- if (ctx->task_measure && measure_schedule)
- schedule_timeout_uninterruptible(measure_schedule_jiffies);
+ if (ctx->task_measure)
+ dim_measure_schedule(ctx->m);
return 0;
}
@@ -508,18 +540,23 @@ static int walk_tasks(task_measurer f, struct task_measure_ctx *ctx)
return 0;
}
-int dim_core_measure_task(int baseline_init)
+static int user_text_measure(int mode, struct dim_measure *m)
{
- int ret = 0;
struct task_measure_ctx *ctx = NULL;
- ctx = kzalloc(sizeof(struct task_measure_ctx), GFP_KERNEL);
+ if (m == NULL)
+ return -EINVAL;
+
+ ctx = vmalloc(sizeof(struct task_measure_ctx));
if (ctx == NULL)
return -ENOMEM;
- ctx->baseline = baseline_init;
- ret = walk_tasks(measure_task, ctx);
- kfree(ctx);
- return ret;
+ ctx->mode = mode;
+ ctx->m = m;
+ return walk_tasks(measure_task, ctx);
}
+struct dim_measure_task dim_core_measure_task_user_text = {
+ .name = "dim_core_measure_task_user_text",
+ .measure = user_text_measure,
+};
diff --git a/src/core/measure_task/dim_core_measure_task.h b/src/core/measure_task/dim_core_measure_task.h
new file mode 100644
index 0000000..0e26af2
--- /dev/null
+++ b/src/core/measure_task/dim_core_measure_task.h
@@ -0,0 +1,8 @@
+#ifndef __DIM_CORE_MEASURE_TASK_H
+#define __DIM_CORE_MEASURE_TASK_H
+
+extern struct dim_measure_task dim_core_measure_task_module_text;
+extern struct dim_measure_task dim_core_measure_task_kernel_text;
+extern struct dim_measure_task dim_core_measure_task_user_text;
+
+#endif
diff --git a/src/measure/dim_measure.c b/src/measure/dim_measure.c
new file mode 100644
index 0000000..06e9bb5
--- /dev/null
+++ b/src/measure/dim_measure.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#include "dim_measure.h"
+
+static int cfg_check(struct dim_measure_cfg *cfg)
+{
+ if (cfg->log_cap < MEASURE_LOG_CAP_MIN ||
+ cfg->log_cap > MEASURE_LOG_CAP_MAX) {
+ dim_err("invalid log capacity: %d\n", cfg->log_cap);
+ return -ERANGE;
+ }
+
+ if (cfg->schedule_ms > MEASURE_SCHEDULE_MAX) {
+ dim_err("invalid measure schedule: %d\n", cfg->schedule_ms);
+ return -ERANGE;
+ }
+
+ if (cfg->pcr > DIM_PCR_MAX) {
+ dim_err("invalid TPM pcr number: %d\n", cfg->pcr);
+ return -ERANGE;
+ }
+
+ return 0;
+}
+
+int dim_measure_init(struct dim_measure *m, struct dim_measure_cfg *cfg)
+{
+ int ret = 0;
+
+ if (m == NULL || cfg == NULL || cfg_check(cfg) < 0)
+ return -EINVAL;
+
+ INIT_LIST_HEAD(&m->task_list);
+
+ /* 1. init hash algorithm */
+ ret = dim_hash_init(cfg->alg_name, &m->hash);
+ if (ret < 0) {
+ dim_err("failed to init hash algorithm: %d\n", ret);
+ goto err;
+ }
+
+ /* 2. init TPM, dont break if init fail */
+ if (cfg->pcr > 0) {
+ ret = dim_tpm_init(&m->tpm, HASH_ALGO_SHA256);
+ if (ret < 0)
+ dim_warn("failed to init tpm chip: %d\n", ret);
+ } else {
+ memset(&m->tpm, 0, sizeof(struct dim_tpm));
+ }
+
+ /* 3. init baseline data (static and dynamic) */
+ ret = dim_baseline_init_tree(cfg->sta_malloc, cfg->sta_free,
+ &m->static_baseline);
+ if (ret < 0) {
+ dim_err("failed to init static baseline root: %d\n", ret);
+ goto err;
+ }
+
+ ret = dim_baseline_init_tree(cfg->dyn_malloc, cfg->dyn_free,
+ &m->dynamic_baseline);
+ if (ret < 0) {
+ dim_err("failed to init dynamic baseline root: %d\n", ret);
+ goto err;
+ }
+
+ /* 4. init measure log */
+ ret = dim_measure_log_init_tree(&m->log, &m->hash, &m->tpm,
+ cfg->log_cap, cfg->pcr);
+ if (ret < 0) {
+ dim_err("failed to init measure log: %d\n", ret);
+ goto err;
+ }
+
+ /* 5. set measure schedule time */
+ m->schedule_jiffies = cfg->schedule_ms == 0 ? 0 :
+ msecs_to_jiffies(cfg->schedule_ms);
+
+ /* 6. set initial status */
+ atomic_set(&m->status, MEASURE_STATUS_NO_BASELINE);
+ return 0;
+err:
+ dim_measure_destroy(m);
+ return ret;
+}
+
+void dim_measure_destroy(struct dim_measure *m)
+{
+ if (m == NULL)
+ return;
+
+ mutex_lock(&m->measure_lock);
+ dim_measure_log_destroy_tree(&m->log);
+ dim_baseline_destroy_tree(&m->static_baseline);
+ dim_baseline_destroy_tree(&m->dynamic_baseline);
+ dim_tpm_destroy(&m->tpm);
+ dim_hash_destroy(&m->hash);
+ mutex_unlock(&m->measure_lock);
+}
diff --git a/src/measure/dim_measure.h b/src/measure/dim_measure.h
new file mode 100644
index 0000000..d2ca326
--- /dev/null
+++ b/src/measure/dim_measure.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#ifndef __DIM_MEASURE_H
+#define __DIM_MEASURE_H
+
+#include <linux/list.h>
+#include <linux/mutex.h>
+
+#include "dim_baseline.h"
+#include "dim_hash.h"
+#include "dim_measure_log.h"
+#include "dim_tpm.h"
+#include "dim_utils.h"
+
+#define DIM_MEASURE 0
+#define DIM_BASELINE 1
+
+/* limit of measure parameter */
+#define MEASURE_LOG_CAP_MAX (UINT_MAX)
+#define MEASURE_LOG_CAP_MIN (100)
+#define MEASURE_SCHEDULE_MAX (1000)
+
+/* status of measurement */
+enum dim_measure_status {
+ MEASURE_STATUS_OFF,
+ MEASURE_STATUS_NO_BASELINE,
+ MEASURE_STATUS_BASELINE_RUNNING,
+ MEASURE_STATUS_MEASURE_RUNNING,
+ MEASURE_STATUS_PROTECTED,
+ MEASURE_STATUS_ERROR,
+ MEASURE_STATUS_LAST,
+};
+
+/* the common configuration for measurement */
+struct dim_measure_cfg {
+ /* hash algorithm for measurement */
+ char *alg_name;
+ /* schedule time (ms) after one valid measurement */
+ unsigned int schedule_ms;
+ /* PCR number for TPM extending */
+ unsigned int pcr;
+ /* max measure log number */
+ unsigned int log_cap;
+ /* memory function for baseline store */
+ malloc_func dyn_malloc;
+ free_func dyn_free;
+ malloc_func sta_malloc;
+ free_func sta_free;
+};
+
+/* the dim measurement global handle */
+struct dim_measure {
+ /* schedule time (jittfies) after one valid measurement */
+ unsigned long schedule_jiffies;
+ /* lock to prevent concurrent measurement */
+ struct mutex measure_lock;
+ /* measure hash algorithm */
+ struct dim_hash hash;
+ /* TPM chip handle */
+ struct dim_tpm tpm;
+ /* measure log */
+ struct dim_measure_log_tree log;
+ /* measure baseline */
+ struct dim_baseline_tree static_baseline;
+ struct dim_baseline_tree dynamic_baseline;
+ /* function called before doing baseline */
+ int (*baseline_prepare)(struct dim_measure *m);
+ /* measure status */
+ atomic_t status;
+ /* task list */
+ struct list_head task_list;
+};
+
+/* the task definition for measurement function */
+struct dim_measure_task {
+ struct list_head node;
+ /* task name for log printing */
+ const char *name;
+ /* measure function */
+ int (*measure)(int mode, struct dim_measure *m);
+};
+
+/* functions for dim measure handle */
+int dim_measure_init(struct dim_measure *m, struct dim_measure_cfg *cfg);
+void dim_measure_destroy(struct dim_measure *m);
+
+/* functions for measurement results processing */
+int dim_measure_process_static_result(struct dim_measure *m, int mode,
+ const char *name,
+ struct dim_digest *digest,
+ int *log_flag);
+int dim_measure_process_dynamic_result(struct dim_measure *m, int mode,
+ const char *name,
+ struct dim_digest *digest,
+ int *log_flag);
+int dim_measure_static_baseline_add(struct dim_measure *m,
+ const char *name, int type,
+ struct dim_digest *digest);
+int dim_measure_dynamic_baseline_search(struct dim_measure *m,
+ const char *name, int type,
+ struct dim_digest *digest);
+/* functions for dim measurement task */
+int dim_measure_tasks_register(struct dim_measure *m,
+ struct dim_measure_task **tasks,
+ unsigned int num);
+void dim_measure_task_measure(int mode, struct dim_measure *m);
+
+/* functions for dim measurement status */
+const char *dim_measure_status_print(struct dim_measure *m);
+bool dim_measure_status_error(struct dim_measure *m);
+
+/* tool functions used for implementing measure tasks */
+void dim_measure_schedule(struct dim_measure *m);
+
+#endif
diff --git a/src/measure/dim_measure_baseline.c b/src/measure/dim_measure_baseline.c
new file mode 100644
index 0000000..dc358a7
--- /dev/null
+++ b/src/measure/dim_measure_baseline.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#include <linux/utsname.h>
+
+#include "dim_measure.h"
+
+static inline bool is_valid_mode(int mode)
+{
+ return mode == DIM_BASELINE || mode == DIM_MEASURE;
+}
+
+static const char *process_static_name(const char *name, int type,
+ char *buf, int buf_len)
+{
+ const char *kr = init_uts_ns.name.release;
+
+ if (type != DIM_BASELINE_KERNEL || strcmp(name, kr) == 0)
+ return name;
+
+ /* name of kernel module has a kernel prefix in static baseline */
+ if (sprintf(buf, "%s/%s", kr, name) < 0)
+ return NULL;
+
+ return buf;
+}
+
+static int static_baseline_add(struct dim_measure *m,
+ const char *name, int type,
+ struct dim_digest *digest)
+{
+ int ret = dim_baseline_add(&m->static_baseline, name, type, digest);
+ if (ret < 0 && ret != -EEXIST) {
+ dim_err("failed to add static baseline of %s\n", name);
+ return ret;
+ }
+
+ return 0;
+}
+
+static int dynamic_baseline_add(struct dim_measure *m,
+ const char *name, int type,
+ struct dim_digest *digest)
+{
+ int ret = dim_baseline_add(&m->dynamic_baseline, name, type, digest);
+ if (ret < 0 && ret != -EEXIST) {
+ dim_err("failed to add dynamic baseline of %s\n", name);
+ return ret;
+ }
+
+ return 0;
+}
+
+static bool static_baseline_match(struct dim_measure *m,
+ const char *name, int type,
+ struct dim_digest *digest)
+{
+ char buf[NAME_MAX + NAME_MAX + 1 + 1] = { 0 };
+ return dim_baseline_match(&m->static_baseline,
+ process_static_name(name, type, buf, sizeof(buf)),
+ type, digest);
+}
+
+static bool dynamic_baseline_match(struct dim_measure *m,
+ const char *name, int type,
+ struct dim_digest *digest)
+{
+ return dim_baseline_match(&m->dynamic_baseline, name, type, digest);
+}
+
+static int static_baseline_search(struct dim_measure *m,
+ const char *name, int type,
+ struct dim_digest *digest)
+{
+ char buf[NAME_MAX + NAME_MAX + 1 + 1] = { 0 };
+ return dim_baseline_search_digest(&m->static_baseline,
+ process_static_name(name, type, buf, sizeof(buf)),
+ type, digest);
+}
+
+static int dynamic_baseline_search(struct dim_measure *m,
+ const char *name, int type,
+ struct dim_digest *digest)
+{
+ return dim_baseline_search_digest(&m->dynamic_baseline, name,
+ type, digest);
+}
+
+static int measure_log_add(struct dim_measure *m, const char *name,
+ struct dim_digest *digest, int flag)
+{
+ int ret = dim_measure_log_add(&m->log, name, digest, flag);
+ if (ret < 0 && ret != -EEXIST) {
+ dim_err("failed to add measure log of %s: %d\n", name, ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+/* check dynamic measurement result in baseline stage */
+static int process_dynamic_baseline(struct dim_measure *m, const char *name,
+ struct dim_digest *digest, int *log_flag) // TODO
+{
+ int ret = 0;
+ struct dim_digest digest_static = { 0 };
+ int def_flag = log_flag == NULL ? LOG_NO_SATIC_BASELINE : *log_flag;
+
+ if (m == NULL || name == NULL || digest == NULL)
+ return -EINVAL;
+
+ /* 1. add digest to dynamic baseline */
+ ret = dynamic_baseline_add(m, name, DIM_BASELINE_KERNEL, digest);
+ if (ret < 0)
+ return ret;
+
+ /* 2. search digest from static baseline */
+ ret = static_baseline_search(m, name, DIM_BASELINE_KERNEL, &digest_static);
+ if (ret < 0)
+ /* 2.1. if not find, log the dynamic baseline */
+ return measure_log_add(m, name, digest, def_flag);
+
+ /* 2.2. if find, log the static baseline */
+ return measure_log_add(m, name, &digest_static, LOG_STATIC_BASELINE);
+}
+
+/* process dynamic measurement result in measure stage */
+static int process_dynamic_measure(struct dim_measure *m, const char *name,
+ struct dim_digest *digest, int *log_flag)
+{
+ if (m == NULL || name == NULL || digest == NULL)
+ return -EINVAL;
+
+ if(!dynamic_baseline_match(m, name, DIM_BASELINE_KERNEL, digest)) {
+ dim_err("mismatch dynamic baseline of kernel %s\n", name);
+ if (log_flag != NULL) // TODO
+ *log_flag = LOG_TAMPERED;
+
+ return measure_log_add(m, name, digest, LOG_TAMPERED);
+ }
+
+ return 0;
+}
+
+/* process static measurement result in baseline stage */
+static int process_static_baseline(struct dim_measure *m, const char *name,
+ struct dim_digest *digest, int *log_flag)
+{
+ int ret = 0;
+ struct dim_digest digest_static = { 0 };
+
+ /* 1. add digest to dynamic baseline */
+ ret = dynamic_baseline_add(m, name, DIM_BASELINE_USER, digest);
+ if (ret < 0)
+ return ret;
+
+ /* 2. search digest from static baseline */
+ ret = static_baseline_search(m, name, DIM_BASELINE_USER, &digest_static);
+ if (ret < 0) /* 2.1. if not find, log the dynamic baseline */
+ return measure_log_add(m, name, digest, LOG_NO_SATIC_BASELINE);
+
+ /* 2.2. if find, compare with the static baseline */
+ if (static_baseline_match(m, name, DIM_BASELINE_USER, digest))
+ return measure_log_add(m, name, digest, LOG_STATIC_BASELINE);
+
+ dim_warn("mismatch static baseline of user process %s\n", name);
+ if (log_flag != NULL) // TODO
+ *log_flag = LOG_TAMPERED;
+
+ return measure_log_add(m, name, digest, LOG_TAMPERED);
+}
+
+/* process static measurement result in measure stage */
+static int process_static_measure(struct dim_measure *m, const char *name,
+ struct dim_digest *digest, int *log_flag)
+{
+ if(!dynamic_baseline_match(m, name, DIM_BASELINE_USER, digest)) {
+ dim_err("mismatch dynamic baseline of user %s\n", name);
+ if (log_flag != NULL) // TODO
+ *log_flag = LOG_TAMPERED;
+
+ return measure_log_add(m, name, digest, LOG_TAMPERED);
+ }
+
+ return 0;
+}
+
+int dim_measure_process_static_result(struct dim_measure *m, int mode,
+ const char *name,
+ struct dim_digest *digest,
+ int *log_flag)
+{
+ if (m == NULL || name == NULL || digest == NULL ||
+ !is_valid_mode(mode))
+ return -EINVAL;
+
+ return mode == DIM_BASELINE ?
+ process_static_baseline(m, name, digest, log_flag) :
+ process_static_measure(m, name, digest, log_flag);
+}
+
+int dim_measure_process_dynamic_result(struct dim_measure *m, int mode,
+ const char *name,
+ struct dim_digest *digest,
+ int *log_flag)
+{
+ if (m == NULL || name == NULL || digest == NULL ||
+ !is_valid_mode(mode))
+ return -EINVAL;
+
+ return mode == DIM_BASELINE ?
+ process_dynamic_baseline(m, name, digest, log_flag) :
+ process_dynamic_measure(m, name, digest, log_flag);
+}
+
+int dim_measure_static_baseline_add(struct dim_measure *m,
+ const char *name, int type,
+ struct dim_digest *digest)
+{
+ if (m == NULL)
+ return -EINVAL;
+
+ return static_baseline_add(m, name, type, digest);
+}
+
+int dim_measure_dynamic_baseline_search(struct dim_measure *m,
+ const char *name, int type,
+ struct dim_digest *digest)
+{
+ if (m == NULL)
+ return -EINVAL;
+
+ return dynamic_baseline_search(m, name, type, digest);
+}
diff --git a/src/measure/dim_measure_status.c b/src/measure/dim_measure_status.c
new file mode 100644
index 0000000..28cfb43
--- /dev/null
+++ b/src/measure/dim_measure_status.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#include "dim_measure.h"
+
+static const char* status_name[MEASURE_STATUS_LAST + 1] = {
+ [MEASURE_STATUS_OFF] = "DIM_OFF",
+ [MEASURE_STATUS_NO_BASELINE] = "DIM_NO_BASELINE",
+ [MEASURE_STATUS_BASELINE_RUNNING] = "DIM_BASELINE_RUNNING",
+ [MEASURE_STATUS_MEASURE_RUNNING] = "DIM_MEASURE_RUNNING",
+ [MEASURE_STATUS_PROTECTED] = "DIM_PROTECTED",
+ [MEASURE_STATUS_ERROR] = "DIM_ERROR",
+ [MEASURE_STATUS_LAST] = "DIM_UNKNOWN",
+};
+
+const char *dim_measure_status_print(struct dim_measure *m)
+{
+ int status = 0;
+
+ if (m == NULL)
+ return status_name[MEASURE_STATUS_LAST];
+
+ status = atomic_read(&m->status);
+ if (status < 0 || status >= MEASURE_STATUS_LAST)
+ status = MEASURE_STATUS_LAST;
+
+ return status_name[status];
+}
+
+bool dim_measure_status_error(struct dim_measure *m)
+{
+ return atomic_read(&m->status) == MEASURE_STATUS_ERROR;
+}
diff --git a/src/measure/dim_measure_task.c b/src/measure/dim_measure_task.c
new file mode 100644
index 0000000..ed97388
--- /dev/null
+++ b/src/measure/dim_measure_task.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#include "dim_measure.h"
+
+static void call_measure_func(int mode, struct dim_measure_task *t,
+ struct dim_measure *m)
+{
+ int ret = 0;
+
+ if (t->measure == NULL) {
+ dim_warn("no measure function in %s task", t->name);
+ return;
+ }
+
+ dim_info("start to call %s measure task\n", t->name);
+ ret = t->measure(mode, m);
+ if (ret < 0) {
+ dim_err("failed to call measure task %s: %d\n", t->name, ret);
+ return;
+ }
+
+ dim_info("succeed to call measure task %s\n", t->name);
+}
+
+void dim_measure_task_measure(int mode, struct dim_measure *m)
+{
+ int ret = 0;
+ int status = 0;
+ struct dim_measure_task *task = NULL;
+
+ if (m == NULL)
+ return;
+
+ mutex_lock(&m->measure_lock);
+ status = atomic_read(&m->status);
+ if (mode == DIM_MEASURE && status != MEASURE_STATUS_PROTECTED) {
+ dim_info("no baseline, do baseline init instead\n");
+ mode = DIM_BASELINE;
+ }
+
+ atomic_set(&m->status, mode == DIM_BASELINE ?
+ MEASURE_STATUS_BASELINE_RUNNING :
+ MEASURE_STATUS_MEASURE_RUNNING);
+
+ if (mode == DIM_BASELINE && m->baseline_prepare != NULL) {
+ ret = m->baseline_prepare(m);
+ if (ret < 0) {
+ atomic_set(&m->status, MEASURE_STATUS_ERROR);
+ mutex_unlock(&m->measure_lock);
+ return;
+ }
+ }
+
+ list_for_each_entry(task, &m->task_list, node)
+ call_measure_func(mode, task, m);
+
+ atomic_set(&m->status, MEASURE_STATUS_PROTECTED);
+ mutex_unlock(&m->measure_lock);
+}
+
+static int task_register(struct dim_measure *m, struct dim_measure_task *t)
+{
+ if (t == NULL || t->name == NULL || t->measure == NULL)
+ return -EINVAL;
+
+ list_add_tail(&t->node, &m->task_list);
+ return 0;
+}
+
+int dim_measure_tasks_register(struct dim_measure *m,
+ struct dim_measure_task **tasks,
+ unsigned int num)
+{
+ int ret = 0;
+ int i = 0;
+
+ if (m == NULL || tasks == NULL || num == 0)
+ return -EINVAL;
+
+ for (; i < num; i++) {
+ ret = task_register(m, tasks[i]);
+ if (ret < 0)
+ return ret;
+
+ dim_info("register measure task: %s\n", tasks[i]->name);
+ }
+
+ return 0;
+}
diff --git a/src/measure/dim_measure_utils.c b/src/measure/dim_measure_utils.c
new file mode 100644
index 0000000..049d362
--- /dev/null
+++ b/src/measure/dim_measure_utils.c
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#include "dim_measure.h"
+
+void dim_measure_schedule(struct dim_measure *m)
+{
+ if (m == NULL || m->schedule_jiffies == 0)
+ return;
+
+ schedule_timeout_uninterruptible(m->schedule_jiffies);
+}
diff --git a/src/monitor/dim_monitor.h b/src/monitor/dim_monitor.h
index ce3c676..8f1f0f7 100644
--- a/src/monitor/dim_monitor.h
+++ b/src/monitor/dim_monitor.h
@@ -5,37 +5,24 @@
#ifndef __DIM_MONITOR_H
#define __DIM_MONITOR_H
-#include "dim_status.h"
-#include "dim_utils.h"
+#include "dim_measure.h"
#define DIM_MONITOR_HASH_DEFAULT "sha256"
-#define DIM_MODULE "dim_monitor"
+#define DIM_MONITOR_LOG_CAP_DEFAULT 100000
+
#define DIM_CORE "dim_core"
#define DIM_CORE_TEXT "dim_core.text"
#define DIM_CORE_DATA "dim_core.data"
-/* limit of measure parameter */
-#define MEASURE_LOG_CAP_MAX (UINT_MAX)
-#define MEASURE_LOG_CAP_MIN (100)
-
-enum dim_monitor_status {
- DIM_MONITOR_READY,
- DIM_MONITOR_RUNNING,
- DIM_MONITOR_PROTECTED,
- DIM_MONITOR_ERROR,
- DIM_MONITOR_STATUS_LAST,
-};
-
-extern struct dim_status dim_monitor_status;
-extern struct dim_measure_log_tree dim_monitor_log;
-extern unsigned int measure_log_capacity;
-extern unsigned int measure_pcr;
+extern struct dim_measure dim_monitor_handle;
void dim_monitor_destroy_fs(void);
int dim_monitor_create_fs(void);
-int dim_monitor_measure_init(const char *alg_name);
-void dim_monitor_destroy_measure(void);
-int dim_monitor_measure(int baseline);
+int dim_monitor_measure_init(struct dim_measure_cfg *cfg);
+void dim_monitor_measure_destroy(void);
+int dim_monitor_measure_blocking(void);
+int dim_monitor_baseline_blocking(void);
+const char *dim_monitor_status_print(void);
-#endif
\ No newline at end of file
+#endif
diff --git a/src/monitor/dim_monitor_fs.c b/src/monitor/dim_monitor_fs.c
index 5535e59..8bb3120 100644
--- a/src/monitor/dim_monitor_fs.c
+++ b/src/monitor/dim_monitor_fs.c
@@ -7,6 +7,8 @@
#include "dim_entry.h"
#include "dim_utils.h"
+#include "dim_measure.h"
+
#include "dim_monitor.h"
extern struct dim_entry *dim_root_entry(void);
@@ -15,25 +17,25 @@ extern struct dim_entry *dim_root_entry(void);
* monitor trigger interface
* dim_entry struct: dim_monitor_measure_entry
* file entry name: monitor_run
- * function: dim_monitor_measure(0)
+ * function: dim_monitor_measure_blocking()
*/
-dim_trigger_entry(dim_monitor_measure, monitor_run, dim_monitor_measure, 0);
+dim_trigger_entry(dim_monitor_measure, monitor_run, dim_monitor_measure_blocking);
/*
* monitor baseline trigger interface
* dim_entry struct: dim_monitor_baseline_entry
* file entry name: monitor_baseline
- * function: dim_monitor_measure(1)
+ * function: dim_monitor_baseline_blocking()
*/
-dim_trigger_entry(dim_monitor_baseline, monitor_baseline, dim_monitor_measure, 1);
+dim_trigger_entry(dim_monitor_baseline, monitor_baseline, dim_monitor_baseline_blocking);
/*
- * status read interface
- * dim_entry struct: dim_monitor_status_entry
+ * status print interface
+ * dim_entry struct: dim_status_entry
* file entry name: monitor_status
- * data to read: dim_monitor_status
+ * print function: dim_core_status_print
*/
-dim_status_entry(dim_monitor_status, monitor_status, &dim_monitor_status);
+dim_string_print_entry(dim_monitor_status, monitor_status, dim_monitor_status_print);
/*
* measure log read interface
@@ -42,7 +44,7 @@ dim_status_entry(dim_monitor_status, monitor_status, &dim_monitor_status);
* status to read: dim_measure_log_tree
*/
dim_measure_log_entry(dim_monitor_log, monitor_ascii_runtime_measurements,
- &dim_monitor_log);
+ &dim_monitor_handle.log);
static struct dim_entry *dim_monitor_files[] = {
&dim_monitor_measure_entry,
@@ -66,4 +68,4 @@ int dim_monitor_create_fs(void)
return -ENOENT;
return dim_entry_create_list(dim_monitor_files, len, dim_root->dentry);
-}
\ No newline at end of file
+}
diff --git a/src/monitor/dim_monitor_main.c b/src/monitor/dim_monitor_main.c
index 0165d3a..4b3505d 100644
--- a/src/monitor/dim_monitor_main.c
+++ b/src/monitor/dim_monitor_main.c
@@ -4,18 +4,24 @@
#include <linux/module.h>
+#include "dim_measure.h"
+
#include "dim_monitor.h"
#include "dim_monitor_symbol.h"
-static char *measure_hash = NULL;
+/* common measurement configuration */
+static struct dim_measure_cfg cfg = {
+ .alg_name = DIM_MONITOR_HASH_DEFAULT,
+ .log_cap = DIM_MONITOR_LOG_CAP_DEFAULT,
+};
-module_param(measure_log_capacity, uint, 0);
+module_param_named(measure_log_capacity, cfg.log_cap, uint, 0);
MODULE_PARM_DESC(measure_log_capacity, "Max number of measure log");
-module_param(measure_hash, charp, 0);
+module_param_named(measure_hash, cfg.alg_name, charp, 0);
MODULE_PARM_DESC(measure_hash, "Hash algorithm for measurement");
-module_param(measure_pcr, uint, 0);
+module_param_named(measure_pcr, cfg.pcr, uint, 0);
MODULE_PARM_DESC(measure_pcr, "TPM PCR index to extend measure log");
static int __init dim_monitor_init(void)
@@ -28,8 +34,7 @@ static int __init dim_monitor_init(void)
goto err;
}
- ret = dim_monitor_measure_init(measure_hash == NULL ?
- DIM_MONITOR_HASH_DEFAULT : measure_hash);
+ ret = dim_monitor_measure_init(&cfg);
if (ret < 0) {
dim_err("fail to initialize dim measurement: %d\n", ret);
goto err;
@@ -43,17 +48,17 @@ static int __init dim_monitor_init(void)
return 0;
err:
- dim_monitor_destroy_measure();
+ dim_monitor_measure_destroy();
dim_monitor_destroy_fs();
return ret;
}
static void __exit dim_monitor_exit(void)
{
- dim_monitor_destroy_measure();
+ dim_monitor_measure_destroy();
dim_monitor_destroy_fs();
}
module_init(dim_monitor_init);
module_exit(dim_monitor_exit);
-MODULE_LICENSE("GPL");
\ No newline at end of file
+MODULE_LICENSE("GPL");
diff --git a/src/monitor/dim_monitor_measure.c b/src/monitor/dim_monitor_measure.c
index 10a1e7b..f21ed0e 100644
--- a/src/monitor/dim_monitor_measure.c
+++ b/src/monitor/dim_monitor_measure.c
@@ -2,253 +2,94 @@
* Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
*/
-#include <linux/fs.h>
#include <linux/version.h>
#include <linux/genalloc.h>
-#include "dim_baseline.h"
-#include "dim_hash.h"
-#include "dim_measure_log.h"
-#include "dim_tpm.h"
-#include "dim_utils.h"
+#include "dim_measure.h"
#include "dim_core_mem_pool.h"
#include "dim_monitor.h"
#include "dim_monitor_symbol.h"
-static const char *dim_monitor_status_name[DIM_MONITOR_STATUS_LAST] = {
- [DIM_MONITOR_READY] = "ready",
- [DIM_MONITOR_RUNNING] = "running",
- [DIM_MONITOR_PROTECTED] = "protected",
- [DIM_MONITOR_ERROR] = "error",
-};
-
-static struct dim_hash dim_monitor_hash = { 0 };
-static struct dim_tpm dim_monitor_tpm = { 0 };
-static struct dim_baseline_tree dim_monitor_baseline = { 0 };
+#include "measure_task/dim_monitor_measure_task.h"
-struct dim_status dim_monitor_status = { 0 };
-struct dim_measure_log_tree dim_monitor_log = { 0 };
+/* measurement tasks */
+static struct dim_measure_task *dim_core_tasks[] = {
+ &dim_monitor_measure_data,
+ &dim_monitor_measure_text,
+};
-unsigned int measure_log_capacity = 100000;
-unsigned int measure_pcr = 0;
+/* the global measurement handle */
+struct dim_measure dim_monitor_handle = { 0 };
-/* lock to prevent concurrent measurement */
+/* lock to prevent trigger multiple measurement */
DEFINE_MUTEX(dim_monitor_measure_lock);
-static void dim_monitor_status_set(unsigned int status)
+const char *dim_monitor_status_print(void)
{
- dim_status_set(&dim_monitor_status, status);
+ return dim_measure_status_print(&dim_monitor_handle);
}
-static int add_measure_log(const char *name, struct dim_digest *digest, int type)
+int dim_monitor_measure_blocking(void)
{
- int ret = 0;
-
- ret = dim_measure_log_add(&dim_monitor_log, name, digest, type);
- if (ret < 0 && ret != -EEXIST) {
- dim_err("fail to add measure log of %s: %d\n", name, ret);
- return ret;
- }
+ if (!mutex_trylock(&dim_monitor_measure_lock))
+ return -EBUSY;
+ dim_measure_task_measure(DIM_MEASURE, &dim_monitor_handle);
+ mutex_unlock(&dim_monitor_measure_lock);
return 0;
}
-static int add_baseline(const char *name, struct dim_digest *digest, int type)
-{
- int ret = 0;
-
- ret = dim_baseline_add(&dim_monitor_baseline, name, type, digest);
- if (ret < 0) {
- dim_err("fail to add dim baseline of %s: %d\n", name, ret);
- return ret;
- }
-
- return add_measure_log(name, digest, LOG_DYNAMIC_BASELINE);
-}
-
-static int check_digest(const char *name, struct dim_digest *digest, int type)
-{
- return dim_baseline_match(&dim_monitor_baseline, name, type, digest) ?
- 0 : add_measure_log(name, digest, LOG_TAMPERED);
-}
-
-static void calculate_chunk(struct gen_pool *pool,
- struct gen_pool_chunk *chunk,
- void *data)
-{
- struct shash_desc *shash = (struct shash_desc *)data;
-
- if (chunk == NULL || shash == NULL)
- return;
-
- (void)crypto_shash_update(shash, (char *)chunk->start_addr,
- chunk->end_addr - chunk->start_addr);
-}
-
-static int measure_data(int baseline_init)
-{
- int ret = 0;
- struct dim_digest digest = { .algo = dim_monitor_hash.algo };
-
- SHASH_DESC_ON_STACK(shash, dim_monitor_hash.tfm);
- shash->tfm = dim_monitor_hash.tfm;
- ret = crypto_shash_init(shash);
- if (ret < 0)
- return ret;
-
- dim_mem_pool_walk_chunk(calculate_chunk, shash);
- ret = crypto_shash_final(shash, digest.data);
- if (ret < 0)
- return ret;
-
- return baseline_init ?
- add_baseline(DIM_CORE_DATA, &digest, DIM_BASELINE_DATA) :
- check_digest(DIM_CORE_DATA, &digest, DIM_BASELINE_DATA);
-}
-
-static int measure_text(int baseline_init)
+int dim_monitor_baseline_blocking(void)
{
- int ret = 0;
- struct module *mod = NULL;
- struct dim_digest digest = { 0 };
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
- mutex_lock(&module_mutex);
- mod = find_module(DIM_CORE);
-#else
- rcu_read_lock_sched();
- mod = dim_monitor_kernel_symbol.find_module(DIM_CORE);
-#endif
- if (mod == NULL || mod->state != MODULE_STATE_LIVE ||
- !try_module_get(mod))
- mod = NULL; /* target module not exist or is not alive */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
- mutex_unlock(&module_mutex);
-#else
- rcu_read_unlock_sched();
-#endif
- if (mod == NULL)
- return -ENOENT;
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
- ret = dim_hash_calculate(mod->core_layout.base,
- mod->core_layout.text_size,
- &dim_monitor_hash, &digest);
-#else
- ret = dim_hash_calculate(mod->mem[MOD_TEXT].base,
- mod->mem[MOD_TEXT].size,
- &dim_monitor_hash, &digest);
-#endif
- module_put(mod);
- if (ret < 0)
- return ret;
-
- return baseline_init ?
- add_baseline(DIM_CORE_TEXT, &digest, DIM_BASELINE_KERNEL) :
- check_digest(DIM_CORE_TEXT, &digest, DIM_BASELINE_KERNEL);
-}
-
-int dim_monitor_measure(int baseline_init)
-{
- int ret = 0;
-
if (!mutex_trylock(&dim_monitor_measure_lock))
return -EBUSY;
- dim_monitor_status_set(DIM_MONITOR_RUNNING);
- dim_info("start dim monitor measure, baseline_init = %d\n",
- baseline_init);
-
- if (baseline_init) {
- dim_baseline_destroy_tree(&dim_monitor_baseline);
- dim_measure_log_refresh(&dim_monitor_log);
- }
-
- ret = measure_text(baseline_init);
- if (ret < 0) {
- dim_err("fail to measure dim_core text");
- goto out;
- }
-
- ret = measure_data(baseline_init);
- if (ret < 0)
- dim_err("fail to measure dim_core data");
-out:
+ dim_measure_task_measure(DIM_BASELINE, &dim_monitor_handle);
mutex_unlock(&dim_monitor_measure_lock);
- dim_monitor_status_set(ret < 0 ? DIM_MONITOR_ERROR :
- DIM_MONITOR_PROTECTED);
- return ret;
+ return 0;
}
-int dim_monitor_measure_init(const char *alg_name)
+static int baseline_prepare(struct dim_measure *m)
{
- int ret = 0;
-
- /* 1. check the measure parameter */
- if (measure_log_capacity < MEASURE_LOG_CAP_MIN ||
- measure_log_capacity > MEASURE_LOG_CAP_MAX) {
- dim_err("invalid measure_log_capacity parameter\n");
- return -ERANGE;
- }
-
- if (measure_pcr > DIM_PCR_MAX) {
- dim_err("invalid measure_pcr parameter\n");
- return -ERANGE;
- }
-
- /* init TPM, dont break if init fail */
- if (measure_pcr > 0) {
- ret = dim_tpm_init(&dim_monitor_tpm, HASH_ALGO_SHA256);
- if (ret < 0)
- dim_warn("fail to initialize tpm chip: %d\n", ret);
- }
+ dim_baseline_destroy_tree(&m->static_baseline);
+ dim_baseline_destroy_tree(&m->dynamic_baseline);
+ dim_measure_log_refresh(&m->log);
+ return 0;
+}
- ret = dim_hash_init(alg_name, &dim_monitor_hash);
- if (ret < 0) {
- dim_err("fail to initialize hash algorithm: %d\n", ret);
- goto err;
- }
+int dim_monitor_measure_init(struct dim_measure_cfg *cfg)
+{
+ int ret = 0;
- ret = dim_status_init(&dim_monitor_status, dim_monitor_status_name,
- DIM_MONITOR_STATUS_LAST);
+ /* init the measurement handle */
+ ret = dim_measure_init(&dim_monitor_handle, cfg);
if (ret < 0) {
- dim_err("fail to initialize status: %d\n", ret);
- goto err;
+ dim_err("failed to init measurement handle\n");
+ return ret;
}
- ret = dim_baseline_init_tree(dim_kmalloc_gfp, dim_kfree,
- &dim_monitor_baseline);
- if (ret < 0) {
- dim_err("fail to initialize static baseline root: %d\n", ret);
- goto err;
- }
+ /* set the baseline prepare function */
+ dim_monitor_handle.baseline_prepare = baseline_prepare;
- ret = dim_measure_log_init_tree(&dim_monitor_log, &dim_monitor_hash,
- &dim_monitor_tpm, measure_log_capacity,
- measure_pcr);
+ /* register all measurement tasks */
+ ret = dim_measure_tasks_register(&dim_monitor_handle, dim_core_tasks,
+ DIM_ARRAY_LEN(dim_core_tasks));
if (ret < 0) {
- dim_err("fail to initialize measure log: %d\n", ret);
+ dim_err("failed to register measure tasks: %d\n", ret);
goto err;
}
- dim_status_set(&dim_monitor_status, DIM_MONITOR_READY);
return 0;
err:
- dim_measure_log_destroy_tree(&dim_monitor_log);
- dim_baseline_destroy_tree(&dim_monitor_baseline);
- dim_hash_destroy(&dim_monitor_hash);
- dim_tpm_destroy(&dim_monitor_tpm);
+ dim_measure_destroy(&dim_monitor_handle);
return ret;
}
-void dim_monitor_destroy_measure(void)
+void dim_monitor_measure_destroy(void)
{
mutex_lock(&dim_monitor_measure_lock);
- dim_measure_log_destroy_tree(&dim_monitor_log);
- dim_baseline_destroy_tree(&dim_monitor_baseline);
- dim_hash_destroy(&dim_monitor_hash);
- dim_tpm_destroy(&dim_monitor_tpm);
+ dim_measure_destroy(&dim_monitor_handle);
+ mutex_unlock(&dim_monitor_measure_lock);
}
diff --git a/src/monitor/dim_monitor_symbol.c b/src/monitor/dim_monitor_symbol.c
index 975c140..4054099 100644
--- a/src/monitor/dim_monitor_symbol.c
+++ b/src/monitor/dim_monitor_symbol.c
@@ -30,4 +30,4 @@ int dim_monitor_kallsyms_init(void)
#else
return 0;
#endif
-}
\ No newline at end of file
+}
diff --git a/src/monitor/measure_task/dim_monitor_measure_data.c b/src/monitor/measure_task/dim_monitor_measure_data.c
new file mode 100644
index 0000000..5762dc1
--- /dev/null
+++ b/src/monitor/measure_task/dim_monitor_measure_data.c
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#include "dim_measure.h"
+#include "dim_core_mem_pool.h"
+
+#include "dim_monitor.h"
+
+#include "dim_monitor_measure_task.h"
+
+static void calculate_chunk(struct gen_pool *pool,
+ struct gen_pool_chunk *chunk,
+ void *data)
+{
+ struct shash_desc *shash = (struct shash_desc *)data;
+
+ if (chunk == NULL || shash == NULL)
+ return;
+
+ (void)crypto_shash_update(shash, (char *)chunk->start_addr,
+ chunk->end_addr - chunk->start_addr);
+}
+
+static int module_text_measure(int mode, struct dim_measure *m)
+{
+ int ret = 0;
+ int log_flag = LOG_DYNAMIC_BASELINE;
+ struct dim_digest digest = {
+ .algo = m->hash.algo,
+ };
+
+ SHASH_DESC_ON_STACK(shash, m->hash.tfm);
+ shash->tfm = m->hash.tfm;
+
+ ret = crypto_shash_init(shash);
+ if (ret < 0)
+ return ret;
+
+ dim_mem_pool_walk_chunk(calculate_chunk, shash);
+ ret = crypto_shash_final(shash, digest.data);
+ if (ret < 0)
+ return ret;
+
+ ret = dim_measure_process_dynamic_result(m, mode, DIM_CORE_DATA,
+ &digest, &log_flag);
+ if (ret < 0)
+ dim_err("failed to check dim_core data digest: %d\n", ret);
+
+ return 0;
+}
+
+struct dim_measure_task dim_monitor_measure_data = {
+ .name = "dim_monitor_measure_data",
+ .measure = module_text_measure,
+};
diff --git a/src/monitor/measure_task/dim_monitor_measure_task.h b/src/monitor/measure_task/dim_monitor_measure_task.h
new file mode 100644
index 0000000..326fd48
--- /dev/null
+++ b/src/monitor/measure_task/dim_monitor_measure_task.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#ifndef __DIM_MONITOR_MEASURE_TASK_H
+#define __DIM_MONITOR_MEASURE_TASK_H
+
+extern struct dim_measure_task dim_monitor_measure_data;
+extern struct dim_measure_task dim_monitor_measure_text;
+
+#endif
diff --git a/src/monitor/measure_task/dim_monitor_measure_text.c b/src/monitor/measure_task/dim_monitor_measure_text.c
new file mode 100644
index 0000000..de6c77d
--- /dev/null
+++ b/src/monitor/measure_task/dim_monitor_measure_text.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+
+#include "dim_measure.h"
+
+#include "dim_monitor.h"
+#include "dim_monitor_symbol.h"
+#include "dim_monitor_measure_task.h"
+
+static int module_text_measure(int mode, struct dim_measure *m)
+{
+ int ret = 0;
+ int log_flag = LOG_DYNAMIC_BASELINE;
+ struct module *mod = NULL;
+ struct dim_digest digest = { 0 };
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
+ mutex_lock(&module_mutex);
+ mod = find_module(DIM_CORE);
+#else
+ rcu_read_lock_sched();
+ mod = dim_monitor_kernel_symbol.find_module(DIM_CORE);
+#endif
+ if (mod == NULL || mod->state != MODULE_STATE_LIVE ||
+ !try_module_get(mod))
+ mod = NULL; /* target module not exist or is not alive */
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
+ mutex_unlock(&module_mutex);
+#else
+ rcu_read_unlock_sched();
+#endif
+ if (mod == NULL)
+ return -ENOENT;
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0)
+ ret = dim_hash_calculate(mod->core_layout.base,
+ mod->core_layout.text_size,
+ &m->hash, &digest);
+#else
+ ret = dim_hash_calculate(mod->mem[MOD_TEXT].base,
+ mod->mem[MOD_TEXT].size,
+ &m->hash, &digest);
+#endif
+ module_put(mod);
+ if (ret < 0)
+ return ret;
+
+ ret = dim_measure_process_dynamic_result(m, mode, DIM_CORE_TEXT,
+ &digest, &log_flag);
+ if (ret < 0)
+ dim_err("failed to check dim_core text digest: %d\n", ret);
+
+ return 0;
+}
+
+struct dim_measure_task dim_monitor_measure_text = {
+ .name = "dim_monitor_measure_text",
+ .measure = module_text_measure,
+};
--
2.33.0
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。