From b540967b87394d855c26375ac5a9a7265f265053 Mon Sep 17 00:00:00 2001 From: Maximilian Blenk Date: Fri, 2 Jul 2021 14:42:25 +0200 Subject: [PATCH] main: Add option to ignore symlinks When analyzing a complete rootfs (which might not be the rootfs of the analyzing system) symlinks within that rootfs might be broken. In particular absolute symlinks. However, if by chance such a symlink currently points to a valid binary in your system, this binary pointed to is analyzed. This commit adds the possibility to ignore symlinks to files (symlinks to dirs are already ignored by default). This allows to solve the issue described above, and if the whole rootfs is analyzed there shouldn't be a loss of information (because all the binaries will be analyzed anyway). Additionally, this also saves some time when performing the analysis. Upstream-Status: Submitted [https://github.com/Wenzel/checksec.py/pull/106] --- checksec/__main__.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/checksec/__main__.py b/checksec/__main__.py index a14862f..931d850 100644 --- a/checksec/__main__.py +++ b/checksec/__main__.py @@ -8,6 +8,7 @@ Options: -w WORKERS --workers=WORKERS Specify the number of process pool workers [default: 4] -j --json Display results as JSON -s LIBC --set-libc=LIBC Specify LIBC library to use to check for fortify scores (ELF) + -i --ignore-symlinks Ignore symlinks to files -d --debug Enable debug output -h --help Display this message """ @@ -27,18 +28,18 @@ from .pe import PEChecksecData, PESecurity, is_pe from .utils import lief_set_logging -def walk_filepath_list(filepath_list: List[Path], recursive: bool = False) -> Iterator[Path]: +def walk_filepath_list(filepath_list: List[Path], recursive: bool = False, ignore_symlinks: bool = False) -> Iterator[Path]: for path in filepath_list: if path.is_dir() and not path.is_symlink(): try: if recursive: for f in os.scandir(path): - yield from walk_filepath_list([Path(f)], recursive) + yield from walk_filepath_list([Path(f)], recursive, ignore_symlinks) else: yield from (Path(f) for f in os.scandir(path)) except OSError: continue - elif path.is_file(): + elif path.is_file() and (not ignore_symlinks or not path.is_symlink()): yield path @@ -75,6 +76,7 @@ def main(args): json = args["--json"] recursive = args["--recursive"] libc_path = args["--set-libc"] + ignore_symlinks = args["--ignore-symlinks"] # logging formatter = "%(asctime)s %(levelname)s:%(name)s:%(message)s" @@ -110,7 +112,7 @@ def main(args): # we need to consume the iterator once to get the total # for the progress bar check_output.enumerating_tasks_start() - count = sum(1 for i in walk_filepath_list(filepath_list, recursive)) + count = sum(1 for i in walk_filepath_list(filepath_list, recursive, ignore_symlinks)) check_output.enumerating_tasks_stop(count) with ProcessPoolExecutor( max_workers=workers, initializer=worker_initializer, initargs=(libc_path,) @@ -119,7 +121,7 @@ def main(args): check_output.processing_tasks_start() future_to_checksec = { pool.submit(checksec_file, filepath): filepath - for filepath in walk_filepath_list(filepath_list, recursive) + for filepath in walk_filepath_list(filepath_list, recursive, ignore_symlinks) } for future in as_completed(future_to_checksec): filepath = future_to_checksec[future]