From 902c0ad64e79786514618fb32ba8f70c6cdc87f7 Mon Sep 17 00:00:00 2001 From: l30036321 Date: Sat, 16 Dec 2023 13:57:54 +0800 Subject: [PATCH] fix security issues --- .../ptdbg_ascend/common/file_check_util.py | 15 ++++++++- .../ptdbg_ascend/parse_tool/lib/compare.py | 31 ++++++++----------- .../ptdbg_ascend/parse_tool/lib/config.py | 9 +++--- .../parse_tool/lib/parse_exception.py | 3 ++ .../ptdbg_ascend/parse_tool/lib/parse_tool.py | 24 +++++++------- .../ptdbg_ascend/parse_tool/lib/utils.py | 19 ++++++++++-- .../parse_tool/lib/visualization.py | 2 +- 7 files changed, 64 insertions(+), 39 deletions(-) diff --git a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/common/file_check_util.py b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/common/file_check_util.py index 2323124f53..38c58632d2 100644 --- a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/common/file_check_util.py +++ b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/common/file_check_util.py @@ -210,6 +210,20 @@ def check_path_writability(path): raise FileCheckException(FileCheckException.INVALID_PERMISSION_ERROR) +def check_path_executable(path): + if not os.access(path, os.X_OK): + print_error_log('The file path %s is not executable.' % path) + raise FileCheckException(FileCheckException.INVALID_PERMISSION_ERROR) + + +def check_other_user_writable(path): + st = os.stat(path) + if st.st_mode & 0o002: + _user_interactive_confirm( + 'The file path %s may be insecure because other users have write permissions. ' + 'Do you want to continue?' % path) + + def _user_interactive_confirm(message): while True: check_message = input(message + " Enter 'c' to continue or enter 'e' to exit: ") @@ -295,4 +309,3 @@ def change_mode(path, mode): except PermissionError as ex: print_error_log('Failed to change {} authority. {}'.format(path, str(ex))) raise FileCheckException(FileCheckException.INVALID_PERMISSION_ERROR) - diff --git a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/compare.py b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/compare.py index 175b4f9373..ba86925786 100644 --- a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/compare.py +++ b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/compare.py @@ -27,28 +27,23 @@ class Compare: self.util = Util() self.log = self.util.log self.vector_compare_result = {} - self.msaccucmp = None - @property - def call_msaccucmp(self): - if not self.msaccucmp: - self.msaccucmp = self.util.check_msaccucmp(Const.MS_ACCU_CMP_PATH) - return self.msaccucmp - - def npu_vs_npu_compare(self, my_dump_path, golden_dump_path, result_dir): + def npu_vs_npu_compare(self, my_dump_path, golden_dump_path, result_dir, msaccucmp_path): self.log.info("Start Compare ...............") - self.compare_vector(my_dump_path, golden_dump_path, result_dir) + self.compare_vector(my_dump_path, golden_dump_path, result_dir, msaccucmp_path) self.log.info("Compare finished!!") - def compare_vector(self, my_dump_path, golden_dump_path, result_dir): + def compare_vector(self, my_dump_path, golden_dump_path, result_dir, msaccucmp_path): self.util.create_dir(result_dir) self.util.check_path_valid(result_dir) + call_msaccucmp = self.util.check_msaccucmp(msaccucmp_path) cmd = '%s %s compare -m %s -g %s -out %s' % ( - self.util.python, self.call_msaccucmp, my_dump_path, golden_dump_path, result_dir + self.util.python, call_msaccucmp, my_dump_path, golden_dump_path, result_dir ) return self.util.execute_command(cmd) - def convert_dump_to_npy(self, dump_file, data_format, output): + def convert_dump_to_npy(self, dump_file, data_format, output, msaccucmp_path): + dump_file = self.util.path_strip(dump_file) file_name = "" if os.path.isfile(dump_file): self.log.info("Covert file is: %s", dump_file) @@ -57,8 +52,7 @@ class Compare: self.log.info("Convert all files in path: %s", dump_file) file_name = "" output = output if output else Const.DUMP_CONVERT_DIR - self.util.check_path_valid(output) - convert = self.convert(dump_file, data_format, output) + convert = self.convert(dump_file, data_format, output, msaccucmp_path) if convert == 0: convert_files = self.util.list_convert_files(output, file_name) @@ -67,16 +61,17 @@ class Compare: summary_txt.append(" - %s" % convert_file.file_name) self.util.print_panel("\n".join(summary_txt)) - def convert(self, dump_file, data_format, output): + def convert(self, dump_file, data_format, output, msaccucmp_path): self.util.create_dir(output) self.util.check_path_valid(output) + call_msaccucmp = self.util.check_msaccucmp(msaccucmp_path) if data_format: cmd = '%s %s convert -d %s -out %s -f %s' % ( - self.util.python, self.call_msaccucmp, dump_file, output, data_format + self.util.python, call_msaccucmp, dump_file, output, data_format ) else: cmd = '%s %s convert -d %s -out %s' % ( - self.util.python, self.call_msaccucmp, dump_file, output + self.util.python, call_msaccucmp, dump_file, output ) return self.util.execute_command(cmd) @@ -149,7 +144,7 @@ class Compare: err_cnt += 1 if total_cnt == 0: err_percent = float(0) - else: + else: err_percent = float(err_cnt / total_cnt) self.util.print(self.util.create_columns([err_table, top_table])) return total_cnt, all_close, cos_sim, err_percent diff --git a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/config.py b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/config.py index 7c4eb14191..9cf479d644 100644 --- a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/config.py +++ b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/config.py @@ -21,6 +21,7 @@ import os class Const: MS_ACCU_CMP_PATH = '/usr/local/Ascend/ascend-toolkit/latest/tools/operator_cmp/compare/msaccucmp.py' + MS_ACCU_CMP_FILE_NAME = 'msaccucmp.py' ROOT_DIR = "" LOG_LEVEL = "NOTSET" DATA_ROOT_DIR = os.path.join(ROOT_DIR, 'parse_data') @@ -37,10 +38,10 @@ class Const: FILE_PATTERN = r'^[a-zA-Z0-9_./-]+$' ONE_GB = 1 * 1024 * 1024 * 1024 TEN_GB = 10 * 1024 * 1024 * 1024 - HEADER = r""" ____ - / __ \____ ______________ + HEADER = r""" ____ + / __ \____ ______________ / /_/ / __ `/ ___/ ___/ _ \ / ____/ /_/ / / (__ ) __/ - /_/ \__,_/_/ /____/\___/ - + /_/ \__,_/_/ /____/\___/ + """ diff --git a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/parse_exception.py b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/parse_exception.py index 380d84cb2c..53478ecde2 100644 --- a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/parse_exception.py +++ b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/parse_exception.py @@ -15,6 +15,7 @@ # limitations under the License. """ import logging +from ...common.file_check_util import FileCheckException class ParseException(Exception): @@ -46,6 +47,8 @@ def catch_exception(func): log.error("%s: command not found" % line) except ParseException: log.error("Command execution failed") + except FileCheckException: + log.error("Command execution failed") except SystemExit: log.warning("Please enter the correct command") return result diff --git a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/parse_tool.py b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/parse_tool.py index b0b5610070..9a4b7c87f3 100644 --- a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/parse_tool.py +++ b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/parse_tool.py @@ -53,8 +53,8 @@ class ParseTool: required=False ) parser.add_argument( - "-asc", "--ascend_path", dest="ascend_path", default=None, - help=" the Ascend home path", + "-cmp_path", "--msaccucmp_path", dest="msaccucmp_path", default=None, + help=" the msaccucmp.py file path", required=False ) args = parser.parse_args(argv) @@ -71,10 +71,10 @@ class ParseTool: if not os.path.isdir(my_dump_path) or not os.path.isdir(golden_dump_path): self.util.log.error("Please enter a directory not a file") raise ParseException(ParseException.PARSE_INVALID_PATH_ERROR) - if args.ascend_path: - Const.MS_ACCU_CMP_PATH = self.util.path_strip(args.ascend_path) - self.util.check_path_valid(Const.MS_ACCU_CMP_PATH) - self.compare.npu_vs_npu_compare(my_dump_path, golden_dump_path, result_dir) + msaccucmp_path = self.util.path_strip(args.msaccucmp_path) if args.msaccucmp_path else Const.MS_ACCU_CMP_PATH + self.util.check_path_valid(msaccucmp_path) + self.util.check_executable_file(msaccucmp_path) + self.compare.npu_vs_npu_compare(my_dump_path, golden_dump_path, result_dir, msaccucmp_path) @catch_exception def do_convert_dump(self, argv=None): @@ -86,15 +86,15 @@ class ParseTool: parser.add_argument( '-out', '--output_path', dest='output_path', required=False, default=None, help='output path') parser.add_argument( - "-asc", "--ascend_path", dest="ascend_path", default=None, help=" the Ascend home path", - required=False) + "-cmp_path", "--msaccucmp_path", dest="msaccucmp_path", default=None, + help=" the msaccucmp.py file path", required=False) args = parser.parse_args(argv) self.util.check_path_valid(args.path) self.util.check_files_in_path(args.path) - if args.ascend_path: - Const.MS_ACCU_CMP_PATH = self.util.path_strip(args.ascend_path) - self.util.check_path_valid(Const.MS_ACCU_CMP_PATH) - self.compare.convert_dump_to_npy(args.path, args.format, args.output_path) + msaccucmp_path = self.util.path_strip(args.msaccucmp_path) if args.msaccucmp_path else Const.MS_ACCU_CMP_PATH + self.util.check_path_valid(msaccucmp_path) + self.util.check_executable_file(msaccucmp_path) + self.compare.convert_dump_to_npy(args.path, args.format, args.output_path, msaccucmp_path) @catch_exception def do_print_data(self, argv=None): diff --git a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/utils.py b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/utils.py index 20c5f6c749..94387a486f 100644 --- a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/utils.py +++ b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/utils.py @@ -23,6 +23,9 @@ import numpy as np from .config import Const from .file_desc import DumpDecodeFileDesc, FileDesc from .parse_exception import ParseException +from ...common.file_check_util import change_mode, check_other_user_writable,\ + check_path_executable, check_path_owner_consistent +from ...common.file_check_util import FileCheckConst try: from rich.traceback import install @@ -69,6 +72,12 @@ class Util: def _gen_numpy_file_info(name, math, dir_path): return FileDesc(name, dir_path) + @staticmethod + def check_executable_file(path): + check_path_owner_consistent(path) + check_other_user_writable(path) + check_path_executable(path) + def execute_command(self, cmd): if not cmd: self.log.error("Commond is None") @@ -88,7 +97,10 @@ class Util: self.print(Panel(content, title=title)) def check_msaccucmp(self, target_file): - self.log.info("Try to auto detect file with name: %s.", target_file) + if os.path.split(target_file)[-1] != Const.MS_ACCU_CMP_FILE_NAME: + self.log.error( + "Check msaccucmp failed in dir %s. This is not a correct msaccucmp file" % target_file) + raise ParseException(ParseException.PARSE_MSACCUCMP_ERROR) result = subprocess.run( [self.python, target_file, "--help"], stdout=subprocess.PIPE) if result.returncode == 0: @@ -128,6 +140,7 @@ class Util: pad_array = np.zeros((align - data.size % align,)) data = np.append(data, pad_array) np.savetxt(dst_file, data.reshape((-1, align)), delimiter=' ', fmt='%g') + change_mode(dst_file, FileCheckConst.DATA_FILE_AUTHORITY) def list_convert_files(self, path, external_pattern=""): return self._list_file_with_pattern( @@ -176,7 +189,7 @@ class Util: if path.endswith(Const.NPY_SUFFIX) and file_size > Const.TEN_GB: self.log.error('The file {} size is greater than 10GB.'.format(path)) raise ParseException(ParseException.PARSE_INVALID_PATH_ERROR) - + def check_files_in_path(self, path): if os.path.isdir(path) and len(os.listdir(path)) == 0: self.log.error("No files in %s." % path) @@ -221,7 +234,7 @@ class Util: else: self.log.error("The file path %s is invalid" % path) raise ParseException(ParseException.PARSE_INVALID_PATH_ERROR) - + def check_path_name(self, path): if len(os.path.realpath(path)) > Const.DIRECTORY_LENGTH or len(os.path.basename(path)) > \ Const.FILE_NAME_LENGTH: diff --git a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/visualization.py b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/visualization.py index 10dde7e089..6fa571dbb8 100644 --- a/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/visualization.py +++ b/debug/accuracy_tools/ptdbg_ascend/src/python/ptdbg_ascend/parse_tool/lib/visualization.py @@ -41,7 +41,7 @@ class Visualization: summary = ['[yellow]%s[/yellow]' % self.util.gen_npy_info_txt(np_data), 'Path: %s' % target_file, "TextFile: %s.txt" % target_file] self.util.print_panel(self.util.create_columns([table, "\n".join(summary)]), target_file) - self.util.save_npy_to_txt(np_data, target_file + "txt") + self.util.save_npy_to_txt(np_data, target_file + ".txt") def print_npy_data(self, file_name): file_name = self.util.path_strip(file_name) -- Gitee