From 676c89dea157092feca1a1e7c6a0e7a954f2a3a6 Mon Sep 17 00:00:00 2001 From: cheng_jinsong Date: Mon, 19 Jun 2023 18:45:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=90=AF=E5=8A=A8=E8=B5=84?= =?UTF-8?q?=E6=BA=90=E7=AE=A1=E6=8E=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: cheng_jinsong --- .../rules/NO-Config-Cmds-In-Init/README.md | 171 +++++++++++++++--- .../NO-Config-Cmds-In-Init/whitelist.json | 37 ++++ .../README.md | 28 ++- .../startup_guard/startup_checker/__init__.py | 5 - .../startup_checker/cmds_rule.py | 43 +++-- .../startup_checker/system_parameter_rules.py | 7 +- tools/startup_guard/startup_guard.py | 6 +- 7 files changed, 246 insertions(+), 51 deletions(-) diff --git a/tools/startup_guard/rules/NO-Config-Cmds-In-Init/README.md b/tools/startup_guard/rules/NO-Config-Cmds-In-Init/README.md index f71ae94..0fd81e6 100755 --- a/tools/startup_guard/rules/NO-Config-Cmds-In-Init/README.md +++ b/tools/startup_guard/rules/NO-Config-Cmds-In-Init/README.md @@ -1,29 +1,158 @@ -# 耗时命令白名单规则说明 +# cfg文件白名单规则说明 -## 1. 耗时命令说明 - 命令执行超过200ms的命令行。 +## 规则解释 + 白名单严格遵循JSON格式。 -## 2. 规则解释 + ### **耗时命令约束** + **[白名单](whitelist.json)** 约束*.cfg文件中的耗时命令。 - 1. **耗时命令约束**:**[白名单](whitelist.json)** 约束*.cfg文件中的耗时命令。 - 2. **condition服务约束**:白名单中约束service启动方式是:"start-mode" : "condition" 且"ondemand" : false , 且服务通过start命令启动。 - 3. **boot服务约束**:白名单约束service启动方式是:"start-mode" : "boot"。 - 4. **selinux约束**:selinux未打开, 或服务的"secon"没有配置。 - -编译时会提示如下类型的告警: + - 耗时命令 + + 命令执行超过200ms的命令行。 + + - 规则要求 + + 1. 命令行执行时间超过200ms。 + 2. 耗时命令在白名单中配置。 + 3. 耗时命令文件路径在白名单中配置。 + + - 白名单信息解释 + ``` + { + "cmd":"init_global_key", + "location":[ + "/system/etc/init.cfg", + ... + ] + } + ``` + 1. cmd: 命令行 + 2. location: 耗时命令文件路径 + + - 解决方法 + 1. 检查违规项是否是耗时命令。 + 2. 检查该命令是否包含白名单中。 + 3. 检查该命令存在的文件路径是否包含在白名单中。 + 3. 根据评审结果添加命令到白名单。 + +### **condition服务约束** + **[白名单](whitelist.json)** 约束*.cfg文件中的service的启动方式:condition。 + + - condition + + condition 条件启动,对服务的启动方式配置condition,通过start命令拉起服务。 + + - 规则要求 + 1. 服务不是按需启动,即"ondemand" : false。 + 2. 服务是条件启动, 即"start-mode" : "condition", 并且通过start命令拉起服务。 + 3. 服务在白名单中。 + + - 白名单信息解释 + ``` + { + "start-modes": [ + { + "start-mode":"condition", + "service": [ + "hilogd", + ... + ] + } + ] + } + ``` + 1. start-mode:"condition", 服务启动方式。 + 2. service:通过"start-mode" : "condition" 启动的服务。 + + - 解决方法 + 1. 检查服务否是按需启动。 + 2. 检查服务是否配置条件启动, 且通过start命令拉起服务。 + 3. 检查服务是否在白名单中。 + 4. 根据评审结果添加服务到白名单。 + +### **boot服务约束** + **[白名单](whitelist.json)** 约束*.cfg文件中的service的启动方式:boot。 + + - boot + + 在init job阶段启动,其服务的启动方式配置 boot。 + + - 规则要求 + 1. 服务是boot启动, 即"start-mode" : "boot"的服务。 + 2. 服务在白名单中。 + - 白名单信息解释 + ``` + { + "start-modes": [ + { + "start-mode":"boot", + "service": [ + "hiview", + ... + ] + } + ] + } + ``` + 1. start-mode:"boot",服务启动方式。 + 2. service:通过"start-mode" : "boot" 启动的服务。 + + - 解决方法 + 1. 检查服务是否是boot启动。 + 2. 检查服务是否在白名单中。 + 3. 根据评审结果添加服务到白名单。 + +### **start命令约束** + **[白名单](whitelist.json)** 约束*.cfg文件中的通过start执行的命令。 + + - start + + 通过start拉起的服务。 + + - 规则要求 + 1. 通过start命令执行的命令行。 + 2. 命令行在白名单中。 + + - 白名单信息解释 + ``` + { + "start-cmd": [ + "ueventd", + ... + ] + } + ``` + start-cmd: 执行start命令行。 + + - 解决方法 + 1. 检查命令是否是start命令。 + 2. 检查命令行是否在白名单中。 + 3. 根据评审结果添加命令到白名单。 + + ### **selinux约束** + - secon + + 服务的selinux标签 + + - 规则要求 + 1. 服务配置没有配置"secon"。 + 2. 配置配置的"secon"为空。 + + - 解决方法 + 1. 检查服务是否配置"secon", 且"secon"的配置不为空。 + 2. 根据要求修改服务"secon"配置 + +编译时会提示如下类型的告警: ``` - [NOT ALLOWED]: 'mount_fstab' is invalid, in /system/etc/init.cfg - [NOT ALLOWED]: 'load_access_token_id' is invalid, in /system/etc/init/access_token.cfg - [NOT ALLOWED]: 'init_global_key' is invalid, in /system/etc/init.cfg - [NOT ALLOWED]: 'storage_daemon' cannot be started in boot mode - [NOT ALLOWED]: 'hilogd' cannot be started in conditional mode + [NOT ALLOWED]: 'init_global_key' is timeout command, in /system/etc/init.cfg + [NOT ALLOWED]: xxx 'secon' is empty + [WARNING]: 'storage_daemon' cannot be started in boot mode + [WARNING]: 'hilogd' cannot be started in conditional mode [WARNING]: selinux status is xxx - [WARNING]: xxx 'secon' is empty + [WARNING]: multimodalinput is not in start cmd list. path:/system/etc/init/multimodalinput.cfg ``` -## 3. 违规场景及处理方案建议 - - 1. 检查违规项是否是耗时命令,其次该命令存在文件路径是否包含白名单中, 如果不在,根据要求添加命令到白名单 - - 2. 检查服务启动类型, 根据 **[规则解释](README.md#2-规则解释)** 排查修改 +## 违规场景及处理方案建议 + 1. 服务默认按照并行启动配置,如果需要添加白名单,需要评审。 + 2. 根据 **[规则解释](README.md#规则解释)** 排查修改。 diff --git a/tools/startup_guard/rules/NO-Config-Cmds-In-Init/whitelist.json b/tools/startup_guard/rules/NO-Config-Cmds-In-Init/whitelist.json index 8097426..0d21b1c 100755 --- a/tools/startup_guard/rules/NO-Config-Cmds-In-Init/whitelist.json +++ b/tools/startup_guard/rules/NO-Config-Cmds-In-Init/whitelist.json @@ -49,6 +49,43 @@ "hdf_devmgr" ] } + ], + "start-cmd":[ + "ueventd", + "watchdog_service", + "deviceauth_service", + "screenlock_server", + "resource_schedule_service", + "storage_daemon", + "bluetooth_service", + "hilogd", + "device_usage_stats_service", + "wifi_hal_service", + "hdcd", + "bgtaskmgr_service", + "module_update_service", + "hiprofilerd", + "hiprofiler_plugins", + "hiprofiler_daemon", + "pulseaudio", + "audio_host", + "audio_policy", + "huks_service", + "memmgrservice", + "netmanager", + "pinauth", + "updater_sa", + "telephony_sa", + "devattest_service", + "msdp_sa", + "accessibility", + "wallpaper_service", + "time_service", + "udevd_service", + "mmi_uinput_service", + "multimodalinput", + "hdf_devhost", + "concurrent_task_service" ] } ] diff --git a/tools/startup_guard/rules/NO-Config-SystemParameter-In-INIT/README.md b/tools/startup_guard/rules/NO-Config-SystemParameter-In-INIT/README.md index 20fdfba..d0bb419 100755 --- a/tools/startup_guard/rules/NO-Config-SystemParameter-In-INIT/README.md +++ b/tools/startup_guard/rules/NO-Config-SystemParameter-In-INIT/README.md @@ -1,17 +1,31 @@ # 系统参数白名单规则说明 -## 1. 规则解释 - 1. **[白名单](whitelist.json)** 约束系统参数配置文件(\*.para", \*.para.dac)中的名称。 - 2. **[白名单](whitelist.json)** 约束系统参数命名合法性。系统参数命名由:字母、数字、下划线、'.'、 '-'、 '@'、 ':' 、 '_'。 例外:不允许出现".." - 3. 系统参数名未添加在 **[白名单](whitelist.json)**。 + ## **系统参数命名约束** + - 规则要求 + 1. 约束\*.para", \*.para.dac 配置文件中的系统参数。 + 2. 系统参数命名由:字母、数字、下划线、'.'、 '-'、 '@'、 ':' 、 '_'。 + 3. 不允许出现".."。 + + - 解决方法 + 1. 根据系统参数的命名规范排查修改。 + + ## dac配置内存大小约束 + - 规则要求 + 1. dac配置不超过200个。 + + - 解决方法 + 1. 重新配置dac内存大小, 修改 "startup/init/services/param/include/param_osadp.h" 中PARAM_WORKSPACE_DAC。 + 2. 修改 "startup_guard/startup_checker/system_parameter_rules.py" 中CONFIG_DAC_MAX_NUM = 200的大小。 编译时会提示如下类型的告警: ``` [NOT ALLOWED]: Invalid param: distributedsched.continuationmanager.. - [NOT ALLOWED]: persist.resourceschedule.memmgr.eswap.swapOutKBFromBirth is not found in the whitelist + [NOT ALLOWED]: DAC overallocated memory + ``` -## 2. 违规场景及处理方案建议 +# 违规场景及处理方案建议 - 1. 检查白名单和系统参数命名, 根据 **[规则解释](README.md#2-规则解释)** 排查修改 + 1. 检查系统参数命名, 根据 **[系统参数命名约束](README.md#系统参数命名约束)** 排查修改。 + 2. 排查dac配置是否超出内存申请范围, 根据 **[dac配置内存大小约束](README.md#dac配置内存大小约束)** 排查修改。 diff --git a/tools/startup_guard/startup_checker/__init__.py b/tools/startup_guard/startup_checker/__init__.py index 73a52af..5231516 100755 --- a/tools/startup_guard/startup_checker/__init__.py +++ b/tools/startup_guard/startup_checker/__init__.py @@ -31,12 +31,7 @@ def check_all_rules(mgr, args): r.log("Do %s rule checking now:" % rule.RULE_NAME) if not r.__check__(): passed = False - else: - passed = True - - if not passed: r.log(" Please refer to: \033[91m%s\x1b[0m" % r.get_help_url()) - pass if args and args.no_fail: return True diff --git a/tools/startup_guard/startup_checker/cmds_rule.py b/tools/startup_guard/startup_checker/cmds_rule.py index 0c98580..c59657b 100644 --- a/tools/startup_guard/startup_checker/cmds_rule.py +++ b/tools/startup_guard/startup_checker/cmds_rule.py @@ -30,6 +30,7 @@ class cmdRule(BaseRule): self._start_modes = {} self._boot_list = {} self._condition_list = {} + self._start_cmd_list = {} def _get_json_service(self): for i in range(len(self._start_modes)): @@ -40,10 +41,10 @@ class cmdRule(BaseRule): pass def _get_start_cmds(self, parser): - list = [] + list = {} for cmd in parser._cmds: if cmd["name"] == "start": - list.append(cmd["content"]) + list[cmd["content"]] = cmd["fileId"] pass return list @@ -54,26 +55,25 @@ class cmdRule(BaseRule): self._cmds = item if key == "start-modes": self._start_modes = item + if key == "start-cmd": + self._start_cmd_list = item def _check_condition_start_mode(self, cmd_list, service_name, passed): - # print(cmd_list) if service_name in self._condition_list and service_name in cmd_list: pass else: - self.error("\'%s\' cannot be started in conditional mode" % service_name) - passed = False + self.warn("\'%s\' cannot be started in conditional mode" % service_name) return passed def _check_service(self, parser): boot_passed = True condition_passed = True - start_cmd_list = self._get_start_cmds(parser) + start_cmd_list = self._get_start_cmds(parser).keys() for key, item in parser._services.items(): if item.get("start_mode") == "boot": if key not in self._boot_list: - self.error("\'%s\' cannot be started in boot mode" % key) - boot_passed = False + self.warn("\'%s\' cannot be started in boot mode" % key) elif item.get("on_demand") is not True and item.get("start_mode") == "condition": condition_passed = self._check_condition_start_mode(start_cmd_list, key, condition_passed) return boot_passed and condition_passed @@ -99,7 +99,7 @@ class cmdRule(BaseRule): file_lists = cmd["location"] for key, item in parser._files.items(): if item["fileId"] in file_id_list and key not in file_lists: - output = "\'" + cmd["cmd"] + "\' is invalid, in "+ key + output = "\'" + cmd["cmd"] + "\' is timeout command, in "+ key self.error("%s" % str(output)) passed = False file_id_list.clear() @@ -108,26 +108,43 @@ class cmdRule(BaseRule): def _check_selinux(self, parser): if parser._selinux != 'enforcing': self.warn("selinux status is %s" %parser._selinux) - return False + return True passed = True for key, item in parser._services.items(): if item.get("secon") == "": output_str = "%s \'secon\' is empty" % key - self.warn("%s" % str(output_str)) + self.error("%s" % str(output_str)) passed = False return passed + def _check_start_cmd(self, parser): + passed = True + start_cmd_list = self._get_start_cmds(parser) + for cmd, file_id in start_cmd_list.items(): + if cmd in list(self._start_cmd_list): + pass + else: + for key, item in parser._files.items(): + if item["fileId"] == file_id: + log_str = cmd + " is not in start cmd list. " + " path:" + item["file_name"] + self.warn("%s" % log_str) + passed = False + pass + return passed + def check_config_cmd(self): + passed = True self._parse_while_list() cfg_parser = self.get_mgr().get_parser_by_name('cmd_whitelist') self._get_json_service() - self._get_start_cmds(cfg_parser) + start_passed = self._check_start_cmd(cfg_parser) secon_passed = self._check_selinux(cfg_parser) cmd_passed = self._check_cmdline_in_parser(cfg_parser) start_mode_passed = self._check_service(cfg_parser) - return secon_passed and cmd_passed and start_mode_passed + passed = start_passed and secon_passed and cmd_passed and start_mode_passed + return passed def __check__(self): return self.check_config_cmd() diff --git a/tools/startup_guard/startup_checker/system_parameter_rules.py b/tools/startup_guard/startup_checker/system_parameter_rules.py index b91d118..3f11a4d 100644 --- a/tools/startup_guard/startup_checker/system_parameter_rules.py +++ b/tools/startup_guard/startup_checker/system_parameter_rules.py @@ -20,6 +20,7 @@ from .base_rule import BaseRule class SystemParameterRule(BaseRule): RULE_NAME = "NO-Config-SystemParameter-In-INIT" + CONFIG_DAC_MAX_NUM = 200 def _check_param_name(self, param_name, empty_flag): # len: (0, 96] @@ -49,7 +50,10 @@ class SystemParameterRule(BaseRule): value_empty_flag = True white_list =self.get_white_lists() parser = self.get_mgr().get_parser_by_name('system_parameter_whitelist') + counts = 0 for key, item in parser._parameters.items(): + if (item.get("dacMode") != 0): + counts += 1 if str(item)[-1] == "=": value_empty_flag = True else: @@ -60,7 +64,8 @@ class SystemParameterRule(BaseRule): continue if key in white_list: continue - self.error("%s is not found in the whitelist" % key) + if counts > SystemParameterRule.CONFIG_DAC_MAX_NUM: + self.error("DAC overallocated memory") passed = False return passed diff --git a/tools/startup_guard/startup_guard.py b/tools/startup_guard/startup_guard.py index 875763d..92e259c 100755 --- a/tools/startup_guard/startup_guard.py +++ b/tools/startup_guard/startup_guard.py @@ -35,12 +35,10 @@ def startup_guard(out_path, args=None): from startup_checker import check_all_rules passed = check_all_rules(mgr, args) - passed = True if passed: print("All rules passed") - return - - raise Exception("ERROR: config_guard failed.") + else: + print("Please modify according to README.md") if __name__ == '__main__': parser = __create_arg_parser() -- Gitee