image-fuzzer.txt 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. # Specification for the fuzz testing tool
  2. #
  3. # Copyright (C) 2014 Maria Kustova <maria.k@catit.be>
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 2 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. Image fuzzer
  18. ============
  19. Description
  20. -----------
  21. The goal of the image fuzzer is to catch crashes of qemu-io/qemu-img
  22. by providing to them randomly corrupted images.
  23. Test images are generated from scratch and have valid inner structure with some
  24. elements, e.g. L1/L2 tables, having random invalid values.
  25. Test runner
  26. -----------
  27. The test runner generates test images, executes tests utilizing generated
  28. images, indicates their results and collects all test related artifacts (logs,
  29. core dumps, test images, backing files).
  30. The test means execution of all available commands under test with the same
  31. generated test image.
  32. By default, the test runner generates new tests and executes them until
  33. keyboard interruption. But if a test seed is specified via the '--seed' runner
  34. parameter, then only one test with this seed will be executed, after its finish
  35. the runner will exit.
  36. The runner uses an external image fuzzer to generate test images. An image
  37. generator should be specified as a mandatory parameter of the test runner.
  38. Details about interactions between the runner and fuzzers see "Module
  39. interfaces".
  40. The runner activates generation of core dumps during test executions, but it
  41. assumes that core dumps will be generated in the current working directory.
  42. For comprehensive test results, please, set up your test environment
  43. properly.
  44. Paths to binaries under test (SUTs) qemu-img and qemu-io are retrieved from
  45. environment variables. If the environment check fails the runner will
  46. use SUTs installed in system paths.
  47. qemu-img is required for creation of backing files, so it's mandatory to set
  48. the related environment variable if it's not installed in the system path.
  49. For details about environment variables see qemu-iotests/check.
  50. The runner accepts a JSON array of fields expected to be fuzzed via the
  51. '--config' argument, e.g.
  52. '[["feature_name_table"], ["header", "l1_table_offset"]]'
  53. Each sublist can have one or two strings defining image structure elements.
  54. In the latter case a parent element should be placed on the first position,
  55. and a field name on the second one.
  56. The runner accepts a list of commands under test as a JSON array via
  57. the '--command' argument. Each command is a list containing a SUT and all its
  58. arguments, e.g.
  59. runner.py -c '[["qemu-io", "$test_img", "-c", "write $off $len"]]'
  60. /tmp/test ../qcow2
  61. For variable arguments next aliases can be used:
  62. - $test_img for a fuzzed img
  63. - $off for an offset in the fuzzed image
  64. - $len for a data size
  65. Values for last two aliases will be generated based on a size of a virtual
  66. disk of the generated image.
  67. In case when no commands are specified the runner will execute commands from
  68. the default list:
  69. - qemu-img check
  70. - qemu-img info
  71. - qemu-img convert
  72. - qemu-io -c read
  73. - qemu-io -c write
  74. - qemu-io -c aio_read
  75. - qemu-io -c aio_write
  76. - qemu-io -c flush
  77. - qemu-io -c discard
  78. - qemu-io -c truncate
  79. Qcow2 image generator
  80. ---------------------
  81. The 'qcow2' generator is a Python package providing 'create_image' method as
  82. a single public API. See details in 'Test runner/image fuzzer' chapter of
  83. 'Module interfaces'.
  84. Qcow2 contains two submodules: fuzz.py and layout.py.
  85. 'fuzz.py' contains all fuzzing functions, one per image field. It's assumed
  86. that after code analysis every field will have own constraints for its value.
  87. For now only universal potentially dangerous values are used, e.g. type limits
  88. for integers or unsafe symbols as '%s' for strings. For bitmasks random amount
  89. of bits are set to ones. All fuzzed values are checked on non-equality to the
  90. current valid value of the field. In case of equality the value will be
  91. regenerated.
  92. 'layout.py' creates a random valid image, fuzzes a random subset of the image
  93. fields by 'fuzz.py' module and writes a fuzzed image to the file specified.
  94. If a fuzzer configuration is specified, then it has the next interpretation:
  95. 1. If a list contains a parent image element only, then some random portion
  96. of fields of this element will be fuzzed every test.
  97. The same behavior is applied for the entire image if no configuration is
  98. used. This case is useful for the test specialization.
  99. 2. If a list contains a parent element and a field name, then a field
  100. will be always fuzzed for every test. This case is useful for regression
  101. testing.
  102. The generator can create header fields, header extensions, L1/L2 tables and
  103. refcount table and blocks.
  104. Module interfaces
  105. -----------------
  106. * Test runner/image fuzzer
  107. The runner calls an image generator specifying the path to a test image file,
  108. path to a backing file and its format and a fuzzer configuration.
  109. An image generator is expected to provide a
  110. 'create_image(test_img_path, backing_file_path=None,
  111. backing_file_format=None, fuzz_config=None)'
  112. method that creates a test image, writes it to the specified file and returns
  113. the size of the virtual disk.
  114. The file should be created if it doesn't exist or overwritten otherwise.
  115. fuzz_config has a form of a list of lists. Every sublist can have one
  116. or two elements: first element is a name of a parent image element, second one
  117. if exists is a name of a field in this element.
  118. Example,
  119. [['header', 'l1_table_offset'],
  120. ['header', 'nb_snapshots'],
  121. ['feature_name_table']]
  122. Random seed is set by the runner at every test execution for the regression
  123. purpose, so an image generator is not recommended to modify it internally.
  124. Overall fuzzer requirements
  125. ===========================
  126. Input data:
  127. ----------
  128. - image template (generator)
  129. - work directory
  130. - action vector (optional)
  131. - seed (optional)
  132. - SUT and its arguments (optional)
  133. Fuzzer requirements:
  134. -------------------
  135. 1. Should be able to inject random data
  136. 2. Should be able to select a random value from the manually pregenerated
  137. vector (boundary values, e.g. max/min cluster size)
  138. 3. Image template should describe a general structure invariant for all
  139. test images (image format description)
  140. 4. Image template should be autonomous and other fuzzer parts should not
  141. rely on it
  142. 5. Image template should contain reference rules (not only block+size
  143. description)
  144. 6. Should generate the test image with the correct structure based on an image
  145. template
  146. 7. Should accept a seed as an argument (for regression purpose)
  147. 8. Should generate a seed if it is not specified as an input parameter.
  148. 9. The same seed should generate the same image for the same action vector,
  149. specified or generated.
  150. 10. Should accept a vector of actions as an argument (for test reproducing and
  151. for test case specification, e.g. group of tests for header structure,
  152. group of test for snapshots, etc)
  153. 11. Action vector should be randomly generated from the pool of available
  154. actions, if it is not specified as an input parameter
  155. 12. Pool of actions should be defined automatically based on an image template
  156. 13. Should accept a SUT and its call parameters as an argument or select them
  157. randomly otherwise. As far as it's expected to be rarely changed, the list
  158. of all possible test commands can be available in the test runner
  159. internally.
  160. 14. Should support an external cancellation of a test run
  161. 15. Seed should be logged (for regression purpose)
  162. 16. All files related to a test result should be collected: a test image,
  163. SUT logs, fuzzer logs and crash dumps
  164. 17. Should be compatible with python version 2.4-2.7
  165. 18. Usage of external libraries should be limited as much as possible.
  166. Image formats:
  167. -------------
  168. Main target image format is qcow2, but support of image templates should
  169. provide an ability to add any other image format.
  170. Effectiveness:
  171. -------------
  172. The fuzzer can be controlled via template, seed and action vector;
  173. it makes the fuzzer itself invariant to an image format and test logic.
  174. It should be able to perform rather complex and precise tests, that can be
  175. specified via an action vector. Otherwise, knowledge about an image structure
  176. allows the fuzzer to generate the pool of all available areas can be fuzzed
  177. and randomly select some of them and so compose its own action vector.
  178. Also complexity of a template defines complexity of the fuzzer, so its
  179. functionality can be varied from simple model-independent fuzzing to smart
  180. model-based one.
  181. Glossary:
  182. --------
  183. Action vector is a sequence of structure elements retrieved from an image
  184. format, each of them will be fuzzed for the test image. It's a subset of
  185. elements of the action pool. Example: header, refcount table, etc.
  186. Action pool is all available elements of an image structure that generated
  187. automatically from an image template.
  188. Image template is a formal description of an image structure and relations
  189. between image blocks.
  190. Test image is an output image of the fuzzer defined by the current seed and
  191. action vector.