OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Fuzz testing for EncodedProgram serialized format and assembly. | 5 // Fuzz testing for EncodedProgram serialized format and assembly. |
6 // | 6 // |
7 // We would like some assurance that if an EncodedProgram is malformed we will | 7 // We would like some assurance that if an EncodedProgram is malformed we will |
8 // not crash. The EncodedProgram could be malformed either due to malicious | 8 // not crash. The EncodedProgram could be malformed either due to malicious |
9 // attack to due to an error in patch generation. | 9 // attack to due to an error in patch generation. |
10 // | 10 // |
11 // We try a lot of arbitrary modifications to the serialized form and make sure | 11 // We try a lot of arbitrary modifications to the serialized form and make sure |
12 // that the outcome is not a crash. | 12 // that the outcome is not a crash. |
13 #include "courgette/encoded_program.h" | 13 #include "courgette/encoded_program.h" |
14 | 14 |
15 #include <stddef.h> | 15 #include <stddef.h> |
16 | 16 |
17 #include "base/memory/scoped_ptr.h" | 17 #include <memory> |
| 18 |
18 #include "base/test/test_suite.h" | 19 #include "base/test/test_suite.h" |
19 #include "courgette/assembly_program.h" | 20 #include "courgette/assembly_program.h" |
20 #include "courgette/base_test_unittest.h" | 21 #include "courgette/base_test_unittest.h" |
21 #include "courgette/courgette.h" | 22 #include "courgette/courgette.h" |
22 #include "courgette/program_detector.h" | 23 #include "courgette/program_detector.h" |
23 #include "courgette/streams.h" | 24 #include "courgette/streams.h" |
24 | 25 |
25 class DecodeFuzzTest : public BaseTest { | 26 class DecodeFuzzTest : public BaseTest { |
26 public: | 27 public: |
27 void FuzzExe(const char *) const; | 28 void FuzzExe(const char *) const; |
28 | 29 |
29 private: | 30 private: |
30 void FuzzByte(const std::string& buffer, const std::string& output, | 31 void FuzzByte(const std::string& buffer, const std::string& output, |
31 size_t index) const; | 32 size_t index) const; |
32 void FuzzBits(const std::string& buffer, const std::string& output, | 33 void FuzzBits(const std::string& buffer, const std::string& output, |
33 size_t index, int bits_to_flip) const; | 34 size_t index, int bits_to_flip) const; |
34 | 35 |
35 // Returns true if could assemble, false if rejected. | 36 // Returns true if could assemble, false if rejected. |
36 bool TryAssemble(const std::string& buffer, std::string* output) const; | 37 bool TryAssemble(const std::string& buffer, std::string* output) const; |
37 }; | 38 }; |
38 | 39 |
39 // Loads an executable and does fuzz testing in the serialized format. | 40 // Loads an executable and does fuzz testing in the serialized format. |
40 void DecodeFuzzTest::FuzzExe(const char* file_name) const { | 41 void DecodeFuzzTest::FuzzExe(const char* file_name) const { |
41 std::string file1 = FileContents(file_name); | 42 std::string file1 = FileContents(file_name); |
42 | 43 |
43 const void* original_buffer = file1.c_str(); | 44 const void* original_buffer = file1.c_str(); |
44 size_t original_length = file1.length(); | 45 size_t original_length = file1.length(); |
45 | 46 |
46 scoped_ptr<courgette::AssemblyProgram> program; | 47 std::unique_ptr<courgette::AssemblyProgram> program; |
47 const courgette::Status parse_status = | 48 const courgette::Status parse_status = |
48 courgette::ParseDetectedExecutable(original_buffer, original_length, | 49 courgette::ParseDetectedExecutable(original_buffer, original_length, |
49 &program); | 50 &program); |
50 EXPECT_EQ(courgette::C_OK, parse_status); | 51 EXPECT_EQ(courgette::C_OK, parse_status); |
51 | 52 |
52 scoped_ptr<courgette::EncodedProgram> encoded; | 53 std::unique_ptr<courgette::EncodedProgram> encoded; |
53 const courgette::Status encode_status = Encode(*program, &encoded); | 54 const courgette::Status encode_status = Encode(*program, &encoded); |
54 EXPECT_EQ(courgette::C_OK, encode_status); | 55 EXPECT_EQ(courgette::C_OK, encode_status); |
55 | 56 |
56 program.reset(); | 57 program.reset(); |
57 | 58 |
58 courgette::SinkStreamSet sinks; | 59 courgette::SinkStreamSet sinks; |
59 const courgette::Status write_status = | 60 const courgette::Status write_status = |
60 WriteEncodedProgram(encoded.get(), &sinks); | 61 WriteEncodedProgram(encoded.get(), &sinks); |
61 EXPECT_EQ(courgette::C_OK, write_status); | 62 EXPECT_EQ(courgette::C_OK, write_status); |
62 | 63 |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
166 if (index > 60) { // Beyond the origin addresses ... | 167 if (index > 60) { // Beyond the origin addresses ... |
167 EXPECT_NE(0U, changed_byte_count); // ... we expect some difference. | 168 EXPECT_NE(0U, changed_byte_count); // ... we expect some difference. |
168 } | 169 } |
169 // Currently all changes are smaller than this number: | 170 // Currently all changes are smaller than this number: |
170 EXPECT_GE(45000U, changed_byte_count); | 171 EXPECT_GE(45000U, changed_byte_count); |
171 } | 172 } |
172 } | 173 } |
173 | 174 |
174 bool DecodeFuzzTest::TryAssemble(const std::string& buffer, | 175 bool DecodeFuzzTest::TryAssemble(const std::string& buffer, |
175 std::string* output) const { | 176 std::string* output) const { |
176 scoped_ptr<courgette::EncodedProgram> encoded; | 177 std::unique_ptr<courgette::EncodedProgram> encoded; |
177 bool result = false; | 178 bool result = false; |
178 | 179 |
179 courgette::SourceStreamSet sources; | 180 courgette::SourceStreamSet sources; |
180 bool can_get_source_streams = sources.Init(buffer.c_str(), buffer.length()); | 181 bool can_get_source_streams = sources.Init(buffer.c_str(), buffer.length()); |
181 if (can_get_source_streams) { | 182 if (can_get_source_streams) { |
182 const courgette::Status read_status = | 183 const courgette::Status read_status = |
183 ReadEncodedProgram(&sources, &encoded); | 184 ReadEncodedProgram(&sources, &encoded); |
184 if (read_status == courgette::C_OK) { | 185 if (read_status == courgette::C_OK) { |
185 courgette::SinkStream assembled; | 186 courgette::SinkStream assembled; |
186 const courgette::Status assemble_status = | 187 const courgette::Status assemble_status = |
(...skipping 15 matching lines...) Expand all Loading... |
202 } | 203 } |
203 | 204 |
204 TEST_F(DecodeFuzzTest, All) { | 205 TEST_F(DecodeFuzzTest, All) { |
205 FuzzExe("setup1.exe"); | 206 FuzzExe("setup1.exe"); |
206 FuzzExe("elf-32-1.exe"); | 207 FuzzExe("elf-32-1.exe"); |
207 } | 208 } |
208 | 209 |
209 int main(int argc, char** argv) { | 210 int main(int argc, char** argv) { |
210 return base::TestSuite(argc, argv).Run(); | 211 return base::TestSuite(argc, argv).Run(); |
211 } | 212 } |
OLD | NEW |