Skip to content

Commit 02bed39

Browse files
committed
Update of Python driver scripts: It provides driving of the whole analysis pipeline up to recognition of error traces by CBMC, including presentation of results in HTML format (not complete yet though - presentation of results of last 2 phases is not clear/implemented yet).
1 parent 705ed22 commit 02bed39

File tree

3 files changed

+526
-72
lines changed

3 files changed

+526
-72
lines changed

security-scanner/analyser.py

Lines changed: 109 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,32 @@
11
import os
22
import time
33
import json
4+
import shutil
45

56

67
def __get_my_dir(): return os.path.dirname(os.path.realpath(__file__))
78

89

9-
def get_possible_analyser_binary_pathnames():
10+
def get_possible_directories_of_analysers():
11+
return ["./", "../src/driver", "../cbmc/src/cbmc", "../cbmc/src/symex"]
12+
13+
14+
def get_possible_analyser_binary_pathnames(analyser_name):
1015
result = []
11-
for rdir in ["./", "../src/driver"]:
12-
fname = os.path.abspath(os.path.join(__get_my_dir(), rdir, "security-analyzer"))
16+
for rdir in get_possible_directories_of_analysers():
17+
fname = os.path.abspath(os.path.join(__get_my_dir(), rdir, analyser_name))
1318
result.append(fname)
1419
return result
1520

1621

17-
def get_analyser_binary_pathname():
18-
for fname in get_possible_analyser_binary_pathnames():
22+
def get_analyser_binary_pathname(analyser_name):
23+
for fname in get_possible_analyser_binary_pathnames(analyser_name):
1924
if os.path.exists(fname) and os.path.isfile(fname):
2025
return fname
2126
return None
2227

2328

24-
def run_analyser(
29+
def run_secutiry_analyser(
2530
root_jar,
2631
transition_rules_file_pathname,
2732
timeout,
@@ -86,12 +91,12 @@ def run_analyser(
8691
old_cwd = os.getcwd()
8792
os.chdir(results_dir)
8893
command = (
89-
get_analyser_binary_pathname() + " "
94+
get_analyser_binary_pathname("security-analyzer") + " "
9095
+ "'./" + os.path.relpath(root_jar,results_dir) + "' "
9196
"--security-scanner '" + os.path.relpath(root_config_json_fname,results_dir) + "' "
9297
)
9398
prof["calling_goto_analyser"] = { "duration": time.time() }
94-
print("Invoking 'security_analyser' ...")
99+
print("Invoking 'security-analyser' ...")
95100
if verbosity >= 9:
96101
print("CWD: " + results_dir)
97102
print("CMD: " + command)
@@ -101,3 +106,99 @@ def run_analyser(
101106
prof["duration"] = time.time() - prof["duration"]
102107

103108
return prof
109+
110+
111+
def run_program_slicing(
112+
json_cfg_fname,
113+
results_dir,
114+
timeout,
115+
verbosity
116+
):
117+
prof = { "duration": time.time() }
118+
119+
# TODO: once the slicer in "goto-instrument" tool is available, then provide proper implementation here!
120+
# Until then we assume the slicing removes nothing from the instrumented program.
121+
shutil.copyfile(json_cfg_fname, os.path.join(os.path.dirname(json_cfg_fname),"sliced_goto_programs.json"))
122+
123+
prof["duration"] = time.time() - prof["duration"]
124+
return prof
125+
126+
127+
def run_search_for_error_traces(
128+
json_cfg_fname,
129+
results_dir,
130+
timeout,
131+
verbosity
132+
):
133+
prof = { "duration": time.time() }
134+
if not os.path.exists(results_dir):
135+
os.makedirs(results_dir)
136+
137+
trace_id = 0
138+
traces_list = []
139+
140+
with open(json_cfg_fname) as data_file:
141+
cfgs = json.load(data_file)
142+
for cfg in cfgs:
143+
old_cwd = os.getcwd()
144+
os.chdir(results_dir)
145+
command = (
146+
get_analyser_binary_pathname("cbmc") + " " +
147+
cfg["goto_binary_file"] + " " +
148+
" --trace --lazy-methods --json-ui --unwind 10 " +
149+
"--verbosity " + str(1) + " "
150+
"> \"cbmc_results.json\""
151+
)
152+
prof["calling_cbmc"] = { "duration": time.time() }
153+
print("Invoking 'cbmc' ...")
154+
if verbosity >= 9:
155+
print("CWD: " + results_dir)
156+
print("CMD: " + command)
157+
os.system(command)
158+
prof["calling_cbmc"]["duration"] = time.time() - prof["calling_cbmc"]["duration"]
159+
os.chdir(old_cwd)
160+
161+
with open(os.path.join(results_dir,"cbmc_results.json")) as data_file:
162+
cbmc_results = json.load(data_file)
163+
for outer_element in cbmc_results:
164+
if "result" in outer_element:
165+
for inner_element in outer_element["result"]:
166+
if "trace" in inner_element and len(inner_element["trace"]) > 0:
167+
trace=inner_element["trace"]
168+
last_rec=trace[len(trace)-1]
169+
if "sourceLocation" in last_rec:
170+
loc=last_rec["sourceLocation"]
171+
for sink in cfg["sinks"]:
172+
if loc["file"] == sink["file"] and \
173+
loc["function"] == sink["function"] and \
174+
loc["line"] == str(sink["line"]):
175+
trace_fname = os.path.join(results_dir, "error_trace_" + str(trace_id) + ".json")
176+
with open(trace_fname,"w") as trace_file:
177+
trace_file.write(json.dumps(trace,sort_keys=False,indent=4))
178+
trace_id += 1
179+
180+
found = False
181+
for rec in traces_list:
182+
if rec["file"] == sink["file"] and \
183+
rec["function"] == sink["function"] and \
184+
rec["line"] == sink["line"] and \
185+
rec["goto_binary_file"] == cfg["goto_binary_file"]:
186+
rec["error_traces"].append(trace_fname)
187+
if found == False:
188+
rec=sink
189+
rec["goto_binary_file"]=cfg["goto_binary_file"]
190+
rec["error_traces"]=[trace_fname]
191+
traces_list.append(rec)
192+
break
193+
194+
with open(os.path.join(results_dir, "error_traces.json"), "w") as traces_file:
195+
traces_file.write(json.dumps(traces_list, sort_keys=True, indent=4))
196+
197+
prof["duration"] = time.time() - prof["duration"]
198+
return prof
199+
200+
201+
202+
203+
if __name__ == "__main__":
204+
pass

0 commit comments

Comments
 (0)