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>
This commit is contained in:
Qiuhao Li 2021-01-11 14:11:52 +08:00 committed by Thomas Huth
parent dd21ed0edf
commit 4cc5752303

View File

@ -88,6 +88,43 @@ def check_if_trace_crashes(trace, path):
return False 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): def remove_lines(newtrace, outpath):
remove_step = 1 remove_step = 1
i = 0 i = 0
@ -151,6 +188,25 @@ def remove_lines(newtrace, outpath):
length = int(newtrace[i].split()[2], 16) length = int(newtrace[i].split()[2], 16)
data = newtrace[i].split()[3][2:] data = newtrace[i].split()[3][2:]
if length > 1: 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) leftlength = int(length/2)
rightlength = length - leftlength rightlength = length - leftlength
newtrace.insert(i+1, "") newtrace.insert(i+1, "")