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.
20 IPC_MESSAGE_UTIL_APPLICATION
= 'ipc_message_util'
21 IPC_MUTATE_APPLICATION
= 'ipc_fuzzer_mutate'
22 IPC_REPLAY_APPLICATION
= 'ipc_fuzzer_replay'
23 IPCDUMP_MERGE_LIMIT
= 50
25 class MutationalFuzzer
:
26 def parse_arguments(self
):
27 self
.args
= utils
.parse_arguments()
29 def set_application_paths(self
):
30 chrome_application_path
= utils
.get_application_path()
31 chrome_application_directory
= os
.path
.dirname(chrome_application_path
)
33 self
.ipc_message_util_binary
= utils
.application_name_for_platform(
34 IPC_MESSAGE_UTIL_APPLICATION
)
35 self
.ipc_mutate_binary
= utils
.application_name_for_platform(
36 IPC_MUTATE_APPLICATION
)
37 self
.ipc_replay_binary
= utils
.application_name_for_platform(
38 IPC_REPLAY_APPLICATION
)
39 self
.ipc_message_util_binary_path
= os
.path
.join(
40 chrome_application_directory
, self
.ipc_message_util_binary
)
41 self
.ipc_mutate_binary_path
= os
.path
.join(
42 chrome_application_directory
, self
.ipc_mutate_binary
)
43 self
.ipc_replay_binary_path
= os
.path
.join(
44 chrome_application_directory
, self
.ipc_replay_binary
)
47 input_directory
= self
.args
.input_dir
48 entries
= os
.listdir(input_directory
)
49 entries
= [i
for i
in entries
if i
.endswith(utils
.IPCDUMP_EXTENSION
)]
50 self
.corpus
= [os
.path
.join(input_directory
, entry
) for entry
in entries
]
52 def create_mutated_ipcdump_testcase(self
):
53 ipcdumps
= ','.join(random
.sample(self
.corpus
, IPCDUMP_MERGE_LIMIT
))
54 tmp_ipcdump_testcase
= utils
.create_temp_file()
55 mutated_ipcdump_testcase
= (
56 utils
.random_ipcdump_testcase_path(self
.args
.output_dir
))
58 # Concatenate ipcdumps -> tmp_ipcdump.
60 self
.ipc_message_util_binary_path
,
64 if subprocess
.call(cmd
):
65 sys
.exit('%s failed.' % self
.ipc_message_util_binary
)
67 # Mutate tmp_ipcdump -> mutated_ipcdump.
69 self
.ipc_mutate_binary_path
,
71 mutated_ipcdump_testcase
,
73 if subprocess
.call(cmd
):
74 sys
.exit('%s failed.' % self
.ipc_mutate_binary
)
76 utils
.create_flags_file(
77 mutated_ipcdump_testcase
, self
.ipc_replay_binary_path
)
78 os
.remove(tmp_ipcdump_testcase
)
81 self
.parse_arguments()
82 self
.set_application_paths()
84 for _
in xrange(self
.args
.no_of_files
):
85 self
.create_mutated_ipcdump_testcase()
89 if __name__
== "__main__":
90 fuzzer
= MutationalFuzzer()
91 sys
.exit(fuzzer
.main())