diff options
author | Qiuhao Li | 2021-01-11 07:11:52 +0100 |
---|---|---|
committer | Thomas Huth | 2021-01-11 14:59:21 +0100 |
commit | 4cc5752303c83b55e56961d91b7cf83c4e73f393 (patch) | |
tree | 76e720f7ef1aa0f31de5c854383899a8622dddb7 /scripts/oss-fuzz | |
parent | fuzz: add minimization options (diff) | |
download | qemu-4cc5752303c83b55e56961d91b7cf83c4e73f393.tar.gz qemu-4cc5752303c83b55e56961d91b7cf83c4e73f393.tar.xz qemu-4cc5752303c83b55e56961d91b7cf83c4e73f393.zip |
fuzz: heuristic split write based on past IOs
If previous write commands write the same length of data with the same step,
we view it as a hint.
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: <SYCPR01MB3502480AD07811A6A49B8FEAFCAB0@SYCPR01MB3502.ausprd01.prod.outlook.com>
Signed-off-by: Thomas Huth <thuth@redhat.com>
Diffstat (limited to 'scripts/oss-fuzz')
-rwxr-xr-x | scripts/oss-fuzz/minimize_qtest_trace.py | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/scripts/oss-fuzz/minimize_qtest_trace.py b/scripts/oss-fuzz/minimize_qtest_trace.py index 0e59bdbb01..4cba96dee2 100755 --- a/scripts/oss-fuzz/minimize_qtest_trace.py +++ b/scripts/oss-fuzz/minimize_qtest_trace.py @@ -88,6 +88,43 @@ def check_if_trace_crashes(trace, path): return False +# If previous write commands write the same length of data at the same +# interval, we view it as a hint. +def split_write_hint(newtrace, i): + HINT_LEN = 3 # > 2 + if i <=(HINT_LEN-1): + return None + + #find previous continuous write traces + k = 0 + l = i-1 + writes = [] + while (k != HINT_LEN and l >= 0): + if newtrace[l].startswith("write "): + writes.append(newtrace[l]) + k += 1 + l -= 1 + elif newtrace[l] == "": + l -= 1 + else: + return None + if k != HINT_LEN: + return None + + length = int(writes[0].split()[2], 16) + for j in range(1, HINT_LEN): + if length != int(writes[j].split()[2], 16): + return None + + step = int(writes[0].split()[1], 16) - int(writes[1].split()[1], 16) + for j in range(1, HINT_LEN-1): + if step != int(writes[j].split()[1], 16) - \ + int(writes[j+1].split()[1], 16): + return None + + return (int(writes[0].split()[1], 16)+step, length) + + def remove_lines(newtrace, outpath): remove_step = 1 i = 0 @@ -151,6 +188,25 @@ def remove_lines(newtrace, outpath): length = int(newtrace[i].split()[2], 16) data = newtrace[i].split()[3][2:] if length > 1: + + # Can we get a hint from previous writes? + hint = split_write_hint(newtrace, i) + if hint is not None: + hint_addr = hint[0] + hint_len = hint[1] + if hint_addr >= addr and hint_addr+hint_len <= addr+length: + newtrace[i] = "write {addr} {size} 0x{data}\n".format( + addr=hex(hint_addr), + size=hex(hint_len), + data=data[(hint_addr-addr)*2:\ + (hint_addr-addr)*2+hint_len*2]) + if check_if_trace_crashes(newtrace, outpath): + # next round + i += 1 + continue + newtrace[i] = prior[0] + + # Try splitting it using a binary approach leftlength = int(length/2) rightlength = length - leftlength newtrace.insert(i+1, "") |