update_engine: add omaha_request_action_fuzzer target

It fuzzes the XML response sent from Omaha.

It also refactored .gyp file to separate fake*/mock* libraries from
unittest* themselves.

BUG=chromium:906815
TEST=cros_fuzz

Change-Id: Ic7d0e7d18784e48f4e43b538f9797e5d2d452d08
Reviewed-on: https://chromium-review.googlesource.com/1344914
Commit-Ready: Xiaochu Liu <xiaochu@chromium.org>
Tested-by: Xiaochu Liu <xiaochu@chromium.org>
Reviewed-by: Amin Hassani <ahassani@chromium.org>
diff --git a/fuzz/xml.dict b/fuzz/xml.dict
new file mode 100644
index 0000000..8449cb0
--- /dev/null
+++ b/fuzz/xml.dict
@@ -0,0 +1,125 @@
+#
+# AFL dictionary for XML
+# ----------------------
+#
+# Several basic syntax elements and attributes, modeled on libxml2.
+#
+# Created by Michal Zalewski <lcamtuf@google.com>
+#
+
+attr_encoding=" encoding=\"1\""
+attr_generic=" a=\"1\""
+attr_href=" href=\"1\""
+attr_standalone=" standalone=\"no\""
+attr_version=" version=\"1\""
+attr_xml_base=" xml:base=\"1\""
+attr_xml_id=" xml:id=\"1\""
+attr_xml_lang=" xml:lang=\"1\""
+attr_xml_space=" xml:space=\"1\""
+attr_xmlns=" xmlns=\"1\""
+
+entity_builtin="&lt;"
+entity_decimal="&#1;"
+entity_external="&a;"
+entity_hex="&#x1;"
+
+# keywords
+"ANY"
+"ATTLIST"
+"CDATA"
+"DOCTYPE"
+"ELEMENT"
+"EMPTY"
+"ENTITIES"
+"ENTITY"
+"FIXED"
+"ID"
+"IDREF"
+"IDREFS"
+"IGNORE"
+"IMPLIED"
+"INCLUDE"
+"NDATA"
+"NMTOKEN"
+"NMTOKENS"
+"NOTATION"
+"PCDATA"
+"PUBLIC"
+"REQUIRED"
+"SYSTEM"
+
+# Various tag parts
+"<"
+">"
+"/>"
+"</"
+"<?"
+"?>"
+"<!"
+"!>"
+"[]"
+"]]"
+"<![CDATA["
+"<![CDATA[]]>"
+"\"\""
+"''"
+"=\"\""
+"=''"
+
+# DTD
+"<!ATTLIST"
+"<!DOCTYPE"
+"<!ELEMENT"
+"<!ENTITY"
+"<![IGNORE["
+"<![INCLUDE["
+"<!NOTATION"
+"#CDATA"
+"#FIXED"
+"#IMPLIED"
+"#PCDATA"
+"#REQUIRED"
+
+# Encodings
+"ISO-8859-1"
+"US-ASCII"
+"UTF-8"
+"UTF-16"
+"UTF-16BE"
+"UTF-16LE"
+
+# Namespaces and schemas
+"xmlns"
+"xmlns:"
+"xmlns:xhtml=\"http://www.w3.org/1999/xhtml\""
+"xmlns:xml=\"http://www.w3.org/XML/1998/namespace\""
+"xmlns:xmlns=\"http://www.w3.org/2000/xmlns\""
+
+string_col_fallback=":fallback"
+string_col_generic=":a"
+string_col_include=":include"
+string_dashes="--"
+string_parentheses="()"
+string_percent="%a"
+string_schema=":schema"
+string_ucs4="UCS-4"
+tag_close="</a>"
+tag_open="<a>"
+tag_open_close="<a />"
+
+
+"<?xml?>"
+"http://docboo"
+"http://www.w"
+"he30"
+"he2"
+"IET"
+"FDF-10"
+"aDUCS-4OPveb:"
+"a>"
+"UT"
+"xMl"
+"/usr/share/sg"
+"ha07"
+"http://www.oa"
+"cle"
diff --git a/omaha_request_action_fuzzer.cc b/omaha_request_action_fuzzer.cc
new file mode 100644
index 0000000..6c2f7ca
--- /dev/null
+++ b/omaha_request_action_fuzzer.cc
@@ -0,0 +1,53 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#include <brillo/message_loops/fake_message_loop.h>
+
+#include "update_engine/common/mock_http_fetcher.h"
+#include "update_engine/common/test_utils.h"
+#include "update_engine/fake_system_state.h"
+#include "update_engine/omaha_request_action.h"
+
+class Environment {
+ public:
+  Environment() { logging::SetMinLogLevel(logging::LOG_FATAL); }
+};
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+  static Environment env;
+  brillo::FakeMessageLoop loop(nullptr);
+  loop.SetAsCurrent();
+
+  chromeos_update_engine::FakeSystemState fake_system_state;
+  auto omaha_request_action =
+      std::make_unique<chromeos_update_engine::OmahaRequestAction>(
+          &fake_system_state,
+          nullptr,
+          std::make_unique<chromeos_update_engine::MockHttpFetcher>(
+              data, size, nullptr),
+          false);
+  auto collector_action =
+      std::make_unique<chromeos_update_engine::ObjectCollectorAction<
+          chromeos_update_engine::OmahaResponse>>();
+  BondActions(omaha_request_action.get(), collector_action.get());
+  chromeos_update_engine::ActionProcessor action_processor;
+  action_processor.EnqueueAction(std::move(omaha_request_action));
+  action_processor.EnqueueAction(std::move(collector_action));
+  action_processor.StartProcessing();
+
+  loop.Run();
+  return 0;
+}
diff --git a/update_engine.gyp b/update_engine.gyp
index c9e05d8..345b544 100644
--- a/update_engine.gyp
+++ b/update_engine.gyp
@@ -447,6 +447,32 @@
         'payload_generator/generate_delta_main.cc',
       ],
     },
+    {
+      'target_name': 'update_engine_test_libs',
+      'type': 'static_library',
+      'variables': {
+        'deps': [
+          'libshill-client-test',
+        ],
+      },
+      'dependencies': [
+        'libupdate_engine',
+      ],
+      'includes': [
+        '../../../platform2/common-mk/common_test.gypi',
+      ],
+      'sources': [
+        'common/fake_prefs.cc',
+        'common/file_fetcher.cc',  # Only required for tests.
+        'common/mock_http_fetcher.cc',
+        'common/test_utils.cc',
+        'fake_shill_proxy.cc',
+        'fake_system_state.cc',
+        'payload_consumer/fake_file_descriptor.cc',
+        'payload_generator/fake_filesystem.cc',
+        'update_manager/umtest_utils.cc',
+      ],
+    },
   ],
   'conditions': [
     ['USE_test == 1', {
@@ -511,8 +537,8 @@
           'dependencies': [
             'libupdate_engine',
             'libpayload_generator',
+            'update_engine_test_libs',
           ],
-          'includes': ['../../../platform2/common-mk/common_test.gypi'],
           'sources': [
             'boot_control_chromeos_unittest.cc',
             'certificate_checker_unittest.cc',
@@ -520,21 +546,15 @@
             'common/action_processor_unittest.cc',
             'common/action_unittest.cc',
             'common/cpu_limiter_unittest.cc',
-            'common/fake_prefs.cc',
-            'common/file_fetcher.cc',  # Only required for tests.
             'common/hash_calculator_unittest.cc',
             'common/http_fetcher_unittest.cc',
             'common/hwid_override_unittest.cc',
-            'common/mock_http_fetcher.cc',
             'common/prefs_unittest.cc',
             'common/subprocess_unittest.cc',
             'common/terminator_unittest.cc',
-            'common/test_utils.cc',
             'common/utils_unittest.cc',
             'common_service_unittest.cc',
             'connection_manager_unittest.cc',
-            'fake_shill_proxy.cc',
-            'fake_system_state.cc',
             'hardware_chromeos_unittest.cc',
             'image_properties_chromeos_unittest.cc',
             'metrics_reporter_omaha_unittest.cc',
@@ -551,7 +571,6 @@
             'payload_consumer/download_action_unittest.cc',
             'payload_consumer/extent_reader_unittest.cc',
             'payload_consumer/extent_writer_unittest.cc',
-            'payload_consumer/fake_file_descriptor.cc',
             'payload_consumer/file_descriptor_utils_unittest.cc',
             'payload_consumer/file_writer_unittest.cc',
             'payload_consumer/filesystem_verifier_action_unittest.cc',
@@ -566,7 +585,6 @@
             'payload_generator/ext2_filesystem_unittest.cc',
             'payload_generator/extent_ranges_unittest.cc',
             'payload_generator/extent_utils_unittest.cc',
-            'payload_generator/fake_filesystem.cc',
             'payload_generator/full_update_generator_unittest.cc',
             'payload_generator/graph_utils_unittest.cc',
             'payload_generator/inplace_generator_unittest.cc',
@@ -595,7 +613,6 @@
             'update_manager/real_time_provider_unittest.cc',
             'update_manager/real_updater_provider_unittest.cc',
             'update_manager/staging_utils_unittest.cc',
-            'update_manager/umtest_utils.cc',
             'update_manager/update_manager_unittest.cc',
             'update_manager/update_time_restrictions_policy_impl_unittest.cc',
             'update_manager/variable_unittest.cc',
@@ -604,5 +621,30 @@
         },
       ],
     }],
+    # Fuzzer target.
+    ['USE_fuzzer == 1', {
+      'targets': [
+        {
+          'target_name': 'update_engine_omaha_request_action_fuzzer',
+          'type': 'executable',
+          'variables': {
+            'deps': [
+              'libbrillo-test-<(libbase_ver)',
+              'libchrome-test-<(libbase_ver)',
+            ],
+          },
+          'includes': [
+            '../../../platform2/common-mk/common_fuzzer.gypi',
+          ],
+          'dependencies': [
+            'libupdate_engine',
+            'update_engine_test_libs',
+          ],
+          'sources': [
+            'omaha_request_action_fuzzer.cc',
+          ],
+        },
+      ],
+    }],
   ],
 }