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