Skip to content

Commit

Permalink
fuzz: accelerate non-crash detection
Browse files Browse the repository at this point in the history
We spend much time waiting for the timeout program during the minimization
process until it passes a time limit. This patch hacks the CLOSED (indicates
the redirection file closed) notification in QTest's output if it doesn't
crash.

Test with quadrupled trace input at:
  https://bugs.launchpad.net/qemu/+bug/1890333/comments/1

Original version:
  real	1m37.246s
  user	0m13.069s
  sys	0m8.399s

Refined version:
  real	0m45.904s
  user	0m16.874s
  sys	0m10.042s

Note:

Sometimes the mutated or the same trace may trigger a different crash
summary (second-to-last line) but indicates the same bug. For example, Bug
1910826 [1], which will trigger a stack overflow, may output summaries
like:

SUMMARY: AddressSanitizer: stack-overflow
/home/qiuhao/hack/qemu/build/../softmmu/physmem.c:488 in
flatview_do_translate

or

SUMMARY: AddressSanitizer: stack-overflow
(/home/qiuhao/hack/qemu/build/qemu-system-i386+0x27ca049) in __asan_memcpy

Etc.

If we use the whole summary line as the token, we may be prevented from
further minimization. So in this patch, we only use the first three words
which indicate the type of crash:

SUMMARY: AddressSanitizer: stack-overflow

[1] https://bugs.launchpad.net/qemu/+bug/1910826

Signed-off-by: Qiuhao Li <Qiuhao.Li@outlook.com>
Reviewed-by: Alexander Bulekov <alxndr@bu.edu>
Tested-by: Alexander Bulekov <alxndr@bu.edu>
Message-Id: <SYCPR01MB350251DC04003450348FAF68FCAB0@SYCPR01MB3502.ausprd01.prod.outlook.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
  • Loading branch information
QiuhaoLi authored and huth committed Jan 11, 2021
1 parent 124bd3e commit 22ec0c6
Showing 1 changed file with 31 additions and 13 deletions.
44 changes: 31 additions & 13 deletions scripts/oss-fuzz/minimize_qtest_trace.py
Expand Up @@ -29,8 +29,14 @@ def usage():
crash by setting CRASH_TOKEN=
""".format((sys.argv[0])))

deduplication_note = """\n\
Note: While trimming the input, sometimes the mutated trace triggers a different
type crash but indicates the same bug. Under this situation, our minimizer is
incapable of recognizing and stopped from removing it. In the future, we may
use a more sophisticated crash case deduplication method.
\n"""

def check_if_trace_crashes(trace, path):
global CRASH_TOKEN
with open(path, "w") as tracefile:
tracefile.write("".join(trace))

Expand All @@ -41,18 +47,31 @@ def check_if_trace_crashes(trace, path):
trace_path=path),
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
stdo = rc.communicate()[0]
output = stdo.decode('unicode_escape')
if rc.returncode == 137: # Timed Out
return False
if len(output.splitlines()) < 2:
return False

stdout=subprocess.PIPE,
encoding="utf-8")
global CRASH_TOKEN
if CRASH_TOKEN is None:
CRASH_TOKEN = output.splitlines()[-2]

return CRASH_TOKEN in output
try:
outs, _ = rc.communicate(timeout=5)
CRASH_TOKEN = " ".join(outs.splitlines()[-2].split()[0:3])
except subprocess.TimeoutExpired:
print("subprocess.TimeoutExpired")
return False
print("Identifying Crashes by this string: {}".format(CRASH_TOKEN))
global deduplication_note
print(deduplication_note)
return True

for line in iter(rc.stdout.readline, ""):
if "CLOSED" in line:
return False
if CRASH_TOKEN in line:
return True

print("\nWarning:")
print(" There is no 'CLOSED'or CRASH_TOKEN in the stdout of subprocess.")
print(" Usually this indicates a different type of crash.\n")
return False


def minimize_trace(inpath, outpath):
Expand All @@ -66,7 +85,6 @@ def minimize_trace(inpath, outpath):
print("Crashed in {} seconds".format(end-start))
TIMEOUT = (end-start)*5
print("Setting the timeout for {} seconds".format(TIMEOUT))
print("Identifying Crashes by this string: {}".format(CRASH_TOKEN))

i = 0
newtrace = trace[:]
Expand Down

0 comments on commit 22ec0c6

Please sign in to comment.