Skip to content

Commit 76812f0

Browse files
syz-introspector: enable limiting ioctls to what is used in sources (#2038)
Signed-off-by: David Korczynski <[email protected]>
1 parent 81734df commit 76812f0

File tree

1 file changed

+39
-10
lines changed

1 file changed

+39
-10
lines changed

tools/syz-introspector/src/main.py

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@
3434
def create_workdir() -> str:
3535
"""Creates the next available auto-syzkaller-XXX dir."""
3636
idx = 0
37-
while os.path.isdir("auto-syzkaller-%d" % (idx)):
37+
while os.path.isdir(f"auto-syzkaller-{idx}"):
3838
idx += 1
39-
workdir = os.path.abspath("auto-syzkaller-%d" % (idx))
39+
workdir = os.path.abspath(f"auto-syzkaller-{idx}")
4040

4141
logger.info('[+] workdir: %s', workdir)
4242
os.mkdir(workdir)
@@ -92,6 +92,11 @@ def parse_args() -> argparse.Namespace:
9292
'-cr',
9393
help='JSON file holding kernel coverage',
9494
default='')
95+
parser.add_argument(
96+
'--strict-ioctls',
97+
'-s',
98+
help='will limit ioctl inclusion to ioctls mention in driver\'s C code',
99+
action='store_true')
95100

96101
args = parser.parse_args()
97102
return args
@@ -157,14 +162,17 @@ def get_possible_devnodes(ioctl_handlers):
157162

158163

159164
def analyse_ioctl_handler(ioctl_handler, workdir, kernel_folder, target_path):
165+
"""Extracts the calltree from a given ioctl handler and creates a Fuzz
166+
Introspector HTML report for it as well. The data will be written in a
167+
folder within the working directory.
168+
"""
160169
logger.info('- %s', ioctl_handler['func']['functionName'])
161170

162171
# Get the next index that we will use to store data in the target
163172
# workdir.
164173
next_workdir_idx = syz_core.get_next_handler_workdir_idx(workdir)
165174

166-
fi_data_dir = os.path.join(workdir,
167-
'handler-analysis-%d' % (next_workdir_idx),
175+
fi_data_dir = os.path.join(workdir, f'handler-analysis-{next_workdir_idx}',
168176
'fi-data')
169177
logger.info('Creating handler dir: %s', fi_data_dir)
170178
os.makedirs(fi_data_dir)
@@ -184,7 +192,7 @@ def analyse_ioctl_handler(ioctl_handler, workdir, kernel_folder, target_path):
184192
for filename in os.listdir(fi_data_dir):
185193
if filename.endswith('.data'):
186194
dst = os.path.join(workdir,
187-
'handler-analysis-%d' % (next_workdir_idx),
195+
f'handler-analysis-{next_workdir_idx}',
188196
'fi-data', filename)
189197
shutil.copy(os.path.join(fi_data_dir, 'targetCalltree.txt'),
190198
dst)
@@ -216,6 +224,29 @@ def analyse_ioctl_handler(ioctl_handler, workdir, kernel_folder, target_path):
216224
ioctl_handler['calltree'] = ''
217225

218226

227+
def extract_ioctls_in_driver(kernel_folder, report, workdir, all_sources,
228+
strict_ioctls):
229+
"""Extracts ioctls defined/used in driver"""
230+
ioctls_defined = textual_source_analysis.extract_raw_ioctls_text_from_header_files(
231+
report['header_files'], kernel_folder)
232+
c_files_in_driver = fuzz_introspector_utils.get_all_c_files_mentioned_in_light(
233+
workdir, all_sources)
234+
if strict_ioctls:
235+
refined_ioctls = []
236+
for ioctl in ioctls_defined:
237+
is_used = False
238+
for src_file in c_files_in_driver:
239+
with open(src_file, 'r', encoding='utf-8') as f:
240+
if ioctl.name in f.read():
241+
is_used = True
242+
if is_used:
243+
break
244+
if is_used:
245+
refined_ioctls.append(ioctl)
246+
ioctls_defined = refined_ioctls
247+
return ioctls_defined
248+
249+
219250
def main() -> None:
220251
"""Main entrypoint"""
221252
args = parse_args()
@@ -241,7 +272,6 @@ def main() -> None:
241272
all_sources = identify_kernel_source_files(kernel_folder)
242273

243274
# Run base introspector. In this run there are no entrypoints analysed.
244-
245275
run_light_fi(target_path, workdir)
246276
extract_source_loc_analysis(workdir, all_sources, report)
247277

@@ -270,10 +300,9 @@ def main() -> None:
270300

271301
# Extract ioctls.
272302
logger.info('[+] Extracting raw ioctls')
273-
report[
274-
'ioctls'] = textual_source_analysis.extract_raw_ioctls_text_from_header_files(
275-
report['header_files'], kernel_folder)
276-
303+
report['ioctls'] = extract_ioctls_in_driver(kernel_folder, report, workdir,
304+
all_sources,
305+
args.strict_ioctls)
277306
for ioctl in report['ioctls']:
278307
logger.info('%s ::: %s', ioctl.raw_definition, ioctl.name)
279308

0 commit comments

Comments
 (0)