1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
#!/usr/bin/env python3
import os, sys
from subprocess import run, SubprocessError, DEVNULL, PIPE
from tempfile import NamedTemporaryFile
csmith_command = [
"csmith",
"--no-checksum",
"--nomain",
"--max-block-size", "1",
"--max-block-depth", "1",
]
def cat(path, title=None):
if not title:
title = path
print("-------------------- {} --------------------".format(title))
run(["cat", path])
def run_logged(cmd):
with NamedTemporaryFile() as stdout, NamedTemporaryFile() as stderr:
result = run(cmd, stdin=DEVNULL, stdout=stdout, stderr=stderr)
if result.returncode != 0:
print()
print("Error: '{}' exited with code {}".format(" ".join(cmd), result.returncode))
cat(stdout.name, title="stdout")
cat(stdout.name, title="stderr")
return result
def run_bindgen(input, output):
return run_logged([
"bindgen",
"--with-derive-partialeq",
"--with-derive-eq",
"--with-derive-partialord",
"--with-derive-ord",
"--with-derive-hash",
"--with-derive-default",
"-o", output.name,
input.name,
"--",
"-I", os.path.abspath(os.path.dirname(sys.argv[0])),
])
def run_rustc(output, test):
return run_logged([
"rustc",
"--crate-type", "lib",
"--test",
output.name,
"-o", test.name,
])
def main():
print("Fuzzing `bindgen` with C-Smith...\n")
iterations = 0
while True:
print("\rIteration: {}".format(iterations), end="", flush=True)
input = NamedTemporaryFile(delete=False, prefix="input-", suffix=".h")
input.close()
result = run_logged(csmith_command + ["-o", input.name])
if result.returncode != 0:
exit(1)
output = NamedTemporaryFile(delete=False, prefix="output-", suffix=".rs")
output.close()
result = run_bindgen(input, output)
if result.returncode != 0:
cat(input.name)
cat(output.name)
exit(1)
test = NamedTemporaryFile(delete=False, prefix="test-")
test.close()
result = run_rustc(output, test)
if result.returncode != 0:
cat(input.name)
cat(output.name)
exit(1)
result = run_logged([test.name])
if result.returncode != 0:
cat(input.name)
cat(output.name)
exit(1)
os.remove(input.name)
os.remove(output.name)
os.remove(test.name)
iterations += 1
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
exit()
|