From 165a4ee20f82cbf9f94e934742fd21f215833129 Mon Sep 17 00:00:00 2001 From: David Korczynski Date: Sat, 1 Feb 2025 09:27:56 -0800 Subject: [PATCH] nit Signed-off-by: David Korczynski --- .../src/fuzz_introspector_utils.py | 6 +-- tools/syz-introspector/src/main.py | 35 ++++++--------- tools/syz-introspector/src/syz_core.py | 43 ++++++++----------- .../src/textual_source_analysis.py | 4 +- 4 files changed, 37 insertions(+), 51 deletions(-) diff --git a/tools/syz-introspector/src/fuzz_introspector_utils.py b/tools/syz-introspector/src/fuzz_introspector_utils.py index 03cba6352..0c734934d 100644 --- a/tools/syz-introspector/src/fuzz_introspector_utils.py +++ b/tools/syz-introspector/src/fuzz_introspector_utils.py @@ -80,7 +80,7 @@ def cleanup_files(workdir: str = ""): os.remove('targetCalltree.txt') -def get_all_c_files_mentioned_in_light(workdir, all_source) -> List[str]: +def get_c_files_mentioned_in_light(workdir) -> List[str]: """Gets C source files mention in light FI report.""" with open(os.path.join(workdir, 'report.yaml'), 'r', encoding='utf-8') as f: @@ -92,7 +92,7 @@ def get_all_c_files_mentioned_in_light(workdir, all_source) -> List[str]: return all_files -def get_all_header_files_in_light(workdir, all_sources) -> List[str]: +def get_all_header_files_in_light(workdir) -> List[str]: """Gets list of header files in light introspector report and finds them in the target kernel folder.""" all_header_files = [] @@ -108,7 +108,7 @@ def get_all_header_files_in_light(workdir, all_sources) -> List[str]: return all_header_files -def extract_calltree_light(target_function, kernel_dir, workdir, target_dir): +def extract_calltree_light(target_function, workdir, target_dir): """Light introspector run""" # logging.info('Analysing: %s' % (workdir)) diff --git a/tools/syz-introspector/src/main.py b/tools/syz-introspector/src/main.py index db3bc96ed..ff0ab4afd 100644 --- a/tools/syz-introspector/src/main.py +++ b/tools/syz-introspector/src/main.py @@ -102,11 +102,10 @@ def parse_args() -> argparse.Namespace: return args -def extract_source_loc_analysis(workdir: str, all_sources: List[str], - report) -> None: +def extract_source_loc_analysis(workdir: str, report) -> None: """Extracts the lines of code in each C source code file.""" - all_c_files = fuzz_introspector_utils.get_all_c_files_mentioned_in_light( - workdir, all_sources) + all_c_files = fuzz_introspector_utils.get_c_files_mentioned_in_light( + workdir) logger.info('[+] Source files:') source_files = [] total_loc = 0 @@ -161,7 +160,7 @@ def get_possible_devnodes(ioctl_handlers): return all_devnodes -def analyse_ioctl_handler(ioctl_handler, workdir, kernel_folder, target_path): +def analyse_ioctl_handler(ioctl_handler, workdir, target_path): """Extracts the calltree from a given ioctl handler and creates a Fuzz Introspector HTML report for it as well. The data will be written in a folder within the working directory. @@ -180,8 +179,7 @@ def analyse_ioctl_handler(ioctl_handler, workdir, kernel_folder, target_path): # Extract the calltree. Do this by running an introspector run # to generate the calltree as well as analysis files. calltree = fuzz_introspector_utils.extract_calltree_light( - ioctl_handler['func']['functionName'], kernel_folder, fi_data_dir, - target_path) + ioctl_handler['func']['functionName'], fi_data_dir, target_path) if calltree: ioctl_handler['calltree'] = calltree @@ -224,13 +222,12 @@ def analyse_ioctl_handler(ioctl_handler, workdir, kernel_folder, target_path): ioctl_handler['calltree'] = '' -def extract_ioctls_in_driver(kernel_folder, report, workdir, all_sources, - strict_ioctls): +def extract_ioctls_in_driver(kernel_folder, report, workdir, strict_ioctls): """Extracts ioctls defined/used in driver""" - ioctls_defined = textual_source_analysis.extract_raw_ioctls_text_from_header_files( + ioctls_defined = textual_source_analysis.extract_ioctls_from_files( report['header_files'], kernel_folder) - c_files_in_driver = fuzz_introspector_utils.get_all_c_files_mentioned_in_light( - workdir, all_sources) + c_files_in_driver = fuzz_introspector_utils.get_c_files_mentioned_in_light( + workdir) if strict_ioctls: refined_ioctls = [] for ioctl in ioctls_defined: @@ -269,16 +266,15 @@ def main() -> None: os.environ['FI_KERNEL_COV'] = args.coverage_report # Extract source file structure. - all_sources = identify_kernel_source_files(kernel_folder) + identify_kernel_source_files(kernel_folder) # Run base introspector. In this run there are no entrypoints analysed. run_light_fi(target_path, workdir) - extract_source_loc_analysis(workdir, all_sources, report) + extract_source_loc_analysis(workdir, report) # Find all header files. logger.info('[+] Finding header files') - report['header_files'] = syz_core.extract_header_files_referenced( - workdir, all_sources) + report['header_files'] = syz_core.extract_header_files_referenced(workdir) logger.debug('Found a total of %d header files', len(report['header_files'])) for header_file in report['header_files']: @@ -301,7 +297,6 @@ def main() -> None: # Extract ioctls. logger.info('[+] Extracting raw ioctls') report['ioctls'] = extract_ioctls_in_driver(kernel_folder, report, workdir, - all_sources, args.strict_ioctls) logger.info('[+] Found the following ioctls') for ioctl in report['ioctls']: @@ -309,8 +304,7 @@ def main() -> None: logger.info('[+] Scanning for ioctl handler using text analysis') ioctl_handlers = syz_core.get_ioctl_handlers(report['ioctls'], - kernel_folder, report, - workdir) + kernel_folder, workdir) # Get possible set of devnodes. all_devnodes = get_possible_devnodes(ioctl_handlers) @@ -319,8 +313,7 @@ def main() -> None: # extract calltrees for ioctl_handler in report['ioctl_handlers']: - analyse_ioctl_handler(ioctl_handler, workdir, kernel_folder, - target_path) + analyse_ioctl_handler(ioctl_handler, workdir, target_path) logger.info('[+] Showing complexity of ioctl handlers') syz_core.interpret_complexity_of_ioctl_handlers(report['ioctl_handlers']) diff --git a/tools/syz-introspector/src/syz_core.py b/tools/syz-introspector/src/syz_core.py index 660f1b8dc..ac463d622 100644 --- a/tools/syz-introspector/src/syz_core.py +++ b/tools/syz-introspector/src/syz_core.py @@ -53,18 +53,19 @@ def find_ioctl_first_case_uses(ioctl_handler, kernel_folder): for idx, line in enumerate(content.split('\n')): already_seen = set() for ioctl in ioctl_handler['ioctls']: - if ioctl.name in line and ioctl.name not in already_seen and 'case' in line: + if (ioctl.name in line and ioctl.name not in already_seen + and 'case' in line): logger.debug("%s :: %d", line.replace("\n", ""), idx) already_seen.add(ioctl.name) pair_starts.append((ioctl.name, idx + 1)) return pair_starts -def extract_header_files_referenced(workdir, all_sources) -> Set[str]: +def extract_header_files_referenced(workdir) -> Set[str]: """extract the source of all header files from FI output.""" raw_header_file_references = fuzz_introspector_utils.get_all_header_files_in_light( - workdir, all_sources) + workdir) all_files = set() for raw_file_reference in raw_header_file_references: @@ -115,8 +116,7 @@ def extract_header_files_referenced(workdir, all_sources) -> Set[str]: return found_files -def extract_syzkaller_types_to_analyze(ioctls, syzkaller_description, - typedict) -> Dict[str, str]: +def extract_syzkaller_types_to_analyze(ioctls, typedict) -> Dict[str, str]: """goes through ioctls_per_fp and syzkaller_description, and sets something in syzkaller_description and returns a set of types to analyse.""" @@ -181,8 +181,8 @@ def extract_syzkaller_types_to_analyze(ioctls, syzkaller_description, target = '%s array[%s, %s]' % (field_name, arr_type, array_count) else: - target = '%s %s' % (syz_name, syz_type) - description_str += ' %s\n' % (target) + target = f'{syz_name} {syz_type}' + description_str += f' {target}\n' description_str += '}' description_types[dtype] = description_str @@ -201,7 +201,7 @@ def get_next_syzkaller_workdir(): def write_syzkaller_description(ioctls, syzkaller_description, workdir, - all_devnodes, header_file, target_path): + all_devnodes, target_path): """Writes a description-X.txt representing syzkaller description.""" # Ensure there are actually ioctls to generate @@ -257,7 +257,7 @@ def write_syzkaller_description(ioctls, syzkaller_description, workdir, f.write('\n' * 2) # Describe the types - for st, text in syzkaller_description.items(): #['types']: + for _, text in syzkaller_description.items(): #['types']: f.write(text) f.write('\n' * 2) return next_syz_descr @@ -274,8 +274,7 @@ def get_function_containing_line_idx(line_idx, sorted_functions): return None -def check_source_files_for_ioctl(kernel_folder, src_file, ioctls, - all_files_with_func): +def check_source_files_for_ioctl(src_file, ioctls, all_files_with_func): """For a given set of of IOCTLs and a source file, finds the functions in the source file from the `all_files_with_func` that uses the IOCTLs.""" all_ioctl_func_handlers = list() @@ -323,14 +322,10 @@ def check_source_files_for_ioctl(kernel_folder, src_file, ioctls, if len(functions_with_ioctls_in_them) > 0: logger.debug('Functions with ioctls in them') - for interesting_func in functions_with_ioctls_in_them: - all_ioctl_func_handlers.append( - functions_with_ioctls_in_them[interesting_func]) - logger.debug( - "- %s", - functions_with_ioctls_in_them[interesting_func]['func']) - for ioctl in functions_with_ioctls_in_them[interesting_func][ - 'ioctls']: + for func_obj in functions_with_ioctls_in_them.values(): + all_ioctl_func_handlers.append(func_obj) + logger.debug("- %s", func_obj['func']) + for ioctl in func_obj['ioctls']: logger.debug(' - %s', (ioctl.name)) return all_ioctl_func_handlers @@ -375,7 +370,7 @@ def find_all_unlocked_ioctls(source_files_to_functions_mapping): return unlocked_ioctl_functions -def get_ioctl_handlers(ioctls, kernel_folder, report, fi_data_dir): +def get_ioctl_handlers(ioctls, kernel_folder, fi_data_dir): """Finds the places in the source code where IOCTL commands are used.""" logger.info('Getting ioctl handlers') @@ -408,8 +403,7 @@ def get_ioctl_handlers(ioctls, kernel_folder, report, fi_data_dir): for src_file in source_files_to_functions_mapping: tmp_ioctl_handlers = check_source_files_for_ioctl( - kernel_folder, src_file, ioctls, - source_files_to_functions_mapping) + src_file, ioctls, source_files_to_functions_mapping) ioctl_handlers += tmp_ioctl_handlers for unlocked_ioctl_handler in unlocked_ioctl_handlers: @@ -667,9 +661,8 @@ def extract_types_of_syzkaller_description(ioctls, fi_data_dir): type_dict['structs'] += struct_list type_dict['typedefs'] += typedefs - syzkaller_description = {'types': dict()} all_types_to_decipher = extract_syzkaller_types_to_analyze( - ioctls, syzkaller_description, type_dict) + ioctls, type_dict) logger.info('All types extracted from struct to include in description:') logger.info(json.dumps(list(all_types_to_decipher), indent=2)) @@ -707,7 +700,7 @@ def create_and_dump_syzkaller_description(ioctls_per_fp, workdir: str, logger.info('[+] Creating syzkaller description for ') syzkaller_description_path = write_syzkaller_description( - all_ioctls, syzkaller_description_types, workdir, all_devnodes, '', + all_ioctls, syzkaller_description_types, workdir, all_devnodes, target_path) if syzkaller_description_path: logger.info('[+] - auto-generated description: %s', diff --git a/tools/syz-introspector/src/textual_source_analysis.py b/tools/syz-introspector/src/textual_source_analysis.py index 677511900..4846099c5 100644 --- a/tools/syz-introspector/src/textual_source_analysis.py +++ b/tools/syz-introspector/src/textual_source_analysis.py @@ -237,8 +237,8 @@ def find_file(target_file: str) -> str: return '' -def extract_raw_ioctls_text_from_header_files( - all_header_files: List[str], kernel_folder: str) -> list[IOCTL]: +def extract_ioctls_from_files(all_header_files: List[str], + kernel_folder: str) -> list[IOCTL]: """Scans a list of header files and finds the lines of code having IOCTL definitions.""" ioctls = []