From af326ccd9958b1b3b19e34d562a69c05e49d3d5e Mon Sep 17 00:00:00 2001 From: limerence Date: Wed, 11 Oct 2023 19:39:56 +0800 Subject: [PATCH] add developer proc Signed-off-by: limerence --- xpm/Kconfig | 9 +++ xpm/Makefile | 1 + xpm/core/dsmm_developer.c | 112 +++++++++++++++++++++++++++++++++++ xpm/core/xpm_module.c | 6 ++ xpm/include/dsmm_developer.h | 31 ++++++++++ 5 files changed, 159 insertions(+) create mode 100644 xpm/core/dsmm_developer.c create mode 100644 xpm/include/dsmm_developer.h diff --git a/xpm/Kconfig b/xpm/Kconfig index c83c625..e74ba0d 100755 --- a/xpm/Kconfig +++ b/xpm/Kconfig @@ -15,6 +15,15 @@ config SECURITY_XPM mmap and etc. It can control not to execute an illegal signature process. +config DSMM_DEVELOPER_ENABLE + bool "Enables device developer mode feature" + depends on SECURITY_XPM + default n + help + This option should only be enabled for the device support developer + mode feature. But whether or not developer mode is enabled on the + device ultimately depends on the developer_mode valude in cmdline. + config SECURITY_XPM_DEBUG bool "Enables excutable permission manager debug mode" depends on SECURITY_XPM diff --git a/xpm/Makefile b/xpm/Makefile index 3f94ecd..36494c3 100755 --- a/xpm/Makefile +++ b/xpm/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_SECURITY_XPM) += \ core/xpm_misc.o \ core/xpm_hck.o \ core/xpm_report.o \ + core/dsmm_developer.o \ validator/elf_code_segment_info.o \ validator/exec_signature_info.o diff --git a/xpm/core/dsmm_developer.c b/xpm/core/dsmm_developer.c new file mode 100644 index 0000000..66b10f8 --- /dev/null +++ b/xpm/core/dsmm_developer.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + */ + +#include +#include "dsmm_developer.h" +#include "xpm_log.h" + +#define DSMM_DIR "dsmm" +#define DSMM_DEVELOPER_FILE "developer" +#define DSMM_DEVELOPER_PARAM_NAME "const.security.developermode.state" + +static struct proc_dir_entry *g_dsmm_dir; + +static const char *g_developer_status[BUILD_VARIANT_MAX][DEVELOPER_PROC_STATUS_MAX] = { + { DEVELOPER_STATUS_OFF, DEVELOPER_STATUS_ON, DEVELOPER_STATUS_OFF }, + { DEVELOPER_STATUS_ON, DEVELOPER_STATUS_ON, DEVELOPER_STATUS_OFF }, +}; + +static int get_developer_status(uint32_t *status) +{ + if (!strstr(saved_command_line, "developer_mode=")) { + *status = DEVELOPER_PROC_STATUS_NA; + } else if (strstr(saved_command_line, "developer_mode=1")) { + *status = DEVELOPER_PROC_STATUS_ON; + } else if (strstr(saved_command_line, "developer_mode=0")) { + *status = DEVELOPER_PROC_STATUS_OFF; + } else { + xpm_log_error("invalid developer_mode value in cmdline"); + return -EINVAL; + } + + return 0; +} + +static int get_build_variant(uint32_t *variant) +{ + if (strstr(saved_command_line, "buildvariant=user")) { + *variant = BUILD_VARIANT_USER; + } else if (strstr(saved_command_line, "buildvariant=eng")) { + *variant = BUILD_VARIANT_ENG; + } else { + xpm_log_error("invalid buildvariant value in cmdline"); + return -EINVAL; + } + + return 0; +} + +const char *developer_mode_state(void) +{ + uint32_t variant, status; + +#ifdef CONFIG_DSMM_DEVELOPER_ENABLE + if (get_build_variant(&variant) || get_developer_status(&status)) { + xpm_log_error("get build variant or developer status failed"); + return NULL; + } + + return g_developer_status[variant][status]; +#else + return DEVELOPER_STATUS_ON; +#endif +} + +#define PROC_DEVELOPER_LEN 50 +static ssize_t dsmm_read_developer_proc(struct file *file, char __user *buf, + size_t count, loff_t *pos) +{ + size_t len; + char proc_developer[PROC_DEVELOPER_LEN] = {0}; + const char *developer_state = developer_mode_state(); + + if (!developer_state) { + xpm_log_error("developer mode state invalid"); + return 0; + } + + len = snprintf(proc_developer, PROC_DEVELOPER_LEN - 1, + DSMM_DEVELOPER_PARAM_NAME"=%s", developer_state); + + return simple_read_from_buffer(buf, count, pos, proc_developer, len); +} + +static const struct proc_ops dsmm_proc_fops_developer = { + .proc_read = dsmm_read_developer_proc, +}; + +void dsmm_developer_proc_create(void) +{ + g_dsmm_dir = proc_mkdir(DSMM_DIR, NULL); + if (!g_dsmm_dir) { + xpm_log_error("[%s] proc dir create failed", DSMM_DIR); + return; + } + + if(!proc_create(DSMM_DEVELOPER_FILE, S_IRUGO, g_dsmm_dir, + &dsmm_proc_fops_developer)) { + xpm_log_error("[%s] proc file create failed", + DSMM_DEVELOPER_FILE); + } +} + +void dsmm_developer_proc_clean(void) +{ + if (!g_dsmm_dir) + return; + + remove_proc_entry(DSMM_DEVELOPER_FILE, g_dsmm_dir); + remove_proc_entry(DSMM_DIR, NULL); +} diff --git a/xpm/core/xpm_module.c b/xpm/core/xpm_module.c index 498932c..d2fcb50 100755 --- a/xpm/core/xpm_module.c +++ b/xpm/core/xpm_module.c @@ -12,6 +12,7 @@ #include "xpm_misc.h" #include "xpm_report.h" #include "xpm_debugfs.h" +#include "dsmm_developer.h" static int __init xpm_module_init(void) { @@ -35,6 +36,8 @@ static int __init xpm_module_init(void) xpm_register_xpm_hooks(); xpm_register_hck_hooks(); + dsmm_developer_proc_create(); + xpm_log_info("xpm module init success"); return 0; } @@ -43,6 +46,9 @@ static void __exit xpm_module_exit(void) { xpm_deregister_misc_device(); xpm_debugfs_exit(); + + dsmm_developer_proc_clean(); + xpm_log_info("xpm module exit success"); } diff --git a/xpm/include/dsmm_developer.h b/xpm/include/dsmm_developer.h new file mode 100644 index 0000000..5f19bec --- /dev/null +++ b/xpm/include/dsmm_developer.h @@ -0,0 +1,31 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + */ + +#ifndef DSMM_DEVELOPER_H +#define DSMM_DEVELOPER_H + +#define DEVELOPER_STATUS_ON "true" +#define DEVELOPER_STATUS_OFF "false" + +enum build_variant { + BUILD_VARIANT_USER = 0, + BUILD_VARIANT_ENG, + BUILD_VARIANT_MAX, +}; + +enum developer_proc_status { + DEVELOPER_PROC_STATUS_NA = 0, + DEVELOPER_PROC_STATUS_ON, + DEVELOPER_PROC_STATUS_OFF, + DEVELOPER_PROC_STATUS_MAX, +}; + +const char *developer_mode_state(void); + +void dsmm_developer_proc_create(void); + +void dsmm_developer_proc_clean(void); + +#endif // DSMM_DEVELOPER_H -- Gitee