Skip to content

Commit 0be298b

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 0be298b

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

checksec/__main__.py

+19-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,23 @@
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+
yield from walk_filepath_list(
41+
list(map(lambda x: Path(root).joinpath(x), filenames)),
42+
recursive,
43+
ignore_symlinks
44+
)
45+
if not recursive:
46+
break
47+
elif path.is_file() and (not ignore_symlinks or not path.is_symlink()):
3948
yield path
4049

4150

@@ -72,6 +81,7 @@ def main(args):
7281
json = args["--json"]
7382
recursive = args["--recursive"]
7483
libc_path = args["--set-libc"]
84+
ignore_symlinks = args["--ignore-symlinks"]
7585

7686
# logging
7787
formatter = "%(asctime)s %(levelname)s:%(name)s:%(message)s"
@@ -107,7 +117,7 @@ def main(args):
107117
# we need to consume the iterator once to get the total
108118
# for the progress bar
109119
check_output.enumerating_tasks_start()
110-
count = sum(1 for i in walk_filepath_list(filepath_list, recursive))
120+
count = sum(1 for i in walk_filepath_list(filepath_list, recursive, ignore_symlinks))
111121
check_output.enumerating_tasks_stop(count)
112122
with ProcessPoolExecutor(
113123
max_workers=workers, initializer=worker_initializer, initargs=(libc_path,)
@@ -116,7 +126,7 @@ def main(args):
116126
check_output.processing_tasks_start()
117127
future_to_checksec = {
118128
pool.submit(checksec_file, filepath): filepath
119-
for filepath in walk_filepath_list(filepath_list, recursive)
129+
for filepath in walk_filepath_list(filepath_list, recursive, ignore_symlinks)
120130
}
121131
for future in as_completed(future_to_checksec):
122132
filepath = future_to_checksec[future]

0 commit comments

Comments
 (0)