2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Mutational ClusterFuzz fuzzer. A pre-built corpus of ipcdump files has
7 to be uploaded to ClusterFuzz along with this script. As chrome is being
8 developed, the corpus will become out-of-date and needs to be updated.
10 This fuzzer will pick some ipcdumps from the corpus, concatenate them with
11 ipc_message_util and mutate the result with ipc_fuzzer_mutate.
23 # Number of ipcdumps to concatenate
26 def create_temp_file():
27 temp_file
= tempfile
.NamedTemporaryFile(delete
=False)
31 def random_id(size
=16, chars
=string
.ascii_lowercase
):
32 return ''.join(random
.choice(chars
) for x
in range(size
))
34 def random_ipcdump_path(ipcdump_dir
):
35 return os
.path
.join(ipcdump_dir
, 'fuzz-' + random_id() + '.ipcdump')
37 class MutationalFuzzer
:
38 def parse_cf_args(self
):
39 parser
= argparse
.ArgumentParser()
40 parser
.add_argument('--input_dir')
41 parser
.add_argument('--output_dir')
42 parser
.add_argument('--no_of_files', type=int)
43 self
.args
= args
= parser
.parse_args();
44 if not args
.input_dir
or not args
.output_dir
or not args
.no_of_files
:
49 app_path_key
= 'APP_PATH'
50 self
.util_binary
= 'ipc_message_util'
51 self
.mutate_binary
= 'ipc_fuzzer_mutate'
53 if app_path_key
not in os
.environ
:
54 sys
.exit('Env var %s should be set to chrome path' % app_path_key
)
55 chrome_path
= os
.environ
[app_path_key
]
56 out_dir
= os
.path
.dirname(chrome_path
)
57 self
.util_path
= os
.path
.join(out_dir
, self
.util_binary
)
58 self
.mutate_path
= os
.path
.join(out_dir
, self
.mutate_binary
)
60 def list_corpus(self
):
61 input_dir
= self
.args
.input_dir
62 entries
= os
.listdir(input_dir
)
63 entries
= [i
for i
in entries
if i
.endswith('.ipcdump')]
64 self
.corpus
= [os
.path
.join(input_dir
, entry
) for entry
in entries
]
66 def create_mutated_ipcdump(self
):
67 ipcdumps
= ','.join(random
.sample(self
.corpus
, NUM_IPCDUMPS
))
68 tmp_ipcdump
= create_temp_file()
69 mutated_ipcdump
= random_ipcdump_path(self
.args
.output_dir
)
71 # concatenate ipcdumps -> tmp_ipcdump
72 cmd
= [self
.util_path
, ipcdumps
, tmp_ipcdump
]
73 if subprocess
.call(cmd
):
74 sys
.exit('%s failed' % self
.util_binary
)
76 # mutate tmp_ipcdump -> mutated_ipcdump
77 cmd
= [self
.mutate_path
, tmp_ipcdump
, mutated_ipcdump
]
78 if subprocess
.call(cmd
):
79 sys
.exit('%s failed' % self
.mutate_binary
)
80 os
.remove(tmp_ipcdump
)
86 for i
in xrange(self
.args
.no_of_files
):
87 self
.create_mutated_ipcdump()
90 if __name__
== "__main__":
91 fuzzer
= MutationalFuzzer()
92 sys
.exit(fuzzer
.main())