Skip to content

Commit 3e544f8

Browse files
Maximilian BlenkMaximilian Blenk
Maximilian Blenk
authored and
Maximilian Blenk
committed
main: Add option to ignore symlinks
When analyzing a complete rootfs (which might not be the rootfs of the analyzing system) symlink 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. This commit also involves some refactoring of the walk_filepath_list() function.
1 parent 4335ecd commit 3e544f8

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

checksec/__main__.py

+16-9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
-w WORKERS --workers=WORKERS Specify the number of process pool workers [default: 4]
99
-j --json Display results as JSON
1010
-s LIBC --set-libc=LIBC Specify LIBC library to use to check for fortify scores (ELF)
11+
-i --ignore-symlinks Ignore symlinks to files
1112
-d --debug Enable debug output
1213
-h --help Display this message
1314
"""
@@ -27,15 +28,20 @@
2728
from .utils import lief_set_logging
2829

2930

30-
def walk_filepath_list(filepath_list: List[Path], recursive: bool = False) -> Iterator[Path]:
31+
def walk_filepath_list(filepath_list: List[Path], recursive: bool = False, ignore_symlinks: bool = False) \
32+
-> Iterator[Path]:
33+
def error_handler(exception):
34+
# Fail loudly
35+
raise exception
36+
3137
for path in filepath_list:
3238
if path.is_dir() and not path.is_symlink():
33-
if recursive:
34-
for f in os.scandir(path):
35-
yield from walk_filepath_list([Path(f)], recursive)
36-
else:
37-
yield from (Path(f) for f in os.scandir(path))
38-
elif path.is_file():
39+
for root, _, filenames in os.walk(path, onerror=error_handler):
40+
for filename in filenames:
41+
yield from walk_filepath_list([Path(root).joinpath(filename)], recursive, ignore_symlinks)
42+
if not recursive:
43+
break
44+
elif path.is_file() and (not ignore_symlinks or not path.is_symlink()):
3945
yield path
4046

4147

@@ -72,6 +78,7 @@ def main(args):
7278
json = args["--json"]
7379
recursive = args["--recursive"]
7480
libc_path = args["--set-libc"]
81+
ignore_symlinks = args["--ignore-symlinks"]
7582

7683
# logging
7784
formatter = "%(asctime)s %(levelname)s:%(name)s:%(message)s"
@@ -107,7 +114,7 @@ def main(args):
107114
# we need to consume the iterator once to get the total
108115
# for the progress bar
109116
check_output.enumerating_tasks_start()
110-
count = sum(1 for i in walk_filepath_list(filepath_list, recursive))
117+
count = sum(1 for i in walk_filepath_list(filepath_list, recursive, ignore_symlinks))
111118
check_output.enumerating_tasks_stop(count)
112119
with ProcessPoolExecutor(
113120
max_workers=workers, initializer=worker_initializer, initargs=(libc_path,)
@@ -116,7 +123,7 @@ def main(args):
116123
check_output.processing_tasks_start()
117124
future_to_checksec = {
118125
pool.submit(checksec_file, filepath): filepath
119-
for filepath in walk_filepath_list(filepath_list, recursive)
126+
for filepath in walk_filepath_list(filepath_list, recursive, ignore_symlinks)
120127
}
121128
for future in as_completed(future_to_checksec):
122129
filepath = future_to_checksec[future]

0 commit comments

Comments
 (0)