diff --git a/backport-Add-memory-debug-in-mem_pool.patch b/backport-Add-memory-debug-in-mem_pool.patch new file mode 100644 index 0000000000000000000000000000000000000000..640e56ced8943c0e1128f9814af3f427f55c64e9 --- /dev/null +++ b/backport-Add-memory-debug-in-mem_pool.patch @@ -0,0 +1,45 @@ +From 2ca49371b548b56d192f571866fb28c548746ad1 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Mon, 19 Feb 2024 10:35:34 +0800 +Subject: [PATCH 20/26] Add memory debug in mem_pool + +--- + src/core/dim_core_mem_pool.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/src/core/dim_core_mem_pool.c b/src/core/dim_core_mem_pool.c +index 974033f..a9f0177 100644 +--- a/src/core/dim_core_mem_pool.c ++++ b/src/core/dim_core_mem_pool.c +@@ -4,6 +4,7 @@ + + #include + ++#include "dim_safe_func.h" + #include "dim_utils.h" + + #include "dim_core_mem_pool.h" +@@ -108,6 +109,9 @@ void *dim_mem_pool_alloc(size_t size) + if (data == NULL) + return NULL; + out: ++ #ifdef DIM_DEBUG_MEMORY_LEAK ++ dim_alloc_debug_inc(); ++ #endif + data->size = mem_size; + return data->data; + } +@@ -130,6 +134,10 @@ void dim_mem_pool_free(const void *data) + } + + gen_pool_free(dim_pool, (uintptr_t)mem, mem->size); ++ ++ #ifdef DIM_DEBUG_MEMORY_LEAK ++ dim_alloc_debug_dec(); ++ #endif + } + + void dim_mem_pool_walk_chunk(pool_chunk_visitor f, void *data) +-- +2.33.0 + diff --git a/backport-Add-safe-wapper-for-some-memory-and-string-functions.patch b/backport-Add-safe-wapper-for-some-memory-and-string-functions.patch new file mode 100644 index 0000000000000000000000000000000000000000..31fb164bfc380e4e3491f087558e8cf99143340b --- /dev/null +++ b/backport-Add-safe-wapper-for-some-memory-and-string-functions.patch @@ -0,0 +1,1088 @@ +From 91fb7cbfd3b2d02c68a54fb7c35efc9d274a1bc6 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Wed, 14 Feb 2024 14:52:29 +0800 +Subject: [PATCH 18/26] Add safe wapper for some memory and string functions + +1. Warp some memory and strings functions to make them more safe. +2. Add detection for memory leakage. + +Signed-off-by: Huaxin Lu +--- + src/Makefile | 4 + + src/common/dim_baseline.c | 5 +- + src/common/dim_baseline.h | 2 +- + src/common/dim_measure_log.c | 17 +-- + src/common/dim_measure_log.h | 4 +- + src/common/dim_safe_func.c | 18 +++ + src/common/dim_safe_func.h | 135 ++++++++++++++++++ + src/common/dim_symbol.c | 3 +- + src/common/dim_tpm.c | 9 +- + src/common/dim_utils.c | 28 +--- + src/common/dim_utils.h | 2 - + src/core/dim_core_main.c | 6 + + src/core/dim_core_mem_pool.c | 2 +- + src/core/dim_core_mem_pool.h | 2 +- + src/core/dim_core_sig.c | 30 ++-- + src/core/policy/dim_core_policy.c | 25 ++-- + src/core/policy/dim_core_policy_complex.c | 11 +- + .../dim_core_static_baseline.c | 6 +- + .../dim_core_static_baseline_complex.c | 2 +- + src/core/tasks/dim_core_measure_kernel.c | 2 +- + .../dim_core_measure_process.c | 18 ++- + .../dim_core_measure_process_elf.c | 22 +-- + .../dim_core_measure_process/dim_vm_hash.c | 7 +- + src/measure/dim_measure_baseline.c | 10 +- + src/monitor/dim_monitor_main.c | 4 + + 25 files changed, 268 insertions(+), 106 deletions(-) + create mode 100644 src/common/dim_safe_func.c + create mode 100644 src/common/dim_safe_func.h + +diff --git a/src/Makefile b/src/Makefile +index 8f4dce8..6782fd1 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -34,6 +34,7 @@ dim_core-objs += common/dim_hash.o + dim_core-objs += common/dim_measure_log.o + dim_core-objs += common/dim_tpm.o + dim_core-objs += common/dim_symbol.o ++dim_core-objs += common/dim_safe_func.o + dim_core-objs += measure/dim_measure.o + dim_core-objs += measure/dim_measure_baseline.o + dim_core-objs += measure/dim_measure_task.o +@@ -55,6 +56,7 @@ 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 += common/dim_safe_func.o + dim_monitor-objs += measure/dim_measure.o + dim_monitor-objs += measure/dim_measure_baseline.o + dim_monitor-objs += measure/dim_measure_task.o +@@ -72,6 +74,8 @@ ccflags-y += -I$(src)/common + ccflags-y += -I$(src)/measure + + ccflags-y += -Wall -Werror -D_FORTIFY_SOURCE=2 -O2 -fstack-protector-strong ++# For check memory leakage ++# ccflags-y += -DDIM_DEBUG_MEMORY_LEAK + + KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) +diff --git a/src/common/dim_baseline.c b/src/common/dim_baseline.c +index ec53b1c..e79458d 100644 +--- a/src/common/dim_baseline.c ++++ b/src/common/dim_baseline.c +@@ -5,6 +5,7 @@ + #include "dim_rb.h" + #include "dim_baseline.h" + #include "dim_utils.h" ++#include "dim_safe_func.h" + + static int dim_baseline_compare(struct dim_baseline *x, + struct dim_baseline *y) +@@ -14,7 +15,7 @@ static int dim_baseline_compare(struct dim_baseline *x, + if (x->type != y->type) + return x->type > y->type ? 1 : -1; + +- ret = strcmp(x->name, y->name); ++ ret = dim_strcmp(x->name, y->name); + if (ret != 0) + return ret; + +@@ -150,7 +151,7 @@ int dim_baseline_init_tree(malloc_func malloc, free_func free, + rwlock_init(&root->lock); + root->rb_root = RB_ROOT; + /* use kmalloc by default */ +- root->malloc = malloc == NULL ? dim_kmalloc_gfp : malloc; ++ root->malloc = malloc == NULL ? dim_kzalloc_gfp : malloc; + root->free = free == NULL ? dim_kfree : free; + return 0; + } +diff --git a/src/common/dim_baseline.h b/src/common/dim_baseline.h +index 6e9d943..345b348 100644 +--- a/src/common/dim_baseline.h ++++ b/src/common/dim_baseline.h +@@ -9,7 +9,7 @@ + #include "dim_hash.h" + + typedef void *(*malloc_func)(size_t); +-typedef void (*free_func)(void*); ++typedef void (*free_func)(const void*); + + enum dim_baseline_type { + DIM_BASELINE_USER, /* baseline of user process */ +diff --git a/src/common/dim_measure_log.c b/src/common/dim_measure_log.c +index b4185d2..b84e635 100644 +--- a/src/common/dim_measure_log.c ++++ b/src/common/dim_measure_log.c +@@ -6,6 +6,7 @@ + + #include "dim_rb.h" + #include "dim_tpm.h" ++#include "dim_safe_func.h" + #include "dim_measure_log.h" + + /* +@@ -102,7 +103,7 @@ static int measure_info_insert(struct dim_measure_name *name, + + static void measure_log_destroy_info(struct dim_measure_log *info) + { +- kfree(info); ++ dim_kfree(info); + } + + static void measure_log_destroy_name(struct dim_measure_name *name) +@@ -114,8 +115,8 @@ static void measure_log_destroy_name(struct dim_measure_name *name) + list_for_each_entry_safe(pos, n, &name->log_root, node) + measure_log_destroy_info(pos); + /* free self */ +- kfree(name->name); +- kfree(name); ++ dim_kfree(name->name); ++ dim_kfree(name); + } + + static int measure_log_create_name(const char *name_str, +@@ -123,13 +124,13 @@ static int measure_log_create_name(const char *name_str, + { + struct dim_measure_name *new = NULL; + +- new = kzalloc(sizeof(struct dim_measure_name), GFP_KERNEL); ++ new = dim_kzalloc_gfp(sizeof(struct dim_measure_name)); + if (new == NULL) + return -ENOMEM; + +- new->name = kstrdup(name_str, GFP_KERNEL); ++ new->name = dim_kstrdup_gfp(name_str); + if (new->name == NULL) { +- kfree(new); ++ dim_kfree(new); + return -ENOMEM; + } + +@@ -145,7 +146,7 @@ static int measure_log_create_info(char pcr, struct dim_digest *digest, + int ret = 0; + struct dim_measure_log *new = NULL; + +- new = kzalloc(sizeof(struct dim_measure_log), GFP_KERNEL); ++ new = dim_kzalloc_gfp(sizeof(struct dim_measure_log)); + if (new == NULL) + return -ENOMEM; + +@@ -153,7 +154,7 @@ static int measure_log_create_info(char pcr, struct dim_digest *digest, + new->type = flag; + ret = dim_digest_copy(&new->digest, digest); + if (ret < 0) { +- kfree(new); ++ dim_kfree(new); + return ret; + } + +diff --git a/src/common/dim_measure_log.h b/src/common/dim_measure_log.h +index 28f8a00..6ea2361 100644 +--- a/src/common/dim_measure_log.h ++++ b/src/common/dim_measure_log.h +@@ -7,7 +7,9 @@ + + #include + #include ++ + #include "dim_hash.h" ++#include "dim_safe_func.h" + + #define DIM_NG "dim-ng" + #define LOG_MAX_LENGTH_PCR 3 +@@ -61,7 +63,7 @@ struct dim_measure_log { + static inline int dim_measure_name_compare(struct dim_measure_name *x, + struct dim_measure_name *y) + { +- return strcmp(x->name, y->name); ++ return dim_strcmp(x->name, y->name); + } + + static inline const char *dim_measure_log_type_to_name(int type) +diff --git a/src/common/dim_safe_func.c b/src/common/dim_safe_func.c +new file mode 100644 +index 0000000..f13168c +--- /dev/null ++++ b/src/common/dim_safe_func.c +@@ -0,0 +1,18 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#include "dim_safe_func.h" ++ ++#ifdef DIM_DEBUG_MEMORY_LEAK ++atomic_t dim_alloc_num = ATOMIC_INIT(0);; ++ ++void dim_check_memory_leak(void) ++{ ++ unsigned int n = atomic_read(&dim_alloc_num); ++ if (n != 0) ++ dim_warn("warning: detect %u memory leakage\n", n); ++ else ++ dim_info("not detect memory leakage\n"); ++} ++#endif +\ No newline at end of file +diff --git a/src/common/dim_safe_func.h b/src/common/dim_safe_func.h +new file mode 100644 +index 0000000..3e97f4e +--- /dev/null ++++ b/src/common/dim_safe_func.h +@@ -0,0 +1,135 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#ifndef __DIM_SAFE_FUNC_H ++#define __DIM_SAFE_FUNC_H ++ ++#include ++#include ++#include ++#include ++ ++#include "dim_utils.h" ++ ++#ifdef DIM_DEBUG_MEMORY_LEAK ++extern atomic_t dim_alloc_num; ++ ++static inline void dim_alloc_debug_inc(void) ++{ ++ atomic_inc(&dim_alloc_num); ++} ++ ++static inline void dim_alloc_debug_dec(void) ++{ ++ atomic_dec(&dim_alloc_num); ++} ++ ++static inline void dim_print_alloc_num(const char *s) ++{ ++ dim_info("%s: dim_alloc_num=%d\n", s, atomic_read(&dim_alloc_num)); ++} ++ ++void dim_check_memory_leak(void); ++#endif ++ ++static inline void *dim_kzalloc_gfp(size_t size) ++{ ++#ifdef DIM_DEBUG_MEMORY_LEAK ++ void *data = kzalloc(size, GFP_KERNEL); ++ if (data != NULL) ++ dim_alloc_debug_inc(); ++ return data; ++#else ++ return kzalloc(size, GFP_KERNEL); ++#endif ++} ++ ++static inline void *dim_kcalloc_gfp(size_t n, size_t size) ++{ ++#ifdef DIM_DEBUG_MEMORY_LEAK ++ void *data = kcalloc(n, size, GFP_KERNEL); ++ if (data != NULL) ++ dim_alloc_debug_inc(); ++ return data; ++#else ++ return kcalloc(n, size, GFP_KERNEL); ++#endif ++} ++ ++static inline void *dim_krealloc_atom(const void *p, size_t new_size) ++{ ++ return krealloc(p, new_size, GFP_ATOMIC); ++} ++ ++static inline void *dim_kmemdup_gfp(const void *src, size_t len) ++{ ++#ifdef DIM_DEBUG_MEMORY_LEAK ++ void *data = kmemdup(src, len, GFP_KERNEL); ++ if (data != NULL) ++ dim_alloc_debug_inc(); ++ return data; ++#else ++ return kmemdup(src, len, GFP_KERNEL); ++#endif ++} ++ ++static inline void dim_kfree(const void *objp) ++{ ++#ifdef DIM_DEBUG_MEMORY_LEAK ++ if (objp != NULL) ++ dim_alloc_debug_dec(); ++#endif ++ kfree(objp); ++} ++ ++static inline void *dim_vzalloc(size_t size) ++{ ++#ifdef DIM_DEBUG_MEMORY_LEAK ++ void *data = vzalloc(size); ++ if (data != NULL) ++ dim_alloc_debug_inc(); ++ return data; ++#else ++ return vzalloc(size); ++#endif ++} ++ ++static inline void dim_vfree(void *data) ++{ ++#ifdef DIM_DEBUG_MEMORY_LEAK ++ if (data != NULL) ++ dim_alloc_debug_dec(); ++#endif ++ vfree(data); ++} ++ ++static inline char *dim_kstrdup_gfp(const char *s) ++{ ++#ifdef DIM_DEBUG_MEMORY_LEAK ++ void *data = kstrdup(s, GFP_KERNEL); ++ if (data != NULL) ++ dim_alloc_debug_inc(); ++ return data; ++#else ++ return kstrdup(s, GFP_KERNEL); ++#endif ++} ++ ++static inline int dim_strcmp(const char *cs, const char *ct) ++{ ++ if (cs == NULL || ct == NULL) ++ return -1; ++ ++ return strcmp(cs, ct); ++} ++ ++static inline int dim_strncmp(const char *cs, const char *ct, size_t count) ++{ ++ if (cs == NULL || ct == NULL) ++ return -1; ++ ++ return strncmp(cs, ct, count); ++} ++ ++#endif +\ No newline at end of file +diff --git a/src/common/dim_symbol.c b/src/common/dim_symbol.c +index 48f6491..63824e6 100644 +--- a/src/common/dim_symbol.c ++++ b/src/common/dim_symbol.c +@@ -4,6 +4,7 @@ + + #include + ++#include "dim_safe_func.h" + #include "dim_symbol.h" + + static int find_kernel_symbol(unsigned long addr, +@@ -34,7 +35,7 @@ DIM_SYMBOL_LOOKUP_FUNC dim_get_symbol_lookup_func(void) + if (ret < 0 || offset > size) + break; + +- if (strcmp(symbol_name, DIM_KALLSYMS_LOOKUP_NAME) == 0) ++ if (dim_strcmp(symbol_name, DIM_KALLSYMS_LOOKUP_NAME) == 0) + return (DIM_SYMBOL_LOOKUP_FUNC)(kaddr - offset); + + if (kaddr == next) { +diff --git a/src/common/dim_tpm.c b/src/common/dim_tpm.c +index 5d983e8..6d3c255 100644 +--- a/src/common/dim_tpm.c ++++ b/src/common/dim_tpm.c +@@ -4,6 +4,7 @@ + + #include + ++#include "dim_safe_func.h" + #include "dim_tpm.h" + + int dim_tpm_init(struct dim_tpm *tpm, int algo) +@@ -15,8 +16,8 @@ int dim_tpm_init(struct dim_tpm *tpm, int algo) + if (tpm->chip == NULL) + return -ENODEV; + +- tpm->digests = kcalloc(tpm->chip->nr_allocated_banks, +- sizeof(struct tpm_digest), GFP_KERNEL); ++ tpm->digests = dim_kcalloc_gfp(tpm->chip->nr_allocated_banks, ++ sizeof(struct tpm_digest)); + if (tpm->digests == NULL) { + ret = -ENOMEM; + goto err; +@@ -40,7 +41,7 @@ int dim_tpm_init(struct dim_tpm *tpm, int algo) + err: + put_device(&tpm->chip->dev); + if (tpm->digests != NULL) { +- kfree(tpm->digests); ++ dim_kfree(tpm->digests); + tpm->digests = NULL; + } + +@@ -72,5 +73,5 @@ void dim_tpm_destroy(struct dim_tpm *tpm) + return; + + put_device(&tpm->chip->dev); +- kfree(tpm->digests); ++ dim_kfree(tpm->digests); + } +\ No newline at end of file +diff --git a/src/common/dim_utils.c b/src/common/dim_utils.c +index 4c99879..598e824 100644 +--- a/src/common/dim_utils.c ++++ b/src/common/dim_utils.c +@@ -5,22 +5,10 @@ + #include + #include + #include +-#include +-#include + ++#include "dim_safe_func.h" + #include "dim_utils.h" + +-void *dim_kmalloc_gfp(size_t size) +-{ +- return kmalloc(size, GFP_KERNEL); +-} +- +-void dim_kfree(void *data) +-{ +- if (data != NULL) +- kfree(data); +-} +- + int dim_get_absolute_path(const char *path, const char **result) + { + int ret = 0; +@@ -35,7 +23,7 @@ int dim_get_absolute_path(const char *path, const char **result) + if (ret < 0) + return ret; + +- buf = dim_kmalloc_gfp(PATH_MAX); ++ buf = dim_kzalloc_gfp(PATH_MAX); + if (buf == NULL) { + ret = -ENOMEM; + goto out; +@@ -47,16 +35,14 @@ int dim_get_absolute_path(const char *path, const char **result) + goto out; + } + +- *result = kstrdup(apath, GFP_KERNEL); ++ *result = dim_kstrdup_gfp(apath); + if (*result == NULL) { + ret = -ENOMEM; + goto out; + } + out: + path_put(&p); +- if (buf != NULL) +- dim_kfree(buf); +- ++ dim_kfree(buf); + return ret; + } + +@@ -72,7 +58,7 @@ bool dim_string_end_with(const char *str, const char *ext) + if (name_len < ext_len) + return false; + +- return strcmp(str + name_len - ext_len, ext) == 0; ++ return dim_strcmp(str + name_len - ext_len, ext) == 0; + } + + int dim_parse_line_buf(char *buf, loff_t len, int (*line_parser)(char *, int, void *), void *data) +@@ -97,7 +83,7 @@ int dim_parse_line_buf(char *buf, loff_t len, int (*line_parser)(char *, int, vo + line = &buf[i + 1]; + } else { + line_len = buf + i - line + 1; +- line_buf = kzalloc(line_len + 1, GFP_KERNEL); ++ line_buf = dim_kzalloc_gfp(line_len + 1); + if (line_buf == NULL) + return -ENOMEM; + +@@ -118,7 +104,7 @@ int dim_parse_line_buf(char *buf, loff_t len, int (*line_parser)(char *, int, vo + } + out: + if (line_buf != NULL) +- kfree(line_buf); ++ dim_kfree(line_buf); + + return ret; + } +diff --git a/src/common/dim_utils.h b/src/common/dim_utils.h +index 5a9f132..8c7d855 100644 +--- a/src/common/dim_utils.h ++++ b/src/common/dim_utils.h +@@ -17,8 +17,6 @@ + #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); +-void dim_kfree(void *data); + 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, void *), void *data); +diff --git a/src/core/dim_core_main.c b/src/core/dim_core_main.c +index ae34e81..c62fa09 100644 +--- a/src/core/dim_core_main.c ++++ b/src/core/dim_core_main.c +@@ -4,6 +4,8 @@ + + #include + ++#include "dim_safe_func.h" ++ + #include "dim_core_policy.h" + #include "dim_core_symbol.h" + #include "dim_core_fs.h" +@@ -99,6 +101,10 @@ static void __exit dim_core_exit(void) + + if (signature) + dim_core_sig_destroy(); ++ ++#ifdef DIM_DEBUG_MEMORY_LEAK ++ dim_check_memory_leak(); ++#endif + } + + module_init(dim_core_init); +diff --git a/src/core/dim_core_mem_pool.c b/src/core/dim_core_mem_pool.c +index 160f819..974033f 100644 +--- a/src/core/dim_core_mem_pool.c ++++ b/src/core/dim_core_mem_pool.c +@@ -112,7 +112,7 @@ out: + return data->data; + } + +-void dim_mem_pool_free(void *data) ++void dim_mem_pool_free(const void *data) + { + struct dim_pool_mem *mem = NULL; + +diff --git a/src/core/dim_core_mem_pool.h b/src/core/dim_core_mem_pool.h +index c566dc8..5c4cdea 100644 +--- a/src/core/dim_core_mem_pool.h ++++ b/src/core/dim_core_mem_pool.h +@@ -25,7 +25,7 @@ typedef void (*pool_chunk_visitor)(struct gen_pool *, + int dim_mem_pool_init(void); + void dim_mem_pool_destroy(void); + void *dim_mem_pool_alloc(size_t size); +-void dim_mem_pool_free(void *data); ++void dim_mem_pool_free(const void *data); + void dim_mem_pool_walk_chunk(pool_chunk_visitor f, void *data); + + #endif +diff --git a/src/core/dim_core_sig.c b/src/core/dim_core_sig.c +index 70a3469..f142050 100644 +--- a/src/core/dim_core_sig.c ++++ b/src/core/dim_core_sig.c +@@ -13,6 +13,7 @@ + + #include "dim_hash.h" + #include "dim_utils.h" ++#include "dim_safe_func.h" + + #include "dim_core_sig.h" + +@@ -26,7 +27,7 @@ static char *add_suffix(const char *str, const char *suffix) + char *buf = NULL; + + len = strlen(str) + strlen(suffix) + 1; +- buf = dim_kmalloc_gfp(len); ++ buf = dim_kzalloc_gfp(len); + if (buf == NULL) + return NULL; + +@@ -39,10 +40,16 @@ static int read_file_root(struct path *root, const char *name, void **buf) + int ret = 0; + struct file *file = NULL; + +- if (root == NULL) +- return kernel_read_file_from_path(name, 0, buf, ++ if (root == NULL) { ++ ret = kernel_read_file_from_path(name, 0, buf, + DIM_CORE_MAX_FILE_SIZE, + NULL, READING_UNKNOWN); ++#ifdef DIM_DEBUG_MEMORY_LEAK ++ if (*buf != NULL) ++ dim_alloc_debug_inc(); ++#endif ++ return ret; ++ } + + file = file_open_root(root, name, O_RDONLY, 0); + if (IS_ERR(file)) +@@ -50,6 +57,10 @@ static int read_file_root(struct path *root, const char *name, void **buf) + + ret = kernel_read_file(file, 0, buf, DIM_CORE_MAX_FILE_SIZE, + NULL, READING_UNKNOWN); ++#ifdef DIM_DEBUG_MEMORY_LEAK ++ if (*buf != NULL) ++ dim_alloc_debug_inc(); ++#endif + (void)filp_close(file, NULL); + return ret; + } +@@ -114,12 +125,10 @@ int dim_read_verify_file(struct path *root, const char *name, void **buf) + sig_size = ret; + ret = dim_core_sig_verify(file_buf, file_size, sig_buf, sig_size); + out: +- if (sig_name != NULL) +- kfree(sig_name); +- if (sig_buf != NULL) +- vfree(sig_buf); +- if (file_buf != NULL && ret < 0) +- vfree(file_buf); ++ dim_kfree(sig_name); ++ dim_vfree(sig_buf); ++ if (ret < 0) ++ dim_vfree(file_buf); + if (ret == 0) { + *buf = file_buf; + ret = file_size; +@@ -172,8 +181,7 @@ int dim_core_sig_init(void) + dim_info("load DIM cert: %s\n", dim_core_key->description); + ret = 0; + err: +- if (data != NULL) +- vfree(data); ++ dim_vfree(data); + if (ret < 0) + key_put(dim_core_keyring); + return ret; +diff --git a/src/core/policy/dim_core_policy.c b/src/core/policy/dim_core_policy.c +index 4d7bcc1..f10a256 100644 +--- a/src/core/policy/dim_core_policy.c ++++ b/src/core/policy/dim_core_policy.c +@@ -11,8 +11,9 @@ + #include + #include + +-#include "dim_utils.h" + #include "dim_rb.h" ++#include "dim_utils.h" ++#include "dim_safe_func.h" + + #include "dim_core_sig.h" + #include "dim_core_policy.h" +@@ -26,13 +27,9 @@ static int dim_policy_compare(struct dim_policy *x, struct dim_policy *y) + + switch (x->obj) { + case DIM_POLICY_OBJ_BPRM_TEXT: +- if (x->path == NULL || y->path == NULL) +- return -1; +- return strcmp(x->path, y->path); ++ return dim_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); ++ return dim_strcmp(x->name, y->name); + case DIM_POLICY_OBJ_KERNEL_TEXT: + return 0; + default: +@@ -60,8 +57,8 @@ void policy_destroy(struct dim_policy *policy) + if (policy == NULL) + return; + +- dim_kfree((char *)policy->name); +- dim_kfree((char *)policy->path); ++ dim_kfree(policy->name); ++ dim_kfree(policy->path); + dim_kfree(policy); + } + +@@ -100,15 +97,15 @@ static int policy_check_add_bprm_text(struct dim_policy *policy) + return 0; + } + +- if (strcmp(apath, policy->path) == 0) { ++ if (dim_strcmp(apath, policy->path) == 0) { + /* the two paths are same, no need to add another policy */ +- dim_kfree((char *)apath); ++ dim_kfree(apath); + return 0; + } + +- p = kmemdup(policy, sizeof(struct dim_policy), GFP_KERNEL); ++ p = dim_kmemdup_gfp(policy, sizeof(struct dim_policy)); + if (p == NULL) { +- dim_kfree((char *)apath); ++ dim_kfree(apath); + return -ENOMEM; + } + +@@ -191,7 +188,7 @@ int dim_core_policy_load(void) + dim_core_policy_destroy(); + } + +- vfree(buf); ++ dim_vfree(buf); + return ret; + } + +diff --git a/src/core/policy/dim_core_policy_complex.c b/src/core/policy/dim_core_policy_complex.c +index b29483d..18a9e58 100644 +--- a/src/core/policy/dim_core_policy_complex.c ++++ b/src/core/policy/dim_core_policy_complex.c +@@ -4,7 +4,9 @@ + + #include + ++#include "dim_rb.h" + #include "dim_utils.h" ++#include "dim_safe_func.h" + + #include "dim_core_policy.h" + +@@ -41,7 +43,7 @@ static const char *dim_policy_action_str[DIM_POLICY_KEY_LAST] = { + + static const char *policy_get_string_value(const char *s) + { +- return kstrdup(s, GFP_KERNEL); ++ return dim_kstrdup_gfp(s); + } + + static int policy_get_action(const char *s) +@@ -121,7 +123,7 @@ static int parse_line(char *line_str, struct dim_policy *policy) + char *p = NULL; + + if ((p = strsep(&line_str, " ")) == NULL || +- strcmp(p, DIM_POLICY_MEASURE) != 0) { ++ dim_strcmp(p, DIM_POLICY_MEASURE) != 0) { + dim_err("invalid policy prefix, must start with %s\n", + DIM_POLICY_MEASURE); + return -EINVAL; +@@ -156,14 +158,13 @@ static int policy_parse_line(char* line, int line_no, void *data) + return -EINVAL; + } + +- policy = dim_kmalloc_gfp(sizeof(struct dim_policy)); ++ policy = dim_kzalloc_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) { ++ policy_destroy(policy); + dim_err("fail to parse policy at line %d: %d\n", line_no, ret); + return ret; + } +diff --git a/src/core/static_baseline/dim_core_static_baseline.c b/src/core/static_baseline/dim_core_static_baseline.c +index 49810f3..e33c67c 100644 +--- a/src/core/static_baseline/dim_core_static_baseline.c ++++ b/src/core/static_baseline/dim_core_static_baseline.c +@@ -28,12 +28,12 @@ static bool baseline_match_policy(const char *name, int type) + return dim_core_policy_match(DIM_POLICY_OBJ_BPRM_TEXT, + DIM_POLICY_KEY_PATH, name); + +- if (strcmp(name, kr) == 0) ++ if (dim_strcmp(name, kr) == 0) + return dim_core_policy_match(DIM_POLICY_OBJ_KERNEL_TEXT, + DIM_POLICY_KEY_NAME, kr); + + if (name_len <= kr_len + 2 || /* / */ +- strncmp(kr, name, kr_len) != 0 || ++ dim_strncmp(kr, name, kr_len) != 0 || + *(name + kr_len) != '/') + return false; + +@@ -82,7 +82,7 @@ static_baseline_load(struct dir_context *__ctx, + dim_err("failed to parse baseline file %s: %d\n", name, ret); + out: + if (buf != NULL) +- vfree(buf); ++ dim_vfree(buf); + + #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) + return 0; /* ignore fail */ +diff --git a/src/core/static_baseline/dim_core_static_baseline_complex.c b/src/core/static_baseline/dim_core_static_baseline_complex.c +index 685118f..8ff7c86 100644 +--- a/src/core/static_baseline/dim_core_static_baseline_complex.c ++++ b/src/core/static_baseline/dim_core_static_baseline_complex.c +@@ -37,7 +37,7 @@ static int parse_line(char* line, int line_no, void *data) + } + + if ((p = strsep(&line_str, " ")) == NULL || +- strcmp(p, DIM_STATIC_BASELINE_PREFIX) != 0) { ++ dim_strcmp(p, DIM_STATIC_BASELINE_PREFIX) != 0) { + dim_warn("invalid baseline prefix at line %d\n", line_no); + return 0; + } +diff --git a/src/core/tasks/dim_core_measure_kernel.c b/src/core/tasks/dim_core_measure_kernel.c +index e13e177..d49095b 100644 +--- a/src/core/tasks/dim_core_measure_kernel.c ++++ b/src/core/tasks/dim_core_measure_kernel.c +@@ -131,7 +131,7 @@ static int calc_kernel_digest(struct dim_hash *hash, struct dim_digest *digest) + if (ret < 0) + dim_err("failed to calculate kernel digest: %d\n", ret); + +- vfree(jcode_sort); ++ dim_vfree(jcode_sort); + return ret; + } + +diff --git a/src/core/tasks/dim_core_measure_process/dim_core_measure_process.c b/src/core/tasks/dim_core_measure_process/dim_core_measure_process.c +index 513f5a0..8522085 100644 +--- a/src/core/tasks/dim_core_measure_process/dim_core_measure_process.c ++++ b/src/core/tasks/dim_core_measure_process/dim_core_measure_process.c +@@ -60,9 +60,8 @@ static int store_task_tree(struct task_struct *p, void *data) + + /* realloc to size * 2 */ + new_size = ctx->size << 1; +- tmp = krealloc(ctx->buf, +- new_size * sizeof(struct task_struct *), +- GFP_ATOMIC); ++ tmp = dim_krealloc_atom(ctx->buf, ++ new_size * sizeof(struct task_struct *)); + if (tmp == NULL) + return -ENOMEM; + +@@ -79,7 +78,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 = dim_kmalloc_gfp(def_size * sizeof(struct task_struct *)); ++ ctx.buf = dim_kzalloc_gfp(def_size * sizeof(struct task_struct *)); + if (ctx.buf == NULL) + return -ENOMEM; + +@@ -91,7 +90,7 @@ static int kill_task_tree(struct task_struct *tsk) + } + } + +- kfree(ctx.buf); ++ dim_kfree(ctx.buf); + send_sig(SIGKILL, tsk, 1); + return 0; + } +@@ -166,7 +165,6 @@ static void measure_task_module(struct vm_area_struct *vma, + ret = measure_process_text(vma, ctx); + if (ret < 0) + dim_err("failed to measure module file text: %d", ret); +- + } + + static int measure_task(struct task_struct *task, struct task_measure_ctx *ctx) +@@ -238,7 +236,7 @@ static int store_task_pids(pid_t **pid_buf, unsigned int *pid_cnt) + unsigned int max_cnt = (PID_MAX_DEFAULT << 1); + + /* maximum processing of PID_MAX_DEFAULT * 2 pids */ +- buf = vmalloc(max_cnt); ++ buf = dim_vzalloc(max_cnt); + if (buf == NULL) { + dim_err("failed to allocate memory for pid buffer\n"); + return -ENOMEM; +@@ -294,7 +292,7 @@ static int walk_measure_tasks(struct task_measure_ctx *ctx) + } + } + +- vfree(pid_buf); ++ dim_vfree(pid_buf); + return 0; + } + +@@ -306,7 +304,7 @@ static int user_text_measure(int mode, struct dim_measure *m) + if (m == NULL) + return -EINVAL; + +- ctx = vmalloc(sizeof(struct task_measure_ctx)); ++ ctx = dim_vzalloc(sizeof(struct task_measure_ctx)); + if (ctx == NULL) + return -ENOMEM; + +@@ -315,7 +313,7 @@ static int user_text_measure(int mode, struct dim_measure *m) + ctx->check = check_process_digest; + + ret = walk_measure_tasks(ctx); +- vfree(ctx); ++ dim_vfree(ctx); + return ret; + } + +diff --git a/src/core/tasks/dim_core_measure_process/dim_core_measure_process_elf.c b/src/core/tasks/dim_core_measure_process/dim_core_measure_process_elf.c +index 9210f47..3821c7f 100644 +--- a/src/core/tasks/dim_core_measure_process/dim_core_measure_process_elf.c ++++ b/src/core/tasks/dim_core_measure_process/dim_core_measure_process_elf.c +@@ -57,7 +57,7 @@ static int get_elf_phdrs(struct file *elf_file, struct elfhdr *ehdr, + return -ENOEXEC; + + phdr_size = sizeof(struct elf_phdr) * ehdr->e_phnum; +- elf_phdata = dim_kmalloc_gfp(phdr_size); ++ elf_phdata = dim_kzalloc_gfp(phdr_size); + if (elf_phdata == NULL) + return -ENOMEM; + +@@ -89,7 +89,7 @@ static int get_elf_section(struct file *elf_file, struct elfhdr *ehdr, + if (ehdr->e_shentsize != sizeof(struct elf_shdr)) + return -EBADF; + +- sh_table = dim_kmalloc_gfp(ehdr->e_shentsize); ++ sh_table = dim_kzalloc_gfp(ehdr->e_shentsize); + if (sh_table == NULL) + return -ENOMEM; + +@@ -103,21 +103,21 @@ static int get_elf_section(struct file *elf_file, struct elfhdr *ehdr, + + str_size = sh_table->sh_size; + if (str_size > i_size_read(file_inode(elf_file))) { +- kfree(sh_table); ++ dim_kfree(sh_table); + return -EBADF; + } + +- sh_str = vmalloc(str_size); ++ sh_str = dim_vzalloc(str_size); + if (sh_str == NULL) { +- kfree(sh_table); ++ dim_kfree(sh_table); + return -ENOMEM; + } + + pos = sh_table->sh_offset; + size = kernel_read(elf_file, sh_str, sh_table->sh_size, &pos); + if (size != sh_table->sh_size) { +- kfree(sh_table); +- vfree(sh_str); ++ dim_kfree(sh_table); ++ dim_vfree(sh_str); + return size < 0 ? (int)size : -EBADF; + } + +@@ -135,15 +135,15 @@ static int get_elf_section(struct file *elf_file, struct elfhdr *ehdr, + sh_table->sh_name + name_len >= str_size) + break; + +- if (strcmp(name, sh_str + sh_table->sh_name) == 0) { ++ if (dim_strcmp(name, sh_str + sh_table->sh_name) == 0) { + memcpy(shdr, sh_table, sizeof(struct elf_shdr)); + ret = 0; + break; + } + } + +- kfree(sh_table); +- vfree(sh_str); ++ dim_kfree(sh_table); ++ dim_vfree(sh_str); + return ret; + } + +@@ -179,7 +179,7 @@ static int get_elf_text_phdrs(struct file *elf_file, + } + + /* alloc memory buffer for phdrs */ +- phdrs_text = dim_kmalloc_gfp(phdrs_text_num * sizeof(struct elf_phdr)); ++ phdrs_text = dim_kzalloc_gfp(phdrs_text_num * sizeof(struct elf_phdr)); + if (phdrs_text == NULL) { + dim_kfree(phdrs_get); + return -ENOMEM; +diff --git a/src/core/tasks/dim_core_measure_process/dim_vm_hash.c b/src/core/tasks/dim_core_measure_process/dim_vm_hash.c +index 0c59b9e..c3a8887 100644 +--- a/src/core/tasks/dim_core_measure_process/dim_vm_hash.c ++++ b/src/core/tasks/dim_core_measure_process/dim_vm_hash.c +@@ -7,6 +7,7 @@ + #include + + #include "dim_utils.h" ++#include "dim_safe_func.h" + + #include "dim_vm_hash.h" + +@@ -26,7 +27,7 @@ int dim_vm_hash_update_address(struct mm_struct *mm, + if (mm == NULL || addr_len == 0 || shash == NULL) + return -EINVAL; + +- pages = vzalloc(nr_pages * sizeof(struct page *)); ++ pages = dim_vzalloc(nr_pages * sizeof(struct page *)); + if (pages == NULL) + return -ENOMEM; + +@@ -38,7 +39,7 @@ int dim_vm_hash_update_address(struct mm_struct *mm, + #endif + if (ret_pages < 0) { + dim_err("failed to get remote pages: %ld\n", ret_pages); +- vfree(pages); ++ dim_vfree(pages); + return ret_pages; + } else if (ret_pages != nr_pages) { + dim_warn("failed to get all remote pages\n"); +@@ -64,7 +65,7 @@ int dim_vm_hash_update_address(struct mm_struct *mm, + put_page(pages[i]); + } + +- vfree(pages); ++ dim_vfree(pages); + return 0; + } + +diff --git a/src/measure/dim_measure_baseline.c b/src/measure/dim_measure_baseline.c +index dc358a7..c62d6be 100644 +--- a/src/measure/dim_measure_baseline.c ++++ b/src/measure/dim_measure_baseline.c +@@ -16,7 +16,7 @@ static const char *process_static_name(const char *name, int type, + { + const char *kr = init_uts_ns.name.release; + +- if (type != DIM_BASELINE_KERNEL || strcmp(name, kr) == 0) ++ if (type != DIM_BASELINE_KERNEL || dim_strcmp(name, kr) == 0) + return name; + + /* name of kernel module has a kernel prefix in static baseline */ +@@ -101,7 +101,7 @@ static int measure_log_add(struct dim_measure *m, const char *name, + + /* 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 ++ struct dim_digest *digest, int *log_flag) + { + int ret = 0; + struct dim_digest digest_static = { 0 }; +@@ -134,7 +134,7 @@ static int process_dynamic_measure(struct dim_measure *m, const char *name, + + 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 ++ if (log_flag != NULL) + *log_flag = LOG_TAMPERED; + + return measure_log_add(m, name, digest, LOG_TAMPERED); +@@ -165,7 +165,7 @@ static int process_static_baseline(struct dim_measure *m, const char *name, + 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 ++ if (log_flag != NULL) + *log_flag = LOG_TAMPERED; + + return measure_log_add(m, name, digest, LOG_TAMPERED); +@@ -177,7 +177,7 @@ static int process_static_measure(struct dim_measure *m, const char *name, + { + 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 ++ if (log_flag != NULL) + *log_flag = LOG_TAMPERED; + + return measure_log_add(m, name, digest, LOG_TAMPERED); +diff --git a/src/monitor/dim_monitor_main.c b/src/monitor/dim_monitor_main.c +index 4b3505d..d0e89f1 100644 +--- a/src/monitor/dim_monitor_main.c ++++ b/src/monitor/dim_monitor_main.c +@@ -57,6 +57,10 @@ static void __exit dim_monitor_exit(void) + { + dim_monitor_measure_destroy(); + dim_monitor_destroy_fs(); ++ ++ #ifdef DIM_DEBUG_MEMORY_LEAK ++ dim_check_memory_leak(); ++ #endif + } + + module_init(dim_monitor_init); +-- +2.33.0 + diff --git a/backport-Add-warpper-for-strncmp-and-strncpy.patch b/backport-Add-warpper-for-strncmp-and-strncpy.patch new file mode 100644 index 0000000000000000000000000000000000000000..cec959b2ccc10433b854842433d59b2af1ba2e37 --- /dev/null +++ b/backport-Add-warpper-for-strncmp-and-strncpy.patch @@ -0,0 +1,58 @@ +From f41760b3595c893ac0d3f0238401a2aae94224a7 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Tue, 20 Feb 2024 10:58:12 +0800 +Subject: [PATCH 22/26] Add warpper for strncmp and strncpy + +--- + src/common/dim_baseline.c | 2 +- + src/common/dim_safe_func.h | 8 ++++++++ + src/core/policy/dim_core_policy_complex.c | 2 +- + 3 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/src/common/dim_baseline.c b/src/common/dim_baseline.c +index e79458d..3fae1f9 100644 +--- a/src/common/dim_baseline.c ++++ b/src/common/dim_baseline.c +@@ -106,7 +106,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); ++ dim_strncpy((char *)baseline->name, name, buf_len - 1); + ((char *)baseline->name)[buf_len - 1] = '\0'; + + write_lock(&root->lock); +diff --git a/src/common/dim_safe_func.h b/src/common/dim_safe_func.h +index 3e97f4e..15c716c 100644 +--- a/src/common/dim_safe_func.h ++++ b/src/common/dim_safe_func.h +@@ -132,4 +132,12 @@ static inline int dim_strncmp(const char *cs, const char *ct, size_t count) + return strncmp(cs, ct, count); + } + ++static inline char *dim_strncpy(char *dest, const char *src, size_t count) ++{ ++ if (dest == NULL || src == NULL) ++ return NULL; ++ ++ return strncpy(dest, src, count); ++} ++ + #endif +\ No newline at end of file +diff --git a/src/core/policy/dim_core_policy_complex.c b/src/core/policy/dim_core_policy_complex.c +index 18a9e58..8c02227 100644 +--- a/src/core/policy/dim_core_policy_complex.c ++++ b/src/core/policy/dim_core_policy_complex.c +@@ -63,7 +63,7 @@ static int policy_get_key(const char *s, const char **val) + + for (; i < DIM_POLICY_KEY_LAST; i++) { + len = strlen(dim_policy_key_str[i]); +- if (strncmp(s, dim_policy_key_str[i], len) == 0) { ++ if (dim_strncmp(s, dim_policy_key_str[i], len) == 0) { + *val = s + len; + return i; + } +-- +2.33.0 + diff --git a/backport-Disable-dfx-testcase-by-default.patch b/backport-Disable-dfx-testcase-by-default.patch new file mode 100644 index 0000000000000000000000000000000000000000..a1e97be19a5d92e6d762b5df766b49371fde471d --- /dev/null +++ b/backport-Disable-dfx-testcase-by-default.patch @@ -0,0 +1,37 @@ +From 134b666b9ea72c640a20c4a6f3eb87a9b301542a Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Tue, 20 Feb 2024 12:52:39 +0800 +Subject: [PATCH 25/26] Disable dfx testcase by default + +--- + test/test_dfx/test_dim_core_dfx.sh | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/test/test_dfx/test_dim_core_dfx.sh b/test/test_dfx/test_dim_core_dfx.sh +index 78deb33..f3f64f0 100644 +--- a/test/test_dfx/test_dim_core_dfx.sh ++++ b/test/test_dfx/test_dim_core_dfx.sh +@@ -28,9 +28,10 @@ test_rmmod_when_baseline() { + done + } + +-case_list=" +- test_rmmod_when_baseline \ +- " ++# The following testcases are disabled by default: ++# test_rmmod_when_baseline ++ ++case_list="" + + echo "===== Start testing dim_core DFX =====" + +@@ -45,4 +46,4 @@ for case in $case_list; do + test_post + done + +-echo "===== End testing dim_core DFX =====" +\ No newline at end of file ++echo "===== End testing dim_core DFX =====" +-- +2.33.0 + diff --git a/backport-Dont-queue-measurement-task-when-baseline-failed.patch b/backport-Dont-queue-measurement-task-when-baseline-failed.patch new file mode 100644 index 0000000000000000000000000000000000000000..2f930129bf00511b84687c3b93b2aa8714e34223 --- /dev/null +++ b/backport-Dont-queue-measurement-task-when-baseline-failed.patch @@ -0,0 +1,34 @@ +From 6617fb034f69009893c33c8dd6b4e1485b77800f Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Wed, 14 Feb 2024 13:21:27 +0800 +Subject: [PATCH 17/26] Dont queue measurement task when baseline failed + +--- + src/core/dim_core_measure.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/core/dim_core_measure.c b/src/core/dim_core_measure.c +index 4ccbd0c..ff134e5 100644 +--- a/src/core/dim_core_measure.c ++++ b/src/core/dim_core_measure.c +@@ -120,6 +120,10 @@ static void measure_work_cb(struct work_struct *work) + static void baseline_work_cb(struct work_struct *work) + { + dim_measure_task_measure(DIM_BASELINE, &dim_core_handle); ++ /* if baseline is failed, dont perform measurement */ ++ if (dim_measure_status_error(&dim_core_handle)) ++ return; ++ + queue_delayed_measure_work(); + } + +@@ -244,4 +248,4 @@ void dim_core_measure_destroy(void) + dim_measure_destroy(&dim_core_handle); + dim_core_policy_destroy(); + mutex_unlock(&dim_core_measure_lock); +-} +\ No newline at end of file ++} +-- +2.33.0 + diff --git a/backport-Fix-potential-integer-overflow.patch b/backport-Fix-potential-integer-overflow.patch new file mode 100644 index 0000000000000000000000000000000000000000..d28a58b4253b52b2f4fef648c4d94fe361755033 --- /dev/null +++ b/backport-Fix-potential-integer-overflow.patch @@ -0,0 +1,25 @@ +From f298f9aaef28f5846b746e1c9596ad9d8c85b155 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Mon, 19 Feb 2024 10:01:41 +0800 +Subject: [PATCH 19/26] Fix potential integer overflow + +--- + src/core/tasks/dim_core_measure_kernel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/tasks/dim_core_measure_kernel.c b/src/core/tasks/dim_core_measure_kernel.c +index d49095b..077f30a 100644 +--- a/src/core/tasks/dim_core_measure_kernel.c ++++ b/src/core/tasks/dim_core_measure_kernel.c +@@ -21,7 +21,7 @@ + + static int code_cmp(const void *a, const void *b) + { +- return *(unsigned long *)a - *(unsigned long *)b; ++ return *(unsigned long *)a > *(unsigned long *)b ? 1 : 0; + } + + static int sort_jump_table(struct jump_entry *sjump, +-- +2.33.0 + diff --git a/backport-Optimize-Makefile.patch b/backport-Optimize-Makefile.patch new file mode 100644 index 0000000000000000000000000000000000000000..84a85299588814773cf99418bd2f4cbd2bfe26f4 --- /dev/null +++ b/backport-Optimize-Makefile.patch @@ -0,0 +1,209 @@ +From fef290b506eb5aad0afab0183b577567d0d4d5ac Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Tue, 13 Feb 2024 21:33:21 +0800 +Subject: [PATCH 16/26] Optimize Makefile + +1. Support to set the compile macro for different measure methods. +2. Support the "make test" command +--- + Makefile | 13 +++++++++++++ + src/Makefile | 40 ++++++++++++++++++++------------------- + test/Makefile | 11 +++++++++++ + test/common.sh | 6 +++--- + test/test_dim_core.sh | 2 +- + test/test_module/Makefile | 16 ++++++++-------- + 6 files changed, 57 insertions(+), 31 deletions(-) + create mode 100644 Makefile + create mode 100644 test/Makefile + +diff --git a/Makefile b/Makefile +new file mode 100644 +index 0000000..4ac7c58 +--- /dev/null ++++ b/Makefile +@@ -0,0 +1,13 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ ++.PHONY: all test clean ++ ++all: ++ make -C src/ ++ ++test: ++ make -C test/ ++ ++clean: ++ make -C src/ clean ++ make -C test/ clean +\ No newline at end of file +diff --git a/src/Makefile b/src/Makefile +index af058d9..8f4dce8 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -9,17 +9,21 @@ dim_core-objs += core/dim_core_mem_pool.o + dim_core-objs += core/dim_core_measure.o + dim_core-objs += core/dim_core_symbol.o + dim_core-objs += core/dim_core_sig.o +-dim_core-objs += core/static_baseline/dim_core_static_baseline.o +-dim_core-objs += core/static_baseline/dim_core_static_baseline_complex.o ++ + dim_core-objs += core/tasks/dim_core_measure_kernel.o + dim_core-objs += core/tasks/dim_core_measure_module.o ++dim_core-objs += core/tasks/dim_core_measure_process/dim_vm_hash.o ++dim_core-objs += core/tasks/dim_core_measure_process/dim_core_measure_process.o ++ifeq ($(DIM_CORE_MEASURE_PROCESS_ELF), y) + dim_core-objs += core/tasks/dim_core_measure_process/dim_core_measure_process_elf.o ++ccflags-y += -DDIM_CORE_MEASURE_PROCESS_ELF ++else + dim_core-objs += core/tasks/dim_core_measure_process/dim_core_measure_process_vma.o +-dim_core-objs += core/tasks/dim_core_measure_process/dim_core_measure_process.o +-dim_core-objs += core/tasks/dim_core_measure_process/dim_vm_hash.o ++endif + + dim_core-objs += core/policy/dim_core_policy.o + dim_core-objs += core/policy/dim_core_policy_complex.o ++ + dim_core-objs += core/static_baseline/dim_core_static_baseline.o + dim_core-objs += core/static_baseline/dim_core_static_baseline_complex.o + +@@ -40,6 +44,10 @@ dim_monitor-objs += monitor/dim_monitor_main.o + dim_monitor-objs += monitor/dim_monitor_fs.o + dim_monitor-objs += monitor/dim_monitor_measure.o + dim_monitor-objs += monitor/dim_monitor_symbol.o ++ ++dim_monitor-objs += monitor/measure_task/dim_monitor_measure_data.o ++dim_monitor-objs += monitor/measure_task/dim_monitor_measure_text.o ++ + dim_monitor-objs += common/dim_entry.o + dim_monitor-objs += common/dim_hash.o + dim_monitor-objs += common/dim_utils.o +@@ -52,8 +60,6 @@ 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 + + ccflags-y := -I$(src)/core + ccflags-y += -I$(src)/core/static_baseline +@@ -65,24 +71,20 @@ 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 ++ccflags-y += -Wall -Werror -D_FORTIFY_SOURCE=2 -O2 -fstack-protector-strong + + KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) + +-.PHONY: install test clean ++.PHONY: all modules modules_install clean + +-all: +- $(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules KCPPFLAGS="${cflags-y}" ++all: modules + +-clean: +- $(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean ++modules: ++ $(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules + +-install: +- rmmod -f dim_monitor || : +- rmmod -f dim_core || : +- insmod dim_core.ko +- insmod dim_monitor.ko ++modules_install: ++ $(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules_install + +-test: +- cd ../test && { sh test_dim_core.sh; sh test_dim_monitor.sh; } ++clean: ++ $(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean +diff --git a/test/Makefile b/test/Makefile +new file mode 100644 +index 0000000..4a61307 +--- /dev/null ++++ b/test/Makefile +@@ -0,0 +1,11 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ ++.PHONY: test ++ ++test: ++ sh test_dim_core.sh ++ sh test_dim_monitor.sh ++ ++clean: ++ rm -f log ++ make -C test_module/ clean +\ No newline at end of file +diff --git a/test/common.sh b/test/common.sh +index 3bd8ced..a16c564 100644 +--- a/test/common.sh ++++ b/test/common.sh +@@ -6,8 +6,8 @@ TEST_DEMO_DIR=/opt/dim/demo + TEST_DEMO_BPRM=$TEST_DEMO_DIR/dim_test_demo + + TEST_LOG=log +-DIM_CORE_PATH=/root/dim/dim_core.ko +-DIM_MONITOR_PATH=/root/dim/dim_monitor.ko ++DIM_CORE_PATH=../src/dim_core.ko ++DIM_MONITOR_PATH=../src/dim_monitor.ko + + DIM_BASELINE_DIR_PATH=/etc/dim/digest_list + DIM_POLICY_PATH=/etc/dim/policy +@@ -144,7 +144,7 @@ DIM_BASELINE_DIR_ALL=("/usr/bin" "/usr/sbin" "/usr/lib64" "/usr/libexec" "/usr/l + + dim_gen_baseline_all() { + if [ $1 ]; then +- digest_algorithm="-a sm3" ++ digest_algorithm="-a$1" + else + digest_algorithm="" + fi +diff --git a/test/test_dim_core.sh b/test/test_dim_core.sh +index 01fa2b9..8d707cc 100644 +--- a/test/test_dim_core.sh ++++ b/test/test_dim_core.sh +@@ -88,7 +88,7 @@ test_measure_all_text_normal() { + } + + test_measure_all_text_normal_sm3() { +- dim_gen_baseline_all 1 ++ dim_gen_baseline_all sm3 + dim_gen_policy_all + load_dim_modules "measure_hash=sm3" + check_dim_core_log_normal +diff --git a/test/test_module/Makefile b/test/test_module/Makefile +index 4255525..240e73e 100644 +--- a/test/test_module/Makefile ++++ b/test/test_module/Makefile +@@ -2,15 +2,15 @@ + + obj-m := dim_test_module_demo.o + +-KERNEL := $(DESTDIR)/lib/modules/$(shell uname -r)/build +-CONFIG_MODULE_SIG=n +- ++KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) + +-modules : +- $(MAKE) -C $(KERNEL) M=$(PWD) modules ++.PHONY: all modules clean ++ ++all: modules + +-.PHONEY:clean ++modules: ++ $(MAKE) -C $(KERNEL_SRC) M=$(PWD) modules + +-clean : +- $(MAKE) -C $(KERNEL) SUBDIRS=$(PWD) clean ++clean: ++ $(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean +\ No newline at end of file +-- +2.33.0 + diff --git a/backport-Optimize-test-framework-and-add-testcases.patch b/backport-Optimize-test-framework-and-add-testcases.patch new file mode 100644 index 0000000000000000000000000000000000000000..da5699b045c7c042971eb4eb4afbc19e8e5d1d59 --- /dev/null +++ b/backport-Optimize-test-framework-and-add-testcases.patch @@ -0,0 +1,747 @@ +From cfa580aa836f8c7f93e28971827bc67fdc20c679 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Mon, 19 Feb 2024 15:18:49 +0800 +Subject: [PATCH 21/26] Optimize test framework and add testcases + +--- + test/Makefile | 16 ++- + test/README.md | 23 ---- + test/common.sh | 47 ++++--- + test/test_dfx/Makefile | 11 ++ + test/test_dfx/test_dim_core_dfx.sh | 48 ++++++++ + test/test_dim_monitor.sh | 32 ----- + test/test_function/Makefile | 11 ++ + test/{ => test_function}/dim_test_demo.c | 2 +- + .../dim_test_demo_tamper.c | 2 +- + test/{ => test_function}/test_dim_core.sh | 34 +++-- + test/test_function/test_dim_monitor.sh | 47 +++++++ + test/{ => test_function}/test_module/Makefile | 2 +- + .../test_module/dim_test_module_demo.c | 2 +- + .../test_module/dim_test_module_demo_tamper.c | 2 +- + test/test_interface/Makefile | 12 ++ + test/test_interface/test_dim_core_modparam.sh | 116 ++++++++++++++++++ + .../test_dim_monitor_modparam.sh | 79 ++++++++++++ + 17 files changed, 393 insertions(+), 93 deletions(-) + delete mode 100644 test/README.md + create mode 100644 test/test_dfx/Makefile + create mode 100644 test/test_dfx/test_dim_core_dfx.sh + delete mode 100644 test/test_dim_monitor.sh + create mode 100644 test/test_function/Makefile + rename test/{ => test_function}/dim_test_demo.c (64%) + rename test/{ => test_function}/dim_test_demo_tamper.c (68%) + rename test/{ => test_function}/test_dim_core.sh (85%) + create mode 100644 test/test_function/test_dim_monitor.sh + rename test/{ => test_function}/test_module/Makefile (68%) + rename test/{ => test_function}/test_module/dim_test_module_demo.c (80%) + rename test/{ => test_function}/test_module/dim_test_module_demo_tamper.c (82%) + create mode 100644 test/test_interface/Makefile + create mode 100644 test/test_interface/test_dim_core_modparam.sh + create mode 100644 test/test_interface/test_dim_monitor_modparam.sh + +diff --git a/test/Makefile b/test/Makefile +index 4a61307..435e818 100644 +--- a/test/Makefile ++++ b/test/Makefile +@@ -1,11 +1,15 @@ +-# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. + +-.PHONY: test ++.PHONY: test clean ++ ++all: test + + test: +- sh test_dim_core.sh +- sh test_dim_monitor.sh ++ make -C test_interface/ test ++ make -C test_function/ test ++ make -C test_dfx/ test + + clean: +- rm -f log +- make -C test_module/ clean +\ No newline at end of file ++ make -C test_interface/ clean ++ make -C test_function/ clean ++ make -C test_dfx/ clean +\ No newline at end of file +diff --git a/test/README.md b/test/README.md +deleted file mode 100644 +index b75f3e6..0000000 +--- a/test/README.md ++++ /dev/null +@@ -1,23 +0,0 @@ +-# DIM 测试文档 +- +-## 1 前置条件 +- +-**OS版本支持**:openEuler 23.09以上版本; +- +-**内核版本支持**:当前支持openEuler kernel 5.10/6.4版本; +- +-**注意**:DIM包含内核组件,相关步骤需要以管理员(root)权限运行。 +- +-## 2 使用openEuler源进行安装 +-``` +-yum install dim dim_tools make gcc +-``` +- +-## 3 执行测试用例 +-``` +-cd dim/test/ +-sh test/test_dim_core.sh +-sh test/test_monitor_core.sh +-``` +- +-**注意**:全量度量功能默认关闭,如有需要,请将用例添加到对应的case_list中 +\ No newline at end of file +diff --git a/test/common.sh b/test/common.sh +index a16c564..6772a35 100644 +--- a/test/common.sh ++++ b/test/common.sh +@@ -6,8 +6,8 @@ TEST_DEMO_DIR=/opt/dim/demo + TEST_DEMO_BPRM=$TEST_DEMO_DIR/dim_test_demo + + TEST_LOG=log +-DIM_CORE_PATH=../src/dim_core.ko +-DIM_MONITOR_PATH=../src/dim_monitor.ko ++DIM_CORE_PATH=../../src/dim_core.ko ++DIM_MONITOR_PATH=../../src/dim_monitor.ko + + DIM_BASELINE_DIR_PATH=/etc/dim/digest_list + DIM_POLICY_PATH=/etc/dim/policy +@@ -23,6 +23,22 @@ DIM_TEST_MOD_DEMO_TAMPER_C=$TEST_MODULE_DIR/dim_test_module_demo_tamper.c + + TEST_RESULT=0 + ++check_value_zero() { ++ if [ $1 -ne 0 ]; then ++ echo "failed to check value: $1 == 0, context: $2" ++ TEST_RESULT=1 ++ return 1 ++ fi ++} ++ ++check_value_not_zero() { ++ if [ $1 -eq 0 ]; then ++ echo "failed to check value: $1 != 0, context: $2" ++ TEST_RESULT=1 ++ return 1 ++ fi ++} ++ + dim_core_status() { + cat /sys/kernel/security/dim/runtime_status + } +@@ -64,11 +80,11 @@ remove_dim_modules() { + + load_dim_modules () { + remove_dim_modules +- load_dim_core_modules $1 +- load_dim_monitor_modules $2 ++ load_dim_core_module $1 ++ load_dim_monitor_module $2 + } + +-load_dim_core_modules () { ++load_dim_core_module () { + # load dim_core module + if [ ! $DIM_CORE_PATH ]; then + modprobe dim_core $1 +@@ -78,11 +94,11 @@ load_dim_core_modules () { + + if [ $? -ne 0 ]; then + echo "fail to load dim_core!" +- exit 1 ++ return 1 + fi + } + +-load_dim_monitor_modules () { ++load_dim_monitor_module () { + # load dim_monitor module + if [ ! $DIM_MONITOR_PATH ]; then + modprobe dim_monitor $1 +@@ -92,11 +108,15 @@ load_dim_monitor_modules () { + + if [ $? -ne 0 ]; then + echo "fail to load dim_monitor!" +- exit 1 ++ return 1 + fi + } + + dim_backup_baseline_and_policy() { ++ if [ -d $DIM_BASELINE_DIR_PATH.bak ]; then ++ rm -rf $DIM_BASELINE_DIR_PATH.bak ++ fi ++ + if [ -d $DIM_BASELINE_DIR_PATH ]; then + mv $DIM_BASELINE_DIR_PATH $DIM_BASELINE_DIR_PATH.bak + fi +@@ -376,15 +396,4 @@ run_dim_core_and_check_log() { + fi + } + +-test_pre() { +- mkdir -p $TEST_DEMO_DIR +- gcc dim_test_demo.c -o $TEST_DEMO_DIR/dim_test_demo +- dim_backup_baseline_and_policy +- load_dim_modules +-} +- +-test_post() { +- remove_dim_modules +- dim_restore_baseline_and_policy +-} + +diff --git a/test/test_dfx/Makefile b/test/test_dfx/Makefile +new file mode 100644 +index 0000000..ed229ae +--- /dev/null ++++ b/test/test_dfx/Makefile +@@ -0,0 +1,11 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. ++ ++.PHONY: test clean ++ ++all: test ++ ++test: ++ sh test_dim_core_dfx.sh ++ ++clean: ++ rm -f log +\ No newline at end of file +diff --git a/test/test_dfx/test_dim_core_dfx.sh b/test/test_dfx/test_dim_core_dfx.sh +new file mode 100644 +index 0000000..78deb33 +--- /dev/null ++++ b/test/test_dfx/test_dim_core_dfx.sh +@@ -0,0 +1,48 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++#!/bin/bash ++ ++. ../common.sh ++ ++test_pre() { ++ dim_backup_baseline_and_policy ++ load_dim_core_module ++ dim_gen_baseline_all ++ dim_gen_policy_all ++ TEST_RESULT=0 ++} ++ ++test_post() { ++ remove_dim_modules ++ dim_restore_baseline_and_policy ++} ++ ++test_rmmod_when_baseline() { ++ dim_core_baseline & ++ # try to remove module when doing measurement ++ for i in {1..1000}; do ++ sleep 0.1 ++ rmmod dim_core &> /dev/null ++ if [ $? -eq 0 ]; then ++ break ++ fi ++ done ++} ++ ++case_list=" ++ test_rmmod_when_baseline \ ++ " ++ ++echo "===== Start testing dim_core DFX =====" ++ ++for case in $case_list; do ++ test_pre ++ $case ++ if [ $TEST_RESULT -eq 0 ]; then ++ echo "$case PASS" ++ else ++ echo "$case FAIL" ++ fi ++ test_post ++done ++ ++echo "===== End testing dim_core DFX =====" +\ No newline at end of file +diff --git a/test/test_dim_monitor.sh b/test/test_dim_monitor.sh +deleted file mode 100644 +index b4a1ea8..0000000 +--- a/test/test_dim_monitor.sh ++++ /dev/null +@@ -1,32 +0,0 @@ +-# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. +-#!/bin/bash +- +-. ./common.sh +- +-test_measure_monitor_normal() { +- dim_gen_baseline_all +- dim_gen_policy_all +- check_dim_core_log_normal +- check_dim_monitor_log_normal +-} +- +-test_measure_monitor_tamper() { +- test_measure_monitor_normal +- check_dim_monitor_log_tampered +-} +- +-# Full measurement. The test is disabled by default. +-# case_list="test_measure_monitor_normal \ +-# test_measure_monitor_tamper" +-case_list="" +- +-for case in $case_list; do +- test_pre +- $case +- if [ $TEST_RESULT -eq 0 ]; then +- echo "$case PASS" +- else +- echo "$case FAIL" +- fi +- test_post +-done +diff --git a/test/test_function/Makefile b/test/test_function/Makefile +new file mode 100644 +index 0000000..2d792cd +--- /dev/null ++++ b/test/test_function/Makefile +@@ -0,0 +1,11 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. ++ ++.PHONY: test clean ++ ++test: ++ sh test_dim_core.sh ++ sh test_dim_monitor.sh ++ ++clean: ++ rm -f log ++ make -C test_module/ clean +\ No newline at end of file +diff --git a/test/dim_test_demo.c b/test/test_function/dim_test_demo.c +similarity index 64% +rename from test/dim_test_demo.c +rename to test/test_function/dim_test_demo.c +index 113fc3d..5312d6d 100644 +--- a/test/dim_test_demo.c ++++ b/test/test_function/dim_test_demo.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. + */ + + #include +diff --git a/test/dim_test_demo_tamper.c b/test/test_function/dim_test_demo_tamper.c +similarity index 68% +rename from test/dim_test_demo_tamper.c +rename to test/test_function/dim_test_demo_tamper.c +index 7f95775..40cae5d 100644 +--- a/test/dim_test_demo_tamper.c ++++ b/test/test_function/dim_test_demo_tamper.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. + */ + + #include +diff --git a/test/test_dim_core.sh b/test/test_function/test_dim_core.sh +similarity index 85% +rename from test/test_dim_core.sh +rename to test/test_function/test_dim_core.sh +index 8d707cc..6ee5038 100644 +--- a/test/test_dim_core.sh ++++ b/test/test_function/test_dim_core.sh +@@ -1,7 +1,19 @@ +-# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. + #!/bin/bash + +-. ./common.sh ++. ../common.sh ++ ++test_pre() { ++ mkdir -p $TEST_DEMO_DIR ++ gcc dim_test_demo.c -o $TEST_DEMO_DIR/dim_test_demo ++ dim_backup_baseline_and_policy ++ load_dim_modules ++} ++ ++test_post() { ++ remove_dim_modules ++ dim_restore_baseline_and_policy ++} + + test_measure_bprm_text_normal() { + gen_dim_test_demo +@@ -118,11 +130,13 @@ test_invalid_policy() { + done &>> $TEST_LOG + } + +-# Full measurement. The test is disabled by default. +-# test_measure_all_text_normal \ +-# test_measure_all_text_normal_sm3 \ +-# test_measure_all_text_normal_sign \ +-case_list="test_measure_bprm_text_normal \ ++# The following testcases are disabled by default: ++# test_measure_all_text_normal ++# test_measure_all_text_normal_sm3 ++# test_measure_all_text_normal_sign ++ ++case_list=" ++ test_measure_bprm_text_normal \ + test_measure_bprm_text_no_baseline \ + test_measure_bprm_text_tamper_1 \ + test_measure_bprm_text_tamper_2 \ +@@ -130,7 +144,10 @@ case_list="test_measure_bprm_text_normal \ + test_measure_module_text_no_baseline \ + test_measure_module_text_tamper \ + test_measure_kernel_normal \ +- test_invalid_policy" ++ test_invalid_policy \ ++ " ++ ++echo "===== Start testing dim_core function =====" + + for case in $case_list; do + test_pre +@@ -143,3 +160,4 @@ for case in $case_list; do + test_post + done + ++echo "===== End testing dim_core function =====" +\ No newline at end of file +diff --git a/test/test_function/test_dim_monitor.sh b/test/test_function/test_dim_monitor.sh +new file mode 100644 +index 0000000..2f9319b +--- /dev/null ++++ b/test/test_function/test_dim_monitor.sh +@@ -0,0 +1,47 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. ++#!/bin/bash ++ ++. ../common.sh ++ ++test_pre() { ++ dim_backup_baseline_and_policy ++ load_dim_modules ++} ++ ++test_post() { ++ remove_dim_modules ++ dim_restore_baseline_and_policy ++} ++ ++test_measure_monitor_normal() { ++ dim_gen_baseline_all ++ dim_gen_policy_all ++ check_dim_core_log_normal ++ check_dim_monitor_log_normal ++} ++ ++test_measure_monitor_tamper() { ++ test_measure_monitor_normal ++ check_dim_monitor_log_tampered ++} ++ ++# The following testcases are disabled by default: ++# test_measure_monitor_normal ++# test_measure_monitor_tamper ++ ++case_list="" ++ ++echo "===== Start testing dim_monitor function =====" ++ ++for case in $case_list; do ++ test_pre ++ $case ++ if [ $TEST_RESULT -eq 0 ]; then ++ echo "$case PASS" ++ else ++ echo "$case FAIL" ++ fi ++ test_post ++done ++ ++echo "===== End testing dim_monitor function =====" +\ No newline at end of file +diff --git a/test/test_module/Makefile b/test/test_function/test_module/Makefile +similarity index 68% +rename from test/test_module/Makefile +rename to test/test_function/test_module/Makefile +index 240e73e..e3e945b 100644 +--- a/test/test_module/Makefile ++++ b/test/test_function/test_module/Makefile +@@ -1,4 +1,4 @@ +-# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. + + obj-m := dim_test_module_demo.o + +diff --git a/test/test_module/dim_test_module_demo.c b/test/test_function/test_module/dim_test_module_demo.c +similarity index 80% +rename from test/test_module/dim_test_module_demo.c +rename to test/test_function/test_module/dim_test_module_demo.c +index 3303365..f1a2ca7 100644 +--- a/test/test_module/dim_test_module_demo.c ++++ b/test/test_function/test_module/dim_test_module_demo.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. + */ + + #include +diff --git a/test/test_module/dim_test_module_demo_tamper.c b/test/test_function/test_module/dim_test_module_demo_tamper.c +similarity index 82% +rename from test/test_module/dim_test_module_demo_tamper.c +rename to test/test_function/test_module/dim_test_module_demo_tamper.c +index c443d7b..25cb6f2 100644 +--- a/test/test_module/dim_test_module_demo_tamper.c ++++ b/test/test_function/test_module/dim_test_module_demo_tamper.c +@@ -1,5 +1,5 @@ + /* +- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. + */ + + #include +diff --git a/test/test_interface/Makefile b/test/test_interface/Makefile +new file mode 100644 +index 0000000..0c41839 +--- /dev/null ++++ b/test/test_interface/Makefile +@@ -0,0 +1,12 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. ++ ++.PHONY: test clean ++ ++all: test ++ ++test: ++ sh test_dim_core_modparam.sh ++ sh test_dim_monitor_modparam.sh ++ ++clean: ++ rm -f log +\ No newline at end of file +diff --git a/test/test_interface/test_dim_core_modparam.sh b/test/test_interface/test_dim_core_modparam.sh +new file mode 100644 +index 0000000..67cd815 +--- /dev/null ++++ b/test/test_interface/test_dim_core_modparam.sh +@@ -0,0 +1,116 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. ++#!/bin/bash ++ ++. ../common.sh ++ ++test_pre() { ++ TEST_RESULT=0 ++} ++ ++check_valid_module_param() ++{ ++ remove_dim_modules ++ load_dim_core_module $1 &> /dev/null ++ check_value_zero $? $1 ++ remove_dim_modules ++} ++ ++check_invalid_module_param() ++{ ++ remove_dim_modules ++ load_dim_core_module $1 &> /dev/null ++ check_value_not_zero $? $1 ++ remove_dim_modules ++} ++ ++test_module_param_measure_hash() ++{ ++ check_valid_module_param measure_hash=sha256 ++ check_valid_module_param measure_hash=sm3 ++ check_invalid_module_param measure_hash=md5 ++ check_invalid_module_param measure_hash=abc ++} ++ ++test_module_param_measure_pcr() ++{ ++ check_valid_module_param measure_pcr=0 ++ check_valid_module_param measure_pcr=1 ++ check_valid_module_param measure_pcr=11 ++ check_valid_module_param measure_pcr=127 ++ check_invalid_module_param measure_pcr=128 ++ check_invalid_module_param measure_pcr=-1 ++ check_invalid_module_param measure_pcr=abc ++} ++ ++test_module_param_measure_schedule() ++{ ++ check_valid_module_param measure_schedule=0 ++ check_valid_module_param measure_schedule=50 ++ check_valid_module_param measure_schedule=1000 ++ check_invalid_module_param measure_schedule=-1 ++ check_invalid_module_param measure_schedule=abc ++ check_invalid_module_param measure_schedule=1001 ++} ++ ++test_module_param_measure_interval() ++{ ++ dim_backup_baseline_and_policy ++ dim_gen_policy_bprm_path /usr/bin/bash ++ dim_gen_baseline_file /usr/bin/bash test.hash ++ check_valid_module_param measure_interval=0 ++ check_valid_module_param measure_interval=1000 ++ check_valid_module_param measure_interval=525600 ++ check_invalid_module_param measure_interval=-1 ++ check_invalid_module_param measure_interval=abc ++ # check_invalid_module_param measure_interval=525601 ++ dim_restore_baseline_and_policy ++} ++ ++test_module_param_measure_action() ++{ ++ check_valid_module_param measure_action=0 ++ check_valid_module_param measure_action=1 ++ check_invalid_module_param measure_action=abc ++} ++ ++test_module_param_signature() ++{ ++ check_valid_module_param signature=0 ++ check_valid_module_param signature=1 ++ check_invalid_module_param signature=abc ++} ++ ++test_module_param_measure_log_capacity() ++{ ++ check_valid_module_param measure_log_capacity=100 ++ check_valid_module_param measure_log_capacity=10000 ++ check_valid_module_param measure_log_capacity=4294967295 ++ check_invalid_module_param measure_log_capacity=99 ++ check_invalid_module_param measure_log_capacity=0 ++ check_invalid_module_param measure_log_capacity=4294967296 ++ check_invalid_module_param measure_log_capacity=abc ++} ++ ++case_list=" ++ test_module_param_measure_hash \ ++ test_module_param_measure_pcr \ ++ test_module_param_measure_schedule \ ++ test_module_param_measure_interval \ ++ test_module_param_measure_action \ ++ test_module_param_signature \ ++ test_module_param_measure_log_capacity \ ++ " ++ ++echo "===== Start testing dim_core module parameters =====" ++ ++for case in $case_list; do ++ test_pre ++ $case ++ if [ $TEST_RESULT -eq 0 ]; then ++ echo "$case PASS" ++ else ++ echo "$case FAIL" ++ fi ++done ++ ++echo "===== End testing dim_core module parameters =====" +\ No newline at end of file +diff --git a/test/test_interface/test_dim_monitor_modparam.sh b/test/test_interface/test_dim_monitor_modparam.sh +new file mode 100644 +index 0000000..1aaedf1 +--- /dev/null ++++ b/test/test_interface/test_dim_monitor_modparam.sh +@@ -0,0 +1,79 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2024. All rights reserved. ++#!/bin/bash ++ ++. ../common.sh ++ ++test_pre() { ++ remove_dim_modules ++ load_dim_core_module ++ TEST_RESULT=0 ++} ++ ++test_post() { ++ remove_dim_modules ++} ++ ++check_valid_module_param() ++{ ++ load_dim_monitor_module $1 &> /dev/null ++ check_value_zero $? $1 ++ rmmod dim_monitor &> /dev/null ++} ++ ++check_invalid_module_param() ++{ ++ load_dim_monitor_module $1 &> /dev/null ++ check_value_not_zero $? $1 ++ rmmod dim_monitor &> /dev/null ++} ++ ++test_module_param_measure_hash() ++{ ++ check_valid_module_param measure_hash=sha256 ++ check_valid_module_param measure_hash=sm3 ++ check_invalid_module_param measure_hash=md5 ++ check_invalid_module_param measure_hash=abc ++} ++ ++test_module_param_measure_pcr() ++{ ++ check_valid_module_param measure_pcr=0 ++ check_valid_module_param measure_pcr=1 ++ check_valid_module_param measure_pcr=11 ++ check_valid_module_param measure_pcr=127 ++ check_invalid_module_param measure_pcr=128 ++ check_invalid_module_param measure_pcr=-1 ++ check_invalid_module_param measure_pcr=abc ++} ++ ++test_module_param_measure_log_capacity() ++{ ++ check_valid_module_param measure_log_capacity=100 ++ check_valid_module_param measure_log_capacity=10000 ++ check_valid_module_param measure_log_capacity=4294967295 ++ check_invalid_module_param measure_log_capacity=99 ++ check_invalid_module_param measure_log_capacity=0 ++ check_invalid_module_param measure_log_capacity=4294967296 ++ check_invalid_module_param measure_log_capacity=abc ++} ++ ++ ++case_list=" ++ test_module_param_measure_hash \ ++ test_module_param_measure_pcr \ ++ test_module_param_measure_log_capacity \ ++ " ++ ++echo "===== Start testing dim_monitor module parameters =====" ++ ++for case in $case_list; do ++ test_pre ++ $case ++ if [ $TEST_RESULT -eq 0 ]; then ++ echo "$case PASS" ++ else ++ echo "$case FAIL" ++ fi ++done ++ ++echo "===== End testing dim_monitor module parameters =====" +\ No newline at end of file +-- +2.33.0 + diff --git a/backport-Refactor-dim_core-policy-and-support-the-action-poli.patch b/backport-Refactor-dim_core-policy-and-support-the-action-poli.patch new file mode 100644 index 0000000000000000000000000000000000000000..25f0df60f4ab2ec032ec7044dbfeabbf85855c1a --- /dev/null +++ b/backport-Refactor-dim_core-policy-and-support-the-action-poli.patch @@ -0,0 +1,1280 @@ +From 0e193ae62a67dd4141ec6089f515e651c7e6a515 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +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 + ++#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 +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#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 +- +-#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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 ++ ++/* 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 ++ ++#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 + diff --git a/backport-Refactor-the-dim_core-static-baseline-implement.patch b/backport-Refactor-the-dim_core-static-baseline-implement.patch new file mode 100644 index 0000000000000000000000000000000000000000..3a7f745a9b6fafdb252193c450b858d4f33a6b62 --- /dev/null +++ b/backport-Refactor-the-dim_core-static-baseline-implement.patch @@ -0,0 +1,404 @@ +From c31d3b93f68151bf82196500b6f664e6ce8e1373 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Tue, 13 Feb 2024 16:44:40 +0800 +Subject: [PATCH 14/26] Refactor the dim_core static baseline implement + +Refactor the static baseline code and separate baseline text parsing +and baseline management to make it easier to extend other file format. +--- + src/Makefile | 4 +- + src/core/dim_core_measure.c | 2 +- + src/core/dim_core_static_baseline.h | 21 ---- + .../dim_core_static_baseline.c | 98 +++---------------- + .../dim_core_static_baseline.h | 42 ++++++++ + .../dim_core_static_baseline_complex.c | 89 +++++++++++++++++ + 6 files changed, 151 insertions(+), 105 deletions(-) + delete mode 100644 src/core/dim_core_static_baseline.h + rename src/core/{ => static_baseline}/dim_core_static_baseline.c (52%) + create mode 100644 src/core/static_baseline/dim_core_static_baseline.h + create mode 100644 src/core/static_baseline/dim_core_static_baseline_complex.c + +diff --git a/src/Makefile b/src/Makefile +index a17ce5b..8f94052 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -6,13 +6,14 @@ 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_static_baseline.o + dim_core-objs += core/dim_core_measure.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 += core/static_baseline/dim_core_static_baseline.o ++dim_core-objs += core/static_baseline/dim_core_static_baseline_complex.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 +@@ -48,6 +49,7 @@ dim_monitor-objs += monitor/measure_task/dim_monitor_measure_data.o + dim_monitor-objs += monitor/measure_task/dim_monitor_measure_text.o + + ccflags-y := -I$(src)/core ++ccflags-y += -I$(src)/core/static_baseline + ccflags-y += -I$(src)/core/measure_task + ccflags-y += -I$(src)/core/policy + ccflags-y += -I$(src)/monitor +diff --git a/src/core/dim_core_measure.c b/src/core/dim_core_measure.c +index 3f1d6e4..4ccbd0c 100644 +--- a/src/core/dim_core_measure.c ++++ b/src/core/dim_core_measure.c +@@ -86,7 +86,7 @@ static int baseline_prepare(struct dim_measure *m) + dim_baseline_destroy_tree(&m->dynamic_baseline); + + /* 3. reload dim baseline */ +- ret = dim_core_static_baseline_load(); ++ ret = dim_core_static_baseline_load(m); + if (ret < 0) { + dim_err("failed to load dim static baseline: %d\n", ret); + dim_core_policy_destroy(); +diff --git a/src/core/dim_core_static_baseline.h b/src/core/dim_core_static_baseline.h +deleted file mode 100644 +index af4d1f9..0000000 +--- a/src/core/dim_core_static_baseline.h ++++ /dev/null +@@ -1,21 +0,0 @@ +-/* +- * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. +- */ +- +-#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 +- +-#define DIM_STATIC_BASELINE_PREFIX "dim" +-/* dim KERNEL sha256:{digest} {PATH_MAX}\n*/ +-#define DIM_STATIC_BASELINE_LEN_MAX (strlen(DIM_STATIC_BASELINE_PREFIX) + 1 + \ +- NAME_MAX + 1 + NAME_MAX + 1 + \ +- PATH_MAX + 1 + 1) +- +-int dim_core_static_baseline_load(void); +- +-#endif +diff --git a/src/core/dim_core_static_baseline.c b/src/core/static_baseline/dim_core_static_baseline.c +similarity index 52% +rename from src/core/dim_core_static_baseline.c +rename to src/core/static_baseline/dim_core_static_baseline.c +index 1a87cfd..49810f3 100644 +--- a/src/core/dim_core_static_baseline.c ++++ b/src/core/static_baseline/dim_core_static_baseline.c +@@ -2,12 +2,8 @@ + * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. + */ + +-#include +-#include +-#include + #include + #include +-#include + #include + #include + #include +@@ -15,14 +11,13 @@ + + #include "dim_utils.h" + #include "dim_hash.h" +-#include "dim_baseline.h" + + #include "dim_core_sig.h" + #include "dim_core_policy.h" + #include "dim_core_measure.h" + #include "dim_core_static_baseline.h" + +-static bool match_policy(const char *name, int type) ++static bool baseline_match_policy(const char *name, int type) + { + const char *kr = init_uts_ns.name.release; + unsigned int kr_len = strlen(kr); +@@ -47,81 +42,13 @@ 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, void *data) ++static int baseline_check_add(const char *name, int type, ++ struct dim_digest *digest, ++ struct dim_measure *m) + { +- int ret = 0; +- int type = 0; +- size_t len = 0; +- char *p = NULL; +- char *line_str = line; +- struct dim_digest digest = { 0 }; +- +- if (line_no > DIM_STATIC_BASELINE_LINE_MAX) { +- dim_warn("more than %d baseline items will be ignored\n", +- DIM_STATIC_BASELINE_LINE_MAX); +- return -E2BIG; +- } +- +- if (strlen(line) == 0 || line[0] == '#') +- return 0; /* ignore blank line and comment */ +- +- if (strlen(line) > DIM_STATIC_BASELINE_LEN_MAX) { +- dim_err("overlength item at line %d\n", line_no); +- return 0; /* ignore baseline parsing failed */ +- } +- +- if ((p = strsep(&line_str, " ")) == NULL || +- strcmp(p, DIM_STATIC_BASELINE_PREFIX) != 0) { +- dim_warn("invalid baseline prefix at line %d\n", line_no); +- return 0; +- } +- +- if ((p = strsep(&line_str, " ")) == NULL || +- (type = dim_baseline_get_type(p)) == DIM_BASELINE_LAST) { +- dim_warn("invalid baseline type at line %d\n", line_no); +- return 0; +- } +- +- if ((p = strsep(&line_str, ":")) == NULL || +- (digest.algo = dim_hash_algo(p)) == HASH_ALGO__LAST) { +- dim_warn("invalid baseline algo at line %d\n", line_no); +- return 0; +- } +- +- if ((p = strsep(&line_str, " ")) == NULL || +- strlen(p) != (dim_digest_size(digest.algo) << 1) || +- hex2bin(digest.data, p, dim_digest_size(digest.algo)) < 0) { +- dim_warn("invalid baseline digest at line %d\n", line_no); +- return 0; +- } +- +- if (line_str == NULL) { +- dim_warn("no baseline name at line %d\n", line_no); +- return 0; +- } +- +- len = strlen(line_str); +- if (len == 0 || len > PATH_MAX) { +- dim_warn("invalid baseline name at line %d\n", line_no); +- return 0; +- } +- +- if (!match_policy(line_str, type)) +- return 0; +- +- 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); +- return 0; ++ return dim_measure_static_baseline_add(m, name, type, digest); + } + +-struct readdir_ctx { +- struct dir_context ctx; +- struct path *path; +-}; +- + #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) + static int + #else +@@ -134,11 +61,12 @@ static_baseline_load(struct dir_context *__ctx, + unsigned long long ino, + unsigned d_type) + { +- struct readdir_ctx *ctx = container_of(__ctx, typeof(*ctx), ctx); ++ struct baseline_parse_ctx *ctx = container_of(__ctx, typeof(*ctx), ctx); + int ret; + void *buf = NULL; + unsigned long buf_len = 0; + ++ /* baseline file must end with '.hash' */ + if (d_type != DT_REG || (!dim_string_end_with(name, ".hash"))) + goto out; /* ignore invalid files */ + +@@ -149,7 +77,7 @@ static_baseline_load(struct dir_context *__ctx, + } + + buf_len = ret; +- ret = dim_parse_line_buf(buf, buf_len, parse_simple_baseline_line, NULL); ++ ret = dim_baseline_parse(buf, buf_len, ctx); + if (ret < 0) + dim_err("failed to parse baseline file %s: %d\n", name, ret); + out: +@@ -163,16 +91,22 @@ out: + #endif + } + +-int dim_core_static_baseline_load(void) ++int dim_core_static_baseline_load(struct dim_measure *m) + { + int ret = 0; + struct path kpath; + struct file *file = NULL; +- struct readdir_ctx buf = { ++ struct baseline_parse_ctx buf = { + .ctx.actor = static_baseline_load, + .path = &kpath, ++ .m = m, ++ .add = baseline_check_add, ++ .match = baseline_match_policy, + }; + ++ if (m == NULL) ++ return -EINVAL; ++ + ret = kern_path(DIM_STATIC_BASELINE_ROOT, LOOKUP_DIRECTORY, &kpath); + if (ret < 0) { + dim_err("failed to get dim baseline root path: %d", ret); +diff --git a/src/core/static_baseline/dim_core_static_baseline.h b/src/core/static_baseline/dim_core_static_baseline.h +new file mode 100644 +index 0000000..988b02d +--- /dev/null ++++ b/src/core/static_baseline/dim_core_static_baseline.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#ifndef __DIM_CORE_STATIC_BASELINE_H ++#define __DIM_CORE_STATIC_BASELINE_H ++ ++#include ++ ++#include "dim_measure.h" ++ ++/* directory to store the static baseline files */ ++#define DIM_STATIC_BASELINE_ROOT "/etc/dim/digest_list" ++ ++/* callback function to check if a baseline is matched the policy */ ++typedef bool (*baseline_match_func)(const char *name, int type); ++ ++/* callback function to add baseline to measurement handle */ ++typedef int (*baseline_add_func)(const char *name, int type, ++ struct dim_digest *digest, ++ struct dim_measure *m); ++ ++/* the context used in directory walking and file parsing */ ++struct baseline_parse_ctx { ++ /* context for directory walking */ ++ struct dir_context ctx; ++ /* current directory path */ ++ struct path *path; ++ struct dim_measure *m; ++ baseline_match_func match; ++ baseline_add_func add; ++}; ++ ++/* function implemented to parse the static baseline file in complex format */ ++int baseline_parse_complex_format(char *buf, size_t buf_len, ++ struct baseline_parse_ctx *ctx); ++#define dim_baseline_parse baseline_parse_complex_format ++ ++/* build or rebuild the static baseline into the measurement handle */ ++int dim_core_static_baseline_load(struct dim_measure *m); ++ ++#endif +diff --git a/src/core/static_baseline/dim_core_static_baseline_complex.c b/src/core/static_baseline/dim_core_static_baseline_complex.c +new file mode 100644 +index 0000000..685118f +--- /dev/null ++++ b/src/core/static_baseline/dim_core_static_baseline_complex.c +@@ -0,0 +1,89 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#include "dim_utils.h" ++#include "dim_core_static_baseline.h" ++ ++#define DIM_STATIC_BASELINE_LINE_MAX 10000 ++ ++#define DIM_STATIC_BASELINE_PREFIX "dim" ++/* dim KERNEL sha256:{digest} {PATH_MAX}\n*/ ++#define DIM_STATIC_BASELINE_LEN_MAX (strlen(DIM_STATIC_BASELINE_PREFIX) + 1 + \ ++ NAME_MAX + 1 + NAME_MAX + 1 + \ ++ PATH_MAX + 1 + 1) ++ ++static int parse_line(char* line, int line_no, void *data) ++{ ++ int type = 0; ++ size_t len = 0; ++ char *p = NULL; ++ char *line_str = line; ++ struct dim_digest digest = { 0 }; ++ struct baseline_parse_ctx *ctx = data; ++ ++ if (line_no > DIM_STATIC_BASELINE_LINE_MAX) { ++ dim_warn("more than %d baseline items will be ignored\n", ++ DIM_STATIC_BASELINE_LINE_MAX); ++ return -E2BIG; ++ } ++ ++ if (strlen(line) == 0 || line[0] == '#') ++ return 0; /* ignore blank line and comment */ ++ ++ if (strlen(line) > DIM_STATIC_BASELINE_LEN_MAX) { ++ dim_err("overlength item at line %d\n", line_no); ++ return 0; /* ignore baseline parsing failed */ ++ } ++ ++ if ((p = strsep(&line_str, " ")) == NULL || ++ strcmp(p, DIM_STATIC_BASELINE_PREFIX) != 0) { ++ dim_warn("invalid baseline prefix at line %d\n", line_no); ++ return 0; ++ } ++ ++ if ((p = strsep(&line_str, " ")) == NULL || ++ (type = dim_baseline_get_type(p)) == DIM_BASELINE_LAST) { ++ dim_warn("invalid baseline type at line %d\n", line_no); ++ return 0; ++ } ++ ++ if ((p = strsep(&line_str, ":")) == NULL || ++ (digest.algo = dim_hash_algo(p)) == HASH_ALGO__LAST) { ++ dim_warn("invalid baseline algo at line %d\n", line_no); ++ return 0; ++ } ++ ++ if ((p = strsep(&line_str, " ")) == NULL || ++ strlen(p) != (dim_digest_size(digest.algo) << 1) || ++ hex2bin(digest.data, p, dim_digest_size(digest.algo)) < 0) { ++ dim_warn("invalid baseline digest at line %d\n", line_no); ++ return 0; ++ } ++ ++ if (line_str == NULL) { ++ dim_warn("no baseline name at line %d\n", line_no); ++ return 0; ++ } ++ ++ len = strlen(line_str); ++ if (len == 0 || len > PATH_MAX) { ++ dim_warn("invalid baseline name at line %d\n", line_no); ++ return 0; ++ } ++ ++ if (!ctx->match(line_str, type)) ++ return 0; ++ ++ return ctx->add(line_str, type, &digest, ctx->m); ++} ++ ++int baseline_parse_complex_format(char *buf, size_t buf_len, ++ struct baseline_parse_ctx *ctx) ++{ ++ if (buf == NULL || buf_len == 0 || ctx == NULL || ctx->m == NULL || ++ ctx->match == NULL || ctx->add == NULL) ++ return -EINVAL; ++ ++ return dim_parse_line_buf(buf, buf_len, parse_line, ctx); ++} +-- +2.33.0 + diff --git a/backport-Refactor-the-measurement-code.patch b/backport-Refactor-the-measurement-code.patch new file mode 100644 index 0000000000000000000000000000000000000000..a20ce63636dd11139f3851fd0d306f1d8526d82a --- /dev/null +++ b/backport-Refactor-the-measurement-code.patch @@ -0,0 +1,3198 @@ +From f1751e2438811f861e24e7be285a333942132b47 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +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 + + #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 +- +-#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 +- +-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 +-#include +- +-#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 + +-#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 +-#include +-#include ++#include + +-#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 + +-#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 ++ + #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 + + #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 + #include + +-#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 ++#include ++ ++#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 ++ ++#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 + ++#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 + #include + #include + +-#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 ++#include ++ ++#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 + diff --git a/backport-Set-dim_core_keyring-to-NULL-when-initialize-failed.patch b/backport-Set-dim_core_keyring-to-NULL-when-initialize-failed.patch new file mode 100644 index 0000000000000000000000000000000000000000..6effcdf6e0be72a3ff01cfebc4c341a7490c50cb --- /dev/null +++ b/backport-Set-dim_core_keyring-to-NULL-when-initialize-failed.patch @@ -0,0 +1,29 @@ +From 388653ae7f32fe19af71405f5d08d0f7cde7b2ba Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Tue, 20 Feb 2024 12:50:23 +0800 +Subject: [PATCH 24/26] Set dim_core_keyring to NULL when initialize failed + +--- + src/core/dim_core_sig.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/core/dim_core_sig.c b/src/core/dim_core_sig.c +index f142050..07e11d8 100644 +--- a/src/core/dim_core_sig.c ++++ b/src/core/dim_core_sig.c +@@ -182,8 +182,11 @@ int dim_core_sig_init(void) + ret = 0; + err: + dim_vfree(data); +- if (ret < 0) ++ if (ret < 0) { + key_put(dim_core_keyring); ++ dim_core_keyring = NULL; ++ } ++ + return ret; + } + +-- +2.33.0 + diff --git a/backport-Support-init-function-for-measure-tasks.patch b/backport-Support-init-function-for-measure-tasks.patch new file mode 100644 index 0000000000000000000000000000000000000000..43d486e8a130b5598e5c7497d1f085df3abeae8c --- /dev/null +++ b/backport-Support-init-function-for-measure-tasks.patch @@ -0,0 +1,193 @@ +From 76f757dd080abd646128ec39d8752ca1ab746355 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Fri, 8 Mar 2024 18:45:36 +0800 +Subject: [PATCH 26/26] Support init function for measure tasks + +--- + src/core/dim_core_measure.c | 4 ++- + src/core/tasks/dim_core_measure_kernel.c | 2 ++ + src/core/tasks/dim_core_measure_module.c | 2 ++ + src/measure/dim_measure.c | 1 + + src/measure/dim_measure.h | 4 +++ + src/measure/dim_measure_task.c | 32 ++++++++++++++++++- + src/monitor/dim_monitor_measure.c | 4 ++- + .../measure_task/dim_monitor_measure_data.c | 2 ++ + .../measure_task/dim_monitor_measure_text.c | 2 ++ + 9 files changed, 50 insertions(+), 3 deletions(-) + +diff --git a/src/core/dim_core_measure.c b/src/core/dim_core_measure.c +index ff134e5..f5b378c 100644 +--- a/src/core/dim_core_measure.c ++++ b/src/core/dim_core_measure.c +@@ -18,7 +18,9 @@ static struct dim_measure_task *dim_core_tasks[] = { + }; + + /* the global measurement handle */ +-struct dim_measure dim_core_handle = { 0 }; ++struct dim_measure dim_core_handle = { ++ .task_list = LIST_HEAD_INIT(dim_core_handle.task_list), ++}; + + /* lock to prevent trigger multiple measurement */ + DEFINE_MUTEX(dim_core_measure_lock); +diff --git a/src/core/tasks/dim_core_measure_kernel.c b/src/core/tasks/dim_core_measure_kernel.c +index dbf0dfe..fa04ae4 100644 +--- a/src/core/tasks/dim_core_measure_kernel.c ++++ b/src/core/tasks/dim_core_measure_kernel.c +@@ -165,5 +165,7 @@ static int kernel_text_measure(int mode, struct dim_measure *m) + + struct dim_measure_task dim_core_measure_task_kernel_text = { + .name = "dim_core_measure_task_kernel_text", ++ .init = NULL, ++ .destroy = NULL, + .measure = kernel_text_measure, + }; +diff --git a/src/core/tasks/dim_core_measure_module.c b/src/core/tasks/dim_core_measure_module.c +index aa3e2f3..feb6624 100644 +--- a/src/core/tasks/dim_core_measure_module.c ++++ b/src/core/tasks/dim_core_measure_module.c +@@ -108,5 +108,7 @@ static int module_text_measure(int mode, struct dim_measure *m) + + struct dim_measure_task dim_core_measure_task_module_text = { + .name = "dim_core_measure_task_module_text", ++ .init = NULL, ++ .destroy = NULL, + .measure = module_text_measure, + }; +diff --git a/src/measure/dim_measure.c b/src/measure/dim_measure.c +index 06e9bb5..dd35cb8 100644 +--- a/src/measure/dim_measure.c ++++ b/src/measure/dim_measure.c +@@ -91,6 +91,7 @@ void dim_measure_destroy(struct dim_measure *m) + return; + + mutex_lock(&m->measure_lock); ++ dim_measure_tasks_unregister_all(m); + dim_measure_log_destroy_tree(&m->log); + dim_baseline_destroy_tree(&m->static_baseline); + dim_baseline_destroy_tree(&m->dynamic_baseline); +diff --git a/src/measure/dim_measure.h b/src/measure/dim_measure.h +index d2ca326..d73fbaf 100644 +--- a/src/measure/dim_measure.h ++++ b/src/measure/dim_measure.h +@@ -78,6 +78,9 @@ struct dim_measure_task { + struct list_head node; + /* task name for log printing */ + const char *name; ++ /* init and destroy functions */ ++ int (*init)(void); ++ void (*destroy)(void); + /* measure function */ + int (*measure)(int mode, struct dim_measure *m); + }; +@@ -105,6 +108,7 @@ int dim_measure_dynamic_baseline_search(struct dim_measure *m, + int dim_measure_tasks_register(struct dim_measure *m, + struct dim_measure_task **tasks, + unsigned int num); ++void dim_measure_tasks_unregister_all(struct dim_measure *m); + void dim_measure_task_measure(int mode, struct dim_measure *m); + + /* functions for dim measurement status */ +diff --git a/src/measure/dim_measure_task.c b/src/measure/dim_measure_task.c +index ed97388..adfc57d 100644 +--- a/src/measure/dim_measure_task.c ++++ b/src/measure/dim_measure_task.c +@@ -62,13 +62,29 @@ void dim_measure_task_measure(int mode, struct dim_measure *m) + + static int task_register(struct dim_measure *m, struct dim_measure_task *t) + { ++ int ret = 0; ++ + if (t == NULL || t->name == NULL || t->measure == NULL) + return -EINVAL; + ++ if (t->init != NULL) { ++ ret = t->init(); ++ if (ret < 0) ++ return ret; ++ } ++ + list_add_tail(&t->node, &m->task_list); + return 0; + } + ++static void task_unregister(struct dim_measure_task *t) ++{ ++ if (t->destroy != NULL) ++ t->destroy(); ++ ++ list_del(&t->node); ++} ++ + int dim_measure_tasks_register(struct dim_measure *m, + struct dim_measure_task **tasks, + unsigned int num) +@@ -81,11 +97,25 @@ int dim_measure_tasks_register(struct dim_measure *m, + + for (; i < num; i++) { + ret = task_register(m, tasks[i]); +- if (ret < 0) ++ if (ret < 0) { ++ dim_measure_tasks_unregister_all(m); + return ret; ++ } + + dim_info("register measure task: %s\n", tasks[i]->name); + } + + return 0; + } ++ ++void dim_measure_tasks_unregister_all(struct dim_measure *m) ++{ ++ struct dim_measure_task *pos = NULL; ++ struct dim_measure_task *n = NULL; ++ ++ if (m == NULL) ++ return; ++ ++ list_for_each_entry_safe(pos, n, &m->task_list, node) ++ task_unregister(pos); ++} +diff --git a/src/monitor/dim_monitor_measure.c b/src/monitor/dim_monitor_measure.c +index f21ed0e..748d5f9 100644 +--- a/src/monitor/dim_monitor_measure.c ++++ b/src/monitor/dim_monitor_measure.c +@@ -21,7 +21,9 @@ static struct dim_measure_task *dim_core_tasks[] = { + }; + + /* the global measurement handle */ +-struct dim_measure dim_monitor_handle = { 0 }; ++struct dim_measure dim_monitor_handle = { ++ .task_list = LIST_HEAD_INIT(dim_monitor_handle.task_list), ++}; + + /* lock to prevent trigger multiple measurement */ + DEFINE_MUTEX(dim_monitor_measure_lock); +diff --git a/src/monitor/measure_task/dim_monitor_measure_data.c b/src/monitor/measure_task/dim_monitor_measure_data.c +index 5762dc1..029840c 100644 +--- a/src/monitor/measure_task/dim_monitor_measure_data.c ++++ b/src/monitor/measure_task/dim_monitor_measure_data.c +@@ -52,5 +52,7 @@ static int module_text_measure(int mode, struct dim_measure *m) + + struct dim_measure_task dim_monitor_measure_data = { + .name = "dim_monitor_measure_data", ++ .init = NULL, ++ .destroy = NULL, + .measure = module_text_measure, + }; +diff --git a/src/monitor/measure_task/dim_monitor_measure_text.c b/src/monitor/measure_task/dim_monitor_measure_text.c +index de6c77d..fc7dbf7 100644 +--- a/src/monitor/measure_task/dim_monitor_measure_text.c ++++ b/src/monitor/measure_task/dim_monitor_measure_text.c +@@ -60,5 +60,7 @@ static int module_text_measure(int mode, struct dim_measure *m) + + struct dim_measure_task dim_monitor_measure_text = { + .name = "dim_monitor_measure_text", ++ .init = NULL, ++ .destroy = NULL, + .measure = module_text_measure, + }; +-- +2.33.0 + diff --git a/backport-Support-user-process-measurement-by-ELF-parsing.patch b/backport-Support-user-process-measurement-by-ELF-parsing.patch new file mode 100644 index 0000000000000000000000000000000000000000..344870edf0e102ccbd12f2708f97c00fb6528a1d --- /dev/null +++ b/backport-Support-user-process-measurement-by-ELF-parsing.patch @@ -0,0 +1,1163 @@ +From a0d84883a2ebd71715bc044218341c645eb9b06b Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Tue, 13 Feb 2024 17:09:46 +0800 +Subject: [PATCH 15/26] Support user process measurement by ELF parsing + +1. Refactor the implement for process measurement, separate the process + modules (different binary files) measurement and process walking, + to make it easier to extend different measurement methods. +2. Implement a user process measurement method based on ELF parsing. + Support to measure memory of the ELF segment and section. +--- + src/Makefile | 18 +- + .../dim_core_measure_kernel.c | 0 + .../dim_core_measure_module.c | 0 + .../dim_core_measure_process.c} | 279 +-------------- + .../dim_core_measure_process.h | 82 +++++ + .../dim_core_measure_process_elf.c | 338 ++++++++++++++++++ + .../dim_core_measure_process_vma.c | 93 +++++ + .../dim_core_measure_process/dim_vm_hash.c | 107 ++++++ + .../dim_core_measure_process/dim_vm_hash.h | 25 ++ + .../dim_core_measure_task.h | 17 +- + 10 files changed, 686 insertions(+), 273 deletions(-) + rename src/core/{measure_task => tasks}/dim_core_measure_kernel.c (100%) + rename src/core/{measure_task => tasks}/dim_core_measure_module.c (100%) + rename src/core/{measure_task/dim_core_measure_task.c => tasks/dim_core_measure_process/dim_core_measure_process.c} (51%) + create mode 100644 src/core/tasks/dim_core_measure_process/dim_core_measure_process.h + create mode 100644 src/core/tasks/dim_core_measure_process/dim_core_measure_process_elf.c + create mode 100644 src/core/tasks/dim_core_measure_process/dim_core_measure_process_vma.c + create mode 100644 src/core/tasks/dim_core_measure_process/dim_vm_hash.c + create mode 100644 src/core/tasks/dim_core_measure_process/dim_vm_hash.h + rename src/core/{measure_task => tasks}/dim_core_measure_task.h (74%) + +diff --git a/src/Makefile b/src/Makefile +index 8f94052..af058d9 100644 +--- a/src/Makefile ++++ b/src/Makefile +@@ -9,13 +9,20 @@ dim_core-objs += core/dim_core_mem_pool.o + dim_core-objs += core/dim_core_measure.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 += core/static_baseline/dim_core_static_baseline.o + dim_core-objs += core/static_baseline/dim_core_static_baseline_complex.o ++dim_core-objs += core/tasks/dim_core_measure_kernel.o ++dim_core-objs += core/tasks/dim_core_measure_module.o ++dim_core-objs += core/tasks/dim_core_measure_process/dim_core_measure_process_elf.o ++dim_core-objs += core/tasks/dim_core_measure_process/dim_core_measure_process_vma.o ++dim_core-objs += core/tasks/dim_core_measure_process/dim_core_measure_process.o ++dim_core-objs += core/tasks/dim_core_measure_process/dim_vm_hash.o ++ + dim_core-objs += core/policy/dim_core_policy.o + dim_core-objs += core/policy/dim_core_policy_complex.o ++dim_core-objs += core/static_baseline/dim_core_static_baseline.o ++dim_core-objs += core/static_baseline/dim_core_static_baseline_complex.o ++ + dim_core-objs += common/dim_entry.o + dim_core-objs += common/dim_utils.o + dim_core-objs += common/dim_baseline.o +@@ -50,14 +57,15 @@ dim_monitor-objs += monitor/measure_task/dim_monitor_measure_text.o + + ccflags-y := -I$(src)/core + ccflags-y += -I$(src)/core/static_baseline +-ccflags-y += -I$(src)/core/measure_task ++ccflags-y += -I$(src)/core/tasks ++ccflags-y += -I$(src)/core/tasks/dim_core_measure_process + ccflags-y += -I$(src)/core/policy + 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 ++EXTRA_CFLAGS += -Wall -Werror -D_FORTIFY_SOURCE=2 -O2 -fstack-protector-strong + + KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build + PWD := $(shell pwd) +diff --git a/src/core/measure_task/dim_core_measure_kernel.c b/src/core/tasks/dim_core_measure_kernel.c +similarity index 100% +rename from src/core/measure_task/dim_core_measure_kernel.c +rename to src/core/tasks/dim_core_measure_kernel.c +diff --git a/src/core/measure_task/dim_core_measure_module.c b/src/core/tasks/dim_core_measure_module.c +similarity index 100% +rename from src/core/measure_task/dim_core_measure_module.c +rename to src/core/tasks/dim_core_measure_module.c +diff --git a/src/core/measure_task/dim_core_measure_task.c b/src/core/tasks/dim_core_measure_process/dim_core_measure_process.c +similarity index 51% +rename from src/core/measure_task/dim_core_measure_task.c +rename to src/core/tasks/dim_core_measure_process/dim_core_measure_process.c +index c9d21b1..513f5a0 100644 +--- a/src/core/measure_task/dim_core_measure_task.c ++++ b/src/core/tasks/dim_core_measure_process/dim_core_measure_process.c +@@ -7,8 +7,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + +@@ -21,26 +19,11 @@ + #include "dim_core_measure.h" + + #include "dim_core_measure_task.h" ++#include "dim_core_measure_process.h" + +-/* max number of kill tasks */ ++/* max number of tasks to kill */ + #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; +@@ -48,86 +31,6 @@ struct task_kill_ctx { + int ret; + }; + +-typedef int (*task_measurer)(struct task_struct *, struct task_measure_ctx *); +- +-static struct file *get_vm_file(struct vm_area_struct *vma) +-{ +-#ifdef CONFIG_EULEROS_EXEC_HUGEPAGES +- if (is_vm_exec_hugepages(vma) && vma->vm_real_file != NULL) +- return vma->vm_real_file; +-#endif +- return vma->vm_file; +-} +- +-/* Dont process vsyscall and vdso vma currently */ +-static bool vma_is_special_text(struct vm_area_struct *vma) +-{ +- const char *name = NULL; +- +- if (vma->vm_ops == NULL || vma->vm_ops->name == NULL) +- return false; +- +- name = vma->vm_ops->name(vma); +- if (name == NULL) +- return false; +- +- return (strcmp(name, "[vsyscall]") == 0) || +- (strcmp(name, "[vdso]") == 0); +-} +- +-static inline bool vma_is_text(struct vm_area_struct *vma) +-{ +- return (vma->vm_flags & VM_READ) && (vma->vm_flags & VM_EXEC) && +- !(vma->vm_flags & VM_WRITE) && !vma_is_special_text(vma); +-} +- +-static inline bool vma_is_file_text(struct vm_area_struct *vma) +-{ +- return vma_is_text(vma) && get_vm_file(vma) != NULL; +-} +- +-static inline bool vma_is_anon_text(struct vm_area_struct *vma) +-{ +- return vma_is_text(vma) && get_vm_file(vma) == NULL; +-} +- +-static inline bool vma_file_is_same(struct vm_area_struct *first, +- struct vm_area_struct *second) +-{ +- return get_vm_file(first) == get_vm_file(second); +-} +- +-static inline bool vma_can_merge(struct vm_area_struct *first, +- struct vm_area_struct *second) +-{ +- return (first->vm_end == second->vm_start) && +- (vma_file_is_same(first, second)); +-} +- +-static inline bool vma_is_not_same_module(struct vm_area_struct *a, +- struct vm_area_struct *b) +-{ +- struct file *fa = get_vm_file(a); +- struct file *fb = get_vm_file(b); +- return (fa != NULL && fb != NULL && fa != fb); +-} +- +-static struct vm_area_struct *next_file_text_vma(struct vm_area_struct *vma) +-{ +- struct vm_area_struct *v = NULL; +-#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) +- for (v = vma->vm_next; v != NULL && +- !vma_is_file_text(v); v = v->vm_next) {} +-#else +- VMA_ITERATOR(vmi, vma->vm_mm, vma->vm_end); +- for_each_vma(vmi, v) { +- if (vma_is_file_text(v)) +- break; +- } +-#endif +- return v; +-} +- + static struct vm_area_struct *next_module_text_vma(struct vm_area_struct *vma) + { + struct vm_area_struct *v = NULL; +@@ -145,25 +48,6 @@ static struct vm_area_struct *next_module_text_vma(struct vm_area_struct *vma) + return v; + } + +-static struct vm_area_struct *find_text_vma_end(struct vm_area_struct *vma) +-{ +- struct vm_area_struct *v = NULL; +- struct vm_area_struct *vma_end = vma; +-#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) +- for (v = vma->vm_next; v != NULL && +- vma_can_merge(vma_end, v); v = v->vm_next) {} +-#else +- VMA_ITERATOR(vmi, vma->vm_mm, vma->vm_end); +- for_each_vma(vmi, v) { +- if (!vma_is_file_text(v) || !vma_can_merge(vma_end, v)) +- break; +- +- vma_end = v; +- } +-#endif +- return vma_end; +-} +- + static int store_task_tree(struct task_struct *p, void *data) + { + unsigned int new_size = 0; +@@ -233,58 +117,16 @@ static bool vm_file_match_policy(struct file *vm_file, + DIM_BASELINE_USER, &dig) == 0; + } + +-static int update_vma_digest(struct vm_area_struct *vma_start, +- struct vm_area_struct *vma_end, +- struct shash_desc *shash) +-{ +- long i; +- long ret_pages = 0; +- void *page_ptr = NULL; +- struct page **pages = NULL; +- unsigned long addr_start = vma_start->vm_start; +- unsigned long addr_end = vma_end->vm_end; +- unsigned long addr_len = addr_end - addr_start; +- unsigned long nr_pages = DIV_ROUND_UP(addr_len, PAGE_SIZE); +- +- pages = vzalloc(nr_pages * sizeof(struct page *)); +- if (pages == NULL) +- return -ENOMEM; +- +- ret_pages = get_user_pages_remote(vma_start->vm_mm, addr_start, nr_pages, +-#if LINUX_VERSION_CODE <= KERNEL_VERSION(6,4,0) +- 0, pages, NULL, NULL); +-#else +- 0, pages, NULL); +-#endif +- if (ret_pages < 0) { +- dim_err("failed to get vma pages: %ld\n", ret_pages); +- vfree(pages); +- return ret_pages; +- } +- +- for (i = 0; i < ret_pages; i++) { +- page_ptr = kmap(pages[i]); +- if (page_ptr == NULL) { +- dim_err("failed to kmap page\n"); +- put_page(pages[i]); +- continue; +- } +- +- (void)crypto_shash_update(shash, page_ptr, PAGE_SIZE); +- kunmap(pages[i]); +- put_page(pages[i]); +- } +- +- vfree(pages); +- return 0; +-} +- +-static int check_user_digest(struct dim_digest *digest, +- struct task_measure_ctx *ctx) ++static int check_process_digest(struct dim_digest *digest, ++ void *data) + { + int ret = 0; + int log_flag = 0; + int action = 0; ++ struct task_measure_ctx *ctx = data; ++ ++ if (digest == NULL || data == NULL) ++ return -EINVAL; + + ret = dim_measure_process_static_result(ctx->m, ctx->mode, ctx->path, + digest, &log_flag); +@@ -308,91 +150,6 @@ static int check_user_digest(struct dim_digest *digest, + return 0; + } + +-#ifdef DIM_CORE_MEASURE_ANON_TEXT +-static int measure_anon_text_vma(struct vm_area_struct *vma, +- struct task_measure_ctx *ctx) +-{ +- int ret = 0; +- struct dim_digest digest = { +- .algo = ctx->m->hash.algo, +- }; +- SHASH_DESC_ON_STACK(shash, ctx->hash.tfm); +- +- shash->tfm = ctx->hash.tfm; +- ret = crypto_shash_init(shash); +- if (ret < 0) +- return ret; +- +- ret = update_vma_digest(vma, vma, shash); +- if (ret < 0) +- return ret; +- +- ret = crypto_shash_final(shash, digest.data); +- if (ret < 0) +- return ret; +- +- return check_user_digest(&digest, ctx); +-} +- +-/* For anonymous text segment, measure individual vma */ +-static int measure_task_module_anon_text(struct vm_area_struct *vma, +- struct task_measure_ctx *ctx) +-{ +- int ret = 0; +- struct vm_area_struct *v = vma; +-#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) +- for (; v != NULL && !vma_is_not_same_module(v, vma); v = v->vm_next) { +-#else +- VMA_ITERATOR(vmi, vma->vm_mm, vma->vm_start); +- for_each_vma(vmi, v) { +- if (vma_is_not_same_module(v, vma)) +- break; +-#endif +- if (!vma_is_anon_text(v)) +- continue; +- +- ret = measure_anon_text_vma(v, ctx); +- if (ret < 0) +- dim_err("failed to measure anon text vma: %d\n", ret); +- } +- +- return 0; +-} +-#endif +- +-/* For file text segment, merge all file mapping text vma and measure */ +-static int measure_task_module_file_text(struct vm_area_struct *vma, +- struct task_measure_ctx *ctx) +-{ +- int ret = 0; +- struct vm_area_struct *v = vma; +- struct vm_area_struct *v_end = NULL; +- struct dim_digest digest = { +- .algo = ctx->m->hash.algo +- }; +- SHASH_DESC_ON_STACK(shash, ctx->m->hash.tfm); +- +- shash->tfm = ctx->m->hash.tfm; +- ret = crypto_shash_init(shash); +- if (ret < 0) +- return ret; +- +- while (v != NULL && vma_file_is_same(v, vma)) { +- v_end = find_text_vma_end(v); +- ret = update_vma_digest(v, v_end, shash); +- if (ret < 0) +- return ret; +- +- v = next_file_text_vma(v_end); +- } +- +- ret = crypto_shash_final(shash, digest.data); +- if (ret < 0) +- return ret; +- +- return check_user_digest(&digest, ctx); +-} +- + static void measure_task_module(struct vm_area_struct *vma, + struct task_measure_ctx *ctx) + { +@@ -405,14 +162,11 @@ static void measure_task_module(struct vm_area_struct *vma, + + ctx->task_measure = true; + +- ret = measure_task_module_file_text(vma, ctx); ++ /* now we only measure the text memory */ ++ ret = measure_process_text(vma, ctx); + if (ret < 0) + dim_err("failed to measure module file text: %d", ret); +-#ifdef DIM_CORE_MEASURE_ANON_TEXT +- ret = measure_task_module_anon_text(vma, ctx); +- if (ret < 0) +- dim_err("failed to measure module anon text: %d", ret); +-#endif ++ + } + + static int measure_task(struct task_struct *task, struct task_measure_ctx *ctx) +@@ -510,7 +264,7 @@ static int store_task_pids(pid_t **pid_buf, unsigned int *pid_cnt) + return 0; + } + +-static int walk_tasks(task_measurer f, struct task_measure_ctx *ctx) ++static int walk_measure_tasks(struct task_measure_ctx *ctx) + { + int ret = 0; + unsigned int i = 0; +@@ -531,7 +285,7 @@ static int walk_tasks(task_measurer f, struct task_measure_ctx *ctx) + if (task == NULL) + continue; + +- ret = f(task, ctx); ++ ret = measure_task(task, ctx); + put_task_struct(task); + if (ret < 0) { + dim_err("failed to measure task, pid = %d: %d", pid_buf[i], ret); +@@ -546,6 +300,7 @@ static int walk_tasks(task_measurer f, struct task_measure_ctx *ctx) + + static int user_text_measure(int mode, struct dim_measure *m) + { ++ int ret = 0; + struct task_measure_ctx *ctx = NULL; + + if (m == NULL) +@@ -557,7 +312,11 @@ static int user_text_measure(int mode, struct dim_measure *m) + + ctx->mode = mode; + ctx->m = m; +- return walk_tasks(measure_task, ctx); ++ ctx->check = check_process_digest; ++ ++ ret = walk_measure_tasks(ctx); ++ vfree(ctx); ++ return ret; + } + + struct dim_measure_task dim_core_measure_task_user_text = { +diff --git a/src/core/tasks/dim_core_measure_process/dim_core_measure_process.h b/src/core/tasks/dim_core_measure_process/dim_core_measure_process.h +new file mode 100644 +index 0000000..6d2ceba +--- /dev/null ++++ b/src/core/tasks/dim_core_measure_process/dim_core_measure_process.h +@@ -0,0 +1,82 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#ifndef __DIM_CORE_MEASURE_PROCESS_H ++#define __DIM_CORE_MEASURE_PROCESS_H ++ ++#include ++#include ++ ++/* callback funtion to check results when do measurement */ ++typedef int (*process_digest_check_func) (struct dim_digest *digest, ++ void *ctx); ++ ++/* the context used in user process measurement */ ++struct task_measure_ctx { ++ struct dim_measure *m; ++ /* DIM_BASELINE or DIM_MEASURE */ ++ int mode; ++ char path_buf[PATH_MAX]; ++ /* current measured process name */ ++ const char *path; ++ /* current measured process */ ++ struct task_struct *task; ++ /* this process need to be killed */ ++ bool task_kill; ++ /* this process is measured */ ++ bool task_measure; ++ /* check function */ ++ process_digest_check_func check; ++}; ++ ++static inline struct file *get_vm_file(struct vm_area_struct *vma) ++{ ++ return vma == NULL ? NULL : vma->vm_file; ++} ++ ++static inline bool vma_is_text(struct vm_area_struct *vma) ++{ ++ return (vma->vm_flags & VM_READ) && (vma->vm_flags & VM_EXEC) && ++ !(vma->vm_flags & VM_WRITE); ++} ++ ++static inline bool vma_is_file_text(struct vm_area_struct *vma) ++{ ++ return vma_is_text(vma) && get_vm_file(vma) != NULL; ++} ++ ++static inline bool vma_file_is_same(struct vm_area_struct *first, ++ struct vm_area_struct *second) ++{ ++ return get_vm_file(first) == get_vm_file(second); ++} ++ ++static inline bool vma_can_merge(struct vm_area_struct *first, ++ struct vm_area_struct *second) ++{ ++ return (first->vm_end == second->vm_start) && ++ (vma_file_is_same(first, second)); ++} ++ ++static inline bool vma_is_not_same_module(struct vm_area_struct *a, ++ struct vm_area_struct *b) ++{ ++ struct file *fa = get_vm_file(a); ++ struct file *fb = get_vm_file(b); ++ return (fa != NULL && fb != NULL && fa != fb); ++} ++ ++#ifdef DIM_CORE_MEASURE_PROCESS_ELF ++int measure_process_module_text_elf(struct vm_area_struct *vma, ++ struct task_measure_ctx *ctx); ++#define measure_process_text measure_process_module_text_elf ++#else ++int measure_process_module_text_vma(struct vm_area_struct *vma, ++ struct task_measure_ctx *ctx); ++#define measure_process_text measure_process_module_text_vma ++#endif ++ ++extern struct dim_measure_task dim_core_measure_task_user_text; ++ ++#endif +\ No newline at end of file +diff --git a/src/core/tasks/dim_core_measure_process/dim_core_measure_process_elf.c b/src/core/tasks/dim_core_measure_process/dim_core_measure_process_elf.c +new file mode 100644 +index 0000000..9210f47 +--- /dev/null ++++ b/src/core/tasks/dim_core_measure_process/dim_core_measure_process_elf.c +@@ -0,0 +1,338 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include "dim_hash.h" ++#include "dim_utils.h" ++#include "dim_measure.h" ++ ++#include "dim_vm_hash.h" ++#include "dim_core_measure_process.h" ++ ++#define TRAMPOLINE_SECTION_NAME ".vos_patch_trampoline_seg" ++ ++static inline bool is_text_phdr(struct elf_phdr *phdr) ++{ ++ return (phdr->p_type == PT_LOAD) && (phdr->p_flags & PF_R) && ++ (phdr->p_flags & PF_X) && !(phdr->p_flags & PF_W); ++} ++ ++/* parse ELF header from an ELF file */ ++static int get_elf_ehdr(struct file *elf_file, struct elfhdr *ehdr) ++{ ++ loff_t pos = 0; ++ ssize_t size = 0; ++ ++ size = kernel_read(elf_file, ehdr, sizeof(struct elfhdr), &pos); ++ if (size != sizeof(struct elfhdr)) ++ return size < 0 ? (int)size : -EIO; ++ ++ /* check elf header valid, now we only support the little end */ ++ if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0 || ++ ehdr->e_ident[EI_CLASS] != ELF_CLASS || ++ ehdr->e_ident[EI_DATA] != ELFDATA2LSB || ++ (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)) ++ return -ENOEXEC; ++ ++ return 0; ++} ++ ++/* parse ELF phders from an ELF file */ ++static int get_elf_phdrs(struct file *elf_file, struct elfhdr *ehdr, ++ struct elf_phdr **phdrs, unsigned int *num) ++{ ++ struct elf_phdr *elf_phdata = NULL; ++ size_t phdr_size = 0; ++ ssize_t read_size = 0; ++ ++ if (ehdr->e_phentsize != sizeof(struct elf_phdr) || ++ ehdr->e_phnum < 1 || ++ ehdr->e_phnum > 65536U / sizeof(struct elf_phdr)) ++ return -ENOEXEC; ++ ++ phdr_size = sizeof(struct elf_phdr) * ehdr->e_phnum; ++ elf_phdata = dim_kmalloc_gfp(phdr_size); ++ if (elf_phdata == NULL) ++ return -ENOMEM; ++ ++ read_size = kernel_read(elf_file, elf_phdata, phdr_size, ++ &ehdr->e_phoff); ++ if (read_size != phdr_size) { ++ dim_kfree(elf_phdata); ++ return read_size < 0 ? (int)read_size : -EIO; ++ } ++ ++ *phdrs = elf_phdata; ++ *num = ehdr->e_phnum; ++ return 0; ++} ++ ++/* parse ELF section by name from an ELF file */ ++static int get_elf_section(struct file *elf_file, struct elfhdr *ehdr, ++ const char *name, struct elf_shdr *shdr) ++{ ++ int ret = 0; ++ int i = 0; ++ ssize_t size = 0; ++ ssize_t name_len = 0; ++ ssize_t str_size = 0; ++ struct elf_shdr *sh_table = NULL; ++ char *sh_str = NULL; ++ loff_t pos; ++ ++ if (ehdr->e_shentsize != sizeof(struct elf_shdr)) ++ return -EBADF; ++ ++ sh_table = dim_kmalloc_gfp(ehdr->e_shentsize); ++ if (sh_table == NULL) ++ return -ENOMEM; ++ ++ /* find the shdr for section name */ ++ pos = ehdr->e_shoff + ehdr->e_shentsize * ehdr->e_shstrndx; ++ size = kernel_read(elf_file, sh_table, ehdr->e_shentsize, &pos); ++ if (size != ehdr->e_shentsize) { ++ dim_kfree(sh_table); ++ return size < 0 ? (int)size : -EBADF; ++ } ++ ++ str_size = sh_table->sh_size; ++ if (str_size > i_size_read(file_inode(elf_file))) { ++ kfree(sh_table); ++ return -EBADF; ++ } ++ ++ sh_str = vmalloc(str_size); ++ if (sh_str == NULL) { ++ kfree(sh_table); ++ return -ENOMEM; ++ } ++ ++ pos = sh_table->sh_offset; ++ size = kernel_read(elf_file, sh_str, sh_table->sh_size, &pos); ++ if (size != sh_table->sh_size) { ++ kfree(sh_table); ++ vfree(sh_str); ++ return size < 0 ? (int)size : -EBADF; ++ } ++ ++ ret = -ENOENT; ++ pos = ehdr->e_shoff; ++ name_len = strlen(name); ++ for (i = 0; i < ehdr->e_shnum; i++) { ++ size = kernel_read(elf_file, sh_table, ehdr->e_shentsize, &pos); ++ if (size != ehdr->e_shentsize) { ++ ret = size < 0 ? (int)size : -EBADF; ++ break; ++ } ++ ++ if (sh_table->sh_name + name_len < sh_table->sh_name || ++ sh_table->sh_name + name_len >= str_size) ++ break; ++ ++ if (strcmp(name, sh_str + sh_table->sh_name) == 0) { ++ memcpy(shdr, sh_table, sizeof(struct elf_shdr)); ++ ret = 0; ++ break; ++ } ++ } ++ ++ kfree(sh_table); ++ vfree(sh_str); ++ return ret; ++} ++ ++static int get_elf_text_phdrs(struct file *elf_file, ++ struct elfhdr *ehdr, ++ struct elf_phdr **phdrs_find, ++ unsigned int *phdrs_find_num) ++{ ++ int ret = 0; ++ int i = 0; ++ struct elf_phdr *phdr = NULL; ++ unsigned int phdr_idx = 0; ++ struct elf_phdr *phdrs_get = NULL; ++ unsigned int phdrs_get_num = 0; ++ struct elf_phdr *phdrs_text = NULL; ++ unsigned int phdrs_text_num = 0; ++ ++ /* get all elf program headers */ ++ ret = get_elf_phdrs(elf_file, ehdr, &phdrs_get, &phdrs_get_num); ++ if (ret < 0) ++ return ret; ++ ++ /* get the number of the text phdr */ ++ for (i = 0, phdr = phdrs_get; i < phdrs_get_num; i++, phdr++) { ++ if (!is_text_phdr(phdr)) ++ continue; ++ phdrs_text_num++; ++ } ++ ++ if (phdrs_text_num == 0) { ++ dim_kfree(phdrs_get); ++ return -ENOEXEC; ++ } ++ ++ /* alloc memory buffer for phdrs */ ++ phdrs_text = dim_kmalloc_gfp(phdrs_text_num * sizeof(struct elf_phdr)); ++ if (phdrs_text == NULL) { ++ dim_kfree(phdrs_get); ++ return -ENOMEM; ++ } ++ ++ /* store the text phdrs */ ++ for (i = 0, phdr = phdrs_get; i < phdrs_get_num; i++, phdr++) { ++ if (!is_text_phdr(phdr)) ++ continue; ++ ++ memcpy(&phdrs_text[phdr_idx], phdr, sizeof(struct elf_phdr)); ++ if (++phdr_idx >= phdrs_text_num) ++ break; ++ } ++ ++ *phdrs_find = phdrs_text; ++ *phdrs_find_num = phdrs_text_num; ++ dim_kfree(phdrs_get); ++ return 0; ++} ++ ++static int get_elf_measure_area(struct file *elf_file, ++ struct elf_phdr **phdrs_text, ++ unsigned int *phdrs_text_num, ++ struct elf_shdr *shdr_trampoline, ++ bool *shdr_trampoline_find) ++{ ++ int ret = 0; ++ struct elfhdr ehdr = { 0 }; ++ ++ ret = get_elf_ehdr(elf_file, &ehdr); ++ if (ret < 0) { ++ dim_err("fail to get ELF header: %d\n", ret); ++ return ret; ++ } ++ ++ ret = get_elf_text_phdrs(elf_file, &ehdr, phdrs_text, phdrs_text_num); ++ if (ret < 0) { ++ dim_err("fail to get ELF text phdrs: %d\n", ret); ++ return ret; ++ } ++ ++ // TODO ++ ret = get_elf_section(elf_file, &ehdr, TRAMPOLINE_SECTION_NAME, shdr_trampoline); ++ if (ret == 0) ++ *shdr_trampoline_find = true; ++ else if (ret < 0 && ret != -ENOENT) ++ dim_warn("fail to get ELF trampoline shdr: %d\n", ret); ++ ++ return 0; ++} ++ ++static int measure_elf_trampoline(struct vm_area_struct *vma, ++ struct elf_shdr *shdr_trampoline, ++ struct task_measure_ctx *ctx) ++{ ++ int ret = 0; ++ struct vm_area_struct *vma_trampoline = NULL; ++ unsigned long addr_trampoline = 0; ++ struct dim_digest digest = { ++ .algo = ctx->m->hash.algo, ++ }; ++ ++ addr_trampoline = vma->vm_start + shdr_trampoline->sh_addr; ++ vma_trampoline = find_vma(vma->vm_mm, addr_trampoline); ++ if (vma_trampoline == NULL || !vma_is_text(vma_trampoline) || ++ vma_trampoline->vm_start != addr_trampoline) ++ return -ENOENT; ++ ++ ret = dim_vm_hash_calculate_vma(vma_trampoline, &ctx->m->hash, &digest); ++ if (ret < 0) { ++ dim_err("failed to calculate trampoline vma digest\n"); ++ return ret; ++ } ++ ++ return ctx->check(&digest, ctx); ++} ++ ++static int measure_elf_text(struct vm_area_struct *vma, ++ struct elf_phdr *phdrs_text, ++ unsigned int phdrs_text_num, ++ struct task_measure_ctx *ctx) ++{ ++ int ret = 0; ++ unsigned int i = 0; ++ unsigned long addr = 0; ++ struct elf_phdr *phdr = NULL; ++ struct dim_digest digest = { ++ .algo = ctx->m->hash.algo, ++ }; ++ SHASH_DESC_ON_STACK(shash, ctx->m->hash.tfm); ++ ++ shash->tfm = ctx->m->hash.tfm; ++ ret = crypto_shash_init(shash); ++ if (ret < 0) ++ return ret; ++ ++ for (; i < phdrs_text_num; i++) { ++ phdr = &phdrs_text[i]; ++ addr = vma->vm_start + phdr->p_vaddr - vma->vm_pgoff * PAGE_SIZE; ++ ret = dim_vm_hash_update_address(vma->vm_mm, addr, ++ phdr->p_memsz, shash); ++ if (ret < 0) ++ dim_err("failed to update elf text: %d\n", ret); ++ } ++ ++ ret = crypto_shash_final(shash, digest.data); ++ if (ret < 0) ++ return ret; ++ ++ return ctx->check(&digest, ctx); ++} ++ ++int measure_process_module_text_elf(struct vm_area_struct *vma, ++ struct task_measure_ctx *ctx) ++{ ++ int ret = 0; ++ struct file *elf_file = get_vm_file(vma); ++ struct elf_phdr *phdrs_text = NULL; ++ unsigned int phdrs_text_num = 0; ++ struct elf_shdr shdr_trampoline = { 0 }; ++ bool shdr_trampoline_find = false; ++ ++ if (vma == NULL || !vma_is_file_text(vma) || ctx == NULL ++ || ctx->m == NULL || ctx->check == NULL) ++ return -EINVAL; ++ ++ if (elf_file == NULL) { ++ dim_err("failed to get elf file from vma\n"); ++ return -ENOEXEC; ++ } ++ ++ ret = get_elf_measure_area(elf_file, &phdrs_text, &phdrs_text_num, ++ &shdr_trampoline, &shdr_trampoline_find); ++ if (ret < 0) { ++ dim_err("failed to get elf measure area from vma\n"); ++ return ret; ++ } ++ ++ ret = measure_elf_text(vma, phdrs_text, phdrs_text_num, ctx); ++ dim_kfree(phdrs_text); ++ if (ret < 0) { ++ dim_err("failed to measure elf text: %d\n", ret); ++ return ret; ++ } ++ ++ if (shdr_trampoline_find) { ++ ret = measure_elf_trampoline(vma, &shdr_trampoline, ctx); ++ if (ret < 0) { ++ dim_err("failed to measure elf trampoline: %d\n", ret); ++ return ret; ++ } ++ } ++ ++ return 0; ++} +diff --git a/src/core/tasks/dim_core_measure_process/dim_core_measure_process_vma.c b/src/core/tasks/dim_core_measure_process/dim_core_measure_process_vma.c +new file mode 100644 +index 0000000..d3ba241 +--- /dev/null ++++ b/src/core/tasks/dim_core_measure_process/dim_core_measure_process_vma.c +@@ -0,0 +1,93 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#include ++#include ++ ++#include "dim_measure.h" ++#include "dim_vm_hash.h" ++#include "dim_core_measure_process.h" ++ ++static struct vm_area_struct *find_text_vma_end(struct vm_area_struct *vma) ++{ ++ struct vm_area_struct *v = NULL; ++ struct vm_area_struct *vma_end = vma; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) ++ for (v = vma->vm_next; v != NULL && vma_is_file_text(v) && ++ vma_can_merge(vma_end, v); v = v->vm_next) ++ vma_end = v; ++#else ++ VMA_ITERATOR(vmi, vma->vm_mm, vma->vm_end); ++ for_each_vma(vmi, v) { ++ if (!vma_is_file_text(v) || !vma_can_merge(vma_end, v)) ++ break; ++ ++ vma_end = v; ++ } ++#endif ++ return vma_end; ++} ++ ++static struct vm_area_struct *next_file_text_vma(struct vm_area_struct *vma) ++{ ++ struct vm_area_struct *v = NULL; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) ++ for (v = vma->vm_next; v != NULL && ++ !vma_is_file_text(v); v = v->vm_next) {} ++#else ++ VMA_ITERATOR(vmi, vma->vm_mm, vma->vm_end); ++ for_each_vma(vmi, v) { ++ if (vma_is_file_text(v)) ++ break; ++ } ++ ++ if (!vma_is_file_text(v)) ++ v = NULL; ++#endif ++ return v; ++} ++ ++/* For file text segment, merge all file mapping text vma and measure */ ++int measure_text_vma(struct vm_area_struct *vma, struct task_measure_ctx *ctx) ++{ ++ int ret = 0; ++ struct vm_area_struct *v = vma; ++ struct vm_area_struct *v_end = NULL; ++ struct dim_digest digest = { ++ .algo = ctx->m->hash.algo ++ }; ++ SHASH_DESC_ON_STACK(shash, ctx->m->hash.tfm); ++ ++ shash->tfm = ctx->m->hash.tfm; ++ ret = crypto_shash_init(shash); ++ if (ret < 0) ++ return ret; ++ ++ /* now the vma is the first file text vma of a process module */ ++ while (v != NULL && vma_file_is_same(v, vma)) { ++ v_end = find_text_vma_end(v); ++ /* update all the continuous text vma */ ++ ret = dim_vm_hash_update_vmas(v, v_end, shash); ++ if (ret < 0) ++ return ret; ++ ++ v = next_file_text_vma(v_end); ++ } ++ ++ ret = crypto_shash_final(shash, digest.data); ++ if (ret < 0) ++ return ret; ++ ++ return ctx->check(&digest, ctx); ++} ++ ++int measure_process_module_text_vma(struct vm_area_struct *vma, ++ struct task_measure_ctx *ctx) ++{ ++ if (vma == NULL || !vma_is_file_text(vma) || ctx == NULL ++ || ctx->m == NULL || ctx->check == NULL) ++ return -EINVAL; ++ ++ return measure_text_vma(vma, ctx); ++} +diff --git a/src/core/tasks/dim_core_measure_process/dim_vm_hash.c b/src/core/tasks/dim_core_measure_process/dim_vm_hash.c +new file mode 100644 +index 0000000..0c59b9e +--- /dev/null ++++ b/src/core/tasks/dim_core_measure_process/dim_vm_hash.c +@@ -0,0 +1,107 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#include ++#include ++#include ++ ++#include "dim_utils.h" ++ ++#include "dim_vm_hash.h" ++ ++int dim_vm_hash_update_address(struct mm_struct *mm, ++ unsigned long addr_start, ++ unsigned long addr_len, ++ struct shash_desc *shash) ++{ ++ int ret = 0; ++ unsigned long i = 0; ++ long ret_pages = 0; ++ void *page_ptr = NULL; ++ struct page **pages = NULL; ++ unsigned int update_size = PAGE_SIZE; ++ unsigned long nr_pages = DIV_ROUND_UP(addr_len, PAGE_SIZE); ++ ++ if (mm == NULL || addr_len == 0 || shash == NULL) ++ return -EINVAL; ++ ++ pages = vzalloc(nr_pages * sizeof(struct page *)); ++ if (pages == NULL) ++ return -ENOMEM; ++ ++ ret_pages = get_user_pages_remote(mm, addr_start, nr_pages, ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(6,4,0) ++ 0, pages, NULL, NULL); ++#else ++ 0, pages, NULL); ++#endif ++ if (ret_pages < 0) { ++ dim_err("failed to get remote pages: %ld\n", ret_pages); ++ vfree(pages); ++ return ret_pages; ++ } else if (ret_pages != nr_pages) { ++ dim_warn("failed to get all remote pages\n"); ++ } ++ ++ for (i = 0; i < ret_pages; i++) { ++ page_ptr = kmap(pages[i]); ++ if (page_ptr == NULL) { ++ dim_err("failed to kmap remote page\n"); ++ put_page(pages[i]); ++ continue; ++ } ++ ++ if (i == ret_pages - 1) ++ update_size = addr_len % PAGE_SIZE ? ++ addr_len % PAGE_SIZE : PAGE_SIZE; ++ ++ ret = crypto_shash_update(shash, page_ptr, update_size); ++ if (ret < 0) ++ dim_warn("failed to update hash: %d\n", ret); ++ ++ kunmap(pages[i]); ++ put_page(pages[i]); ++ } ++ ++ vfree(pages); ++ return 0; ++} ++ ++/* calculate hash digest of continuous vma */ ++int dim_vm_hash_update_vmas(struct vm_area_struct *vma_start, ++ struct vm_area_struct *vma_end, ++ struct shash_desc *shash) ++{ ++ if (vma_start == NULL || vma_end == NULL || shash == NULL || ++ vma_start->vm_mm != vma_end->vm_mm || ++ vma_start->vm_start >= vma_end->vm_end) ++ return -EINVAL; ++ ++ return dim_vm_hash_update_address(vma_start->vm_mm, vma_start->vm_start, ++ vma_end->vm_end - vma_start->vm_start, shash); ++} ++ ++/* calculate hash digest of vma */ ++int dim_vm_hash_calculate_vma(struct vm_area_struct *vma, ++ struct dim_hash *hash, ++ struct dim_digest *digest) ++{ ++ int ret = 0; ++ /* check here to avoid code check warning */ ++ SHASH_DESC_ON_STACK(shash, hash == NULL ? NULL : hash->tfm); ++ ++ if (vma == NULL || hash == NULL || digest == NULL) ++ return -EINVAL; ++ ++ shash->tfm = hash->tfm; ++ ret = crypto_shash_init(shash); ++ if (ret < 0) ++ return ret; ++ ++ ret = dim_vm_hash_update_vmas(vma, vma, shash); ++ if (ret < 0) ++ return ret; ++ ++ return crypto_shash_final(shash, digest->data); ++} +diff --git a/src/core/tasks/dim_core_measure_process/dim_vm_hash.h b/src/core/tasks/dim_core_measure_process/dim_vm_hash.h +new file mode 100644 +index 0000000..7c996e9 +--- /dev/null ++++ b/src/core/tasks/dim_core_measure_process/dim_vm_hash.h +@@ -0,0 +1,25 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#ifndef __DIM_VM_HASH_H ++#define __DIM_VM_HASH_H ++ ++#include ++ ++#include "dim_hash.h" ++ ++int dim_vm_hash_update_address(struct mm_struct *mm, ++ unsigned long addr_start, ++ unsigned long addr_len, ++ struct shash_desc *shash); ++ ++int dim_vm_hash_update_vmas(struct vm_area_struct *vma_start, ++ struct vm_area_struct *vma_end, ++ struct shash_desc *shash); ++ ++int dim_vm_hash_calculate_vma(struct vm_area_struct *vma, ++ struct dim_hash *hash, ++ struct dim_digest *digest); ++ ++#endif +\ No newline at end of file +diff --git a/src/core/measure_task/dim_core_measure_task.h b/src/core/tasks/dim_core_measure_task.h +similarity index 74% +rename from src/core/measure_task/dim_core_measure_task.h +rename to src/core/tasks/dim_core_measure_task.h +index 0e26af2..145e0f3 100644 +--- a/src/core/measure_task/dim_core_measure_task.h ++++ b/src/core/tasks/dim_core_measure_task.h +@@ -1,8 +1,9 @@ +-#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 ++#ifndef __DIM_CORE_MEASURE_TASK_H ++#define __DIM_CORE_MEASURE_TASK_H ++ ++#include "dim_core_measure_process.h" ++ ++extern struct dim_measure_task dim_core_measure_task_module_text; ++extern struct dim_measure_task dim_core_measure_task_kernel_text; ++ ++#endif +-- +2.33.0 + diff --git a/backport-Use-warpper-dim_vzalloc-to-avoid-false-warning.patch b/backport-Use-warpper-dim_vzalloc-to-avoid-false-warning.patch new file mode 100644 index 0000000000000000000000000000000000000000..0159150b091c673979ab0e0cb517f3f16ab6c01b --- /dev/null +++ b/backport-Use-warpper-dim_vzalloc-to-avoid-false-warning.patch @@ -0,0 +1,25 @@ +From b135b54b3d973d8bd63193be377d8ef6b1bb0ea5 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Tue, 20 Feb 2024 12:49:42 +0800 +Subject: [PATCH 23/26] Use warpper dim_vzalloc to avoid false warning + +--- + src/core/tasks/dim_core_measure_kernel.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/core/tasks/dim_core_measure_kernel.c b/src/core/tasks/dim_core_measure_kernel.c +index 077f30a..dbf0dfe 100644 +--- a/src/core/tasks/dim_core_measure_kernel.c ++++ b/src/core/tasks/dim_core_measure_kernel.c +@@ -31,7 +31,7 @@ static int sort_jump_table(struct jump_entry *sjump, + unsigned int i; + unsigned long *buf = NULL; + +- buf = vzalloc(sizeof(unsigned long) * jump_counts); ++ buf = dim_vzalloc(sizeof(unsigned long) * jump_counts); + if (buf == NULL) + return -ENOMEM; + +-- +2.33.0 + diff --git a/backport-dim-add-test-code.patch b/backport-dim-add-test-code.patch new file mode 100644 index 0000000000000000000000000000000000000000..29fc2c433f0740e3bf3b3e9a87d80151e6b98dea --- /dev/null +++ b/backport-dim-add-test-code.patch @@ -0,0 +1,758 @@ +From 25fde75cbadc10af97e6684a52e72d516b974de5 Mon Sep 17 00:00:00 2001 +From: jinlun +Date: Mon, 6 Nov 2023 20:29:16 +0800 +Subject: [PATCH 04/26] dim: add test code + +--- + test/README.md | 23 ++ + test/common.sh | 390 ++++++++++++++++++ + test/dim_test_demo.c | 12 + + test/dim_test_demo_tamper.c | 13 + + test/test_dim_core.sh | 145 +++++++ + test/test_dim_monitor.sh | 32 ++ + test/test_module/Makefile | 16 + + test/test_module/dim_test_module_demo.c | 20 + + .../test_module/dim_test_module_demo_tamper.c | 23 ++ + 9 files changed, 674 insertions(+) + create mode 100644 test/README.md + create mode 100644 test/common.sh + create mode 100644 test/dim_test_demo.c + create mode 100644 test/dim_test_demo_tamper.c + create mode 100644 test/test_dim_core.sh + create mode 100644 test/test_dim_monitor.sh + create mode 100644 test/test_module/Makefile + create mode 100644 test/test_module/dim_test_module_demo.c + create mode 100644 test/test_module/dim_test_module_demo_tamper.c + +diff --git a/test/README.md b/test/README.md +new file mode 100644 +index 0000000..b75f3e6 +--- /dev/null ++++ b/test/README.md +@@ -0,0 +1,23 @@ ++# DIM 测试文档 ++ ++## 1 前置条件 ++ ++**OS版本支持**:openEuler 23.09以上版本; ++ ++**内核版本支持**:当前支持openEuler kernel 5.10/6.4版本; ++ ++**注意**:DIM包含内核组件,相关步骤需要以管理员(root)权限运行。 ++ ++## 2 使用openEuler源进行安装 ++``` ++yum install dim dim_tools make gcc ++``` ++ ++## 3 执行测试用例 ++``` ++cd dim/test/ ++sh test/test_dim_core.sh ++sh test/test_monitor_core.sh ++``` ++ ++**注意**:全量度量功能默认关闭,如有需要,请将用例添加到对应的case_list中 +\ No newline at end of file +diff --git a/test/common.sh b/test/common.sh +new file mode 100644 +index 0000000..3bd8ced +--- /dev/null ++++ b/test/common.sh +@@ -0,0 +1,390 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++#!/bin/bash ++ ++TEST_ROOT=/opt/dim ++TEST_DEMO_DIR=/opt/dim/demo ++TEST_DEMO_BPRM=$TEST_DEMO_DIR/dim_test_demo ++ ++TEST_LOG=log ++DIM_CORE_PATH=/root/dim/dim_core.ko ++DIM_MONITOR_PATH=/root/dim/dim_monitor.ko ++ ++DIM_BASELINE_DIR_PATH=/etc/dim/digest_list ++DIM_POLICY_PATH=/etc/dim/policy ++ ++DIM_KERNEL_NAME="/boot/vmlinuz-*.$(arch)" ++ ++TEST_MODULE_DIR=test_module ++DIM_MOD_NAME=dim_test_module_demo ++DIM_TEST_MOD_DEMO=$TEST_MODULE_DIR/dim_test_module_demo.ko ++ ++DIM_TEST_MOD_DEMO_C=$TEST_MODULE_DIR/dim_test_module_demo.c ++DIM_TEST_MOD_DEMO_TAMPER_C=$TEST_MODULE_DIR/dim_test_module_demo_tamper.c ++ ++TEST_RESULT=0 ++ ++dim_core_status() { ++ cat /sys/kernel/security/dim/runtime_status ++} ++ ++dim_core_baseline() { ++ echo 1 > /sys/kernel/security/dim/baseline_init ++} ++ ++dim_core_measure() { ++ echo 1 > /sys/kernel/security/dim/measure ++} ++ ++dim_core_measure_log() { ++ cat /sys/kernel/security/dim/ascii_runtime_measurements ++} ++ ++dim_monitor_baseline() { ++ echo 1 > /sys/kernel/security/dim/monitor_baseline ++} ++ ++dim_monitor_measure() { ++ echo 1 > /sys/kernel/security/dim/monitor_run ++} ++ ++dim_monitor_measure_log() { ++ cat /sys/kernel/security/dim/monitor_ascii_runtime_measurements ++} ++ ++remove_dim_modules() { ++ # clean loaded modules ++ rmmod -f dim_monitor &> /dev/null ++ rmmod -f dim_core &> /dev/null ++ lsmod | grep -E 'dim_core|dim_monitor' &> /dev/null ++ if [ $? -eq 0 ]; then ++ echo "fail to remove dim modules!" >> $TEST_LOG ++ exit 1 ++ fi ++} ++ ++load_dim_modules () { ++ remove_dim_modules ++ load_dim_core_modules $1 ++ load_dim_monitor_modules $2 ++} ++ ++load_dim_core_modules () { ++ # load dim_core module ++ if [ ! $DIM_CORE_PATH ]; then ++ modprobe dim_core $1 ++ else ++ insmod $DIM_CORE_PATH $1 ++ fi ++ ++ if [ $? -ne 0 ]; then ++ echo "fail to load dim_core!" ++ exit 1 ++ fi ++} ++ ++load_dim_monitor_modules () { ++ # load dim_monitor module ++ if [ ! $DIM_MONITOR_PATH ]; then ++ modprobe dim_monitor $1 ++ else ++ insmod $DIM_MONITOR_PATH $1 ++ fi ++ ++ if [ $? -ne 0 ]; then ++ echo "fail to load dim_monitor!" ++ exit 1 ++ fi ++} ++ ++dim_backup_baseline_and_policy() { ++ if [ -d $DIM_BASELINE_DIR_PATH ]; then ++ mv $DIM_BASELINE_DIR_PATH $DIM_BASELINE_DIR_PATH.bak ++ fi ++ ++ if [ -f $DIM_POLICY_PATH ]; then ++ mv $DIM_POLICY_PATH $DIM_POLICY_PATH.bak ++ fi ++} ++ ++dim_restore_baseline_and_policy() { ++ if [ -d $DIM_BASELINE_DIR_PATH.bak ]; then ++ rm -rf $DIM_BASELINE_DIR_PATH ++ mv $DIM_BASELINE_DIR_PATH.bak $DIM_BASELINE_DIR_PATH ++ fi ++ ++ if [ -f $DIM_POLICY_PATH.bak ]; then ++ mv -f $DIM_POLICY_PATH.bak $DIM_POLICY_PATH ++ fi ++} ++ ++dim_gen_baseline_file() { ++ mkdir -p $DIM_BASELINE_DIR_PATH ++ if [ -z $2 ]; then ++ dim_gen_baseline $1 ++ else ++ dim_gen_baseline $1 -o "$DIM_BASELINE_DIR_PATH/$2" ++ fi ++} ++ ++dim_gen_baseline_dir() { ++ mkdir -p $DIM_BASELINE_DIR_PATH ++ dim_gen_baseline -r $1 -o $DIM_BASELINE_DIR_PATH/$2 ++} ++ ++dim_gen_baseline_kerenl() { ++ mkdir -p $DIM_BASELINE_DIR_PATH ++ if [ -z $1 ]; then ++ dim_gen_baseline -k "$(uname -r)" $DIM_KERNEL_NAME ++ else ++ dim_gen_baseline -k "$(uname -r)" -o $DIM_BASELINE_DIR_PATH/$1 $DIM_KERNEL_NAME ++ fi ++} ++ ++DIM_BASELINE_DIR_ALL=("/usr/bin" "/usr/sbin" "/usr/lib64" "/usr/libexec" "/usr/lib") ++ ++dim_gen_baseline_all() { ++ if [ $1 ]; then ++ digest_algorithm="-a sm3" ++ else ++ digest_algorithm="" ++ fi ++ ++ mkdir -p /etc/dim/digest_list ++ for baseline_file in "${DIM_BASELINE_DIR_ALL[@]}"; do ++ dim_gen_baseline $digest_algorithm -r $baseline_file -o "$DIM_BASELINE_DIR_PATH/${baseline_file##*/}.hash" ++ done ++ dim_gen_baseline $digest_algorithm -k "$(uname -r)" -o $DIM_BASELINE_DIR_PATH/kernel.hash $DIM_KERNEL_NAME ++} ++ ++ ++dim_gen_policy_bprm_path() { ++ echo "measure obj=BPRM_TEXT path=$1" >> $DIM_POLICY_PATH ++} ++ ++dim_gen_policy_module_name() { ++ echo "measure obj=MODULE_TEXT name=$1" >> $DIM_POLICY_PATH ++} ++ ++dim_gen_policy_kernel() { ++ echo "measure obj=KERNEL_TEXT" >> $DIM_POLICY_PATH ++} ++ ++dim_gen_policy_all() { ++ rm -f $DIM_POLICY_PATH ++ cat $DIM_BASELINE_DIR_PATH/* | awk '{print $4}' | while read line; do ++ if [[ "$line" == /* ]]; then ++ echo "measure obj=BPRM_TEXT path=$line" >> $DIM_POLICY_PATH ++ continue ++ fi ++ if [ "$line" == "$(uname -r)" ]; then ++ echo "measure obj=KERNEL_TEXT" >> $DIM_POLICY_PATH ++ continue ++ fi ++ if [ "$line" != "$(uname -r)" ]; then ++ echo "measure obj=MODULE_TEXT name=$(basename $line)" >> $DIM_POLICY_PATH ++ fi ++ done ++ sed -i '/dim_core/d' $DIM_POLICY_PATH ++ sed -i '/dim_monitor/d' $DIM_POLICY_PATH ++} ++ ++dim_gen_cert() { ++ mkdir -p $TEST_ROOT/cert/ ++ openssl genrsa -out $TEST_ROOT/cert/dim.key 4096 &>> $TEST_LOG ++ openssl req -new -sha256 -key $TEST_ROOT/cert/dim.key -out $TEST_ROOT/cert/dim.csr -subj "/C=AA/ST=BB/O=CC/OU=DD/CN=DIM" &>> $TEST_LOG ++ openssl x509 -req -days 3650 -signkey $TEST_ROOT/cert/dim.key -in $TEST_ROOT/cert/dim.csr -out $TEST_ROOT/cert/dim.crt &>> $TEST_LOG ++ openssl x509 -in $TEST_ROOT/cert/dim.crt -out $TEST_ROOT/cert/dim.der -outform DER &>> $TEST_LOG ++ mkdir -p /etc/keys ++ cp $TEST_ROOT/cert/dim.der /etc/keys/x509_dim.der ++} ++ ++dim_gen_signature() { ++ openssl dgst -sha256 -out $DIM_POLICY_PATH.sig -sign $TEST_ROOT/cert/dim.key $DIM_POLICY_PATH ++ for file in $(ls $DIM_BASELINE_DIR_PATH | grep .hash); do ++ openssl dgst -sha256 -out $DIM_BASELINE_DIR_PATH/$file.sig -sign $TEST_ROOT/cert/dim.key $DIM_BASELINE_DIR_PATH/$file ++ done ++} ++ ++dim_baseline_to_measure_log() { ++ name="$(echo "$1" | awk '{print $4}')" ++ if [[ $name == $(uname -r)/* ]]; then ++ name="$(basename $name)" ++ fi ++ ++ echo "$(echo "$1" | awk '{print $3}') $name" ++} ++ ++tamper_dim_test_demo() { ++ gcc dim_test_demo_tamper.c -o $TEST_DEMO_DIR/dim_test_demo ++} ++ ++tamper_dim_test_mod_demo() { ++ rm -f $TEST_MODULE_DIR/$DIM_MOD_NAME.o ++ mv $DIM_TEST_MOD_DEMO_C $DIM_TEST_MOD_DEMO_C.bak ++ mv $DIM_TEST_MOD_DEMO_TAMPER_C $DIM_TEST_MOD_DEMO_C ++ cd $TEST_MODULE_DIR ++ make > /dev/null ++ cd .. ++} ++ ++tamper_dim_test_mod_demo_end() { ++ rm -f $TEST_MODULE_DIR/$DIM_MOD_NAME.o ++ mv $DIM_TEST_MOD_DEMO_C $DIM_TEST_MOD_DEMO_TAMPER_C ++ mv $DIM_TEST_MOD_DEMO_C.bak $DIM_TEST_MOD_DEMO_C ++} ++ ++gen_dim_test_demo() { ++ gcc dim_test_demo.c -o $TEST_DEMO_BPRM ++ dim_gen_baseline_file $TEST_DEMO_BPRM test.hash ++ dim_gen_policy_bprm_path $TEST_DEMO_BPRM ++} ++ ++gen_dim_test_mod_demo() { ++ rm -f $TEST_MODULE_DIR/$DIM_MOD_NAME.o ++ cd $TEST_MODULE_DIR ++ make > /dev/null ++ cd .. ++ dim_gen_baseline_file $DIM_TEST_MOD_DEMO test.hash ++ dim_gen_policy_module_name $DIM_MOD_NAME ++} ++ ++measure_log_tampered() { ++ if [ $2 ]; then ++ echo "$1 \[tampered\]" ++ else ++ baseline="$(dim_gen_baseline_file $1)" ++ echo "$(dim_baseline_to_measure_log "$baseline") \[tampered\]" ++ fi ++} ++ ++measure_log_static() { ++ if [ $2 ]; then ++ baseline="$(dim_gen_baseline_kerenl)" ++ echo "$(dim_baseline_to_measure_log "$baseline") \[static baseline\]" ++ else ++ baseline="$(dim_gen_baseline_file $1)" ++ echo "$(dim_baseline_to_measure_log "$baseline") \[static baseline\]" ++ fi ++} ++ ++measure_log_no_static() { ++ if [ $2 ]; then ++ echo "$1 \[no static baseline\]" ++ else ++ baseline="$(dim_gen_baseline_file $1)" ++ echo "$(dim_baseline_to_measure_log "$baseline") \[no static baseline\]" ++ fi ++} ++ ++check_dim_measure_log_match() { ++ if [ "$2" == "dim_monitor_measure_log" ]; then ++ dim_monitor_measure_log | grep "$1" &> /dev/null ++ else ++ dim_core_measure_log | grep "$1" &> /dev/null ++ fi ++ ++ if [ $? -ne 0 ]; then ++ echo "check fail:" >> $TEST_LOG ++ echo " get measure log: $($2)" >> $TEST_LOG ++ echo " want measure log: $1" >> $TEST_LOG ++ TEST_RESULT=1 ++ return 1 ++ fi ++ ++ echo "check ok: measure log has $1" >> $TEST_LOG ++} ++ ++check_dim_measure_log_length() { ++ if [ $($2 | wc -l) -ne $1 ]; then ++ echo "check fail: measure log length is not $1" >> $TEST_LOG ++ TEST_RESULT=1 ++ return 1 ++ fi ++ ++ echo "check ok: measure log length is $1" >> $TEST_LOG ++} ++ ++check_dim_measure_log_not_contain() { ++ if [ "$2" == "dim_monitor_measure_log" ]; then ++ dim_monitor_measure_log | grep "$1" &> /dev/null ++ else ++ dim_core_measure_log | grep "$1" &> /dev/null ++ fi ++ if [ $? -eq 0 ]; then ++ echo "check fail" ++ TEST_RESULT=1 ++ return 1 ++ fi ++ ++ echo "check ok: measure log hasn't $1" >> $TEST_LOG ++} ++ ++check_dim_core_log_normal() { ++ dim_core_baseline ++ check_dim_measure_log_not_contain "\[no static baseline\]" "dim_core_measure_log" ++ check_dim_measure_log_not_contain "\[tampered\]" "dim_core_measure_log" ++ dim_core_measure ++ check_dim_measure_log_not_contain "\[no static baseline\]" "dim_core_measure_log" ++ check_dim_measure_log_not_contain "\[tampered\]" "dim_core_measure_log" ++} ++ ++check_dim_monitor_log_normal() { ++ dim_monitor_baseline ++ check_dim_measure_log_length 2 "dim_monitor_measure_log" ++ check_dim_measure_log_not_contain "\[tampered\]" "dim_monitor_measure_log" ++ dim_monitor_measure ++ check_dim_measure_log_length 2 "dim_monitor_measure_log" ++ check_dim_measure_log_not_contain "\[tampered\]" "dim_monitor_measure_log" ++} ++ ++check_dim_monitor_log_tampered() { ++ dim_core_baseline ++ dim_monitor_measure ++ check_dim_measure_log_length 3 "dim_monitor_measure_log" ++ check_dim_measure_log_match "dim_core.data \[tampered\]" "dim_monitor_measure_log" ++} ++ ++run_dim_core_baseline_and_check_log() { ++ dim_core_baseline ++ check_dim_measure_log_length "$2" "dim_core_measure_log" ++ check_dim_measure_log_match "$1" "dim_core_measure_log" ++} ++ ++run_dim_core_measure_and_check_log() { ++ dim_core_measure ++ check_dim_measure_log_length "$2" "dim_core_measure_log" ++ check_dim_measure_log_match "$1" "dim_core_measure_log" ++} ++ ++run_dim_core_and_check_log() { ++ if [ "$1" = "baseline" ]; then ++ run_dim_core_baseline_and_check_log "$2" "$3" ++ if [ $4 ]; then ++ kill $4 ++ fi ++ elif [ "$1" = "measure" ]; then ++ run_dim_core_measure_and_check_log "$2" "$3" ++ if [ $4 ]; then ++ kill $4 ++ fi ++ else ++ run_dim_core_baseline_and_check_log "$1" "$2" ++ run_dim_core_measure_and_check_log "$3" "$4" ++ if [ $5 ]; then ++ kill $5 ++ fi ++ fi ++} ++ ++test_pre() { ++ mkdir -p $TEST_DEMO_DIR ++ gcc dim_test_demo.c -o $TEST_DEMO_DIR/dim_test_demo ++ dim_backup_baseline_and_policy ++ load_dim_modules ++} ++ ++test_post() { ++ remove_dim_modules ++ dim_restore_baseline_and_policy ++} ++ +diff --git a/test/dim_test_demo.c b/test/dim_test_demo.c +new file mode 100644 +index 0000000..113fc3d +--- /dev/null ++++ b/test/dim_test_demo.c +@@ -0,0 +1,12 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#include ++ ++int main() ++{ ++ printf("dim_test_demo\n"); ++ while (1); ++ return 0; ++} +diff --git a/test/dim_test_demo_tamper.c b/test/dim_test_demo_tamper.c +new file mode 100644 +index 0000000..7f95775 +--- /dev/null ++++ b/test/dim_test_demo_tamper.c +@@ -0,0 +1,13 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#include ++ ++int main() ++{ ++ printf("dim_test_demo"); ++ printf("_tamper\n"); ++ while (1); ++ return 0; ++} +diff --git a/test/test_dim_core.sh b/test/test_dim_core.sh +new file mode 100644 +index 0000000..01fa2b9 +--- /dev/null ++++ b/test/test_dim_core.sh +@@ -0,0 +1,145 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++#!/bin/bash ++ ++. ./common.sh ++ ++test_measure_bprm_text_normal() { ++ gen_dim_test_demo ++ $TEST_DEMO_DIR/dim_test_demo > /dev/null & pid=$! ++ # test ++ run_dim_core_and_check_log "$(measure_log_static $TEST_DEMO_BPRM)" 1 "$(measure_log_static $TEST_DEMO_BPRM)" 1 $pid ++} ++ ++test_measure_bprm_text_no_baseline() { ++ gen_dim_test_demo ++ $TEST_DEMO_DIR/dim_test_demo > /dev/null & pid=$! ++ # remove baseline ++ rm -f $DIM_BASELINE_DIR_PATH/test.hash ++ # test ++ run_dim_core_and_check_log "$(measure_log_no_static $TEST_DEMO_BPRM)" 1 "$(measure_log_no_static $TEST_DEMO_BPRM)" 1 $pid ++} ++ ++test_measure_bprm_text_tamper_1() { ++ # prepare ++ gen_dim_test_demo ++ tamper_dim_test_demo ++ $TEST_DEMO_DIR/dim_test_demo > /dev/null & pid=$! ++ # test ++ run_dim_core_and_check_log "$(measure_log_tampered $TEST_DEMO_BPRM)" 1 "$(measure_log_tampered $TEST_DEMO_BPRM)" 1 $pid ++} ++ ++test_measure_bprm_text_tamper_2() { ++ # prepare ++ gen_dim_test_demo ++ $TEST_DEMO_DIR/dim_test_demo > /dev/null & pid=$! ++ # test baseline ++ run_dim_core_and_check_log baseline "$(measure_log_static $TEST_DEMO_BPRM)" 1 $pid ++ # tamper dim_test_demo ++ tamper_dim_test_demo ++ $TEST_DEMO_DIR/dim_test_demo > /dev/null & pid=$! ++ # test measure ++ run_dim_core_and_check_log measure "$(measure_log_tampered $TEST_DEMO_BPRM)" 2 $pid ++ ++ kill $pid ++} ++ ++test_measure_kernel_normal() { ++ dim_gen_policy_kernel ++ dim_gen_baseline_kerenl test.hash ++ ++ run_dim_core_and_check_log "$(measure_log_static $DIM_KERNEL_NAME "kernel")" 1 "$(measure_log_static $DIM_KERNEL_NAME "kernel")" 1 ++} ++ ++test_measure_module_text_normal() { ++ gen_dim_test_mod_demo ++ insmod $DIM_TEST_MOD_DEMO ++ run_dim_core_and_check_log "$(measure_log_static $DIM_TEST_MOD_DEMO)" 1 "$(measure_log_static $DIM_TEST_MOD_DEMO)" 1 ++ rmmod $DIM_TEST_MOD_DEMO ++} ++ ++test_measure_module_text_no_baseline() { ++ gen_dim_test_mod_demo ++ insmod $DIM_TEST_MOD_DEMO ++ ++ # remove baseline ++ rm -f $DIM_BASELINE_DIR_PATH/test.hash ++ ++ run_dim_core_and_check_log "$(measure_log_no_static $DIM_MOD_NAME "mod_no_static")" 1 "$(measure_log_no_static $DIM_MOD_NAME "mod_no_static")" 1 ++ rmmod $DIM_TEST_MOD_DEMO ++} ++ ++test_measure_module_text_tamper() { ++ gen_dim_test_mod_demo ++ insmod $DIM_TEST_MOD_DEMO ++ ++ run_dim_core_and_check_log baseline "$(measure_log_static $DIM_TEST_MOD_DEMO)" 1 ++ rmmod $DIM_TEST_MOD_DEMO ++ tamper_dim_test_mod_demo ++ insmod $DIM_TEST_MOD_DEMO ++ run_dim_core_and_check_log measure "$(measure_log_tampered $DIM_MOD_NAME "module_tampered")" 2 ++ rmmod $DIM_TEST_MOD_DEMO ++ tamper_dim_test_mod_demo_end ++} ++ ++test_measure_all_text_normal() { ++ dim_gen_baseline_all ++ dim_gen_policy_all ++ check_dim_core_log_normal ++} ++ ++test_measure_all_text_normal_sm3() { ++ dim_gen_baseline_all 1 ++ dim_gen_policy_all ++ load_dim_modules "measure_hash=sm3" ++ check_dim_core_log_normal ++} ++ ++test_measure_all_text_normal_sign() { ++ dim_gen_baseline_all ++ dim_gen_policy_all ++ dim_gen_cert ++ dim_gen_signature ++ load_dim_modules "signature=on" ++ check_dim_core_log_normal ++} ++ ++POLICY_INVALID="measure1 obj=BPRM_TEXT path=/opt/dim/demo/dim_test_demo\n\ ++measure obj1=BPRM_TEXT path=/opt/dim/demo/dim_test_demo\n\ ++measure obj=BPRM_TEXT1 path=/opt/dim/demo/dim_test_demo\n\ ++measure obj=BPRM_TEXT name=/opt/dim/demo/dim_test_demo\n\ ++measure obj=MODULE_TEXT path=$(head -c 4096 < /dev/zero | tr '\0' '\141')\n" ++ ++test_invalid_policy() { ++ IFS=$'\n' ++ for policy in $(echo -e $POLICY_INVALID); do ++ echo "$policy" > $DIM_POLICY_PATH ++ dim_core_baseline ++ dim_core_status ++ done &>> $TEST_LOG ++} ++ ++# Full measurement. The test is disabled by default. ++# test_measure_all_text_normal \ ++# test_measure_all_text_normal_sm3 \ ++# test_measure_all_text_normal_sign \ ++case_list="test_measure_bprm_text_normal \ ++ test_measure_bprm_text_no_baseline \ ++ test_measure_bprm_text_tamper_1 \ ++ test_measure_bprm_text_tamper_2 \ ++ test_measure_module_text_normal \ ++ test_measure_module_text_no_baseline \ ++ test_measure_module_text_tamper \ ++ test_measure_kernel_normal \ ++ test_invalid_policy" ++ ++for case in $case_list; do ++ test_pre ++ $case ++ if [ $TEST_RESULT -eq 0 ]; then ++ echo "$case PASS" ++ else ++ echo "$case FAIL" ++ fi ++ test_post ++done ++ +diff --git a/test/test_dim_monitor.sh b/test/test_dim_monitor.sh +new file mode 100644 +index 0000000..b4a1ea8 +--- /dev/null ++++ b/test/test_dim_monitor.sh +@@ -0,0 +1,32 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++#!/bin/bash ++ ++. ./common.sh ++ ++test_measure_monitor_normal() { ++ dim_gen_baseline_all ++ dim_gen_policy_all ++ check_dim_core_log_normal ++ check_dim_monitor_log_normal ++} ++ ++test_measure_monitor_tamper() { ++ test_measure_monitor_normal ++ check_dim_monitor_log_tampered ++} ++ ++# Full measurement. The test is disabled by default. ++# case_list="test_measure_monitor_normal \ ++# test_measure_monitor_tamper" ++case_list="" ++ ++for case in $case_list; do ++ test_pre ++ $case ++ if [ $TEST_RESULT -eq 0 ]; then ++ echo "$case PASS" ++ else ++ echo "$case FAIL" ++ fi ++ test_post ++done +diff --git a/test/test_module/Makefile b/test/test_module/Makefile +new file mode 100644 +index 0000000..4255525 +--- /dev/null ++++ b/test/test_module/Makefile +@@ -0,0 +1,16 @@ ++# Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ ++obj-m := dim_test_module_demo.o ++ ++KERNEL := $(DESTDIR)/lib/modules/$(shell uname -r)/build ++CONFIG_MODULE_SIG=n ++ ++PWD := $(shell pwd) ++ ++modules : ++ $(MAKE) -C $(KERNEL) M=$(PWD) modules ++ ++.PHONEY:clean ++ ++clean : ++ $(MAKE) -C $(KERNEL) SUBDIRS=$(PWD) clean +diff --git a/test/test_module/dim_test_module_demo.c b/test/test_module/dim_test_module_demo.c +new file mode 100644 +index 0000000..3303365 +--- /dev/null ++++ b/test/test_module/dim_test_module_demo.c +@@ -0,0 +1,20 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#include ++ ++static int test_mod_init(void) ++{ ++ pr_info("init!\n"); ++ return 0; ++} ++ ++static void test_mod_exit(void) ++{ ++ pr_info("exit!\n"); ++} ++ ++module_init(test_mod_init); ++module_exit(test_mod_exit); ++MODULE_LICENSE(""); +diff --git a/test/test_module/dim_test_module_demo_tamper.c b/test/test_module/dim_test_module_demo_tamper.c +new file mode 100644 +index 0000000..c443d7b +--- /dev/null ++++ b/test/test_module/dim_test_module_demo_tamper.c +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (c) Huawei Technologies Co., Ltd. 2023-2023. All rights reserved. ++ */ ++ ++#include ++ ++static int test_mod_init(void) ++{ ++ int i = 0; ++ i += 1; ++ pr_info("%d\n", i); ++ pr_info("init!\n"); ++ return 0; ++} ++ ++static void test_mod_exit(void) ++{ ++ pr_info("exit!\n"); ++} ++ ++module_init(test_mod_init); ++module_exit(test_mod_exit); ++MODULE_LICENSE(""); +-- +2.33.0 + diff --git a/fix-build-error-in-kernel-6.6.patch b/backport-fix-build-error-in-kernel-6.6.patch similarity index 72% rename from fix-build-error-in-kernel-6.6.patch rename to backport-fix-build-error-in-kernel-6.6.patch index af80998f7626b8c1f9128c73df7e1bc81268cbe9..013c872f0aa582f48c2ddd62a0a54643af1a285c 100644 --- a/fix-build-error-in-kernel-6.6.patch +++ b/backport-fix-build-error-in-kernel-6.6.patch @@ -1,14 +1,14 @@ -From dd7f8dd49e927be2219a34bf88d09e80a0e6446d Mon Sep 17 00:00:00 2001 +From b43b4c3301ffd1ca27a0826db09465a3d90f5169 Mon Sep 17 00:00:00 2001 From: jinlun -Date: Fri, 26 Jan 2024 15:22:42 +0800 -Subject: [PATCH] fix build error in kernel-6.6 +Date: Mon, 29 Jan 2024 10:17:24 +0800 +Subject: [PATCH 10/26] fix build error in kernel-6.6 --- src/core/dim_core_measure_task.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/dim_core_measure_task.c b/src/core/dim_core_measure_task.c -index f9c53f0..f70d701 100644 +index 0d9b995..6ab60d1 100644 --- a/src/core/dim_core_measure_task.c +++ b/src/core/dim_core_measure_task.c @@ -223,7 +223,11 @@ static int update_vma_digest(struct vm_area_struct *vma_start, @@ -21,7 +21,7 @@ index f9c53f0..f70d701 100644 + 0, pages, NULL); +#endif if (ret_pages < 0) { - dim_err("fail to get vma pages: %ld\n", ret_pages); + dim_err("failed to get vma pages: %ld\n", ret_pages); vfree(pages); -- 2.33.0 diff --git a/backport-fix-build-error.patch b/backport-fix-build-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..8c8c386fa0bef4f65f14c30c017ac3f74caebc19 --- /dev/null +++ b/backport-fix-build-error.patch @@ -0,0 +1,25 @@ +From 0140b4eb57f2c434fed5357944bacb76a66c92ea Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Fri, 9 Feb 2024 19:39:40 +0800 +Subject: [PATCH 11/26] fix build error + +--- + src/common/dim_baseline.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/common/dim_baseline.c b/src/common/dim_baseline.c +index 4733705..09a2780 100644 +--- a/src/common/dim_baseline.c ++++ b/src/common/dim_baseline.c +@@ -105,7 +105,7 @@ int dim_baseline_add(struct dim_baseline_tree *root, const char *name, + goto err; + + strncpy((char *)baseline->name, name, buf_len - 1); +- baseline->name[buf_len - 1] = '\0'; ++ ((char *)baseline->name)[buf_len - 1] = '\0'; + + write_lock(&root->lock); + ret = dim_baseline_rb_add(&root->rb_root, baseline, NULL); +-- +2.33.0 + diff --git a/backport-fix-the-magic-number.patch b/backport-fix-the-magic-number.patch new file mode 100644 index 0000000000000000000000000000000000000000..cca683e3a6a7801e007fa19e67d8d1f400e94ce2 --- /dev/null +++ b/backport-fix-the-magic-number.patch @@ -0,0 +1,39 @@ +From 1ca2bccf3608fafc95c32714127e8ff9c1fefbc4 Mon Sep 17 00:00:00 2001 +From: Huaxin Lu +Date: Thu, 16 Nov 2023 15:03:47 +0800 +Subject: [PATCH 05/26] fix the magic number + +--- + src/core/dim_core_measure.h | 2 ++ + src/core/dim_core_measure_kernel.c | 2 +- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/core/dim_core_measure.h b/src/core/dim_core_measure.h +index c9abc4e..a379cf6 100644 +--- a/src/core/dim_core_measure.h ++++ b/src/core/dim_core_measure.h +@@ -17,6 +17,8 @@ + #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; +diff --git a/src/core/dim_core_measure_kernel.c b/src/core/dim_core_measure_kernel.c +index faaf59c..135899d 100644 +--- a/src/core/dim_core_measure_kernel.c ++++ b/src/core/dim_core_measure_kernel.c +@@ -78,7 +78,7 @@ static int do_calc_kernel_digest(uintptr_t saddr, + #ifdef JUMP_LABEL_NOP_SIZE + cur_addr = jump_code + JUMP_LABEL_NOP_SIZE; + #else +- cur_addr = jump_code + 5; // TODO ++ cur_addr = jump_code + DIM_JUMP_LABEL_NOP_SIZE_MAX; + #endif + } + +-- +2.33.0 + diff --git a/backport-some-word.patch b/backport-some-word.patch new file mode 100644 index 0000000000000000000000000000000000000000..e5ab5b6a4ea2b22963fb23561c0cc57be0bd99f0 --- /dev/null +++ b/backport-some-word.patch @@ -0,0 +1,567 @@ +From 1b6ab8135e1b2f4f5d0f4ce559f46bc8d71022b6 Mon Sep 17 00:00:00 2001 +From: xuyongliang_01 +Date: Wed, 6 Dec 2023 09:55:20 +0800 +Subject: [PATCH 07/26] some word + +--- + src/core/dim_core_baseline.c | 8 ++++---- + src/core/dim_core_fs.c | 2 +- + src/core/dim_core_main.c | 10 +++++----- + src/core/dim_core_measure.c | 24 ++++++++++++------------ + src/core/dim_core_measure_common.c | 2 +- + src/core/dim_core_measure_kernel.c | 8 ++++---- + src/core/dim_core_measure_task.c | 20 ++++++++++---------- + src/core/dim_core_mem_pool.c | 12 ++++++------ + src/core/dim_core_policy.c | 10 +++++----- + src/core/dim_core_sig.c | 10 +++++----- + src/core/dim_core_static_baseline.c | 10 +++++----- + src/core/dim_core_symbol.c | 2 +- + 12 files changed, 59 insertions(+), 59 deletions(-) + +diff --git a/src/core/dim_core_baseline.c b/src/core/dim_core_baseline.c +index a0f4832..27a8114 100644 +--- a/src/core/dim_core_baseline.c ++++ b/src/core/dim_core_baseline.c +@@ -35,7 +35,7 @@ int dim_core_add_static_baseline(const char *name, int type, + { + int ret = dim_baseline_add(&static_baseline, name, type, digest); + if (ret < 0 && ret != -EEXIST) { +- dim_err("fail to add static baseline of %s\n", name); ++ dim_err("failed to add static baseline of %s\n", name); + return ret; + } + +@@ -47,7 +47,7 @@ int dim_core_add_dynamic_baseline(const char *name, int type, + { + int ret = dim_baseline_add(&dynamic_baseline, name, type, digest); + if (ret < 0 && ret != -EEXIST) { +- dim_err("fail to add dynamic baseline of %s\n", name); ++ dim_err("failed to add dynamic baseline of %s\n", name); + return ret; + } + +@@ -93,7 +93,7 @@ int dim_core_baseline_init(void) + dim_kfree, + &static_baseline); + if (ret < 0) { +- dim_err("fail to initialize static baseline root: %d\n", ret); ++ dim_err("failed to initialize static baseline root: %d\n", ret); + return ret; + } + +@@ -101,7 +101,7 @@ int dim_core_baseline_init(void) + dim_mem_pool_free, + &dynamic_baseline); + if (ret < 0) { +- dim_err("fail to initialize dynamic baseline root: %d\n", ret); ++ dim_err("failed to initialize dynamic baseline root: %d\n", ret); + return ret; + } + +diff --git a/src/core/dim_core_fs.c b/src/core/dim_core_fs.c +index d5e39ba..e050a19 100644 +--- a/src/core/dim_core_fs.c ++++ b/src/core/dim_core_fs.c +@@ -105,7 +105,7 @@ int dim_core_create_fs(void) + + ret = dim_entry_create(&dim_core_dir, NULL); + if (ret < 0) { +- dim_err("fail to create dim dir entry: %d\n", ret); ++ dim_err("failed to create dim dir entry: %d\n", ret); + return ret; + } + +diff --git a/src/core/dim_core_main.c b/src/core/dim_core_main.c +index edd86cc..6de0c2a 100644 +--- a/src/core/dim_core_main.c ++++ b/src/core/dim_core_main.c +@@ -38,20 +38,20 @@ static int __init dim_core_init(void) + + ret = dim_core_kallsyms_init(); + if (ret < 0) { +- dim_err("fail to initialize dim kernel symbol: %d\n", ret); ++ dim_err("failed to initialize dim kernel symbol: %d\n", ret); + goto err; + } + + ret = dim_mem_pool_init(); + if (ret < 0) { +- dim_err("fail to initialize dim memory pool: %d\n", ret); ++ dim_err("failed to initialize dim memory pool: %d\n", ret); + goto err; + } + + if (signature) { + ret = dim_core_sig_init(); + if (ret < 0) { +- dim_err("fail to initialize dim signature: %d\n", ret); ++ dim_err("failed to initialize dim signature: %d\n", ret); + goto err; + } + } +@@ -59,13 +59,13 @@ static int __init dim_core_init(void) + ret = dim_core_measure_init(measure_hash == NULL ? + DIM_CORE_HASH_DEFAULT : measure_hash); + if (ret < 0) { +- dim_err("fail to initialize dim measurement: %d\n", ret); ++ dim_err("failed to initialize dim measurement: %d\n", ret); + goto err; + } + + ret = dim_core_create_fs(); + if (ret < 0) { +- dim_err("fail to create dim fs entry: %d\n", ret); ++ dim_err("failed to create dim fs entry: %d\n", ret); + goto err; + } + +diff --git a/src/core/dim_core_measure.c b/src/core/dim_core_measure.c +index 59e2cf8..ed4a464 100644 +--- a/src/core/dim_core_measure.c ++++ b/src/core/dim_core_measure.c +@@ -125,15 +125,15 @@ static void do_measure(void) + + ret = dim_core_measure_task(bi); + if (ret < 0) +- dim_err("fail to measure user process: %d\n", ret); ++ dim_err("failed to measure user process: %d\n", ret); + + ret = dim_core_measure_module(bi); + if (ret < 0) +- dim_err("fail to measure kernel modules: %d\n", ret); ++ dim_err("failed to measure kernel modules: %d\n", ret); + + ret = dim_core_measure_kernel(bi); + if (ret < 0) +- dim_err("fail to measure kernel: %d\n", ret); ++ dim_err("failed to measure kernel: %d\n", ret); + + mutex_unlock(&dim_core_baseline_lock); + } +@@ -144,14 +144,14 @@ static int do_baseline(void) + + ret = dim_core_policy_load(); + if (ret < 0) { +- dim_err("fail to load dim core policy: %d\n", ret); ++ dim_err("failed to load dim core policy: %d\n", ret); + return ret; + } + + dim_core_baseline_destroy(); + ret = dim_core_static_baseline_load(); + if (ret < 0) { +- dim_err("fail to load dim static baseline: %d\n", ret); ++ dim_err("failed to load dim static baseline: %d\n", ret); + dim_core_policy_destroy(); + return ret; + } +@@ -232,7 +232,7 @@ int dim_core_measure_init(const char *alg_name) + /* 2. init measure hash algorithm */ + ret = dim_hash_init(alg_name, &dim_core_hash); + if (ret < 0) { +- dim_err("fail to initialize hash algorithm: %d\n", ret); ++ dim_err("failed to initialize hash algorithm: %d\n", ret); + goto err; + } + +@@ -240,20 +240,20 @@ int dim_core_measure_init(const char *alg_name) + if (measure_pcr > 0) { + ret = dim_tpm_init(&dim_core_tpm, HASH_ALGO_SHA256); + if (ret < 0) +- dim_warn("fail to initialize tpm chip: %d\n", ret); ++ dim_warn("failed to initialize tpm chip: %d\n", ret); + } + + /* 4. init measurement status */ + ret = dim_core_status_init(); + if (ret < 0) { +- dim_err("fail to initialize dim status: %d\n", ret); ++ dim_err("failed to initialize dim status: %d\n", ret); + goto err; + } + + /* 5. init baseline data (static and dynamic) */ + ret = dim_core_baseline_init(); + if (ret < 0) { +- dim_err("fail to initialize dim baseline: %d\n", ret); ++ dim_err("failed to initialize dim baseline: %d\n", ret); + goto err; + } + +@@ -262,7 +262,7 @@ int dim_core_measure_init(const char *alg_name) + &dim_core_hash, &dim_core_tpm, + measure_log_capacity, measure_pcr); + if (ret < 0) { +- dim_err("fail to initialize measure log root: %d\n", ret); ++ dim_err("failed to initialize measure log root: %d\n", ret); + goto err; + } + +@@ -271,7 +271,7 @@ int dim_core_measure_init(const char *alg_name) + dim_work_queue = create_singlethread_workqueue("dim_core"); + if (dim_work_queue == NULL) { + ret = -ENOMEM; +- dim_err("fail to create dim work queue: %d\n", ret); ++ dim_err("failed to create dim work queue: %d\n", ret); + goto err; + } + +@@ -279,7 +279,7 @@ int dim_core_measure_init(const char *alg_name) + if (measure_interval) { + ret = dim_core_measure(1); + if (ret < 0) { +- dim_err("fail to do baseline init: %d\n", ret); ++ dim_err("failed to do baseline init: %d\n", ret); + goto err; + } + +diff --git a/src/core/dim_core_measure_common.c b/src/core/dim_core_measure_common.c +index 4e4c0f4..406ed3f 100644 +--- a/src/core/dim_core_measure_common.c ++++ b/src/core/dim_core_measure_common.c +@@ -15,7 +15,7 @@ int dim_core_add_measure_log(const char *name, struct dim_digest *digest, int fl + { + int ret = dim_measure_log_add(&dim_core_log, name, digest, flag); + if (ret < 0 && ret != -EEXIST) { +- dim_err("fail to add measure log of %s: %d\n", name, ret); ++ dim_err("failed to add measure log of %s: %d\n", name, ret); + return ret; + } + +diff --git a/src/core/dim_core_measure_kernel.c b/src/core/dim_core_measure_kernel.c +index 135899d..3724501 100644 +--- a/src/core/dim_core_measure_kernel.c ++++ b/src/core/dim_core_measure_kernel.c +@@ -111,7 +111,7 @@ static int calc_kernel_digest(struct dim_digest *digest) + sizeof(struct jump_entry); + ret = sort_jump_table(sjump, jcode_cnt, &jcode_sort); + if (ret < 0) { +- dim_err("fail to sort kernel jump table: %d\n", ret); ++ dim_err("failed to sort kernel jump table: %d\n", ret); + return ret; + } + } else { +@@ -121,7 +121,7 @@ static int calc_kernel_digest(struct dim_digest *digest) + + ret = do_calc_kernel_digest(stext, etext, jcode_sort, jcode_cnt, digest); + if (ret < 0) +- dim_err("fail to calculate kernel digest: %d\n", ret); ++ dim_err("failed to calculate kernel digest: %d\n", ret); + + vfree(jcode_sort); + return ret; +@@ -139,13 +139,13 @@ int dim_core_measure_kernel(int baseline_init) + + ret = calc_kernel_digest(&digest); + if (ret < 0) { +- dim_err("fail to calculate kernel digest: %d\n", ret); ++ dim_err("failed to calculate kernel digest: %d\n", ret); + return ret; + } + + ret = dim_core_check_kernel_digest(baseline_init, kr, &digest); + if (ret < 0) +- dim_err("fail to check kernel digest: %d\n", ret); ++ dim_err("failed to check kernel digest: %d\n", ret); + + return ret; + } +diff --git a/src/core/dim_core_measure_task.c b/src/core/dim_core_measure_task.c +index f9c53f0..0d9b995 100644 +--- a/src/core/dim_core_measure_task.c ++++ b/src/core/dim_core_measure_task.c +@@ -192,7 +192,7 @@ static bool vm_file_match_policy(struct file *vm_file, + /* get the module path string */ + ctx->path = d_path(&vm_file->f_path, ctx->path_buf, PATH_MAX); + if (IS_ERR(ctx->path)) { +- dim_warn("fail to get path of vma: %ld\n", PTR_ERR(ctx->path)); ++ dim_warn("failed to get path of vma: %ld\n", PTR_ERR(ctx->path)); + ctx->path = NULL; + return false; + } +@@ -225,7 +225,7 @@ static int update_vma_digest(struct vm_area_struct *vma_start, + ret_pages = get_user_pages_remote(vma_start->vm_mm, addr_start, nr_pages, + 0, pages, NULL, NULL); + if (ret_pages < 0) { +- dim_err("fail to get vma pages: %ld\n", ret_pages); ++ dim_err("failed to get vma pages: %ld\n", ret_pages); + vfree(pages); + return ret_pages; + } +@@ -233,7 +233,7 @@ static int update_vma_digest(struct vm_area_struct *vma_start, + for (i = 0; i < ret_pages; i++) { + page_ptr = kmap(pages[i]); + if (page_ptr == NULL) { +- dim_err("fail to kmap page\n"); ++ dim_err("failed to kmap page\n"); + put_page(pages[i]); + continue; + } +@@ -257,7 +257,7 @@ static int check_user_digest(struct dim_digest *digest, + ret = dim_core_check_user_digest(ctx->baseline, ctx->path, + digest, &log_flag); + if (ret < 0) { +- dim_err("fail to check user digest: %d\n", ret); ++ dim_err("failed to check user digest: %d\n", ret); + return ret; + } + +@@ -315,7 +315,7 @@ static int measure_task_module_anon_text(struct vm_area_struct *vma, + + ret = measure_anon_text_vma(v, ctx); + if (ret < 0) +- dim_err("fail to measure anon text vma: %d\n", ret); ++ dim_err("failed to measure anon text vma: %d\n", ret); + } + + return 0; +@@ -367,11 +367,11 @@ static void measure_task_module(struct vm_area_struct *vma, + + ret = measure_task_module_file_text(vma, ctx); + if (ret < 0) +- dim_err("fail to measure module file text: %d", ret); ++ dim_err("failed to measure module file text: %d", ret); + #ifdef DIM_CORE_MEASURE_ANON_TEXT + ret = measure_task_module_anon_text(vma, ctx); + if (ret < 0) +- dim_err("fail to measure module anon text: %d", ret); ++ dim_err("failed to measure module anon text: %d", ret); + #endif + } + +@@ -425,7 +425,7 @@ out: + if (ctx->task_kill) { + ret = kill_task_tree(task); + if (ret < 0) +- dim_err("fail to kill tampered task, pid = %d: %d\n", ++ dim_err("failed to kill tampered task, pid = %d: %d\n", + task->pid, ret); + } + +@@ -446,7 +446,7 @@ static int store_task_pids(pid_t **pid_buf, unsigned int *pid_cnt) + /* maximum processing of PID_MAX_DEFAULT * 2 pids */ + buf = vmalloc(max_cnt); + if (buf == NULL) { +- dim_err("fail to allocate memory for pid buffer\n"); ++ dim_err("failed to allocate memory for pid buffer\n"); + return -ENOMEM; + } + +@@ -494,7 +494,7 @@ static int walk_tasks(task_measurer f, struct task_measure_ctx *ctx) + ret = f(task, ctx); + put_task_struct(task); + if (ret < 0) { +- dim_err("fail to measure task, pid = %d: %d", pid_buf[i], ret); ++ dim_err("failed to measure task, pid = %d: %d", pid_buf[i], ret); + if (ret == -EINTR) + break; + } +diff --git a/src/core/dim_core_mem_pool.c b/src/core/dim_core_mem_pool.c +index 5688eaf..a16b7bb 100644 +--- a/src/core/dim_core_mem_pool.c ++++ b/src/core/dim_core_mem_pool.c +@@ -18,7 +18,7 @@ static int dim_mem_pool_expand(unsigned int order) + + pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order); + if (pages == NULL) { +- dim_err("fail to allocate pages for memory pool\n"); ++ dim_err("failed to allocate pages for memory pool\n"); + return -ENOMEM; + } + +@@ -27,7 +27,7 @@ static int dim_mem_pool_expand(unsigned int order) + + ret = gen_pool_add(dim_pool, pages_addr, size, -1); + if (ret < 0) { +- dim_err("fail to add pages to memory pool: %d\n", ret); ++ dim_err("failed to add pages to memory pool: %d\n", ret); + return ret; + } + +@@ -41,7 +41,7 @@ int dim_mem_pool_init(void) + + dim_pool = gen_pool_create(DIM_MIN_ALLOC_ORDER, -1); + if (dim_pool == NULL) { +- dim_err("fail to generate memory pool\n"); ++ dim_err("failed to generate memory pool\n"); + return -ENOMEM; + } + +@@ -72,7 +72,7 @@ void dim_mem_pool_destroy(void) + return; + + if (gen_pool_avail(dim_pool) != gen_pool_size(dim_pool)) { +- dim_err("dim_mem_pool_destroy fail, memory leak detected\n"); ++ dim_err("dim_mem_pool_destroy failed, memory leak detected\n"); + return; + } + +@@ -96,10 +96,10 @@ void *dim_mem_pool_alloc(size_t size) + if (data != NULL) + goto out; + +- dim_devel("gen_pool_alloc fail, try dim_mem_pool_expand\n"); ++ dim_devel("gen_pool_alloc failed, try dim_mem_pool_expand\n"); + ret = dim_mem_pool_expand(DIM_EXPEND_ALLOC_PAGE_ORDER); + if (ret < 0) { +- dim_err("fail to expand memory pool: %d\n", ret); ++ dim_err("failed to expand memory pool: %d\n", ret); + return NULL; + } + +diff --git a/src/core/dim_core_policy.c b/src/core/dim_core_policy.c +index a3fa369..0e7fbf3 100644 +--- a/src/core/dim_core_policy.c ++++ b/src/core/dim_core_policy.c +@@ -118,7 +118,7 @@ static int policy_add_path(const char *path, int action) + + apath = dim_absolute_path(path, path_buf, PATH_MAX); + if (IS_ERR(apath)) { +- dim_warn("fail to get absolute path of %s in policy: %ld\n", ++ dim_warn("failed to get absolute path of %s in policy: %ld\n", + path, PTR_ERR(apath)); + kfree(path_buf); + return 0; +@@ -200,7 +200,7 @@ static int policy_parse_line(char* line, int line_no) + if (obj == DIM_POLICY_OBJ_KERNEL_TEXT) { + ret = policy_add_kernel(action); + if (ret < 0) +- dim_err("fail to add measure policy line %d: %d\n", ++ dim_err("failed to add measure policy line %d: %d\n", + line_no, ret); + return ret; + } +@@ -221,7 +221,7 @@ static int policy_parse_line(char* line, int line_no) + policy_add_path(val, action) : + policy_add_module(val, action); + if (ret < 0) +- dim_err("fail to add measure policy line %d: %d\n", ++ dim_err("failed to add measure policy line %d: %d\n", + line_no, ret); + return ret; + } +@@ -237,14 +237,14 @@ int dim_core_policy_load(void) + + ret = dim_read_verify_file(NULL, DIM_POLICY_PATH, &buf); + if (ret < 0 || buf == NULL) { +- dim_err("fail to read policy file: %d\n", ret); ++ 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("fail to parse policy: %d\n", ret); ++ dim_err("failed to parse policy: %d\n", ret); + dim_core_policy_destroy(); + } + +diff --git a/src/core/dim_core_sig.c b/src/core/dim_core_sig.c +index 18f6008..aae323c 100644 +--- a/src/core/dim_core_sig.c ++++ b/src/core/dim_core_sig.c +@@ -141,7 +141,7 @@ int dim_core_sig_init(void) + KEY_ALLOC_NOT_IN_QUOTA, NULL, NULL); + if (IS_ERR(dim_core_keyring)) { + ret = PTR_ERR(dim_core_keyring); +- dim_err("fail to allocate DIM keyring: %ld\n", ret); ++ dim_err("failed to allocate DIM keyring: %ld\n", ret); + return ret; + } + +@@ -149,7 +149,7 @@ int dim_core_sig_init(void) + DIM_CORE_MAX_FILE_SIZE, NULL, + READING_X509_CERTIFICATE); + if (ret < 0) { +- dim_err("fail to read DIM cert file: %ld\n", ret); ++ dim_err("failed to read DIM cert file: %ld\n", ret); + goto err; + } + +@@ -158,13 +158,13 @@ int dim_core_sig_init(void) + DIM_CORE_KEY_PERM, KEY_ALLOC_NOT_IN_QUOTA); + if (IS_ERR(key)) { + ret = PTR_ERR(key); +- dim_err("fail to load DIM cert: %ld\n", ret); ++ dim_err("failed to load DIM cert: %ld\n", ret); + goto err; + } + + ret = dim_hash_init("sha256", &dim_core_sig_hash); + if (ret < 0) { +- dim_err("fail to init dim signature hash: %ld\n", ret); ++ dim_err("failed to init dim signature hash: %ld\n", ret); + goto err; + } + +@@ -186,4 +186,4 @@ void dim_core_sig_destroy(void) + key_put(dim_core_keyring); + + dim_hash_destroy(&dim_core_sig_hash); +-} +\ No newline at end of file ++} +diff --git a/src/core/dim_core_static_baseline.c b/src/core/dim_core_static_baseline.c +index f779da1..0d99f7b 100644 +--- a/src/core/dim_core_static_baseline.c ++++ b/src/core/dim_core_static_baseline.c +@@ -112,7 +112,7 @@ static int parse_simple_baseline_line(char* line, int line_no) + + ret = dim_core_add_static_baseline(line_str, type, &digest); + if (ret < 0) +- dim_warn("fail to add static baseline at line %d: %d\n", ++ dim_warn("failed to add static baseline at line %d: %d\n", + line_no, ret); + return 0; + } +@@ -144,14 +144,14 @@ static_baseline_load(struct dir_context *__ctx, + + ret = dim_read_verify_file(ctx->path, name, &buf); + if (ret < 0 || buf == NULL) { +- dim_err("fail to read and verify %s: %d\n", name, ret); ++ dim_err("failed to read and verify %s: %d\n", name, ret); + goto out; + } + + buf_len = ret; + ret = dim_parse_line_buf(buf, buf_len, parse_simple_baseline_line); + if (ret < 0) +- dim_err("fail to parse baseline file %s: %d\n", name, ret); ++ dim_err("failed to parse baseline file %s: %d\n", name, ret); + out: + if (buf != NULL) + vfree(buf); +@@ -175,14 +175,14 @@ int dim_core_static_baseline_load(void) + + ret = kern_path(DIM_STATIC_BASELINE_ROOT, LOOKUP_DIRECTORY, &kpath); + if (ret < 0) { +- dim_err("fail to get dim baseline root path: %d", ret); ++ dim_err("failed to get dim baseline root path: %d", ret); + return ret; + } + + file = filp_open(DIM_STATIC_BASELINE_ROOT, O_RDONLY | O_DIRECTORY, 0); + if (IS_ERR(file)) { + ret = PTR_ERR(file); +- dim_err("fail to open %s: %d\n", DIM_STATIC_BASELINE_ROOT, ret); ++ dim_err("failed to open %s: %d\n", DIM_STATIC_BASELINE_ROOT, ret); + path_put(&kpath); + return ret; + } +diff --git a/src/core/dim_core_symbol.c b/src/core/dim_core_symbol.c +index 128e595..3da3df2 100644 +--- a/src/core/dim_core_symbol.c ++++ b/src/core/dim_core_symbol.c +@@ -23,7 +23,7 @@ int dim_core_kallsyms_init(void) + + dim_kallsyms_lookup_name = dim_get_symbol_lookup_func(); + if (dim_kallsyms_lookup_name == NULL) { +- dim_err("fail to get symbol_lookup_func\n"); ++ dim_err("failed to get symbol_lookup_func\n"); + return -EINVAL; + } + k->stext = (char *)dim_kallsyms_lookup_name("_stext"); +-- +2.33.0 + diff --git a/backport-update-src-common-dim_baseline.c.patch b/backport-update-src-common-dim_baseline.c.patch new file mode 100644 index 0000000000000000000000000000000000000000..3935d1c066927742b156242def96faf327c6c8e9 --- /dev/null +++ b/backport-update-src-common-dim_baseline.c.patch @@ -0,0 +1,31 @@ +From ee0e50754cb5bf5943d4f16508725b3f65931f24 Mon Sep 17 00:00:00 2001 +From: lixiang_yewu +Date: Tue, 2 Jan 2024 02:27:55 +0000 +Subject: [PATCH 09/26] update src/common/dim_baseline.c. + +Signed-off-by: lixiang_yewu + +update src/common/dim_baseline.c. + +Signed-off-by: lixiang_yewu +--- + src/common/dim_baseline.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/common/dim_baseline.c b/src/common/dim_baseline.c +index 6369d7b..4733705 100644 +--- a/src/common/dim_baseline.c ++++ b/src/common/dim_baseline.c +@@ -104,7 +104,8 @@ int dim_baseline_add(struct dim_baseline_tree *root, const char *name, + if (ret < 0) + goto err; + +- strcpy((char *)baseline->name, name); ++ strncpy((char *)baseline->name, name, buf_len - 1); ++ baseline->name[buf_len - 1] = '\0'; + + write_lock(&root->lock); + ret = dim_baseline_rb_add(&root->rb_root, baseline, NULL); +-- +2.33.0 + diff --git a/dim.spec b/dim.spec index 4953ee4c81e31e78ff5db375162993b31e0b9d3d..183cf27e9c518edbe33a9d4ed299597f7a3c6aff 100644 --- a/dim.spec +++ b/dim.spec @@ -4,7 +4,7 @@ Name : dim Summary : Dynamic Integrity Measurement Version : 1.0.2 -Release : 5 +Release : 6 License : GPL-2.0 Source0 : %{name}-v%{version}.tar.gz BuildRequires: kernel-devel kernel-headers @@ -13,7 +13,28 @@ Requires : kernel Patch0001: Limit-the-max-line-number-of-policy-and-baseline-par.patch Patch0002: Use-jiffies64-interface-to-set-measure-interval.patch Patch0003: Add-the-owner-of-file-operations.patch -Patch0004: fix-build-error-in-kernel-6.6.patch +Patch0004: backport-dim-add-test-code.patch +Patch0005: backport-fix-the-magic-number.patch +Patch0006: backport-some-word.patch +Patch0007: backport-update-src-common-dim_baseline.c.patch +Patch0008: backport-fix-build-error-in-kernel-6.6.patch +Patch0009: backport-fix-build-error.patch +Patch0010: backport-Refactor-the-measurement-code.patch +Patch0011: backport-Refactor-dim_core-policy-and-support-the-action-poli.patch +Patch0012: backport-Refactor-the-dim_core-static-baseline-implement.patch +Patch0013: backport-Support-user-process-measurement-by-ELF-parsing.patch +Patch0014: backport-Optimize-Makefile.patch +Patch0015: backport-Dont-queue-measurement-task-when-baseline-failed.patch +Patch0016: backport-Add-safe-wapper-for-some-memory-and-string-functions.patch +Patch0017: backport-Fix-potential-integer-overflow.patch +Patch0018: backport-Add-memory-debug-in-mem_pool.patch +Patch0019: backport-Optimize-test-framework-and-add-testcases.patch +Patch0020: backport-Add-warpper-for-strncmp-and-strncpy.patch +Patch0021: backport-Use-warpper-dim_vzalloc-to-avoid-false-warning.patch +Patch0022: backport-Set-dim_core_keyring-to-NULL-when-initialize-failed.patch +Patch0023: backport-Disable-dfx-testcase-by-default.patch +Patch0024: backport-Support-init-function-for-measure-tasks.patch + %description Dynamic Integrity Measurement @@ -51,6 +72,9 @@ rm -rf %{buildroot} %attr(0400,root,root) /lib/modules/%{kernel_version}/extra/dim/dim_monitor.ko %changelog +* Tue Apr 16 2024 jinlun 1.0.2-6 +- backport some patches + * Fri Jan 26 2024 jinlun 1.0.2-5 - The compilation error asused by the kernel upgrade is rectified.