diff --git a/DEPS b/DEPS
index 29b2300..366d55a 100644
--- a/DEPS
+++ b/DEPS
@@ -78,7 +78,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '92c7fa6b009b3ea4e93ca179153f837c2d9d7962',
+  'skia_revision': '0482ced2cd10eca60a183682855fe5e92bb7063b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -643,7 +643,7 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'd458ada06171a85af00367251a4ed55db7fe2018',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '221b12666ff66398eed8c815e2065a049e93f294', # commit position 20628
+    Var('webrtc_git') + '/src.git' + '@' + '11556464a62ea14db9eee5e6c2a79a40aa1700ab', # commit position 20628
 
   'src/third_party/xdg-utils': {
       'url': Var('chromium_git') + '/chromium/deps/xdg-utils.git' + '@' + 'd80274d5869b17b8c9067a1022e4416ee7ed5e0d',
@@ -1321,7 +1321,7 @@
     'action': [
       'vpython',
       'src/build/fuchsia/update_sdk.py',
-      'd0241d561e5181bb5d5463d0a8cb2d488686caa5',
+      '0ea54bf34d90fadbb160baea697de60d7ada7b09',
     ],
   },
 
diff --git a/ash/app_list/model/app_list_item.h b/ash/app_list/model/app_list_item.h
index ce688d42..69aa3e05 100644
--- a/ash/app_list/model/app_list_item.h
+++ b/ash/app_list/model/app_list_item.h
@@ -16,6 +16,7 @@
 #include "ui/gfx/image/image_skia.h"
 
 class FastShowPickler;
+class ChromeAppListModelUpdater;
 
 namespace ui {
 class MenuModel;
@@ -88,6 +89,9 @@
   virtual std::string ToDebugString() const;
 
  protected:
+  // TODO(hejq): remove this when we have mojo interfaces.
+  friend class ::ChromeAppListModelUpdater;
+
   friend class ::FastShowPickler;
   friend class AppListItemList;
   friend class AppListItemListTest;
diff --git a/build/android/gyp/dist_aar.py b/build/android/gyp/dist_aar.py
new file mode 100755
index 0000000..51515fa
--- /dev/null
+++ b/build/android/gyp/dist_aar.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+#
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Creates an Android .aar file."""
+
+import argparse
+import os
+import posixpath
+import shutil
+import sys
+import tempfile
+import zipfile
+
+from util import build_utils
+
+
+_ANDROID_BUILD_DIR = os.path.dirname(os.path.dirname(__file__))
+
+
+def _MergeRTxt(r_paths):
+  """Merging the given R.txt files and returns them as a string."""
+  all_lines = set()
+  for r_path in r_paths:
+    with open(r_path) as f:
+      all_lines.update(f.readlines())
+  return ''.join(sorted(all_lines))
+
+
+def _MergeProguardConfigs(proguard_configs):
+  """Merging the given proguard config files and returns them as a string."""
+  ret = []
+  for config in proguard_configs:
+    ret.append('# FROM: {}'.format(config))
+    with open(config) as f:
+      ret.append(f.read())
+  return '\n'.join(ret)
+
+
+def _AddResources(aar_zip, resource_zips):
+  """Adds all resource zips to the given aar_zip.
+
+  Ensures all res/values/* files have unique names by prefixing them.
+  """
+  for i, path in enumerate(resource_zips):
+    with zipfile.ZipFile(path) as res_zip:
+      for info in res_zip.infolist():
+        data = res_zip.read(info)
+        dirname, basename = posixpath.split(info.filename)
+        if 'values' in dirname:
+          basename = '{}_{}'.format(basename, i)
+          info.filename = posixpath.join(dirname, basename)
+        info.filename = posixpath.join('res', info.filename)
+        aar_zip.writestr(info, data)
+
+
+def main(args):
+  args = build_utils.ExpandFileArgs(args)
+  parser = argparse.ArgumentParser()
+  build_utils.AddDepfileOption(parser)
+  parser.add_argument('--output', required=True, help='Path to output aar.')
+  parser.add_argument('--jars', required=True, help='GN list of jar inputs.')
+  parser.add_argument('--dependencies-res-zips', required=True,
+                      help='GN list of resource zips')
+  parser.add_argument('--r-text-files', required=True,
+                      help='GN list of R.txt files to merge')
+  parser.add_argument('--proguard-configs', required=True,
+                      help='GN list of ProGuard flag files to merge.')
+  parser.add_argument(
+      '--android-manifest',
+      help='Path to AndroidManifest.xml to include.',
+      default=os.path.join(_ANDROID_BUILD_DIR, 'AndroidManifest.xml'))
+
+  options = parser.parse_args(args)
+  options.jars = build_utils.ParseGnList(options.jars)
+  options.dependencies_res_zips = build_utils.ParseGnList(
+      options.dependencies_res_zips)
+  options.r_text_files = build_utils.ParseGnList(options.r_text_files)
+  options.proguard_configs = build_utils.ParseGnList(options.proguard_configs)
+
+  with tempfile.NamedTemporaryFile(delete=False) as staging_file:
+    try:
+      with zipfile.ZipFile(staging_file.name, 'w') as z:
+        build_utils.AddToZipHermetic(
+            z, 'AndroidManifest.xml', src_path=options.android_manifest)
+
+        with tempfile.NamedTemporaryFile() as jar_file:
+          build_utils.MergeZips(jar_file.name, options.jars)
+          build_utils.AddToZipHermetic(z, 'classes.jar', src_path=jar_file.name)
+
+        build_utils.AddToZipHermetic(
+            z, 'R.txt', data=_MergeRTxt(options.r_text_files))
+        build_utils.AddToZipHermetic(z, 'public.txt', data='')
+
+        if options.proguard_configs:
+          build_utils.AddToZipHermetic(
+              z, 'proguard.txt',
+              data=_MergeProguardConfigs(options.proguard_configs))
+
+        _AddResources(z, options.dependencies_res_zips)
+    except:
+      os.unlink(staging_file.name)
+      raise
+    shutil.move(staging_file.name, options.output)
+
+  if options.depfile:
+    all_inputs = (options.jars + options.dependencies_res_zips +
+                  options.r_text_files + options.proguard_configs)
+    build_utils.WriteDepfile(options.depfile, options.output, all_inputs)
+
+
+if __name__ == '__main__':
+  main(sys.argv[1:])
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py
index 5b40ada..d9b4999 100755
--- a/build/android/gyp/write_build_config.py
+++ b/build/android/gyp/write_build_config.py
@@ -367,6 +367,7 @@
       'android_resources': ['build_config', 'resources_zip'],
       'android_apk': ['build_config','dex_path'] + jar_path_options,
       'dist_jar': ['build_config'],
+      'dist_aar': ['build_config'],
       'resource_rewriter': ['build_config'],
       'group': ['build_config'],
   }
@@ -389,7 +390,7 @@
 
   is_java_target = options.type in (
       'java_binary', 'junit_binary', 'java_annotation_processor',
-      'java_library', 'android_apk', 'dist_jar')
+      'java_library', 'android_apk', 'dist_aar', 'dist_jar')
 
   deps = _DepsFromPaths(
       build_utils.ParseGnList(options.deps_configs), options.type)
@@ -586,7 +587,8 @@
     deps_info['owned_resources_zips'] = sorted(owned_resource_zips)
 
   if options.type in (
-      'android_resources', 'android_apk', 'junit_binary', 'resource_rewriter'):
+      'android_resources', 'android_apk', 'junit_binary', 'resource_rewriter',
+      'dist_aar'):
     config['resources'] = {}
     config['resources']['dependency_zips'] = [
         c['resources_zip'] for c in all_resources_deps]
@@ -700,7 +702,7 @@
     deps_info['proguard_configs'] = (
         build_utils.ParseGnList(options.proguard_configs))
 
-  if options.type in ('android_apk', 'dist_jar'):
+  if options.type in ('android_apk', 'dist_aar', 'dist_jar'):
     deps_info['proguard_enabled'] = options.proguard_enabled
     deps_info['proguard_info'] = options.proguard_info
     config['proguard'] = {}
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
index d249b3204..5919bbd 100644
--- a/build/config/android/internal_rules.gni
+++ b/build/config/android/internal_rules.gni
@@ -58,7 +58,7 @@
   # consider them in dependency chains.
   if (_type != "android_apk" && _type != "java_binary" &&
       _type != "resource_rewriter" && _type != "dist_jar" &&
-      _type != "java_annotation_processor") {
+      _type != "java_annotation_processor" && _type != "dist_aar") {
     set_sources_assignment_filter(_java_target_whitelist)
     _parent_invoker = invoker.invoker
     _target_label =
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
index cec570c..01e35fc 100644
--- a/build/config/android/rules.gni
+++ b/build/config/android/rules.gni
@@ -1478,6 +1478,88 @@
     }
   }
 
+  # Creates an Android .aar library.
+  #
+  # Currently supports:
+  #   * AndroidManifest.xml
+  #   * classes.jar
+  #   * res/
+  #   * R.txt
+  #   * proguard.txt
+  # Does not yet support:
+  #   * public.txt
+  #   * annotations.zip
+  #   * assets/
+  #   * jni/
+  # See: https://developer.android.com/studio/projects/android-library.html#aar-contents
+  #
+  # Variables:
+  #   output: Path to the output .aar.
+  #   proguard_configs: List of proguard configs (optional).
+  #   android_manifest: Path to AndroidManifest.xml (optional).
+  #
+  # Example
+  #   dist_aar("my_aar") {
+  #     deps = [ ":my_java_lib" ]
+  #     output = "$root_build_dir/MyLibrary.aar"
+  #   }
+  template("dist_aar") {
+    forward_variables_from(invoker, [ "testonly" ])
+
+    _deps = []
+    if (defined(invoker.deps)) {
+      _deps = invoker.deps
+    }
+
+    _build_config = "$target_gen_dir/$target_name.build_config"
+    _build_config_target_name = "${target_name}__build_config"
+
+    write_build_config(_build_config_target_name) {
+      type = "dist_aar"
+      forward_variables_from(invoker, [ "proguard_configs" ])
+      possible_config_deps = _deps
+      supports_android = true
+      requires_android = true
+      build_config = _build_config
+    }
+
+    _deps += [ ":$_build_config_target_name" ]
+
+    _rebased_build_config = rebase_path(_build_config, root_build_dir)
+
+    action(target_name) {
+      forward_variables_from(invoker, [ "data" ])
+      depfile = "$target_gen_dir/$target_name.d"
+      deps = _deps
+      script = "//build/android/gyp/dist_aar.py"
+
+      inputs = [
+        _build_config,
+      ]
+
+      outputs = [
+        invoker.output,
+      ]
+
+      args = [
+        "--depfile",
+        rebase_path(depfile, root_build_dir),
+        "--output",
+        rebase_path(invoker.output, root_build_dir),
+        "--jars=@FileArg($_rebased_build_config:deps_info:javac_full_classpath)",
+        "--dependencies-res-zips=@FileArg($_rebased_build_config:resources:dependency_zips)",
+        "--r-text-files=@FileArg($_rebased_build_config:resources:extra_r_text_files)",
+        "--proguard-configs=@FileArg($_rebased_build_config:proguard:all_configs)",
+      ]
+      if (defined(invoker.android_manifest)) {
+        args += [
+          "--android-manifest",
+          rebase_path(invoker.android_manifest, root_build_dir),
+        ]
+      }
+    }
+  }
+
   # Declare an Android library target
   #
   # This target creates an Android library containing java code and Android
diff --git a/chrome/app/md_extensions_strings.grdp b/chrome/app/md_extensions_strings.grdp
index f5612d5..e43e673 100644
--- a/chrome/app/md_extensions_strings.grdp
+++ b/chrome/app/md_extensions_strings.grdp
@@ -220,6 +220,9 @@
   <message name="IDS_MD_EXTENSIONS_TOOLBAR_UPDATE_NOW_TOOLTIP" desc="Text displayed over the 'update' menu that provides more context as a tooltip.">
     Update extensions now
   </message>
+  <message name="IDS_MD_EXTENSIONS_TOOLBAR_UPDATE_DONE" desc="Text used to announce when extensions have been updated. This is for accessibility.">
+    Extensions updated
+  </message>
   <message name="IDS_MD_EXTENSIONS_TYPE_A_SHORTCUT" desc="The prompt to the user to enter a keyboard shortcut in order to assign it to an extension.">
     Type a shortcut
   </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index a48b0b7..d27de936 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1236,6 +1236,10 @@
     {"ui-disable-partial-swap", flag_descriptions::kUiPartialSwapName,
      flag_descriptions::kUiPartialSwapDescription, kOsAll,
      SINGLE_DISABLE_VALUE_TYPE(switches::kUIDisablePartialSwap)},
+    {"enable-prevent-layer-squashing",
+     flag_descriptions::kEnablePreventLayerSquashingName,
+     flag_descriptions::kEnablePreventLayerSquashingDescription, kOsAll,
+     FEATURE_VALUE_TYPE(features::kEnablePreventLayerSquashing)},
 #if BUILDFLAG(ENABLE_WEBRTC)
     {"disable-webrtc-hw-decoding", flag_descriptions::kWebrtcHwDecodingName,
      flag_descriptions::kWebrtcHwDecodingDescription, kOsAndroid | kOsCrOS,
diff --git a/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc b/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc
index 80f0d540..b12ecc0 100644
--- a/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc
+++ b/chrome/browser/bitmap_fetcher/bitmap_fetcher.cc
@@ -7,6 +7,7 @@
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/storage_partition.h"
+#include "content/public/common/referrer.h"
 #include "net/url_request/url_fetcher.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "net/url_request/url_request_status.h"
@@ -29,7 +30,8 @@
   auto resource_request = std::make_unique<content::ResourceRequest>();
   resource_request->url = url_;
   resource_request->referrer = GURL(referrer);
-  resource_request->referrer_policy = referrer_policy;
+  resource_request->referrer_policy =
+      content::Referrer::ReferrerPolicyForUrlRequest(referrer_policy);
   resource_request->load_flags = load_flags;
   simple_loader_ = content::SimpleURLLoader::Create(std::move(resource_request),
                                                     traffic_annotation_);
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
index 8d03bf41..7b5e198 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -586,9 +586,17 @@
     ExtensionUpdater::CheckParams params;
     params.fetch_priority = ManifestFetchData::FetchPriority::FOREGROUND;
     params.install_immediately = true;
+    // TODO(crbug.com/714018): Replace base::BindRepeating with base::BindOnce.
+    params.callback =
+        base::BindRepeating(&DeveloperPrivateAutoUpdateFunction::OnComplete,
+                            this /* ref counted */);
     updater->CheckNow(params);
   }
-  return RespondNow(NoArguments());
+  return RespondLater();
+}
+
+void DeveloperPrivateAutoUpdateFunction::OnComplete() {
+  Respond(NoArguments());
 }
 
 DeveloperPrivateGetExtensionsInfoFunction::
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.h b/chrome/browser/extensions/api/developer_private/developer_private_api.h
index fe917f45..59840fb 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.h
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.h
@@ -289,6 +289,9 @@
  protected:
   ~DeveloperPrivateAutoUpdateFunction() override;
   ResponseAction Run() override;
+
+ private:
+  void OnComplete();
 };
 
 class DeveloperPrivateGetItemsInfoFunction
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 4ef5e0c..d3be5fe 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -1463,6 +1463,11 @@
 const char kUiPartialSwapName[] = "Partial swap";
 const char kUiPartialSwapDescription[] = "Sets partial swap behavior.";
 
+const char kEnablePreventLayerSquashingName[] = "Prevent layer squashing";
+const char kEnablePreventLayerSquashingDescription[] =
+    "When enabled, the compositor will avoid combining composited layers in "
+    "more situations.";
+
 const char kUseDdljsonApiName[] = "Use new ddljson API for Doodles";
 const char kUseDdljsonApiDescription[] =
     "Enables the new ddljson API to fetch Doodles for the NTP.";
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 523d4fa..b0d05c29 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -898,6 +898,9 @@
 extern const char kUiPartialSwapName[];
 extern const char kUiPartialSwapDescription[];
 
+extern const char kEnablePreventLayerSquashingName[];
+extern const char kEnablePreventLayerSquashingDescription[];
+
 extern const char kUseDdljsonApiName[];
 extern const char kUseDdljsonApiDescription[];
 
diff --git a/chrome/browser/resources/chromeos/login/oobe_change_picture.js b/chrome/browser/resources/chromeos/login/oobe_change_picture.js
index 410c2a8..b9000687 100644
--- a/chrome/browser/resources/chromeos/login/oobe_change_picture.js
+++ b/chrome/browser/resources/chromeos/login/oobe_change_picture.js
@@ -68,7 +68,10 @@
      */
     cameraVideoModeEnabled: {
       type: Boolean,
-      value: false,
+      value: function() {
+        return loadTimeData.getBoolean('changePictureVideoModeEnabled');
+      },
+      readOnly: true,
     },
 
     /**
diff --git a/chrome/browser/resources/md_extensions/compiled_resources2.gyp b/chrome/browser/resources/md_extensions/compiled_resources2.gyp
index 8c5dffac..a78abb0 100644
--- a/chrome/browser/resources/md_extensions/compiled_resources2.gyp
+++ b/chrome/browser/resources/md_extensions/compiled_resources2.gyp
@@ -251,7 +251,9 @@
     {
       'target_name': 'toolbar',
       'dependencies': [
+        '<(DEPTH)/third_party/polymer/v1_0/components-chromium/iron-a11y-announcer/compiled_resources2.gyp:iron-a11y-announcer-extracted',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
+        '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:i18n_behavior',
         '<(EXTERNS_GYP):metrics_private',
       ],
       'includes': ['../../../../third_party/closure_compiler/compile_js2.gypi'],
diff --git a/chrome/browser/resources/md_extensions/service.js b/chrome/browser/resources/md_extensions/service.js
index ec97a7c..2d1e7a7 100644
--- a/chrome/browser/resources/md_extensions/service.js
+++ b/chrome/browser/resources/md_extensions/service.js
@@ -261,8 +261,10 @@
 
     /** @override */
     updateAllExtensions() {
-      chrome.developerPrivate.autoUpdate();
-      chrome.metricsPrivate.recordUserAction('Options_UpdateExtensions');
+      return new Promise((resolve) => {
+        chrome.developerPrivate.autoUpdate(resolve);
+        chrome.metricsPrivate.recordUserAction('Options_UpdateExtensions');
+      });
     }
 
     /** @override */
diff --git a/chrome/browser/resources/md_extensions/toolbar.html b/chrome/browser/resources/md_extensions/toolbar.html
index 5e90a25..a72c956 100644
--- a/chrome/browser/resources/md_extensions/toolbar.html
+++ b/chrome/browser/resources/md_extensions/toolbar.html
@@ -6,6 +6,8 @@
 <link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html">
 <link rel="import" href="chrome://resources/html/assert.html">
 <link rel="import" href="chrome://resources/html/cr.html">
+<link rel="import" href="chrome://resources/html/i18n_behavior.html">
+<link rel="import" href="chrome://resources/polymer/v1_0/iron-a11y-announcer/iron-a11y-announcer.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
 <link rel="import" href="icons.html">
 <link rel="stylesheet" href="chrome://resources/css/md_colors.css">
diff --git a/chrome/browser/resources/md_extensions/toolbar.js b/chrome/browser/resources/md_extensions/toolbar.js
index 9cb22e5c..62cedb6 100644
--- a/chrome/browser/resources/md_extensions/toolbar.js
+++ b/chrome/browser/resources/md_extensions/toolbar.js
@@ -19,7 +19,10 @@
      */
     loadUnpacked() {}
 
-    /** Updates all extensions. */
+    /**
+     * Updates all extensions.
+     * @return {!Promise}
+     */
     updateAllExtensions() {}
   }
 
@@ -49,6 +52,8 @@
       },
     },
 
+    behaviors: [I18nBehavior],
+
     hostAttributes: {
       role: 'banner',
     },
@@ -105,7 +110,12 @@
 
     /** @private */
     onUpdateNowTap_: function() {
-      this.delegate.updateAllExtensions();
+      this.delegate.updateAllExtensions().then(() => {
+        Polymer.IronA11yAnnouncer.requestAvailability();
+        this.fire('iron-announce', {
+          text: this.i18n('toolbarUpdateDone'),
+        });
+      });
     },
   });
 
diff --git a/chrome/browser/resources/settings/people_page/change_picture.js b/chrome/browser/resources/settings/people_page/change_picture.js
index 33100bd..a0e68e7 100644
--- a/chrome/browser/resources/settings/people_page/change_picture.js
+++ b/chrome/browser/resources/settings/people_page/change_picture.js
@@ -60,7 +60,10 @@
      */
     cameraVideoModeEnabled_: {
       type: Boolean,
-      value: false,
+      value: function() {
+        return loadTimeData.getBoolean('changePictureVideoModeEnabled');
+      },
+      readOnly: true,
     },
   },
 
diff --git a/chrome/browser/sync/test/integration/sync_app_list_helper.h b/chrome/browser/sync/test/integration/sync_app_list_helper.h
index f2f80e2e..711e4dc 100644
--- a/chrome/browser/sync/test/integration/sync_app_list_helper.h
+++ b/chrome/browser/sync/test/integration/sync_app_list_helper.h
@@ -13,11 +13,10 @@
 #include "base/memory/singleton.h"
 #include "components/sync/model/string_ordinal.h"
 
+class ChromeAppListItem;
 class Profile;
 class SyncTest;
 
-class ChromeAppListItem;
-
 class SyncAppListHelper {
  public:
   // Singleton implementation.
diff --git a/chrome/browser/ui/app_list/app_list_model_builder.cc b/chrome/browser/ui/app_list/app_list_model_builder.cc
index 9192f2b..6be29d2 100644
--- a/chrome/browser/ui/app_list/app_list_model_builder.cc
+++ b/chrome/browser/ui/app_list/app_list_model_builder.cc
@@ -7,6 +7,8 @@
 #include <utility>
 #include <vector>
 
+#include "chrome/browser/ui/app_list/chrome_app_list_item.h"
+
 AppListModelBuilder::AppListModelBuilder(AppListControllerDelegate* controller,
                                          const char* item_type)
     : controller_(controller), item_type_(item_type) {}
diff --git a/chrome/browser/ui/app_list/app_list_model_builder.h b/chrome/browser/ui/app_list/app_list_model_builder.h
index 7c7c34c8..25bf047 100644
--- a/chrome/browser/ui/app_list/app_list_model_builder.h
+++ b/chrome/browser/ui/app_list/app_list_model_builder.h
@@ -13,6 +13,7 @@
 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
 
 class AppListControllerDelegate;
+class ChromeAppListItem;
 class Profile;
 
 // This abstract class populates and maintains the given |model| with
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.h b/chrome/browser/ui/app_list/app_list_model_updater.h
index d46d0a5b..57640c32 100644
--- a/chrome/browser/ui/app_list/app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/app_list_model_updater.h
@@ -11,11 +11,27 @@
 
 #include "ash/app_list/model/app_list_folder_item.h"
 #include "ash/app_list/model/app_list_model.h"
-#include "chrome/browser/ui/app_list/chrome_app_list_item.h"
+
+class ChromeAppListItem;
 
 // An interface to wrap AppListModel access in browser.
 class AppListModelUpdater {
  public:
+  class TestApi {
+   public:
+    explicit TestApi(AppListModelUpdater* model_updater)
+        : model_updater_(model_updater) {}
+    ~TestApi() = default;
+
+    void SetItemPosition(const std::string& id,
+                         const syncer::StringOrdinal& new_position) {
+      model_updater_->SetItemPosition(id, new_position);
+    }
+
+   private:
+    AppListModelUpdater* const model_updater_;
+  };
+
   // For AppListModel:
   virtual void AddItem(std::unique_ptr<ChromeAppListItem> item) {}
   virtual void AddItemToFolder(std::unique_ptr<ChromeAppListItem> item,
@@ -24,11 +40,8 @@
   virtual void RemoveUninstalledItem(const std::string& id) {}
   virtual void MoveItemToFolder(const std::string& id,
                                 const std::string& folder_id) {}
-  virtual void SetItemPosition(const std::string& id,
-                               const syncer::StringOrdinal& new_position) {}
   virtual void SetStatus(app_list::AppListModel::Status status) {}
   virtual void SetState(app_list::AppListModel::State state) {}
-  virtual void SetItemName(const std::string& id, const std::string& name) {}
   virtual void HighlightItemInstalledFromUI(const std::string& id) {}
   // For SearchModel:
   virtual void SetSearchEngineIsGoogle(bool is_google) {}
@@ -49,6 +62,20 @@
 
  protected:
   virtual ~AppListModelUpdater() {}
+
+  // Item field setters only used by ChromeAppListItem and its derived classes.
+  virtual void SetItemIcon(const std::string& id, const gfx::ImageSkia& icon) {}
+  virtual void SetItemName(const std::string& id, const std::string& name) {}
+  virtual void SetItemNameAndShortName(const std::string& id,
+                                       const std::string& name,
+                                       const std::string& short_name) {}
+  virtual void SetItemPosition(const std::string& id,
+                               const syncer::StringOrdinal& new_position) {}
+  virtual void SetItemFolderId(const std::string& id,
+                               const std::string& folder_id) {}
+  virtual void SetItemIsInstalling(const std::string& id, bool is_installing) {}
+  virtual void SetItemPercentDownloaded(const std::string& id,
+                                        int32_t percent_downloaded) {}
 };
 
 
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service.h b/chrome/browser/ui/app_list/app_list_syncable_service.h
index 82b6116..4ee3bf3 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service.h
+++ b/chrome/browser/ui/app_list/app_list_syncable_service.h
@@ -45,6 +45,7 @@
 
 namespace app_list {
 
+// TODO(hejq): Remove AppListItem when we have a mojo struct for this.
 class AppListItem;
 // TODO(hejq): Remove these when we get rid of |GetModel| and |GetSearchModel|.
 class AppListModel;
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
index ca7ab06..ec1b649 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
+++ b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
@@ -176,8 +176,11 @@
     extensions::ExtensionSystem* extension_system =
         extensions::ExtensionSystem::Get(profile_.get());
     DCHECK(extension_system);
-    app_list_syncable_service_.reset(
-        new app_list::AppListSyncableService(profile_.get(), extension_system));
+    app_list_syncable_service_ =
+        std::make_unique<app_list::AppListSyncableService>(profile_.get(),
+                                                           extension_system);
+    model_updater_test_api_ =
+        std::make_unique<AppListModelUpdater::TestApi>(model_updater());
   }
 
   void TearDown() override { app_list_syncable_service_.reset(); }
@@ -186,6 +189,10 @@
     return app_list_syncable_service_->GetModelUpdater();
   }
 
+  AppListModelUpdater::TestApi* model_updater_test_api() {
+    return model_updater_test_api_.get();
+  }
+
   const app_list::AppListSyncableService::SyncItem* GetSyncItem(
       const std::string& id) const {
     return app_list_syncable_service_->GetSyncItem(id);
@@ -198,6 +205,7 @@
 
  private:
   base::ScopedTempDir temp_dir_;
+  std::unique_ptr<AppListModelUpdater::TestApi> model_updater_test_api_;
   std::unique_ptr<app_list::AppListSyncableService> app_list_syncable_service_;
 
   DISALLOW_COPY_AND_ASSIGN(AppListSyncableServiceTest);
@@ -226,8 +234,8 @@
   ASSERT_TRUE(some_app_item);
 
   // Simulate position conflict.
-  model_updater()->SetItemPosition(web_store_item->id(),
-                                   some_app_item->position());
+  model_updater_test_api()->SetItemPosition(web_store_item->id(),
+                                            some_app_item->position());
 
   // Install an OEM app. It must be placed by default after web store app but in
   // case of app of the same position should be shifted next.
diff --git a/chrome/browser/ui/app_list/chrome_app_list_item.cc b/chrome/browser/ui/app_list/chrome_app_list_item.cc
index ca281a1..602c3a9 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_item.cc
+++ b/chrome/browser/ui/app_list/chrome_app_list_item.cc
@@ -15,7 +15,7 @@
 
 AppListControllerDelegate* g_controller_for_test = nullptr;
 
-} // namespace
+}  // namespace
 
 // static
 void ChromeAppListItem::OverrideAppListControllerDelegateForTesting(
@@ -39,6 +39,16 @@
 ChromeAppListItem::~ChromeAppListItem() {
 }
 
+void ChromeAppListItem::Activate(int event_flags) {}
+
+const char* ChromeAppListItem::GetItemType() const {
+  return "";
+}
+
+ui::MenuModel* ChromeAppListItem::GetContextMenuModel() {
+  return nullptr;
+}
+
 extensions::AppSorting* ChromeAppListItem::GetAppSorting() {
   return extensions::ExtensionSystem::Get(profile())->app_sorting();
 }
@@ -75,3 +85,15 @@
   set_position(syncer::StringOrdinal(page_ordinal.ToInternalValue() +
                                      launch_ordinal.ToInternalValue()));
 }
+
+bool ChromeAppListItem::CompareForTest(
+    const app_list::AppListItem* other) const {
+  return id() == other->id() && folder_id() == other->folder_id() &&
+         name() == other->name() && GetItemType() == other->GetItemType() &&
+         position().Equals(other->position());
+}
+
+std::string ChromeAppListItem::ToDebugString() const {
+  return id().substr(0, 8) + " '" + name() + "'" + " [" +
+         position().ToDebugString() + "]";
+}
diff --git a/chrome/browser/ui/app_list/chrome_app_list_item.h b/chrome/browser/ui/app_list/chrome_app_list_item.h
index 5229474..f8b4f1b 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_item.h
+++ b/chrome/browser/ui/app_list/chrome_app_list_item.h
@@ -5,14 +5,15 @@
 #ifndef CHROME_BROWSER_UI_APP_LIST_CHROME_APP_LIST_ITEM_H_
 #define CHROME_BROWSER_UI_APP_LIST_CHROME_APP_LIST_ITEM_H_
 
+#include <memory>
 #include <string>
+#include <utility>
 
 #include "ash/app_list/model/app_list_item.h"
 #include "base/macros.h"
 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
 
 class AppListControllerDelegate;
-class FakeAppListModelUpdater;
 class Profile;
 
 namespace extensions {
@@ -26,7 +27,26 @@
 // Base class of all chrome app list items.
 class ChromeAppListItem : public app_list::AppListItem {
  public:
+  class TestApi {
+   public:
+    explicit TestApi(ChromeAppListItem* item) : item_(item) {}
+    ~TestApi() = default;
+
+    void set_folder_id(const std::string& folder_id) {
+      item_->set_folder_id(folder_id);
+    }
+
+    void set_position(const syncer::StringOrdinal& position) {
+      item_->set_position(position);
+    }
+
+   private:
+    ChromeAppListItem* item_;
+  };
+
+  ChromeAppListItem(Profile* profile, const std::string& app_id);
   ~ChromeAppListItem() override;
+
   // AppListControllerDelegate is not properly implemented in tests. Use mock
   // |controller| for unit_tests.
   static void OverrideAppListControllerDelegateForTesting(
@@ -34,12 +54,25 @@
 
   static gfx::ImageSkia CreateDisabledIcon(const gfx::ImageSkia& icon);
 
- protected:
-  // TODO(hejq): Remove this once we break the inheritance from AppListItem and
-  //             move those protected methods to public.
-  friend class FakeAppListModelUpdater;
+  // Activates (opens) the item. Does nothing by default.
+  void Activate(int event_flags) override;
 
-  ChromeAppListItem(Profile* profile, const std::string& app_id);
+  // Returns a static const char* identifier for the subclass (defaults to "").
+  // Pointers can be compared for quick type checking.
+  const char* GetItemType() const override;
+
+  // Returns the context menu model for this item, or NULL if there is currently
+  // no menu for the item (e.g. during install).
+  // Note the returned menu model is owned by this item.
+  ui::MenuModel* GetContextMenuModel() override;
+
+  bool CompareForTest(const app_list::AppListItem* other) const override;
+
+  std::string ToDebugString() const override;
+
+ protected:
+  // TODO(hejq): break the inheritance and remove this.
+  friend class ChromeAppListModelUpdater;
 
   Profile* profile() const { return profile_; }
 
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
index 19cdba5..5bf579031 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
+++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.cc
@@ -11,6 +11,7 @@
 #include "ash/app_list/model/app_list_model.h"
 #include "ash/app_list/model/app_list_model_observer.h"
 #include "ash/app_list/model/search/search_model.h"
+#include "chrome/browser/ui/app_list/chrome_app_list_item.h"
 #include "extensions/common/constants.h"
 
 ChromeAppListModelUpdater::ChromeAppListModelUpdater()
@@ -44,13 +45,6 @@
   model_->MoveItemToFolder(item, folder_id);
 }
 
-void ChromeAppListModelUpdater::SetItemPosition(
-    const std::string& id,
-    const syncer::StringOrdinal& new_position) {
-  app_list::AppListItem* item = model_->FindItem(id);
-  model_->SetItemPosition(item, new_position);
-}
-
 void ChromeAppListModelUpdater::SetStatus(
     app_list::AppListModel::Status status) {
   model_->SetStatus(status);
@@ -60,13 +54,6 @@
   model_->SetState(state);
 }
 
-void ChromeAppListModelUpdater::SetItemName(const std::string& id,
-                                            const std::string& name) {
-  app_list::AppListItem* item = model_->FindItem(id);
-  if (item)
-    model_->SetItemName(item, name);
-}
-
 void ChromeAppListModelUpdater::HighlightItemInstalledFromUI(
     const std::string& id) {
   model_->top_level_item_list()->HighlightItemInstalledFromUI(id);
@@ -76,6 +63,65 @@
   search_model_->SetSearchEngineIsGoogle(is_google);
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Methods only used by ChromeAppListItem that talk to ash directly.
+
+void ChromeAppListModelUpdater::SetItemIcon(const std::string& id,
+                                            const gfx::ImageSkia& icon) {
+  app_list::AppListItem* item = model_->FindItem(id);
+  if (item)
+    item->SetIcon(icon);
+}
+
+void ChromeAppListModelUpdater::SetItemName(const std::string& id,
+                                            const std::string& name) {
+  app_list::AppListItem* item = model_->FindItem(id);
+  if (item)
+    model_->SetItemName(item, name);
+}
+
+void ChromeAppListModelUpdater::SetItemNameAndShortName(
+    const std::string& id,
+    const std::string& name,
+    const std::string& short_name) {
+  app_list::AppListItem* item = model_->FindItem(id);
+  if (item)
+    item->SetNameAndShortName(name, short_name);
+}
+
+void ChromeAppListModelUpdater::SetItemPosition(
+    const std::string& id,
+    const syncer::StringOrdinal& new_position) {
+  app_list::AppListItem* item = model_->FindItem(id);
+  if (item)
+    model_->SetItemPosition(item, new_position);
+}
+
+void ChromeAppListModelUpdater::SetItemFolderId(const std::string& id,
+                                                const std::string& folder_id) {
+  app_list::AppListItem* item = model_->FindItem(id);
+  if (item)
+    item->set_folder_id(folder_id);
+}
+
+void ChromeAppListModelUpdater::SetItemIsInstalling(const std::string& id,
+                                                    bool is_installing) {
+  app_list::AppListItem* item = model_->FindItem(id);
+  if (item)
+    item->SetIsInstalling(is_installing);
+}
+
+void ChromeAppListModelUpdater::SetItemPercentDownloaded(
+    const std::string& id,
+    int32_t percent_downloaded) {
+  app_list::AppListItem* item = model_->FindItem(id);
+  if (item)
+    item->SetPercentDownloaded(percent_downloaded);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Methods for item querying
+
 ChromeAppListItem* ChromeAppListModelUpdater::FindItem(const std::string& id) {
   return static_cast<ChromeAppListItem*>(model_->FindItem(id));
 }
@@ -133,7 +179,9 @@
   return oem_folder;
 }
 
-// For AppListSyncableService:
+////////////////////////////////////////////////////////////////////////////////
+// Methods for AppListSyncableService
+
 void ChromeAppListModelUpdater::AddItemToOemFolder(
     std::unique_ptr<ChromeAppListItem> item,
     app_list::AppListSyncableService::SyncItem* oem_sync_item,
@@ -170,6 +218,9 @@
   }
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// TODO(hejq): Move the following methods to ash.
+
 void ChromeAppListModelUpdater::FindOrCreateOemFolder(
     app_list::AppListSyncableService::SyncItem* oem_sync_item,
     const std::string& oem_folder_id,
diff --git a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
index d3f3c9e..7fbca14 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/chrome_app_list_model_updater.h
@@ -12,10 +12,8 @@
 #include "chrome/browser/ui/app_list/app_list_model_updater.h"
 #include "chrome/browser/ui/app_list/app_list_syncable_service.h"
 
-namespace app_list {
-class AppListModel;
+class ChromeAppListItem;
 class SearchModel;
-}  // namespace app_list
 
 class ChromeAppListModelUpdater : public AppListModelUpdater {
  public:
@@ -30,14 +28,12 @@
   void RemoveUninstalledItem(const std::string& id) override;
   void MoveItemToFolder(const std::string& id,
                         const std::string& folder_id) override;
-  void SetItemPosition(const std::string& id,
-                       const syncer::StringOrdinal& new_position) override;
   void SetStatus(app_list::AppListModel::Status status) override;
   void SetState(app_list::AppListModel::State state) override;
-  void SetItemName(const std::string& id, const std::string& name) override;
   void HighlightItemInstalledFromUI(const std::string& id) override;
   void SetSearchEngineIsGoogle(bool is_google) override;
 
+  // Methods for item querying.
   ChromeAppListItem* FindItem(const std::string& id) override;
   size_t ItemCount() override;
   ChromeAppListItem* ItemAtForTest(size_t index) override;
@@ -49,7 +45,7 @@
   bool SearchEngineIsGoogle() override;
   std::map<std::string, size_t> GetIdToAppListIndexMap() override;
 
-  // For SynchableService:
+  // Methods for AppListSyncableService:
   void AddItemToOemFolder(
       std::unique_ptr<ChromeAppListItem> item,
       app_list::AppListSyncableService::SyncItem* oem_sync_item,
@@ -64,6 +60,22 @@
       bool update_name,
       bool update_folder);
 
+ protected:
+  // AppListModelUpdater:
+  // Methods only used by ChromeAppListItem that talk to ash directly.
+  void SetItemIcon(const std::string& id, const gfx::ImageSkia& icon) override;
+  void SetItemName(const std::string& id, const std::string& name) override;
+  void SetItemNameAndShortName(const std::string& id,
+                               const std::string& name,
+                               const std::string& short_name) override;
+  void SetItemPosition(const std::string& id,
+                       const syncer::StringOrdinal& new_position) override;
+  void SetItemFolderId(const std::string& id,
+                       const std::string& folder_id) override;
+  void SetItemIsInstalling(const std::string& id, bool is_installing) override;
+  void SetItemPercentDownloaded(const std::string& id,
+                                int32_t percent_downloaded) override;
+
  private:
   // TODO(hejq): Remove this friend. Currently |model_| and |search_model_| are
   // exposed to AppListViewDelegate via AppListSyncableService. We'll remove
diff --git a/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc b/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc
index ce82099..c3b9db5 100644
--- a/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc
+++ b/chrome/browser/ui/app_list/extension_app_model_builder_unittest.cc
@@ -19,6 +19,7 @@
 #include "chrome/browser/extensions/install_tracker.h"
 #include "chrome/browser/extensions/install_tracker_factory.h"
 #include "chrome/browser/ui/app_list/app_list_test_util.h"
+#include "chrome/browser/ui/app_list/chrome_app_list_item.h"
 #include "chrome/browser/ui/app_list/test/fake_app_list_model_updater.h"
 #include "chrome/browser/ui/app_list/test/test_app_list_controller_delegate.h"
 #include "chrome/common/chrome_constants.h"
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
index 55f0f89..a69e4dfc 100644
--- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
+++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
@@ -6,6 +6,8 @@
 
 #include <utility>
 
+#include "chrome/browser/ui/app_list/chrome_app_list_item.h"
+
 FakeAppListModelUpdater::FakeAppListModelUpdater() {}
 
 FakeAppListModelUpdater::~FakeAppListModelUpdater() {}
@@ -17,7 +19,8 @@
 void FakeAppListModelUpdater::AddItemToFolder(
     std::unique_ptr<ChromeAppListItem> item,
     const std::string& folder_id) {
-  item->set_folder_id(folder_id);
+  ChromeAppListItem::TestApi test_api(item.get());
+  test_api.set_folder_id(folder_id);
   items_.push_back(std::move(item));
 }
 
@@ -34,16 +37,20 @@
 void FakeAppListModelUpdater::MoveItemToFolder(const std::string& id,
                                                const std::string& folder_id) {
   size_t index;
-  if (FindItemIndexForTest(id, &index))
-    items_[index]->set_folder_id(folder_id);
+  if (FindItemIndexForTest(id, &index)) {
+    ChromeAppListItem::TestApi test_api(items_[index].get());
+    test_api.set_folder_id(folder_id);
+  }
 }
 
 void FakeAppListModelUpdater::SetItemPosition(
     const std::string& id,
     const syncer::StringOrdinal& new_position) {
   size_t index;
-  if (FindItemIndexForTest(id, &index))
-    items_[index]->set_position(new_position);
+  if (FindItemIndexForTest(id, &index)) {
+    ChromeAppListItem::TestApi test_api(items_[index].get());
+    test_api.set_position(new_position);
+  }
 }
 
 void FakeAppListModelUpdater::SetSearchEngineIsGoogle(bool is_google) {
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
index 9fee195..4fa4cd1 100644
--- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
@@ -12,6 +12,8 @@
 
 #include "chrome/browser/ui/app_list/app_list_model_updater.h"
 
+class ChromeAppListItem;
+
 class FakeAppListModelUpdater : public AppListModelUpdater {
  public:
   FakeAppListModelUpdater();
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
index e95c6d5d..786868f 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -68,6 +68,7 @@
 #include "chrome/browser/ui/webui/test_files_request_filter.h"
 #include "chrome/browser/ui/webui/theme_source.h"
 #include "chrome/common/chrome_constants.h"
+#include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/common/url_constants.h"
@@ -543,6 +544,9 @@
                                : "on");
   localized_strings->SetString(
       "showMdLogin", ash::switches::IsUsingWebUiLock() ? "off" : "on");
+  localized_strings->SetBoolean(
+      "changePictureVideoModeEnabled",
+      base::FeatureList::IsEnabled(features::kChangePictureVideoMode));
 }
 
 void OobeUI::AddWebUIHandler(std::unique_ptr<BaseWebUIHandler> handler) {
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc
index ebeeb37..457081c5 100644
--- a/chrome/browser/ui/webui/extensions/extensions_ui.cc
+++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -310,6 +310,8 @@
                              IDS_MD_EXTENSIONS_TOOLBAR_UPDATE_NOW);
   source->AddLocalizedString("toolbarUpdateNowTooltip",
                              IDS_MD_EXTENSIONS_TOOLBAR_UPDATE_NOW_TOOLTIP);
+  source->AddLocalizedString("toolbarUpdateDone",
+                             IDS_MD_EXTENSIONS_TOOLBAR_UPDATE_DONE);
   source->AddLocalizedString(
       "updateRequiredByPolicy",
       IDS_MD_EXTENSIONS_DISABLED_UPDATE_REQUIRED_BY_POLICY);
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index 4767004..3eb0679 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -1514,6 +1514,10 @@
 
   html_source->AddBoolean("profileShortcutsEnabled",
                           ProfileShortcutManager::IsFeatureEnabled());
+
+  html_source->AddBoolean(
+      "changePictureVideoModeEnabled",
+      base::FeatureList::IsEnabled(features::kChangePictureVideoMode));
 }
 
 void AddPrintingStrings(content::WebUIDataSource* html_source) {
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index a67f374..4495d94c 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -148,6 +148,10 @@
 const base::Feature kCaptureThumbnailOnNavigatingAway{
     "CaptureThumbnailOnNavigatingAway", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Enables change picture video mode.
+const base::Feature kChangePictureVideoMode{"ChangePictureVideoMode",
+                                            base::FEATURE_ENABLED_BY_DEFAULT};
+
 // Whether to trigger app banner installability checks on page load.
 const base::Feature kCheckInstallabilityForBannerOnLoad{
     "CheckInstallabilityForBannerOnLoad", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 5863e63..019f866f 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -73,6 +73,8 @@
 
 extern const base::Feature kCaptureThumbnailOnNavigatingAway;
 
+extern const base::Feature kChangePictureVideoMode;
+
 extern const base::Feature kCheckInstallabilityForBannerOnLoad;
 
 #if defined(OS_ANDROID)
diff --git a/chrome/common/extensions/api/developer_private.idl b/chrome/common/extensions/api/developer_private.idl
index eb2e5c4..173c4348 100644
--- a/chrome/common/extensions/api/developer_private.idl
+++ b/chrome/common/extensions/api/developer_private.idl
@@ -500,9 +500,8 @@
 
   interface Functions {
     // Runs auto update for extensions and apps immediately.
-    // |callback| : Called with the boolean result, true if autoUpdate is
-    // successful.
-    static void autoUpdate(optional BooleanCallback callback);
+    // |callback| : Called after update check completes.
+    static void autoUpdate(optional VoidCallback callback);
 
     // Returns information of all the extensions and apps installed.
     // |options| : Options to restrict the items returned.
diff --git a/chrome/test/data/webui/extensions/test_service.js b/chrome/test/data/webui/extensions/test_service.js
index 62de4cd3f..a176868 100644
--- a/chrome/test/data/webui/extensions/test_service.js
+++ b/chrome/test/data/webui/extensions/test_service.js
@@ -110,6 +110,7 @@
     /** @override */
     updateAllExtensions() {
       this.methodCalled('updateAllExtensions');
+      return Promise.resolve();
     }
   }
 
diff --git a/content/browser/download/download_utils.cc b/content/browser/download/download_utils.cc
index 5f198aa0..de4ba256 100644
--- a/content/browser/download/download_utils.cc
+++ b/content/browser/download/download_utils.cc
@@ -169,7 +169,8 @@
   request->do_not_prompt_for_login = params->do_not_prompt_for_login();
   request->site_for_cookies = params->url();
   request->referrer = params->referrer().url;
-  request->referrer_policy = params->referrer().policy;
+  request->referrer_policy =
+      Referrer::ReferrerPolicyForUrlRequest(params->referrer().policy);
   request->download_to_file = true;
   request->allow_download = true;
   request->is_main_frame = true;
diff --git a/content/browser/loader/navigation_url_loader_network_service.cc b/content/browser/loader/navigation_url_loader_network_service.cc
index 57328a4..c1c376f 100644
--- a/content/browser/loader/navigation_url_loader_network_service.cc
+++ b/content/browser/loader/navigation_url_loader_network_service.cc
@@ -458,9 +458,7 @@
     resource_request_->method = redirect_info_.new_method;
     resource_request_->site_for_cookies = redirect_info_.new_site_for_cookies;
     resource_request_->referrer = GURL(redirect_info_.new_referrer);
-    resource_request_->referrer_policy =
-        Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
-            redirect_info_.new_referrer_policy);
+    resource_request_->referrer_policy = redirect_info_.new_referrer_policy;
     url_chain_.push_back(redirect_info_.new_url);
 
     Restart();
@@ -723,7 +721,8 @@
   // URLRequest class to set these fields. whereas we use ResourceRequest here.
   new_request->request_initiator = request_info->begin_params->initiator_origin;
   new_request->referrer = request_info->common_params.referrer.url;
-  new_request->referrer_policy = request_info->common_params.referrer.policy;
+  new_request->referrer_policy = Referrer::ReferrerPolicyForUrlRequest(
+      request_info->common_params.referrer.policy);
   new_request->headers.AddHeadersFromString(
       request_info->begin_params->headers);
 
diff --git a/content/browser/loader/resource_dispatcher_host_impl.cc b/content/browser/loader/resource_dispatcher_host_impl.cc
index 17a1d67b..74bcb61 100644
--- a/content/browser/loader/resource_dispatcher_host_impl.cc
+++ b/content/browser/loader/resource_dispatcher_host_impl.cc
@@ -1111,8 +1111,9 @@
     // else it will fail for SSL redirects since net/ will think the blob:https
     // for the stream is not a secure scheme (specifically, in the call to
     // ComputeReferrerForRedirect).
-    const Referrer referrer(
-        request_data.referrer, request_data.referrer_policy);
+    const Referrer referrer(request_data.referrer,
+                            Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
+                                request_data.referrer_policy));
     Referrer::SetReferrerForRequest(new_request.get(), referrer);
 
     new_request->SetExtraRequestHeaders(headers);
@@ -1214,9 +1215,11 @@
       allow_download, request_data.has_user_gesture,
       request_data.enable_load_timing, request_data.enable_upload_progress,
       do_not_prompt_for_login, request_data.keepalive,
-      request_data.referrer_policy, request_data.visibility_state,
-      resource_context, report_raw_headers, !is_sync_load, previews_state,
-      request_data.request_body, request_data.initiated_in_secure_context);
+      Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
+          request_data.referrer_policy),
+      request_data.visibility_state, resource_context, report_raw_headers,
+      !is_sync_load, previews_state, request_data.request_body,
+      request_data.initiated_in_secure_context);
   extra_info->SetBlobHandles(std::move(blob_handles));
 
   // Request takes ownership.
diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc
index 0546843..db4b890 100644
--- a/content/browser/loader/resource_dispatcher_host_unittest.cc
+++ b/content/browser/loader/resource_dispatcher_host_unittest.cc
@@ -102,7 +102,7 @@
   request.site_for_cookies = url;  // bypass third-party cookie blocking
   request.request_initiator =
       url::Origin::Create(url);  // ensure initiator is set
-  request.referrer_policy = blink::kWebReferrerPolicyDefault;
+  request.referrer_policy = Referrer::GetDefaultReferrerPolicy();
   request.load_flags = 0;
   request.plugin_child_id = -1;
   request.resource_type = type;
diff --git a/content/browser/renderer_host/input/fling_controller.cc b/content/browser/renderer_host/input/fling_controller.cc
index f716da42..fb43d429 100644
--- a/content/browser/renderer_host/input/fling_controller.cc
+++ b/content/browser/renderer_host/input/fling_controller.cc
@@ -101,6 +101,13 @@
   if (!fling_booster_)
     return false;
 
+  // TODO(sahel): Don't boost touchpad fling for now. Once browserside
+  // touchscreen fling is implemented, move the fling_controller_ from
+  // GestureEventQueue to RednerWidgetHostImpl. This will gaurantee proper
+  // gesture scroll event order in RednerWidgetHostImpl while boosting.
+  if (gesture_event.event.source_device == blink::kWebGestureDeviceTouchpad)
+    return false;
+
   bool cancel_current_fling;
   bool should_filter_event = fling_booster_->FilterGestureEventForFlingBoosting(
       gesture_event.event, &cancel_current_fling);
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 9293ecf..9889acc 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -1177,6 +1177,7 @@
              blink::WebInputEvent::kGestureScrollEnd) {
     DCHECK(is_in_gesture_scroll_[gesture_event.source_device]);
     is_in_gesture_scroll_[gesture_event.source_device] = false;
+    is_in_touchpad_gesture_fling_ = false;
   } else if (gesture_event.GetType() ==
              blink::WebInputEvent::kGestureFlingStart) {
     if (gesture_event.source_device ==
@@ -1186,13 +1187,25 @@
         // is_in_gesture_scroll must be true.
         DCHECK(is_in_gesture_scroll_[gesture_event.source_device]);
 
-        // When wheel scroll latching is enabled GFS with touchpad source is
-        // handled by FlingController on browser side and GSU events with
-        // inertial phase will be sent to the renderer. Therefore,
-        // is_in_gesture_scroll must stay true till the fling progress is
-        // finished. Then the FlingController will generate and send a GSE event
-        // to show the end of a scroll sequence.
-      } else {
+        // The FlingController handles GFS with touchpad source and sends wheel
+        // events to progress the fling, the wheel events will get processed by
+        // the MouseWheelEventQueue and GSU events with inertial phase will be
+        // sent to the renderer.
+        if (GetView()->IsInVR()) {
+          // Reset the is_in_gesture_scroll since while scrolling in Android VR
+          // the first wheel event sent by the FlingController will cause a GSB
+          // generation in MouseWheelEventQueue. This is because
+          // WebContentsEventForwarder injects gesture scroll events to the RWHI
+          // rather than wheel events. TODO(sahel): Remove this when motion
+          // events are used for Android VR event processing.
+          // https://crbug.com/797322
+          is_in_gesture_scroll_[gesture_event.source_device] = false;
+        } else {
+          // is_in_gesture_scroll must stay true till the fling progress is
+          // finished. Then the FlingController will generate and send a GSE
+          // event to show the end of a scroll sequence.
+        }
+      } else {  // !GetView()->wheel_scroll_latching_enabled()
         // When wheel scroll latching is disabled a GSE is sent before a GFS.
         // The GSE has already finished the scroll sequence.
         DCHECK(!is_in_gesture_scroll_[gesture_event.source_device]);
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 23feea8..55131ef 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -2308,6 +2308,7 @@
     OnDidNotProduceFrame(
         viz::BeginFrameAck(args.source_id, args.sequence_number, false));
   }
+  host_->ProgressFling(args.frame_time);
 }
 
 const viz::BeginFrameArgs& RenderWidgetHostViewAndroid::LastUsedBeginFrameArgs()
diff --git a/content/browser/security_exploit_browsertest.cc b/content/browser/security_exploit_browsertest.cc
index 4b84db0d..f09d54c 100644
--- a/content/browser/security_exploit_browsertest.cc
+++ b/content/browser/security_exploit_browsertest.cc
@@ -122,7 +122,7 @@
   ResourceRequest request;
   request.method = "GET";
   request.url = GURL(url);
-  request.referrer_policy = blink::kWebReferrerPolicyDefault;
+  request.referrer_policy = Referrer::GetDefaultReferrerPolicy();
   request.request_initiator = url::Origin();
   request.load_flags = 0;
   request.plugin_child_id = -1;
diff --git a/content/browser/service_worker/service_worker_fetch_dispatcher.cc b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
index 3c048b41..bb6168b 100644
--- a/content/browser/service_worker/service_worker_fetch_dispatcher.cc
+++ b/content/browser/service_worker/service_worker_fetch_dispatcher.cc
@@ -727,7 +727,8 @@
           ? original_request->initiator()
           : url::Origin::Create(original_request->url());
   request.referrer = GURL(original_request->referrer());
-  request.referrer_policy = original_info->GetReferrerPolicy();
+  request.referrer_policy =
+      Referrer::ReferrerPolicyForUrlRequest(original_info->GetReferrerPolicy());
   request.visibility_state = original_info->GetVisibilityState();
   request.load_flags = original_request->load_flags();
   // Set to SUB_RESOURCE because we shouldn't trigger NavigationResourceThrottle
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 1e78ddc..f8b8ff58 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -311,6 +311,9 @@
   if (base::FeatureList::IsEnabled(features::kCompositorTouchAction))
     WebRuntimeFeatures::EnableCompositorTouchAction(true);
 
+  WebRuntimeFeatures::EnablePreventLayerSquashing(
+      base::FeatureList::IsEnabled(features::kEnablePreventLayerSquashing));
+
   if (base::FeatureList::IsEnabled(features::kGenericSensor)) {
     WebRuntimeFeatures::EnableGenericSensor(true);
     if (base::FeatureList::IsEnabled(features::kGenericSensorExtraClasses))
diff --git a/content/common/service_worker/service_worker_loader_helpers.cc b/content/common/service_worker/service_worker_loader_helpers.cc
index 495f4f63..7ed94070 100644
--- a/content/common/service_worker/service_worker_loader_helpers.cc
+++ b/content/common/service_worker/service_worker_loader_helpers.cc
@@ -62,8 +62,9 @@
   new_request->keepalive = request.keepalive;
   new_request->is_reload = ui::PageTransitionCoreTypeIs(
       request.transition_type, ui::PAGE_TRANSITION_RELOAD);
-  new_request->referrer =
-      Referrer(GURL(request.referrer), request.referrer_policy);
+  new_request->referrer = Referrer(
+      GURL(request.referrer), Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
+                                  request.referrer_policy));
   new_request->fetch_type = ServiceWorkerFetchType::FETCH;
   return new_request;
 }
@@ -125,7 +126,9 @@
   net::URLRequest::ReferrerPolicy referrer_policy;
   Referrer::ComputeReferrerInfo(
       &referrer_string, &referrer_policy,
-      Referrer(original_request.referrer, original_request.referrer_policy));
+      Referrer(original_request.referrer,
+               Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
+                   original_request.referrer_policy)));
 
   // If the request is a MAIN_FRAME request, the first-party URL gets
   // updated on redirects.
diff --git a/content/network/url_loader.cc b/content/network/url_loader.cc
index 488bd13..3ec5a88e 100644
--- a/content/network/url_loader.cc
+++ b/content/network/url_loader.cc
@@ -224,7 +224,9 @@
 
   url_request_->set_site_for_cookies(request.site_for_cookies);
 
-  const Referrer referrer(request.referrer, request.referrer_policy);
+  const Referrer referrer(request.referrer,
+                          Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
+                              request.referrer_policy));
   Referrer::SetReferrerForRequest(url_request_.get(), referrer);
 
   url_request_->SetExtraRequestHeaders(request.headers);
diff --git a/content/network/url_loader_unittest.cc b/content/network/url_loader_unittest.cc
index 99cf117..8475ad8 100644
--- a/content/network/url_loader_unittest.cc
+++ b/content/network/url_loader_unittest.cc
@@ -24,6 +24,7 @@
 #include "content/network/url_loader.h"
 #include "content/public/common/appcache_info.h"
 #include "content/public/common/content_paths.h"
+#include "content/public/common/referrer.h"
 #include "content/public/common/resource_request.h"
 #include "content/public/common/resource_request_body.h"
 #include "content/public/test/controllable_http_response.h"
@@ -64,7 +65,7 @@
   request.site_for_cookies = url;  // bypass third-party cookie blocking
   request.request_initiator =
       url::Origin::Create(url);  // ensure initiator is set
-  request.referrer_policy = blink::kWebReferrerPolicyDefault;
+  request.referrer_policy = Referrer::GetDefaultReferrerPolicy();
   request.load_flags = 0;
   request.plugin_child_id = -1;
   request.resource_type = type;
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc
index 6b94a2c..d599efb5 100644
--- a/content/public/common/content_features.cc
+++ b/content/public/common/content_features.cc
@@ -354,6 +354,9 @@
     "TurnOff2DAndOpacityCompositorAnimations",
     base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kEnablePreventLayerSquashing{
+    "EnablePreventLayerSquashing", base::FEATURE_ENABLED_BY_DEFAULT};
+
 // Use Feature Policy to gate the use of permission features like midi,
 // geolocation, camera, microphone, etc.
 const base::Feature kUseFeaturePolicyForPermissions{
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h
index 8c68e84d..b87fdf0d 100644
--- a/content/public/common/content_features.h
+++ b/content/public/common/content_features.h
@@ -91,6 +91,7 @@
 CONTENT_EXPORT extern const base::Feature kTouchpadAndWheelScrollLatching;
 CONTENT_EXPORT extern const base::Feature
     kTurnOff2DAndOpacityCompositorAnimations;
+CONTENT_EXPORT extern const base::Feature kEnablePreventLayerSquashing;
 CONTENT_EXPORT extern const base::Feature kUseFeaturePolicyForPermissions;
 CONTENT_EXPORT extern const base::Feature kUseMojoAudioOutputStreamFactory;
 CONTENT_EXPORT extern const base::Feature kUserActivationV2;
diff --git a/content/public/common/referrer.cc b/content/public/common/referrer.cc
index 6e7d055..c50518f 100644
--- a/content/public/common/referrer.cc
+++ b/content/public/common/referrer.cc
@@ -105,13 +105,13 @@
     *out_referrer_string = referrer.url.spec();
   }
 
-  *out_policy = ReferrerPolicyForUrlRequest(referrer);
+  *out_policy = ReferrerPolicyForUrlRequest(referrer.policy);
 }
 
 // static
 net::URLRequest::ReferrerPolicy Referrer::ReferrerPolicyForUrlRequest(
-    const Referrer& referrer) {
-  switch (referrer.policy) {
+    blink::WebReferrerPolicy referrer_policy) {
+  switch (referrer_policy) {
     case blink::kWebReferrerPolicyAlways:
       return net::URLRequest::NEVER_CLEAR_REFERRER;
     case blink::kWebReferrerPolicyNever:
@@ -173,4 +173,13 @@
   return blink::kWebReferrerPolicyDefault;
 }
 
+net::URLRequest::ReferrerPolicy Referrer::GetDefaultReferrerPolicy() {
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kReducedReferrerGranularity)) {
+    return net::URLRequest::
+        REDUCE_REFERRER_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN;
+  }
+  return net::URLRequest::CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE;
+}
+
 }  // namespace content
diff --git a/content/public/common/referrer.h b/content/public/common/referrer.h
index 8ed7590..51ae965 100644
--- a/content/public/common/referrer.h
+++ b/content/public/common/referrer.h
@@ -16,7 +16,9 @@
 // This struct holds a referrer URL, as well as the referrer policy to be
 // applied to this URL. When passing around referrers that will eventually end
 // up being used for URL requests, always use this struct.
+
 struct CONTENT_EXPORT Referrer {
+  // TODO(jam): convert this to hold the net enum
   Referrer(const GURL& url, blink::WebReferrerPolicy policy)
       : url(url), policy(policy) {}
   Referrer() : policy(blink::kWebReferrerPolicyDefault) {}
@@ -35,10 +37,12 @@
                                   const Referrer& referrer);
 
   static net::URLRequest::ReferrerPolicy ReferrerPolicyForUrlRequest(
-      const Referrer& referrer);
+      blink::WebReferrerPolicy referrer_policy);
 
   static blink::WebReferrerPolicy NetReferrerPolicyToBlinkReferrerPolicy(
       net::URLRequest::ReferrerPolicy net_policy);
+
+  static net::URLRequest::ReferrerPolicy GetDefaultReferrerPolicy();
 };
 
 }  // namespace content
diff --git a/content/public/common/resource_request.h b/content/public/common/resource_request.h
index 45695dd51..cd94da67 100644
--- a/content/public/common/resource_request.h
+++ b/content/public/common/resource_request.h
@@ -19,6 +19,7 @@
 #include "content/public/common/service_worker_modes.h"
 #include "net/base/request_priority.h"
 #include "net/http/http_request_headers.h"
+#include "net/url_request/url_request.h"
 #include "services/network/public/interfaces/fetch_api.mojom.h"
 #include "services/network/public/interfaces/request_context_frame_type.mojom.h"
 #include "third_party/WebKit/common/page/page_visibility_state.mojom.h"
@@ -57,7 +58,8 @@
   GURL referrer;
 
   // The referrer policy to use.
-  blink::WebReferrerPolicy referrer_policy = blink::kWebReferrerPolicyAlways;
+  net::URLRequest::ReferrerPolicy referrer_policy =
+      net::URLRequest::NEVER_CLEAR_REFERRER;
 
   // The frame's visibility state.
   blink::mojom::PageVisibilityState visibility_state =
diff --git a/content/public/test/navigation_simulator.cc b/content/public/test/navigation_simulator.cc
index f95b1ee..9a7757c 100644
--- a/content/public/test/navigation_simulator.cc
+++ b/content/public/test/navigation_simulator.cc
@@ -324,7 +324,7 @@
   redirect_info.new_site_for_cookies = new_url;
   redirect_info.new_referrer = referrer_.url.spec();
   redirect_info.new_referrer_policy =
-      Referrer::ReferrerPolicyForUrlRequest(referrer_);
+      Referrer::ReferrerPolicyForUrlRequest(referrer_.policy);
 
   url_loader->CallOnRequestRedirected(
       redirect_info, scoped_refptr<ResourceResponse>(new ResourceResponse));
diff --git a/content/public/test/referrer_unittest.cc b/content/public/test/referrer_unittest.cc
index 51146691..b272a98 100644
--- a/content/public/test/referrer_unittest.cc
+++ b/content/public/test/referrer_unittest.cc
@@ -36,10 +36,9 @@
   };
 
   for (auto policy : policies) {
-    EXPECT_EQ(
-        Referrer::ReferrerPolicyForUrlRequest(Referrer(
-            GURL(), Referrer::NetReferrerPolicyToBlinkReferrerPolicy(policy))),
-        policy);
+    EXPECT_EQ(Referrer::ReferrerPolicyForUrlRequest(
+                  Referrer::NetReferrerPolicyToBlinkReferrerPolicy(policy)),
+              policy);
   }
 }
 
diff --git a/content/renderer/fetchers/resource_fetcher_impl.cc b/content/renderer/fetchers/resource_fetcher_impl.cc
index c52e16af..56d57de 100644
--- a/content/renderer/fetchers/resource_fetcher_impl.cc
+++ b/content/renderer/fetchers/resource_fetcher_impl.cc
@@ -10,6 +10,7 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "content/common/possibly_associated_interface_ptr.h"
+#include "content/public/common/referrer.h"
 #include "content/public/common/resource_request_body.h"
 #include "content/public/renderer/child_url_loader_factory_getter.h"
 #include "content/public/renderer/render_frame.h"
@@ -277,7 +278,7 @@
   if (base::LowerCaseEqualsASCII(header, net::HttpRequestHeaders::kReferer)) {
     request_.referrer = GURL(value);
     DCHECK(request_.referrer.is_valid());
-    request_.referrer_policy = blink::kWebReferrerPolicyDefault;
+    request_.referrer_policy = Referrer::GetDefaultReferrerPolicy();
   } else {
     request_.headers.SetHeader(header, value);
   }
diff --git a/content/renderer/loader/resource_dispatcher.cc b/content/renderer/loader/resource_dispatcher.cc
index 0585c63..abdc1df 100644
--- a/content/renderer/loader/resource_dispatcher.cc
+++ b/content/renderer/loader/resource_dispatcher.cc
@@ -56,9 +56,10 @@
 }
 
 void CheckSchemeForReferrerPolicy(const ResourceRequest& request) {
-  if ((request.referrer_policy == blink::kWebReferrerPolicyDefault ||
+  if ((request.referrer_policy == Referrer::GetDefaultReferrerPolicy() ||
        request.referrer_policy ==
-           blink::kWebReferrerPolicyNoReferrerWhenDowngrade) &&
+           net::URLRequest::
+               CLEAR_REFERRER_ON_TRANSITION_FROM_SECURE_TO_INSECURE) &&
       request.referrer.SchemeIsCryptographic() &&
       !request.url.SchemeIsCryptographic()) {
     LOG(FATAL) << "Trying to send secure referrer for insecure request "
diff --git a/content/renderer/loader/resource_dispatcher_unittest.cc b/content/renderer/loader/resource_dispatcher_unittest.cc
index 7e428cb7..71890a9 100644
--- a/content/renderer/loader/resource_dispatcher_unittest.cc
+++ b/content/renderer/loader/resource_dispatcher_unittest.cc
@@ -93,7 +93,7 @@
     request->method = "GET";
     request->url = GURL(kTestPageUrl);
     request->site_for_cookies = GURL(kTestPageUrl);
-    request->referrer_policy = blink::kWebReferrerPolicyDefault;
+    request->referrer_policy = Referrer::GetDefaultReferrerPolicy();
     request->resource_type = RESOURCE_TYPE_SUB_RESOURCE;
     request->priority = net::LOW;
     request->fetch_request_mode = network::mojom::FetchRequestMode::kNoCORS;
diff --git a/content/renderer/loader/web_url_loader_impl.cc b/content/renderer/loader/web_url_loader_impl.cc
index cfa438bf..209a43d 100644
--- a/content/renderer/loader/web_url_loader_impl.cc
+++ b/content/renderer/loader/web_url_loader_impl.cc
@@ -613,7 +613,8 @@
           : base::Optional<url::Origin>(request.RequestorOrigin());
   resource_request->referrer = referrer_url;
 
-  resource_request->referrer_policy = request.GetReferrerPolicy();
+  resource_request->referrer_policy =
+      Referrer::ReferrerPolicyForUrlRequest(request.GetReferrerPolicy());
 
   resource_request->headers = GetWebURLRequestHeaders(request);
   resource_request->load_flags = GetLoadFlagsForWebURLRequest(request);
diff --git a/content/renderer/service_worker/service_worker_context_client.cc b/content/renderer/service_worker/service_worker_context_client.cc
index 6fd8979..a3792e15 100644
--- a/content/renderer/service_worker/service_worker_context_client.cc
+++ b/content/renderer/service_worker/service_worker_context_client.cc
@@ -203,7 +203,8 @@
     web_request->SetBody(body);
   }
   web_request->SetReferrer(blink::WebString::FromUTF8(request.referrer.spec()),
-                           request.referrer_policy);
+                           Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
+                               request.referrer_policy));
   web_request->SetMode(request.fetch_request_mode);
   web_request->SetIsMainResourceLoad(
       ServiceWorkerUtils::IsMainResourceType(request.resource_type));
diff --git a/content/renderer/service_worker/service_worker_subresource_loader.cc b/content/renderer/service_worker/service_worker_subresource_loader.cc
index bae87a0..f2bf7ae 100644
--- a/content/renderer/service_worker/service_worker_subresource_loader.cc
+++ b/content/renderer/service_worker/service_worker_subresource_loader.cc
@@ -452,9 +452,7 @@
   resource_request_.method = redirect_info_->new_method;
   resource_request_.site_for_cookies = redirect_info_->new_site_for_cookies;
   resource_request_.referrer = GURL(redirect_info_->new_referrer);
-  resource_request_.referrer_policy =
-      Referrer::NetReferrerPolicyToBlinkReferrerPolicy(
-          redirect_info_->new_referrer_policy);
+  resource_request_.referrer_policy = redirect_info_->new_referrer_policy;
 
   // Restart the request.
   status_ = Status::kNotStarted;
diff --git a/gin/BUILD.gn b/gin/BUILD.gn
index 53cb543f..299815b 100644
--- a/gin/BUILD.gn
+++ b/gin/BUILD.gn
@@ -2,9 +2,18 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/buildflag_header.gni")
+import("//build/config/allocator.gni")
 import("//testing/test.gni")
 import("//v8/gni/v8.gni")
 
+# "features" to avoid collision with existing gin_features.h file.
+buildflag_header("features") {
+  header = "features.h"
+
+  flags = [ "USE_PARTITION_ALLOC=$use_partition_alloc" ]
+}
+
 component("gin") {
   sources = [
     "arguments.cc",
@@ -80,6 +89,7 @@
   defines = [ "GIN_IMPLEMENTATION" ]
 
   public_deps = [
+    ":features",
     "//base",
     "//v8",
   ]
diff --git a/gin/array_buffer.cc b/gin/array_buffer.cc
index 34e83db..5d503e7 100644
--- a/gin/array_buffer.cc
+++ b/gin/array_buffer.cc
@@ -2,13 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "gin/array_buffer.h"
+
 #include <stddef.h>
 #include <stdlib.h>
 
 #include "base/allocator/partition_allocator/page_allocator.h"
 #include "base/logging.h"
 #include "build/build_config.h"
-#include "gin/array_buffer.h"
+#include "gin/features.h"
 #include "gin/per_isolate_data.h"
 
 #if defined(OS_POSIX)
@@ -17,7 +19,7 @@
 #ifndef MAP_ANONYMOUS
 #define MAP_ANONYMOUS MAP_ANON
 #endif
-#endif
+#endif  // defined(OS_POSIX)
 
 namespace gin {
 
@@ -33,6 +35,7 @@
 // ArrayBufferAllocator -------------------------------------------------------
 
 void* ArrayBufferAllocator::Allocate(size_t length) {
+  // TODO(bbudge) Use partition allocator for malloc/calloc allocations.
   return calloc(1, length);
 }
 
@@ -41,11 +44,14 @@
 }
 
 void* ArrayBufferAllocator::Reserve(size_t length) {
-  void* const hint = nullptr;
-#if defined(OS_POSIX)
+#if BUILDFLAG(USE_PARTITION_ALLOC)
+  const bool commit = false;
+  return base::AllocPages(nullptr, length, base::kPageAllocationGranularity,
+                          base::PageInaccessible, commit);
+#elif defined(OS_POSIX)
   int const access_flag = PROT_NONE;
   void* const ret =
-      mmap(hint, length, access_flag, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+      mmap(nullptr, length, access_flag, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
   if (ret == MAP_FAILED) {
     return nullptr;
   }
@@ -67,16 +73,15 @@
     case AllocationMode::kNormal:
       Free(data, length);
       return;
-    case AllocationMode::kReservation: {
-#if defined(OS_POSIX)
-      int const ret = munmap(data, length);
-      CHECK(!ret);
+    case AllocationMode::kReservation:
+#if BUILDFLAG(USE_PARTITION_ALLOC)
+      base::FreePages(data, length);
+#elif defined(OS_POSIX)
+      CHECK(!munmap(data, length));
 #else
-      BOOL const ret = VirtualFree(data, 0, MEM_RELEASE);
-      CHECK(ret);
+      CHECK(VirtualFree(data, 0, MEM_RELEASE));
 #endif
       return;
-    }
     default:
       NOTREACHED();
   }
@@ -85,27 +90,40 @@
 void ArrayBufferAllocator::SetProtection(void* data,
                                          size_t length,
                                          Protection protection) {
+#if BUILDFLAG(USE_PARTITION_ALLOC)
   switch (protection) {
-    case Protection::kNoAccess: {
-#if defined(OS_POSIX)
-      int ret = mprotect(data, length, PROT_NONE);
-      CHECK(!ret);
-#else
-      BOOL ret = VirtualFree(data, length, MEM_DECOMMIT);
-      CHECK(ret);
-#endif
+    case Protection::kNoAccess:
+      CHECK(base::SetSystemPagesAccess(data, length, base::PageInaccessible));
       break;
-    }
     case Protection::kReadWrite:
-#if defined(OS_POSIX)
-      mprotect(data, length, PROT_READ | PROT_WRITE);
-#else
-      VirtualAlloc(data, length, MEM_COMMIT, PAGE_READWRITE);
-#endif
+      CHECK(base::SetSystemPagesAccess(data, length, base::PageReadWrite));
       break;
     default:
       NOTREACHED();
   }
+#elif defined(OS_POSIX)
+  switch (protection) {
+    case Protection::kNoAccess:
+      CHECK_EQ(0, mprotect(data, length, PROT_NONE));
+      break;
+    case Protection::kReadWrite:
+      CHECK_EQ(0, mprotect(data, length, PROT_READ | PROT_WRITE));
+      break;
+    default:
+      NOTREACHED();
+  }
+#else   // !defined(OS_POSIX)
+  switch (protection) {
+    case Protection::kNoAccess:
+      CHECK_NE(0, VirtualFree(data, length, MEM_DECOMMIT));
+      break;
+    case Protection::kReadWrite:
+      CHECK_NE(nullptr, VirtualAlloc(data, length, MEM_COMMIT, PAGE_READWRITE));
+      break;
+    default:
+      NOTREACHED();
+  }
+#endif  // !defined(OS_POSIX)
 }
 
 ArrayBufferAllocator* ArrayBufferAllocator::SharedInstance() {
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositingLayerAssigner.cpp b/third_party/WebKit/Source/core/paint/compositing/CompositingLayerAssigner.cpp
index 8b2267a..64abb403 100644
--- a/third_party/WebKit/Source/core/paint/compositing/CompositingLayerAssigner.cpp
+++ b/third_party/WebKit/Source/core/paint/compositing/CompositingLayerAssigner.cpp
@@ -26,6 +26,7 @@
 
 #include "core/paint/compositing/CompositingLayerAssigner.h"
 
+#include "core/html/HTMLFrameOwnerElement.h"
 #include "core/inspector/InspectorTraceEvents.h"
 #include "core/layout/LayoutView.h"
 #include "core/page/Page.h"
@@ -99,6 +100,26 @@
          (compositor_->StaleInCompositingMode() && layer->IsRootLayer());
 }
 
+bool CompositingLayerAssigner::PreventsSquashing(
+    const PaintLayer* layer) const {
+  // TODO(crbug.com/788807): This is a temporary heuristic to avoid hit testing
+  // bugs with remote frames. Remove for M65.
+  if (!RuntimeEnabledFeatures::PreventLayerSquashingEnabled())
+    return false;
+
+  auto& layout_object = layer->GetLayoutObject();
+  if (!layout_object.IsLayoutEmbeddedContent())
+    return false;
+
+  auto* node = layout_object.GetNode();
+  if (!node || !node->IsHTMLElement() || !node->IsFrameOwnerElement())
+    return false;
+
+  HTMLFrameOwnerElement* element =
+      ToHTMLFrameOwnerElement(layout_object.GetNode());
+  return element->ContentFrame() && element->ContentFrame()->IsRemoteFrame();
+}
+
 CompositingStateTransitionType
 CompositingLayerAssigner::ComputeCompositedLayerUpdate(PaintLayer* layer) {
   CompositingStateTransitionType update = kNoCompositingStateChange;
@@ -129,6 +150,9 @@
   if (!squashing_state.have_assigned_backings_to_entire_squashing_layer_subtree)
     return SquashingDisallowedReason::kWouldBreakPaintOrder;
 
+  if (squashing_state.preceding_layer_prevents_squashing)
+    return SquashingDisallowedReason::kPrecedingLayerPrecludesSquashing;
+
   DCHECK(squashing_state.has_most_recent_mapping);
   const PaintLayer& squashing_layer =
       squashing_state.most_recent_mapping->OwningLayer();
@@ -287,6 +311,9 @@
     }
   }
 
+  if (PreventsSquashing(layer))
+    squashing_state.preceding_layer_prevents_squashing = true;
+
   CompositingStateTransitionType composited_layer_update =
       ComputeCompositedLayerUpdate(layer);
 
diff --git a/third_party/WebKit/Source/core/paint/compositing/CompositingLayerAssigner.h b/third_party/WebKit/Source/core/paint/compositing/CompositingLayerAssigner.h
index 29e956e..03d9922 100644
--- a/third_party/WebKit/Source/core/paint/compositing/CompositingLayerAssigner.h
+++ b/third_party/WebKit/Source/core/paint/compositing/CompositingLayerAssigner.h
@@ -56,13 +56,6 @@
 
  private:
   struct SquashingState {
-    SquashingState()
-        : most_recent_mapping(nullptr),
-          has_most_recent_mapping(false),
-          have_assigned_backings_to_entire_squashing_layer_subtree(false),
-          next_squashed_layer_index(0),
-          total_area_of_squashed_rects(0) {}
-
     void UpdateSquashingStateForNewMapping(
         CompositedLayerMapping*,
         bool has_new_composited_paint_layer_mapping,
@@ -70,18 +63,18 @@
 
     // The most recent composited backing that the layer should squash onto if
     // needed.
-    CompositedLayerMapping* most_recent_mapping;
-    bool has_most_recent_mapping;
+    CompositedLayerMapping* most_recent_mapping = nullptr;
+    bool has_most_recent_mapping = false;
 
     // Whether all Layers in the stacking subtree rooted at the most recent
     // mapping's owning layer have had CompositedLayerMappings assigned. Layers
     // cannot squash into a CompositedLayerMapping owned by a stacking ancestor,
     // since this changes paint order.
-    bool have_assigned_backings_to_entire_squashing_layer_subtree;
+    bool have_assigned_backings_to_entire_squashing_layer_subtree = false;
 
     // Counter that tracks what index the next Layer would be if it gets
     // squashed to the current squashing layer.
-    size_t next_squashed_layer_index;
+    size_t next_squashed_layer_index = 0;
 
     // The absolute bounding rect of all the squashed layers.
     IntRect bounding_rect;
@@ -89,7 +82,11 @@
     // This is simply the sum of the areas of the squashed rects. This can be
     // very skewed if the rects overlap, but should be close enough to drive a
     // heuristic.
-    uint64_t total_area_of_squashed_rects;
+    uint64_t total_area_of_squashed_rects = 0;
+
+    // This is set to true if we encounter a layer in our paint order walk that
+    // would preclude squashing by subsequent layers.
+    bool preceding_layer_prevents_squashing = false;
   };
 
   void AssignLayersToBackingsInternal(
@@ -107,6 +104,7 @@
       CompositingStateTransitionType,
       Vector<PaintLayer*>& layers_needing_paint_invalidation);
   bool NeedsOwnBacking(const PaintLayer*) const;
+  bool PreventsSquashing(const PaintLayer*) const;
 
   PaintLayerCompositor* compositor_;
   bool layers_changed_;
diff --git a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
index e346d50e..c9ee2d44 100644
--- a/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebRuntimeFeatures.cpp
@@ -298,6 +298,10 @@
       enable);
 }
 
+void WebRuntimeFeatures::EnablePreventLayerSquashing(bool enable) {
+  RuntimeEnabledFeatures::SetPreventLayerSquashingEnabled(enable);
+}
+
 void WebRuntimeFeatures::EnableWebGLDraftExtensions(bool enable) {
   RuntimeEnabledFeatures::SetWebGLDraftExtensionsEnabled(enable);
 }
diff --git a/third_party/WebKit/Source/platform/graphics/SquashingDisallowedReasons.h b/third_party/WebKit/Source/platform/graphics/SquashingDisallowedReasons.h
index 735d67e7..f107fa3 100644
--- a/third_party/WebKit/Source/platform/graphics/SquashingDisallowedReasons.h
+++ b/third_party/WebKit/Source/platform/graphics/SquashingDisallowedReasons.h
@@ -28,7 +28,8 @@
   V(ScrollChildWithCompositedDescendants)       \
   V(SquashingLayerIsAnimating)                  \
   V(RenderingContextMismatch)                   \
-  V(FragmentedContent)
+  V(FragmentedContent)                          \
+  V(PrecedingLayerPrecludesSquashing)
 
 class PLATFORM_EXPORT SquashingDisallowedReason {
  private:
diff --git a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
index 4b08059..d4044af 100644
--- a/third_party/WebKit/Source/platform/runtime_enabled_features.json5
+++ b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
@@ -830,6 +830,10 @@
       status: "stable",
     },
     {
+      name: "PreventLayerSquashing",
+      status: "stable",
+    },
+    {
       name: "PrintBrowser",
     },
     {
diff --git a/third_party/WebKit/public/platform/WebRuntimeFeatures.h b/third_party/WebKit/public/platform/WebRuntimeFeatures.h
index f698f15..a76b897 100644
--- a/third_party/WebKit/public/platform/WebRuntimeFeatures.h
+++ b/third_party/WebKit/public/platform/WebRuntimeFeatures.h
@@ -140,6 +140,7 @@
   BLINK_PLATFORM_EXPORT static void EnableTouchpadAndWheelScrollLatching(bool);
   BLINK_PLATFORM_EXPORT static void
   EnableTurnOff2DAndOpacityCompositorAnimations(bool);
+  BLINK_PLATFORM_EXPORT static void EnablePreventLayerSquashing(bool);
   BLINK_PLATFORM_EXPORT static void EnableUserActivationV2(bool);
   BLINK_PLATFORM_EXPORT static void EnableV8IdleTasks(bool);
   BLINK_PLATFORM_EXPORT static void EnableWebAssemblyStreaming(bool);
diff --git a/third_party/afl/README.chromium b/third_party/afl/README.chromium
index d5fea42..953962e 100644
--- a/third_party/afl/README.chromium
+++ b/third_party/afl/README.chromium
@@ -1,8 +1,8 @@
 Name: American Fuzzy Lop
 Short Name: AFL
 URL: http://lcamtuf.coredump.cx/afl/
-Version: 2.38b
-Date: January 29, 2017
+Version: 2.52b
+Date: December 13, 2017
 License: Apache 2.0
 License File: src/docs/COPYING
 Security Critical: no
@@ -13,7 +13,7 @@
 
 Local Modifications:
 - Use update.py to roll forward.
-- Renamed afl-2.38b/ to src/.
+- Renamed afl-2.52b/ to src/.
 - Removed the following unneeded files/directories:
   - src/experimental/argv_fuzzing/
   - src/docs/vuln_samples
diff --git a/third_party/afl/src/Makefile b/third_party/afl/src/Makefile
index 44d1ffa..0b2c92b0 100644
--- a/third_party/afl/src/Makefile
+++ b/third_party/afl/src/Makefile
@@ -4,7 +4,7 @@
 #
 # Written and maintained by Michal Zalewski <lcamtuf@google.com>
 # 
-# Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved.
+# Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved.
 # 
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -111,8 +111,8 @@
 .NOTPARALLEL: clean
 
 clean:
-	rm -f $(PROGS) afl-as as afl-g++ afl-clang afl-clang++ *.o *~ a.out core core.[1-9][0-9]* *.stackdump test .test test-instr .test-instr0 .test-instr1 qemu_mode/qemu-2.3.0.tar.bz2 afl-qemu-trace
-	rm -rf out_dir qemu_mode/qemu-2.3.0
+	rm -f $(PROGS) afl-as as afl-g++ afl-clang afl-clang++ *.o *~ a.out core core.[1-9][0-9]* *.stackdump test .test test-instr .test-instr0 .test-instr1 qemu_mode/qemu-2.10.0.tar.bz2 afl-qemu-trace
+	rm -rf out_dir qemu_mode/qemu-2.10.0
 	$(MAKE) -C llvm_mode clean
 	$(MAKE) -C libdislocator clean
 	$(MAKE) -C libtokencap clean
diff --git a/third_party/afl/src/afl-analyze.c b/third_party/afl/src/afl-analyze.c
index fd0a522..813e79b 100644
--- a/third_party/afl/src/afl-analyze.c
+++ b/third_party/afl/src/afl-analyze.c
@@ -4,7 +4,7 @@
 
    Written and maintained by Michal Zalewski <lcamtuf@google.com>
 
-   Copyright 2016 Google Inc. All rights reserved.
+   Copyright 2016, 2017 Google Inc. All rights reserved.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -68,6 +68,7 @@
            dev_null_fd = -1;          /* FD to /dev/null                   */
 
 static u8  edges_only,                /* Ignore hit counts?                */
+           use_hex_offsets,           /* Show hex offsets?                 */
            use_stdin = 1;             /* Use stdin for program input?      */
 
 static volatile u8
@@ -486,9 +487,13 @@
       /* Every 16 digits, display offset. */
 
       if (!((i + off) % 16)) {
-    
+
         if (off) SAYF(cRST cLCY ">");
-        SAYF(cRST cGRA "%s[%06u] " cRST, (i + off) ? "\n" : "", i + off);
+
+        if (use_hex_offsets)
+          SAYF(cRST cGRA "%s[%06x] " cRST, (i + off) ? "\n" : "", i + off);
+        else
+          SAYF(cRST cGRA "%s[%06u] " cRST, (i + off) ? "\n" : "", i + off);
 
       }
 
@@ -512,7 +517,10 @@
 
 #else
 
-    SAYF("    Offset %u, length %u: ", i, rlen);
+    if (use_hex_offsets)
+      SAYF("    Offset %x, length %u: ", i, rlen);
+    else
+      SAYF("    Offset %u, length %u: ", i, rlen);
 
     switch (rtype) {
 
@@ -658,15 +666,15 @@
 
     u8* use_dir = ".";
 
-    if (!access(use_dir, R_OK | W_OK | X_OK)) {
+    if (access(use_dir, R_OK | W_OK | X_OK)) {
 
       use_dir = getenv("TMPDIR");
       if (!use_dir) use_dir = "/tmp";
 
-      prog_in = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, getpid());
-
     }
 
+    prog_in = alloc_printf("%s/.afl-analyze-temp-%u", use_dir, getpid());
+
   }
 
   /* Set sane defaults... */
@@ -874,6 +882,10 @@
   char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));
   u8 *tmp, *cp, *rsl, *own_copy;
 
+  /* Workaround for a QEMU stability glitch. */
+
+  setenv("QEMU_LOG", "nochain", 1);
+
   memcpy(new_argv + 3, argv + 1, sizeof(char*) * argc);
 
   /* Now we need to actually find qemu for argv[0]. */
@@ -1026,6 +1038,8 @@
 
   if (optind == argc || !in_file) usage(argv[0]);
 
+  use_hex_offsets = !!getenv("AFL_ANALYZE_HEX");
+
   setup_shm();
   setup_signal_handlers();
 
diff --git a/third_party/afl/src/afl-as.c b/third_party/afl/src/afl-as.c
index 7686fe8a..b15e651 100644
--- a/third_party/afl/src/afl-as.c
+++ b/third_party/afl/src/afl-as.c
@@ -56,7 +56,8 @@
 static u8   be_quiet,           /* Quiet mode (no stderr output)        */
             clang_mode,         /* Running in clang mode?               */
             pass_thru,          /* Just pass data through?              */
-            just_version;       /* Just show version?                   */
+            just_version,       /* Just show version?                   */
+            sanitizer;          /* Using ASAN / MSAN                    */
 
 static u32  inst_ratio = 100,   /* Instrumentation probability (%)      */
             as_par_cnt = 1;     /* Number of params to 'as'             */
@@ -454,7 +455,8 @@
                           pass_thru ? " (pass-thru mode)" : "");
     else OKF("Instrumented %u locations (%s-bit, %s mode, ratio %u%%).",
              ins_lines, use_64bit ? "64" : "32",
-             getenv("AFL_HARDEN") ? "hardened" : "non-hardened",
+             getenv("AFL_HARDEN") ? "hardened" : 
+             (sanitizer ? "ASAN/MSAN" : "non-hardened"),
              inst_ratio);
  
   }
@@ -521,7 +523,10 @@
      ASAN-specific branches. But we can probabilistically compensate for
      that... */
 
-  if (getenv("AFL_USE_ASAN") || getenv("AFL_USE_MSAN")) inst_ratio /= 3;
+  if (getenv("AFL_USE_ASAN") || getenv("AFL_USE_MSAN")) {
+    sanitizer = 1;
+    inst_ratio /= 3;
+  }
 
   if (!just_version) add_instrumentation();
 
diff --git a/third_party/afl/src/afl-cmin b/third_party/afl/src/afl-cmin
index 5af4b77..bc3494e 100755
--- a/third_party/afl/src/afl-cmin
+++ b/third_party/afl/src/afl-cmin
@@ -126,24 +126,28 @@
 # Do a sanity check to discourage the use of /tmp, since we can't really
 # handle this safely from a shell script.
 
-echo "$IN_DIR" | grep -qE '^(/var)?/tmp/'
-T1="$?"
+if [ "$AFL_ALLOW_TMP" = "" ]; then
 
-echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/'
-T2="$?"
+  echo "$IN_DIR" | grep -qE '^(/var)?/tmp/'
+  T1="$?"
 
-echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/'
-T3="$?"
+  echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/'
+  T2="$?"
 
-echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/'
-T4="$?"
+  echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/'
+  T3="$?"
 
-echo "$PWD" | grep -qE '^(/var)?/tmp/'
-T5="$?"
+  echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/'
+  T4="$?"
 
-if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then
-  echo "[-] Error: do not use this script in /tmp or /var/tmp." 1>&2
-  exit 1
+  echo "$PWD" | grep -qE '^(/var)?/tmp/'
+  T5="$?"
+
+  if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then
+    echo "[-] Error: do not use this script in /tmp or /var/tmp." 1>&2
+    exit 1
+  fi
+
 fi
 
 # If @@ is specified, but there's no -f, let's come up with a temporary input
@@ -240,13 +244,23 @@
 IN_COUNT=$((`ls -- "$IN_DIR" 2>/dev/null | wc -l`))
 
 if [ "$IN_COUNT" = "0" ]; then
-  echo "No inputs in the target directory - nothing to be done."
+  echo "[+] Hmm, no inputs in the target directory. Nothing to be done."
   rm -rf "$TRACE_DIR"
   exit 1
 fi
 
 FIRST_FILE=`ls "$IN_DIR" | head -1`
 
+# Make sure that we're not dealing with a directory.
+
+if [ -d "$IN_DIR/$FIRST_FILE" ]; then
+  echo "[-] Error: The target directory contains subdirectories - please fix." 1>&2
+  rm -rf "$TRACE_DIR"
+  exit 1
+fi
+
+# Check for the more efficient way to copy files...
+
 if ln "$IN_DIR/$FIRST_FILE" "$TRACE_DIR/.link_test" 2>/dev/null; then
   CP_TOOL=ln
 else
@@ -384,7 +398,7 @@
   sed 's/^/BEST_FILE[/;s/ /]="/;s/$/"/' >"$TRACE_DIR/.candidate_script"
 
 if [ ! -s "$TRACE_DIR/.candidate_script" ]; then
-  echo "[-] Error: no traces obtained from test cases, check syntax!"
+  echo "[-] Error: no traces obtained from test cases, check syntax!" 1>&2
   test "$AFL_KEEP_TRACES" = "" && rm -rf "$TRACE_DIR"
   exit 1
 fi
diff --git a/third_party/afl/src/afl-fuzz.c b/third_party/afl/src/afl-fuzz.c
index e730cb29..01b4afe 100644
--- a/third_party/afl/src/afl-fuzz.c
+++ b/third_party/afl/src/afl-fuzz.c
@@ -6,7 +6,7 @@
 
    Forkserver design by Jann Horn <jannhorn@googlemail.com>
 
-   Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved.
+   Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -92,7 +92,9 @@
           *orig_cmdline;              /* Original command line            */
 
 EXP_ST u32 exec_tmout = EXEC_TIMEOUT; /* Configurable exec timeout (ms)   */
-EXP_ST u64 mem_limit = MEM_LIMIT;     /* Memory cap for child (MB)        */
+static u32 hang_tmout = EXEC_TIMEOUT; /* Timeout used for hang det (ms)   */
+
+EXP_ST u64 mem_limit  = MEM_LIMIT;    /* Memory cap for child (MB)        */
 
 static u32 stats_update_freq = 1;     /* Stats update frequency (execs)   */
 
@@ -112,12 +114,15 @@
            in_place_resume,           /* Attempt in-place resume?         */
            auto_changed,              /* Auto-generated tokens changed?   */
            no_cpu_meter_red,          /* Feng shui on the status screen   */
+           no_arith,                  /* Skip most arithmetic ops         */
            shuffle_queue,             /* Shuffle input queue?             */
            bitmap_changed = 1,        /* Time to update bitmap?           */
            qemu_mode,                 /* Running in QEMU mode?            */
            skip_requested,            /* Skip request, via SIGUSR1        */
            run_over10m,               /* Run time over 10 minutes?        */
-           persistent_mode;           /* Running in persistent mode?      */
+           persistent_mode,           /* Running in persistent mode?      */
+           deferred_mode,             /* Deferred forkserver mode?        */
+           fast_cal;                  /* Try to calibrate faster?         */
 
 static s32 out_fd,                    /* Persistent fd for out_file       */
            dev_urandom_fd = -1,       /* Persistent fd for /dev/urandom   */
@@ -132,7 +137,7 @@
 EXP_ST u8* trace_bits;                /* SHM with instrumentation bitmap  */
 
 EXP_ST u8  virgin_bits[MAP_SIZE],     /* Regions yet untouched by fuzzing */
-           virgin_hang[MAP_SIZE],     /* Bits we haven't seen in hangs    */
+           virgin_tmout[MAP_SIZE],    /* Bits we haven't seen in tmouts   */
            virgin_crash[MAP_SIZE];    /* Bits we haven't seen in crashes  */
 
 static u8  var_bytes[MAP_SIZE];       /* Bytes that appear to be variable */
@@ -162,7 +167,8 @@
 
 EXP_ST u64 total_crashes,             /* Total number of crashes          */
            unique_crashes,            /* Crashes with unique signatures   */
-           total_hangs,               /* Total number of hangs            */
+           total_tmouts,              /* Total number of timeouts         */
+           unique_tmouts,             /* Timeouts with unique signatures  */
            unique_hangs,              /* Hangs with unique signatures     */
            total_execs,               /* Total execve() calls             */
            start_time,                /* Unix start time (ms)             */
@@ -178,7 +184,7 @@
            blocks_eff_total,          /* Blocks subject to effector maps  */
            blocks_eff_select;         /* Blocks selected as fuzzable      */
 
-static u32 subseq_hangs;              /* Number of hangs in a row         */
+static u32 subseq_tmouts;             /* Number of timeouts in a row      */
 
 static u8 *stage_name = "init",       /* Name of the current fuzz stage   */
           *stage_short,               /* Short stage name                 */
@@ -308,7 +314,7 @@
 
 enum {
   /* 00 */ FAULT_NONE,
-  /* 01 */ FAULT_HANG,
+  /* 01 */ FAULT_TMOUT,
   /* 02 */ FAULT_CRASH,
   /* 03 */ FAULT_ERROR,
   /* 04 */ FAULT_NOINST,
@@ -1031,7 +1037,7 @@
 
 /* Destructively simplify trace by eliminating hit count information
    and replacing it with 0x80 or 0x01 depending on whether the tuple
-   is hit or not. Called on every new crash or hang, should be
+   is hit or not. Called on every new crash or timeout, should be
    reasonably fast. */
 
 static const u8 simplify_lookup[256] = { 
@@ -1122,7 +1128,7 @@
 static u16 count_class_lookup16[65536];
 
 
-static void init_count_class16(void) {
+EXP_ST void init_count_class16(void) {
 
   u32 b1, b2;
 
@@ -1339,7 +1345,7 @@
 
   if (!in_bitmap) memset(virgin_bits, 255, MAP_SIZE);
 
-  memset(virgin_hang, 255, MAP_SIZE);
+  memset(virgin_tmout, 255, MAP_SIZE);
   memset(virgin_crash, 255, MAP_SIZE);
 
   shm_id = shmget(IPC_PRIVATE, MAP_SIZE, IPC_CREAT | IPC_EXCL | 0600);
@@ -2252,7 +2258,7 @@
 /* Execute target application, monitoring for timeouts. Return status
    information. The called program will update trace_bits[]. */
 
-static u8 run_target(char** argv) {
+static u8 run_target(char** argv, u32 timeout) {
 
   static struct itimerval it;
   static u32 prev_timed_out = 0;
@@ -2378,8 +2384,8 @@
 
   /* Configure timeout, as requested by user, then wait for child to terminate. */
 
-  it.it_value.tv_sec = (exec_tmout / 1000);
-  it.it_value.tv_usec = (exec_tmout % 1000) * 1000;
+  it.it_value.tv_sec = (timeout / 1000);
+  it.it_value.tv_usec = (timeout % 1000) * 1000;
 
   setitimer(ITIMER_REAL, &it, NULL);
 
@@ -2429,11 +2435,14 @@
 
   /* Report outcome to caller. */
 
-  if (child_timed_out) return FAULT_HANG;
-
   if (WIFSIGNALED(status) && !stop_soon) {
+
     kill_signal = WTERMSIG(status);
+
+    if (child_timed_out && kill_signal == SIGKILL) return FAULT_TMOUT;
+
     return FAULT_CRASH;
+
   }
 
   /* A somewhat nasty hack for MSAN, which doesn't support abort_on_error and
@@ -2529,7 +2538,8 @@
 
   u64 start_us, stop_us;
 
-  s32 old_sc = stage_cur, old_sm = stage_max, old_tmout = exec_tmout;
+  s32 old_sc = stage_cur, old_sm = stage_max;
+  u32 use_tmout = exec_tmout;
   u8* old_sn = stage_name;
 
   /* Be a bit more generous about timeouts when resuming sessions, or when
@@ -2537,13 +2547,13 @@
      to intermittent latency. */
 
   if (!from_queue || resuming_fuzz)
-    exec_tmout = MAX(exec_tmout + CAL_TMOUT_ADD,
-                     exec_tmout * CAL_TMOUT_PERC / 100);
+    use_tmout = MAX(exec_tmout + CAL_TMOUT_ADD,
+                    exec_tmout * CAL_TMOUT_PERC / 100);
 
   q->cal_failed++;
 
   stage_name = "calibration";
-  stage_max  = CAL_CYCLES;
+  stage_max  = fast_cal ? 3 : CAL_CYCLES;
 
   /* Make sure the forkserver is up before we do anything, and let's not
      count its spin-up time toward binary calibration. */
@@ -2563,7 +2573,7 @@
 
     write_to_testcase(use_mem, q->len);
 
-    fault = run_target(argv);
+    fault = run_target(argv, use_tmout);
 
     /* stop_soon is set by the handler for Ctrl+C. When it's pressed,
        we want to bail out quickly. */
@@ -2657,7 +2667,6 @@
   stage_name = old_sn;
   stage_cur  = old_sc;
   stage_max  = old_sm;
-  exec_tmout = old_tmout;
 
   if (!first_run) show_stats();
 
@@ -2730,7 +2739,7 @@
 
         break;
 
-      case FAULT_HANG:
+      case FAULT_TMOUT:
 
         if (timeout_given) {
 
@@ -2739,7 +2748,7 @@
              out. */
 
           if (timeout_given > 1) {
-            WARNF("Test case results in a hang (skipping)");
+            WARNF("Test case results in a timeout (skipping)");
             q->cal_failed = CAL_CHANCES;
             cal_failures++;
             break;
@@ -2753,7 +2762,7 @@
                "    '+' at the end of the value passed to -t ('-t %u+').\n", exec_tmout,
                exec_tmout);
 
-          FATAL("Test case '%s' results in a hang", fn);
+          FATAL("Test case '%s' results in a timeout", fn);
 
         } else {
 
@@ -2765,7 +2774,7 @@
                "    If this test case is just a fluke, the other option is to just avoid it\n"
                "    altogether, and find one that is less of a CPU hog.\n", exec_tmout);
 
-          FATAL("Test case '%s' results in a hang", fn);
+          FATAL("Test case '%s' results in a timeout", fn);
 
         }
 
@@ -3161,14 +3170,14 @@
 
   switch (fault) {
 
-    case FAULT_HANG:
+    case FAULT_TMOUT:
 
-      /* Hangs are not very interesting, but we're still obliged to keep
+      /* Timeouts are not very interesting, but we're still obliged to keep
          a handful of samples. We use the presence of new bits in the
          hang-specific bitmap as a signal of uniqueness. In "dumb" mode, we
          just keep everything. */
 
-      total_hangs++;
+      total_tmouts++;
 
       if (unique_hangs >= KEEP_UNIQUE_HANG) return keeping;
 
@@ -3180,7 +3189,29 @@
         simplify_trace((u32*)trace_bits);
 #endif /* ^__x86_64__ */
 
-        if (!has_new_bits(virgin_hang)) return keeping;
+        if (!has_new_bits(virgin_tmout)) return keeping;
+
+      }
+
+      unique_tmouts++;
+
+      /* Before saving, we make sure that it's a genuine hang by re-running
+         the target with a more generous timeout (unless the default timeout
+         is already generous). */
+
+      if (exec_tmout < hang_tmout) {
+
+        u8 new_fault;
+        write_to_testcase(mem, len);
+        new_fault = run_target(argv, hang_tmout);
+
+        /* A corner case that one user reported bumping into: increasing the
+           timeout actually uncovers a crash. Make sure we don't discard it if
+           so. */
+
+        if (!stop_soon && new_fault == FAULT_CRASH) goto keep_as_crash;
+
+        if (stop_soon || new_fault != FAULT_TMOUT) return keeping;
 
       }
 
@@ -3204,8 +3235,11 @@
 
     case FAULT_CRASH:
 
-      /* This is handled in a manner roughly similar to hangs,
-         except for slightly different limits. */
+keep_as_crash:
+
+      /* This is handled in a manner roughly similar to timeouts,
+         except for slightly different limits and no need to re-run test
+         cases. */
 
       total_crashes++;
 
@@ -3289,10 +3323,10 @@
   i = read(fd, tmp, sizeof(tmp) - 1); (void)i; /* Ignore errors */
   close(fd);
 
-  off = strstr(tmp, "cur_path       : ");
+  off = strstr(tmp, "cur_path          : ");
   if (!off) return 0;
 
-  ret = atoi(off + 17);
+  ret = atoi(off + 20);
   if (ret >= queued_paths) ret = 0;
   return ret;
 
@@ -3380,7 +3414,7 @@
              "paths_found       : %u\n"
              "paths_imported    : %u\n"
              "max_depth         : %u\n"
-             "cur_path          : %u\n"
+             "cur_path          : %u\n" /* Must match find_start_position() */
              "pending_favs      : %u\n"
              "pending_total     : %u\n"
              "variable_paths    : %u\n"
@@ -3395,6 +3429,7 @@
              "exec_timeout      : %u\n"
              "afl_banner        : %s\n"
              "afl_version       : " VERSION "\n"
+             "target_mode       : %s%s%s%s%s%s%s\n"
              "command_line      : %s\n",
              start_time / 1000, get_cur_time() / 1000, getpid(),
              queue_cycle ? (queue_cycle - 1) : 0, total_execs, eps,
@@ -3403,7 +3438,13 @@
              queued_variable, stability, bitmap_cvg, unique_crashes,
              unique_hangs, last_path_time / 1000, last_crash_time / 1000,
              last_hang_time / 1000, total_execs - last_crash_execs,
-             exec_tmout, use_banner, orig_cmdline);
+             exec_tmout, use_banner,
+             qemu_mode ? "qemu " : "", dumb_mode ? " dumb " : "",
+             no_forkserver ? "no_forksrv " : "", crash_mode ? "crash " : "",
+             persistent_mode ? "persistent " : "", deferred_mode ? "deferred " : "",
+             (qemu_mode || dumb_mode || no_forkserver || crash_mode ||
+              persistent_mode || deferred_mode) ? "" : "default",
+             orig_cmdline);
              /* ignore errors */
 
   fclose(f);
@@ -3668,9 +3709,13 @@
   /* Okay, let's get the ball rolling! First, we need to get rid of the entries
      in <out_dir>/.synced/.../id:*, if any are present. */
 
-  fn = alloc_printf("%s/.synced", out_dir);
-  if (delete_files(fn, NULL)) goto dir_cleanup_failed;
-  ck_free(fn);
+  if (!in_place_resume) {
+
+    fn = alloc_printf("%s/.synced", out_dir);
+    if (delete_files(fn, NULL)) goto dir_cleanup_failed;
+    ck_free(fn);
+
+  }
 
   /* Next, we need to clean up <out_dir>/queue/.state/ subdirectories: */
 
@@ -3976,14 +4021,17 @@
 
   } else {
 
+    u64 min_wo_finds = (cur_ms - last_path_time) / 1000 / 60;
+
     /* First queue cycle: don't stop now! */
-    if (queue_cycle == 1) strcpy(tmp, cMGN); else
+    if (queue_cycle == 1 || min_wo_finds < 15) strcpy(tmp, cMGN); else
 
     /* Subsequent cycles, but we're still making finds. */
-    if (cycles_wo_finds < 25) strcpy(tmp, cYEL); else
+    if (cycles_wo_finds < 25 || min_wo_finds < 30) strcpy(tmp, cYEL); else
 
     /* No finds for a long time and no test cases to try. */
-    if (cycles_wo_finds > 100 && !pending_not_fuzzed) strcpy(tmp, cLGN);
+    if (cycles_wo_finds > 100 && !pending_not_fuzzed && min_wo_finds > 120)
+      strcpy(tmp, cLGN);
 
     /* Default: cautiously OK to stop? */
     else strcpy(tmp, cLBL);
@@ -4129,10 +4177,10 @@
 
   }
 
-  sprintf(tmp, "%s (%s%s unique)", DI(total_hangs), DI(unique_hangs),
+  sprintf(tmp, "%s (%s%s unique)", DI(total_tmouts), DI(unique_tmouts),
           (unique_hangs >= KEEP_UNIQUE_HANG) ? "+" : "");
 
-  SAYF (bSTG bV bSTOP "   total hangs : " cRST "%-22s " bSTG bV "\n", tmp);
+  SAYF (bSTG bV bSTOP "  total tmouts : " cRST "%-22s " bSTG bV "\n", tmp);
 
   /* Aaaalmost there... hold on! */
 
@@ -4385,12 +4433,19 @@
 
   }
 
+  /* In dumb mode, re-running every timing out test case with a generous time
+     limit is very expensive, so let's select a more conservative default. */
+
+  if (dumb_mode && !getenv("AFL_HANG_TMOUT"))
+    hang_tmout = MIN(EXEC_TIMEOUT, exec_tmout * 2 + 100);
+
   OKF("All set and ready to roll!");
 
 }
 
 
-/* Find first power of two greater or equal to val. */
+/* Find first power of two greater or equal to val (assuming val under
+   2^31). */
 
 static u32 next_p2(u32 val) {
 
@@ -4449,7 +4504,7 @@
 
       write_with_gap(in_buf, q->len, remove_pos, trim_avail);
 
-      fault = run_target(argv);
+      fault = run_target(argv, exec_tmout);
       trim_execs++;
 
       if (stop_soon || fault == FAULT_ERROR) goto abort_trimming;
@@ -4517,8 +4572,6 @@
 
   }
 
-
-
 abort_trimming:
 
   bytes_trim_out += q->len;
@@ -4544,18 +4597,18 @@
 
   write_to_testcase(out_buf, len);
 
-  fault = run_target(argv);
+  fault = run_target(argv, exec_tmout);
 
   if (stop_soon) return 1;
 
-  if (fault == FAULT_HANG) {
+  if (fault == FAULT_TMOUT) {
 
-    if (subseq_hangs++ > HANG_LIMIT) {
+    if (subseq_tmouts++ > TMOUT_LIMIT) {
       cur_skipped_paths++;
       return 1;
     }
 
-  } else subseq_hangs = 0;
+  } else subseq_tmouts = 0;
 
   /* Users can hit us with SIGUSR1 to request the current input
      to be abandoned. */
@@ -4600,9 +4653,19 @@
              max_value = HAVOC_BLK_MEDIUM;
              break;
 
-    default: min_value = HAVOC_BLK_MEDIUM;
-             max_value = HAVOC_BLK_LARGE;
+    default: 
 
+             if (UR(10)) {
+
+               min_value = HAVOC_BLK_MEDIUM;
+               max_value = HAVOC_BLK_LARGE;
+
+             } else {
+
+               min_value = HAVOC_BLK_LARGE;
+               max_value = HAVOC_BLK_XL;
+
+             }
 
   }
 
@@ -4950,7 +5013,7 @@
 
   out_buf = ck_alloc_nozero(len);
 
-  subseq_hangs = 0;
+  subseq_tmouts = 0;
 
   cur_depth = queue_cur->depth;
 
@@ -4960,7 +5023,7 @@
 
   if (queue_cur->cal_failed) {
 
-    u8 res = FAULT_HANG;
+    u8 res = FAULT_TMOUT;
 
     if (queue_cur->cal_failed < CAL_CHANCES) {
 
@@ -5356,6 +5419,8 @@
 
 skip_bitflip:
 
+  if (no_arith) goto skip_arith;
+
   /**********************
    * ARITHMETIC INC/DEC *
    **********************/
@@ -5553,7 +5618,7 @@
       /* Little endian first. Same deal as with 16-bit: we only want to
          try if the operation would have effect on more than two bytes. */
 
-      stage_val_type = STAGE_VAL_LE; 
+      stage_val_type = STAGE_VAL_LE;
 
       if ((orig & 0xffff) + j > 0xffff && !could_be_bitflip(r1)) {
 
@@ -5669,7 +5734,7 @@
 
   /* Setting 16-bit integers, both endians. */
 
-  if (len < 2) goto skip_interest;
+  if (no_arith || len < 2) goto skip_interest;
 
   stage_name  = "interest 16/8";
   stage_short = "int16";
@@ -5881,7 +5946,7 @@
 
   ex_tmp = ck_alloc(len + MAX_DICT_FILE);
 
-  for (i = 0; i < len; i++) {
+  for (i = 0; i <= len; i++) {
 
     stage_cur_byte = i;
 
@@ -6230,16 +6295,26 @@
 
         case 13:
 
-          if (temp_len + HAVOC_BLK_LARGE < MAX_FILE) {
+          if (temp_len + HAVOC_BLK_XL < MAX_FILE) {
 
             /* Clone bytes (75%) or insert a block of constant bytes (25%). */
 
+            u8  actually_clone = UR(4);
             u32 clone_from, clone_to, clone_len;
             u8* new_buf;
 
-            clone_len  = choose_block_len(temp_len);
+            if (actually_clone) {
 
-            clone_from = UR(temp_len - clone_len + 1);
+              clone_len  = choose_block_len(temp_len);
+              clone_from = UR(temp_len - clone_len + 1);
+
+            } else {
+
+              clone_len = choose_block_len(HAVOC_BLK_XL);
+              clone_from = 0;
+
+            }
+
             clone_to   = UR(temp_len);
 
             new_buf = ck_alloc_nozero(temp_len + clone_len);
@@ -6250,10 +6325,11 @@
 
             /* Inserted part */
 
-            if (UR(4))
+            if (actually_clone)
               memcpy(new_buf + clone_to, out_buf + clone_from, clone_len);
             else
-              memset(new_buf + clone_to, UR(256), clone_len);
+              memset(new_buf + clone_to,
+                     UR(2) ? UR(256) : out_buf[UR(temp_len)], clone_len);
 
             /* Tail */
             memcpy(new_buf + clone_to + clone_len, out_buf + clone_to,
@@ -6286,7 +6362,8 @@
               if (copy_from != copy_to)
                 memmove(out_buf + copy_to, out_buf + copy_from, copy_len);
 
-            } else memset(out_buf + copy_to, UR(256), copy_len);
+            } else memset(out_buf + copy_to,
+                          UR(2) ? UR(256) : out_buf[UR(temp_len)], copy_len);
 
             break;
 
@@ -6334,7 +6411,7 @@
 
         case 16: {
 
-            u32 use_extra, extra_len, insert_at = UR(temp_len);
+            u32 use_extra, extra_len, insert_at = UR(temp_len + 1);
             u8* new_buf;
 
             /* Insert an extra. Do the same dice-rolling stuff as for the
@@ -6649,7 +6726,7 @@
 
         write_to_testcase(mem, st.st_size);
 
-        fault = run_target(argv);
+        fault = run_target(argv, exec_tmout);
 
         if (stop_soon) return;
 
@@ -6877,6 +6954,7 @@
 
     OKF(cPIN "Deferred forkserver binary detected.");
     setenv(DEFER_ENV_VAR, "1", 1);
+    deferred_mode = 1;
 
   } else if (getenv("AFL_DEFER_FORKSRV")) {
 
@@ -7076,7 +7154,10 @@
   if (sync_id) {
 
     tmp = alloc_printf("%s/.synced/", out_dir);
-    if (mkdir(tmp, 0700)) PFATAL("Unable to create '%s'", tmp);
+
+    if (mkdir(tmp, 0700) && (!in_place_resume || errno != EEXIST))
+      PFATAL("Unable to create '%s'", tmp);
+
     ck_free(tmp);
 
   }
@@ -7155,7 +7236,7 @@
        "    external crash reporting utility. This will cause issues due to the\n"
        "    extended delay between the fuzzed binary malfunctioning and this fact\n"
        "    being relayed to the fuzzer via the standard waitpid() API.\n\n"
-       "    To avoid having crashes misinterpreted as hangs, please run the\n" 
+       "    To avoid having crashes misinterpreted as timeouts, please run the\n" 
        "    following commands:\n\n"
 
        "    SL=/System/Library; PL=com.apple.ReportCrash\n"
@@ -7185,7 +7266,7 @@
          "    between stumbling upon a crash and having this information relayed to the\n"
          "    fuzzer via the standard waitpid() API.\n\n"
 
-         "    To avoid having crashes misinterpreted as hangs, please log in as root\n" 
+         "    To avoid having crashes misinterpreted as timeouts, please log in as root\n" 
          "    and temporarily modify /proc/sys/kernel/core_pattern, like so:\n\n"
 
          "    echo core >/proc/sys/kernel/core_pattern\n");
@@ -7524,6 +7605,10 @@
   char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));
   u8 *tmp, *cp, *rsl, *own_copy;
 
+  /* Workaround for a QEMU stability glitch. */
+
+  setenv("QEMU_LOG", "nochain", 1);
+
   memcpy(new_argv + 3, argv + 1, sizeof(char*) * argc);
 
   new_argv[2] = target_path;
@@ -7831,7 +7916,14 @@
 
   if (getenv("AFL_NO_FORKSRV"))    no_forkserver    = 1;
   if (getenv("AFL_NO_CPU_RED"))    no_cpu_meter_red = 1;
+  if (getenv("AFL_NO_ARITH"))      no_arith         = 1;
   if (getenv("AFL_SHUFFLE_QUEUE")) shuffle_queue    = 1;
+  if (getenv("AFL_FAST_CAL"))      fast_cal         = 1;
+
+  if (getenv("AFL_HANG_TMOUT")) {
+    hang_tmout = atoi(getenv("AFL_HANG_TMOUT"));
+    if (!hang_tmout) FATAL("Invalid value of AFL_HANG_TMOUT");
+  }
 
   if (dumb_mode == 2 && no_forkserver)
     FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive");
diff --git a/third_party/afl/src/afl-gcc.c b/third_party/afl/src/afl-gcc.c
index fa3dec1a..a2b2324 100644
--- a/third_party/afl/src/afl-gcc.c
+++ b/third_party/afl/src/afl-gcc.c
@@ -287,6 +287,8 @@
     cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp";
     cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp";
     cc_params[cc_par_cnt++] = "-fno-builtin-memcmp";
+    cc_params[cc_par_cnt++] = "-fno-builtin-strstr";
+    cc_params[cc_par_cnt++] = "-fno-builtin-strcasestr";
 
   }
 
diff --git a/third_party/afl/src/afl-plot b/third_party/afl/src/afl-plot
index 3bd9359..25ffde64 100755
--- a/third_party/afl/src/afl-plot
+++ b/third_party/afl/src/afl-plot
@@ -38,16 +38,20 @@
 
 fi
 
-echo "$1" | grep -qE '^(/var)?/tmp/'
-T1="$?"
+if [ "$AFL_ALLOW_TMP" = "" ]; then
 
-echo "$2" | grep -qE '^(/var)?/tmp/'
-T2="$?"
+  echo "$1" | grep -qE '^(/var)?/tmp/'
+  T1="$?"
 
-if [ "$T1" = "0" -o "$T2" = "0" ]; then
+  echo "$2" | grep -qE '^(/var)?/tmp/'
+  T2="$?"
 
-  echo "[-] Error: this script shouldn't be used with shared /tmp directories." 1>&2
-  exit 1
+  if [ "$T1" = "0" -o "$T2" = "0" ]; then
+
+    echo "[-] Error: this script shouldn't be used with shared /tmp directories." 1>&2
+    exit 1
+
+  fi
 
 fi
 
diff --git a/third_party/afl/src/afl-showmap.c b/third_party/afl/src/afl-showmap.c
index 4b81862..df3f7cd 100644
--- a/third_party/afl/src/afl-showmap.c
+++ b/third_party/afl/src/afl-showmap.c
@@ -4,7 +4,7 @@
 
    Written and maintained by Michal Zalewski <lcamtuf@google.com>
 
-   Copyright 2013, 2014, 2015, 2016 Google Inc. All rights reserved.
+   Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -64,7 +64,8 @@
 static u8  quiet_mode,                /* Hide non-essential messages?      */
            edges_only,                /* Ignore hit counts?                */
            cmin_mode,                 /* Generate output in afl-cmin mode? */
-           binary_mode;               /* Write output as a binary map      */
+           binary_mode,               /* Write output as a binary map      */
+           keep_cores;                /* Allow coredumps?                  */
 
 static volatile u8
            stop_soon,                 /* Ctrl-C pressed?                   */
@@ -285,9 +286,15 @@
 
     }
 
-    r.rlim_max = r.rlim_cur = 0;
+    if (!keep_cores) r.rlim_max = r.rlim_cur = 0;
+    else r.rlim_max = r.rlim_cur = RLIM_INFINITY;
+
     setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
 
+    if (!getenv("LD_BIND_LAZY")) setenv("LD_BIND_NOW", "1", 0);
+
+    setsid();
+
     execv(target_path, argv);
 
     *(u32*)trace_bits = EXEC_FAIL_SIG;
@@ -479,7 +486,8 @@
        "Other settings:\n\n"
 
        "  -q            - sink program's output and don't show messages\n"
-       "  -e            - show edge coverage only, ignore hit counts\n\n"
+       "  -e            - show edge coverage only, ignore hit counts\n"
+       "  -c            - allow core dumps\n\n"
 
        "This tool displays raw tuple data captured by AFL instrumentation.\n"
        "For additional help, consult %s/README.\n\n" cRST,
@@ -551,6 +559,10 @@
   char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));
   u8 *tmp, *cp, *rsl, *own_copy;
 
+  /* Workaround for a QEMU stability glitch. */
+
+  setenv("QEMU_LOG", "nochain", 1);
+
   memcpy(new_argv + 3, argv + 1, sizeof(char*) * argc);
 
   new_argv[2] = target_path;
@@ -614,7 +626,7 @@
 
   doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
 
-  while ((opt = getopt(argc,argv,"+o:m:t:A:eqZQb")) > 0)
+  while ((opt = getopt(argc,argv,"+o:m:t:A:eqZQbc")) > 0)
 
     switch (opt) {
 
@@ -719,6 +731,12 @@
         binary_mode = 1;
         break;
 
+      case 'c':
+
+        if (keep_cores) FATAL("Multiple -c options not supported");
+        keep_cores = 1;
+        break;
+
       default:
 
         usage(argv[0]);
diff --git a/third_party/afl/src/afl-tmin.c b/third_party/afl/src/afl-tmin.c
index c1abbe7..a58c520 100644
--- a/third_party/afl/src/afl-tmin.c
+++ b/third_party/afl/src/afl-tmin.c
@@ -4,7 +4,7 @@
 
    Written and maintained by Michal Zalewski <lcamtuf@google.com>
 
-   Copyright 2015, 2016 Google Inc. All rights reserved.
+   Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -73,6 +73,7 @@
 static u8  crash_mode,                /* Crash-centric mode?               */
            exit_crash,                /* Treat non-zero exit as crash?     */
            edges_only,                /* Ignore hit counts?                */
+           exact_mode,                /* Require path match for crashes?   */
            use_stdin = 1;             /* Use stdin for program input?      */
 
 static volatile u8
@@ -157,7 +158,7 @@
 
 static void remove_shm(void) {
 
-  unlink(prog_in); /* Ignore errors */
+  if (prog_in) unlink(prog_in); /* Ignore errors */
   shmctl(shm_id, IPC_RMID, NULL);
 
 }
@@ -282,6 +283,8 @@
     close(dev_null_fd);
     close(prog_in_fd);
 
+    setsid();
+
     if (mem_limit) {
 
       r.rlim_max = r.rlim_cur = ((rlim_t)mem_limit) << 20;
@@ -338,8 +341,11 @@
   total_execs++;
 
   if (stop_soon) {
+
     SAYF(cRST cLRD "\n+++ Minimization aborted by user +++\n" cRST);
+    close(write_to_file(out_file, in_data, in_len));
     exit(1);
+
   }
 
   /* Always discard inputs that time out. */
@@ -361,7 +367,7 @@
 
     if (crash_mode) {
 
-      return 1;
+      if (!exact_mode) return 1;
 
     } else {
 
@@ -370,7 +376,7 @@
 
     }
 
-  }
+  } else
 
   /* Handle non-crashing inputs appropriately. */
 
@@ -670,15 +676,15 @@
 
     u8* use_dir = ".";
 
-    if (!access(use_dir, R_OK | W_OK | X_OK)) {
+    if (access(use_dir, R_OK | W_OK | X_OK)) {
 
       use_dir = getenv("TMPDIR");
       if (!use_dir) use_dir = "/tmp";
 
-      prog_in = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, getpid());
-
     }
 
+    prog_in = alloc_printf("%s/.afl-tmin-temp-%u", use_dir, getpid());
+
   }
 
   /* Set sane defaults... */
@@ -888,6 +894,10 @@
   char** new_argv = ck_alloc(sizeof(char*) * (argc + 4));
   u8 *tmp, *cp, *rsl, *own_copy;
 
+  /* Workaround for a QEMU stability glitch. */
+
+  setenv("QEMU_LOG", "nochain", 1);
+
   memcpy(new_argv + 3, argv + 1, sizeof(char*) * argc);
 
   /* Now we need to actually find qemu for argv[0]. */
@@ -1101,6 +1111,8 @@
   else
     use_argv = argv + optind;
 
+  exact_mode = !!getenv("AFL_TMIN_EXACT");
+
   SAYF("\n");
 
   read_initial_file();
@@ -1122,8 +1134,8 @@
 
   } else {
 
-     OKF("Program exits with a signal, minimizing in " cMGN "crash" cRST
-         " mode.");
+     OKF("Program exits with a signal, minimizing in " cMGN "%scrash" cRST
+         " mode.", exact_mode ? "EXACT " : "");
 
   }
 
@@ -1131,6 +1143,9 @@
 
   ACTF("Writing output to '%s'...", out_file);
 
+  unlink(prog_in);
+  prog_in = NULL;
+
   close(write_to_file(out_file, in_data, in_len));
 
   OKF("We're done here. Have a nice day!\n");
diff --git a/third_party/afl/src/config.h b/third_party/afl/src/config.h
index 2fdef50..e74b3b31 100644
--- a/third_party/afl/src/config.h
+++ b/third_party/afl/src/config.h
@@ -21,7 +21,7 @@
 
 /* Version string: */
 
-#define VERSION             "2.38b"
+#define VERSION             "2.52b"
 
 /******************************************************
  *                                                    *
@@ -38,7 +38,8 @@
 
 #define FANCY_BOXES
 
-/* Default timeout for fuzzed code (milliseconds): */
+/* Default timeout for fuzzed code (milliseconds). This is the upper bound,
+   also used for detecting hangs; the actual value is auto-scaled: */
 
 #define EXEC_TIMEOUT        1000
 
@@ -64,9 +65,9 @@
 #define CAL_CYCLES          8
 #define CAL_CYCLES_LONG     40
 
-/* Number of subsequent hangs before abandoning an input file: */
+/* Number of subsequent timeouts before abandoning an input file: */
 
-#define HANG_LIMIT          250
+#define TMOUT_LIMIT         250
 
 /* Maximum number of unique hangs or crashes to record: */
 
@@ -106,6 +107,10 @@
 #define HAVOC_BLK_MEDIUM    128
 #define HAVOC_BLK_LARGE     1500
 
+/* Extra-large blocks, selected very rarely (<5% of the time): */
+
+#define HAVOC_BLK_XL        32768
+
 /* Probabilities of skipping non-favored entries in the queue, expressed as
    percentages: */
 
diff --git a/third_party/afl/src/docs/ChangeLog b/third_party/afl/src/docs/ChangeLog
index 3eb01a7..a1b7da65 100644
--- a/third_party/afl/src/docs/ChangeLog
+++ b/third_party/afl/src/docs/ChangeLog
@@ -13,19 +13,166 @@
 sending a mail to <afl-users+subscribe@googlegroups.com>.
 
 Not sure if you should upgrade? The lowest currently recommended version
-is 2.31b. If you're stuck on an earlier release, it's strongly advisable
+is 2.41b. If you're stuck on an earlier release, it's strongly advisable
 to get on with the times.
 
---------------
-Version 2.38b:
---------------
+---------------------------
+Version 2.52b (2017-11-04):
+---------------------------
+
+  - Upgraded QEMU patches from 2.3.0 to 2.10.0. Required troubleshooting
+    several weird issues. All the legwork done by Andrew Griffiths.
+
+  - Added setsid to afl-showmap. See the notes for 2.51b.
+
+  - Added target mode (deferred, persistent, qemu, etc) to fuzzer_stats.
+    Requested by Jakub Wilk.
+
+  - afl-tmin should now save a partially minimized file when Ctrl-C
+    is pressed. Suggested by Jakub Wilk.
+
+  - Added an option for afl-analyze to dump offsets in hex. Suggested by
+    Jakub Wilk.
+
+  - Added support for parameters in triage_crashes.sh. Patch by Adam of
+    DC949.
+
+---------------------------
+Version 2.51b (2017-08-30):
+---------------------------
+
+  - Made afl-tmin call setsid to prevent glibc traceback junk from showing
+    up on the terminal in some distros. Suggested by Jakub Wilk.
+
+---------------------------
+Version 2.50b (2017-08-19):
+---------------------------
+
+  - Fixed an interesting timing corner case spotted by Jakub Wilk.
+
+  - Addressed a libtokencap / pthreads incompatibility issue. Likewise, spotted
+    by Jakub Wilk.
+
+  - Added a mention of afl-kit and Pythia.
+
+  - Added AFL_FAST_CAL.
+
+  - In-place resume now preserves .synced. Suggested by Jakub Wilk.
+
+---------------------------
+Version 2.49b (2017-07-18):
+---------------------------
+
+  - Added AFL_TMIN_EXACT to allow path constraint for crash minimization.
+
+  - Added dates for releases (retroactively for all of 2017).
+
+---------------------------
+Version 2.48b (2017-07-17):
+---------------------------
+
+  - Added AFL_ALLOW_TMP to permit some scripts to run in /tmp.
+
+  - Fixed cwd handling in afl-analyze (similar to the quirk in afl-tmin).
+
+  - Made it possible to point -o and -f to the same file in afl-tmin.
+
+---------------------------
+Version 2.47b (2017-07-14):
+---------------------------
+
+  - Fixed cwd handling in afl-tmin. Spotted by Jakub Wilk.
+
+---------------------------
+Version 2.46b (2017-07-10):
+---------------------------
+
+  - libdislocator now supports AFL_LD_NO_CALLOC_OVER for folks who do not
+    want to abort on calloc() overflows.
+
+  - Made a minor fix to libtokencap. Reported by Daniel Stender.
+
+  - Added a small JSON dictionary, inspired on a dictionary done by Jakub Wilk.
+
+---------------------------
+Version 2.45b (2017-07-04):
+---------------------------
+
+  - Added strstr, strcasestr support to libtokencap. Contributed by
+    Daniel Hodson.
+
+  - Fixed a resumption offset glitch spotted by Jakub Wilk.
+
+  - There are definitely no bugs in afl-showmap -c now.
+
+---------------------------
+Version 2.44b (2017-06-28):
+---------------------------
+
+  - Added a visual indicator of ASAN / MSAN mode when compiling. Requested
+    by Jakub Wilk.
+
+  - Added support for afl-showmap coredumps (-c). Suggested by Jakub Wilk.
+
+  - Added LD_BIND_NOW=1 for afl-showmap by default. Although not really useful,
+    it reportedly helps reproduce some crashes. Suggested by Jakub Wilk.
+
+  - Added a note about allocator_may_return_null=1 not always working with
+    ASAN. Spotted by Jakub Wilk.
+
+---------------------------
+Version 2.43b (2017-06-16):
+---------------------------
+
+  - Added AFL_NO_ARITH to aid in the fuzzing of text-based formats.
+    Requested by Jakub Wilk.
+
+---------------------------
+Version 2.42b (2017-06-02):
+---------------------------
+
+  - Renamed the R() macro to avoid a problem with llvm_mode in the latest
+    versions of LLVM. Fix suggested by Christian Holler.
+
+---------------------------
+Version 2.41b (2017-04-12):
+---------------------------
+
+  - Addressed a major user complaint related to timeout detection. Timing out
+    inputs are now binned as "hangs" only if they exceed a far more generous
+    time limit than the one used to reject slow paths.
+
+---------------------------
+Version 2.40b (2017-04-02):
+---------------------------
+
+  - Fixed a minor oversight in the insertion strategy for dictionary words.
+    Spotted by Andrzej Jackowski.
+
+  - Made a small improvement to the havoc block insertion strategy.
+
+  - Adjusted color rules for "is it done yet?" indicators.
+
+---------------------------
+Version 2.39b (2017-02-02):
+---------------------------
+
+  - Improved error reporting in afl-cmin. Suggested by floyd.
+
+  - Made a minor tweak to trace-pc-guard support. Suggested by kcc.
+
+  - Added a mention of afl-monitor.
+
+---------------------------
+Version 2.38b (2017-01-22):
+---------------------------
 
   - Added -mllvm -sanitizer-coverage-block-threshold=0 to trace-pc-guard
     mode, as suggested by Kostya Serebryany.
 
---------------
-Version 2.37b:
---------------
+---------------------------
+Version 2.37b (2017-01-22):
+---------------------------
 
   - Fixed a typo. Spotted by Jakub Wilk.
 
@@ -39,9 +186,9 @@
     Note that for some reason, this mode doesn't perform as well as
     "vanilla" afl-clang-fast / afl-clang.
 
---------------
-Version 2.36b:
---------------
+---------------------------
+Version 2.36b (2017-01-14):
+---------------------------
 
   - Fixed a cosmetic bad free() bug when aborting -S sessions. Spotted
     by Johannes S.
@@ -61,7 +208,7 @@
     are unique to the input file, but not to the "boring" baseline.
     Suggested by Sami Liedes.
 
-  - "Fixed" a getPassName() problem with never versions of clang.
+  - "Fixed" a getPassName() problem with newer versions of clang.
     Reported by Craig Young and several other folks.
 
   Yep, I know I have a backlog on several other feature requests.
@@ -2534,8 +2681,8 @@
 
   - Fixed the handling of gcc -pipe, thanks to anonymous reporter.
 
---------------
-Version 0.21b:
---------------
+---------------------------
+Version 0.21b (2013-11-12):
+---------------------------
 
   - Initial public release.
diff --git a/third_party/afl/src/docs/INSTALL b/third_party/afl/src/docs/INSTALL
index 4168e88f..2e24724 100644
--- a/third_party/afl/src/docs/INSTALL
+++ b/third_party/afl/src/docs/INSTALL
@@ -140,7 +140,7 @@
 Do *not* specify --with-as=/usr/gnu/bin/as - this will produce a GCC binary that
 ignores the -B flag and you will be back to square one.
 
-Note that Solaris reportedly comes withe crash reporting enabled, which causes
+Note that Solaris reportedly comes with crash reporting enabled, which causes
 problems with crashes being misinterpreted as hangs, similarly to the gotchas
 for Linux and MacOS X. AFL does not auto-detect crash reporting on this
 particular platform, but you may need to run the following command:
diff --git a/third_party/afl/src/docs/README b/third_party/afl/src/docs/README
index 501bdd4..ac49599 100644
--- a/third_party/afl/src/docs/README
+++ b/third_party/afl/src/docs/README
@@ -220,10 +220,11 @@
                fatal signal (e.g., SIGSEGV, SIGILL, SIGABRT). The entries are 
                grouped by the received signal.
 
-  - hangs/   - unique test cases that cause the tested program to time out. Note
-               that when default (aggressive) timeout settings are in effect,
-               this can be slightly noisy due to latency spikes and other
-               natural phenomena.
+  - hangs/   - unique test cases that cause the tested program to time out. The
+               default time limit before something is classified as a hang is
+               the larger of 1 second and the value of the -t parameter.
+               The value can be fine-tuned by setting AFL_HANG_TMOUT, but this
+               is rarely necessary.
 
 Crashes and hangs are considered "unique" if the associated execution paths
 involve any state transitions not seen in previously-recorded faults. If a
@@ -307,7 +308,7 @@
 queue, making it easier to diagnose faults.
 
 Having said that, it's important to acknowledge that some fuzzing crashes can be
-difficult quickly evaluate for exploitability without a lot of debugging and
+difficult to quickly evaluate for exploitability without a lot of debugging and
 code analysis work. To assist with this task, afl-fuzz supports a very unique
 "crash exploration" mode enabled with the -C flag.
 
@@ -481,6 +482,7 @@
   Joshua J. Drake                       Toby Hutton
   Rene Freingruber                      Sergey Davidoff
   Sami Liedes                           Craig Young
+  Andrzej Jackowski                     Daniel Hodson
 
 Thank you!
 
diff --git a/third_party/afl/src/docs/env_variables.txt b/third_party/afl/src/docs/env_variables.txt
index a91b43a..71f72af3 100644
--- a/third_party/afl/src/docs/env_variables.txt
+++ b/third_party/afl/src/docs/env_variables.txt
@@ -116,6 +116,16 @@
     intermittently, but it's not really recommended under normal operating
     conditions.
 
+  - Setting AFL_HANG_TMOUT allows you to specify a different timeout for
+    deciding if a particular test case is a "hang". The default is 1 second
+    or the value of the -t parameter, whichever is larger. Dialing the value
+    down can be useful if you are very concerned about slow inputs, or if you
+    don't want AFL to spend too much time classifying that stuff and just 
+    rapidly put all timeouts in that bin.
+
+  - AFL_NO_ARITH causes AFL to skip most of the deterministic arithmetics.
+    This can be useful to speed up the fuzzing of text-based file formats.
+
   - AFL_SHUFFLE_QUEUE randomly reorders the input queue on startup. Requested
     by some users for unorthodox parallelized fuzzing setups, but not
     advisable otherwise.
@@ -135,6 +145,9 @@
     mutated files - say, to fix up checksums. See experimental/post_library/
     for more.
 
+  - AFL_FAST_CAL keeps the calibration stage about 2.5x faster (albeit less
+    precise), which can help when starting a session against a slow target.
+
   - The CPU widget shown at the bottom of the screen is fairly simplistic and
     may complain of high load prematurely, especially on systems with low core
     counts. To avoid the alarming red color, you can set AFL_NO_CPU_RED.
@@ -184,6 +197,10 @@
     minimization and normally deleted at exit. The files can be found in the
     <out_dir>/.traces/*.
 
+  - AFL_ALLOW_TMP permits this and some other scripts to run in /tmp. This is
+    a modest security risk on multi-user systems with rogue users, but should
+    be safe on dedicated fuzzing boxes.
+
 6) Settings for afl-tmin
 ------------------------
 
@@ -191,7 +208,18 @@
 searched for afl-qemu-trace. In addition to this, TMPDIR may be used if a
 temporary file can't be created in the current working directory.
 
-7) Settings for libdislocator.so
+You can specify AFL_TMIN_EXACT if you want afl-tmin to require execution paths
+to match when minimizing crashes. This will make minimization less useful, but
+may prevent the tool from "jumping" from one crashing condition to another in
+very buggy software. You probably want to combine it with the -e flag.
+
+7) Settings for afl-analyze
+---------------------------
+
+You can set AFL_ANALYZE_HEX to get file offsets printed as hexadecimal instead
+of decimal.
+
+8) Settings for libdislocator.so
 --------------------------------
 
 The library honors three environmental variables:
@@ -207,14 +235,18 @@
   - AFL_LD_VERBOSE causes the library to output some diagnostic messages
     that may be useful for pinpointing the cause of any observed issues.
 
-8) Settings for libtokencap.so
+  - AFL_LD_NO_CALLOC_OVER inhibits abort() on calloc() overflows. Most
+    of the common allocators check for that internally and return NULL, so
+    it's a security risk only in more exotic setups.
+
+9) Settings for libtokencap.so
 ------------------------------
 
 This library accepts AFL_TOKEN_FILE to indicate the location to which the
 discovered tokens should be written.
 
-9) Third-party variables set by afl-fuzz & other tools
-------------------------------------------------------
+10) Third-party variables set by afl-fuzz & other tools
+-------------------------------------------------------
 
 Several variables are not directly interpreted by afl-fuzz, but are set to
 optimal values if not already present in the environment:
diff --git a/third_party/afl/src/docs/notes_for_asan.txt b/third_party/afl/src/docs/notes_for_asan.txt
index dff89ba..972ca90 100644
--- a/third_party/afl/src/docs/notes_for_asan.txt
+++ b/third_party/afl/src/docs/notes_for_asan.txt
@@ -113,7 +113,23 @@
 seem to appreciate the shadow VM trick used by these tools, and will likely
 just allocate all your physical memory, then crash.
 
-4) What about UBSAN?
+4) ASAN and OOM crashes
+-----------------------
+
+By default, ASAN treats memory allocation failures as fatal errors, immediately
+causing the program to crash. Since this is a departure from normal POSIX
+semantics (and creates the appearance of security issues in otherwise
+properly-behaving programs), we try to disable this by specifying 
+allocator_may_return_null=1 in ASAN_OPTIONS.
+
+Unfortunately, it's been reported that this setting still causes ASAN to
+trigger phantom crashes in situations where the standard allocator would
+simply return NULL. If this is interfering with your fuzzing jobs, you may
+want to cc: yourself on this bug:
+
+  https://bugs.llvm.org/show_bug.cgi?id=22026
+
+5) What about UBSAN?
 --------------------
 
 Some folks expressed interest in fuzzing with UBSAN. This isn't officially
diff --git a/third_party/afl/src/docs/perf_tips.txt b/third_party/afl/src/docs/perf_tips.txt
index 3a8997a..6906d5a 100644
--- a/third_party/afl/src/docs/perf_tips.txt
+++ b/third_party/afl/src/docs/perf_tips.txt
@@ -94,7 +94,11 @@
 when it decides that the input file is a compressed archive.
 
 Some programs may also intentionally call sleep(), usleep(), or nanosleep();
-vim is a good example of that.
+vim is a good example of that. Other programs may attempt fsync() and so on.
+There are third-party libraries that make it easy to get rid of such code,
+e.g.:
+
+  https://launchpad.net/libeatmydata
 
 In programs that are slow due to unavoidable initialization overhead, you may
 want to try the LLVM deferred forkserver mode (see llvm_mode/README.llvm),
diff --git a/third_party/afl/src/docs/sister_projects.txt b/third_party/afl/src/docs/sister_projects.txt
index 1434e37..41701e2 100644
--- a/third_party/afl/src/docs/sister_projects.txt
+++ b/third_party/afl/src/docs/sister_projects.txt
@@ -85,6 +85,10 @@
 
   https://github.com/ivanfratric/winafl
 
+  Another Windows alternative may be:
+
+  https://github.com/carlosgprado/BrundleFuzz/
+
 ----------------
 Network fuzzing:
 ----------------
@@ -120,6 +124,13 @@
 
   https://github.com/MartijnB/disfuzz-afl
 
+AFLDFF (quantumvm)
+------------------
+
+  A nice GUI for managing AFL jobs.
+
+  https://github.com/quantumvm/AFLDFF
+
 afl-launch (Ben Nagy)
 ---------------------
 
@@ -134,6 +145,10 @@
 
   https://github.com/rc0r/afl-utils
 
+  Another crash triage tool:
+
+  https://github.com/floyd-fuh/afl-crash-analyzer
+
 afl-fuzzing-scripts (Tobias Ospelt)
 -----------------------------------
 
@@ -148,6 +163,17 @@
 
   https://github.com/d33tah/afl-sid
 
+  Another Docker-related project:
+
+  https://github.com/ozzyjohnson/docker-afl
+
+afl-monitor (Paul S. Ziegler)
+-----------------------------
+
+  Provides more detailed and versatile statistics about your running AFL jobs.
+
+  https://github.com/reflare/afl-monitor
+
 -----------------------------------------------------------
 Crash triage, coverage analysis, and other companion tools:
 -----------------------------------------------------------
@@ -202,6 +228,14 @@
 
   https://github.com/MarkusTeufelberger/afl-ddmin-mod
 
+afl-kit (Kuang-che Wu)
+----------------------
+
+  Replacements for afl-cmin and afl-tmin with additional features, such
+  as the ability to filter crashes based on stderr patterns.
+
+  https://github.com/kcwu/afl-kit
+
 -------------------------------
 Narrow-purpose or experimental:
 -------------------------------
@@ -219,7 +253,7 @@
 
   Simple automation to suspend and resume groups of fuzzing jobs.
 
-  https://gist.github.com/bnagy/8f0eb29eb125653f73fd
+  https://github.com/bnagy/afl-trivia
 
 Static binary-only instrumentation (Aleksandar Nikolich)
 --------------------------------------------------------
@@ -296,3 +330,25 @@
   https://github.com/google/syzkaller/wiki/Found-Bugs
   https://github.com/dvyukov/linux/commit/33787098ffaaa83b8a7ccf519913ac5fd6125931
   http://events.linuxfoundation.org/sites/events/files/slides/AFL%20filesystem%20fuzzing%2C%20Vault%202016_0.pdf
+
+Android support (ele7enxxh)
+---------------------------
+
+  Based on a somewhat dated version of AFL:
+
+  https://github.com/ele7enxxh/android-afl
+
+CGI wrapper (floyd)
+-------------------
+
+  Facilitates the testing of CGI scripts.
+
+  https://github.com/floyd-fuh/afl-cgi-wrapper
+
+Fuzzing difficulty estimation (Marcel Boehme)
+---------------------------------------------
+
+  A fork of AFL that tries to quantify the likelihood of finding additional
+  paths or crashes at any point in a fuzzing job.
+
+  https://github.com/mboehme/pythia
diff --git a/third_party/afl/src/docs/status_screen.txt b/third_party/afl/src/docs/status_screen.txt
index ac09804..d4c37df1 100644
--- a/third_party/afl/src/docs/status_screen.txt
+++ b/third_party/afl/src/docs/status_screen.txt
@@ -231,7 +231,7 @@
   | favored paths : 879 (41.96%)         |
   |  new edges on : 423 (20.19%)         |
   | total crashes : 0 (0 unique)         |
-  |   total hangs : 24 (19 unique)       |
+  |  total tmouts : 24 (19 unique)       |
   +--------------------------------------+
 
 This gives you several metrics that are of interest mostly to complete nerds.
@@ -239,7 +239,11 @@
 on a minimization algorithm baked into the code (these will get considerably
 more air time), and the number of test cases that actually resulted in better
 edge coverage (versus just pushing the branch hit counters up). There are also
-additional, more detailed counters for crashes and hangs.
+additional, more detailed counters for crashes and timeouts.
+
+Note that the timeout counter is somewhat different from the hang counter; this
+one includes all test cases that exceeded the timeout, even if they did not
+exceed it by a margin sufficient to be classified as hangs.
 
 7) Fuzzing strategy yields
 --------------------------
@@ -293,7 +297,8 @@
 
 Next, we have the number of new paths found during this fuzzing section and
 imported from other fuzzer instances when doing parallelized fuzzing; and the
-number of inputs that produce seemingly variable behavior in the tested binary.
+extent to which identical inputs appear to sometimes produce variable behavior
+in the tested binary.
 
 That last bit is actually fairly interesting: it measures the consistency of
 observed traces. If a program always behaves the same for the same input data,
diff --git a/third_party/afl/src/experimental/crash_triage/triage_crashes.sh b/third_party/afl/src/experimental/crash_triage/triage_crashes.sh
index 9dddefd..5894a4d 100755
--- a/third_party/afl/src/experimental/crash_triage/triage_crashes.sh
+++ b/third_party/afl/src/experimental/crash_triage/triage_crashes.sh
@@ -5,7 +5,7 @@
 #
 # Written and maintained by Michal Zalewski <lcamtuf@google.com>
 #
-# Copyright 2013, 2014 Google Inc. All rights reserved.
+# Copyright 2013, 2014, 2017 Google Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -28,30 +28,34 @@
 ulimit -v 100000 2>/dev/null
 ulimit -d 100000 2>/dev/null
 
-if [ ! "$#" = "2" ]; then
-  echo "Usage: $0 /path/to/afl_output_dir /path/to/tested_binary" 1>&2
-  echo 1>&2
-  echo "Note: the tested binary must accept input on stdin and require no additional" 1>&2
-  echo "parameters. For more complex use cases, you need to edit this script." 1>&2
+if [ "$#" -lt "2" ]; then
+  echo "Usage: $0 /path/to/afl_output_dir /path/to/tested_binary [...target params...]" 1>&2
   echo 1>&2
   exit 1
 fi
 
 DIR="$1"
 BIN="$2"
+shift
+shift
 
-echo "$DIR" | grep -qE '^(/var)?/tmp/'
-T1="$?"
+if [ "$AFL_ALLOW_TMP" = "" ]; then
 
-echo "$BIN" | grep -qE '^(/var)?/tmp/'
-T2="$?"
+  echo "$DIR" | grep -qE '^(/var)?/tmp/'
+  T1="$?"
 
-if [ "$T1" = "0" -o "$T2" = "0" ]; then
-  echo "[-] Error: do not use shared /tmp or /var/tmp directories with this script." 1>&2
-  exit 1
+  echo "$BIN" | grep -qE '^(/var)?/tmp/'
+  T2="$?"
+
+  if [ "$T1" = "0" -o "$T2" = "0" ]; then
+    echo "[-] Error: do not use shared /tmp or /var/tmp directories with this script." 1>&2
+    exit 1
+  fi
+
 fi
 
-if [ "$GDB" = "" ]; then
+if
+ [ "$GDB" = "" ]; then
   GDB=gdb
 fi
 
@@ -79,11 +83,33 @@
   id=`basename -- "$crash" | cut -d, -f1 | cut -d: -f2`
   sig=`basename -- "$crash" | cut -d, -f2 | cut -d: -f2`
 
+  # Grab the args, converting @@ to $crash
+
+  use_args=""
+  use_stdio=1
+
+  for a in $@; do
+
+    if [ "$a" = "@@" ] ; then
+      args="$use_args $crash"
+      unset use_stdio
+    else
+      args="$use_args $a"
+    fi
+
+  done
+
+  # Strip the trailing space
+  use_args="${use_args# }"
+
   echo "+++ ID $id, SIGNAL $sig +++"
   echo
 
-  $GDB --batch -q --ex "r <$crash" --ex 'back' --ex 'disass $pc, $pc+16' --ex 'info reg' --ex 'quit' "$BIN" 0</dev/null
+  if [ "$use_stdio" = "1" ]; then  
+    $GDB --batch -q --ex "r $use_args <$crash" --ex 'back' --ex 'disass $pc, $pc+16' --ex 'info reg' --ex 'quit' "$BIN" 0</dev/null
+  else
+    $GDB --batch -q --ex "r $use_args" --ex 'back' --ex 'disass $pc, $pc+16' --ex 'info reg' --ex 'quit' "$BIN" 0</dev/null
+  fi
   echo
 
 done
-
diff --git a/third_party/afl/src/experimental/distributed_fuzzing/sync_script.sh b/third_party/afl/src/experimental/distributed_fuzzing/sync_script.sh
index 29bcba6..2d5e063 100755
--- a/third_party/afl/src/experimental/distributed_fuzzing/sync_script.sh
+++ b/third_party/afl/src/experimental/distributed_fuzzing/sync_script.sh
@@ -41,9 +41,13 @@
 # Interval (seconds) between sync attempts
 SYNC_INTERVAL=$((30 * 60))
 
-if [ "$PWD" = "/tmp" -o "$PWD" = "/var/tmp" ]; then
-  echo "[-] Error: do not use shared /tmp or /var/tmp directories with this script." 1>&2
-  exit 1
+if [ "$AFL_ALLOW_TMP" = "" ]; then
+
+  if [ "$PWD" = "/tmp" -o "$PWD" = "/var/tmp" ]; then
+    echo "[-] Error: do not use shared /tmp or /var/tmp directories with this script." 1>&2
+    exit 1
+  fi
+
 fi
 
 rm -rf .sync_tmp 2>/dev/null
diff --git a/third_party/afl/src/libdislocator/libdislocator.so.c b/third_party/afl/src/libdislocator/libdislocator.so.c
index 0dfc98e..043480a 100644
--- a/third_party/afl/src/libdislocator/libdislocator.so.c
+++ b/third_party/afl/src/libdislocator/libdislocator.so.c
@@ -73,7 +73,8 @@
 
 static u32 max_mem = MAX_ALLOC;         /* Max heap usage to permit         */
 static u8  alloc_verbose,               /* Additional debug messages        */
-           hard_fail;                   /* abort() when max_mem exceeded?   */
+           hard_fail,                   /* abort() when max_mem exceeded?   */
+           no_calloc_over;              /* abort() on calloc() overflows?   */
 
 static __thread size_t total_mem;       /* Currently allocated mem          */
 
@@ -153,9 +154,17 @@
 
   /* Perform some sanity checks to detect obvious issues... */
 
-  if (elem_cnt && len / elem_cnt != elem_len)
+  if (elem_cnt && len / elem_cnt != elem_len) {
+
+    if (no_calloc_over) {
+      DEBUGF("calloc(%zu, %zu) would overflow, returning NULL", elem_len, elem_cnt);
+      return NULL;
+    }
+
     FATAL("calloc(%zu, %zu) would overflow", elem_len, elem_cnt);
 
+  }
+
   ret = __dislocator_alloc(len);
 
   DEBUGF("calloc(%zu, %zu) = %p [%zu total]", elem_len, elem_cnt, ret,
@@ -254,5 +263,6 @@
 
   alloc_verbose = !!getenv("AFL_LD_VERBOSE");
   hard_fail = !!getenv("AFL_LD_HARD_FAIL");
+  no_calloc_over = !!getenv("AFL_LD_NO_CALLOC_OVER");
 
 }
diff --git a/third_party/afl/src/libtokencap/README.tokencap b/third_party/afl/src/libtokencap/README.tokencap
index 82d80c95..650739f 100644
--- a/third_party/afl/src/libtokencap/README.tokencap
+++ b/third_party/afl/src/libtokencap/README.tokencap
@@ -32,7 +32,8 @@
 when using afl-gcc. This setting specifically adds the following flags:
 
   -fno-builtin-strcmp -fno-builtin-strncmp -fno-builtin-strcasecmp
-  -fno-builtin-strcasencmp -fno-builtin-memcmp
+  -fno-builtin-strcasencmp -fno-builtin-memcmp -fno-builtin-strstr
+  -fno-builtin-strcasestr
 
 The next step is simply loading this library via LD_PRELOAD. The optimal usage
 pattern is to allow afl-fuzz to fuzz normally for a while and build up a corpus,
diff --git a/third_party/afl/src/libtokencap/libtokencap.so.c b/third_party/afl/src/libtokencap/libtokencap.so.c
index 696c913..5407227 100644
--- a/third_party/afl/src/libtokencap/libtokencap.so.c
+++ b/third_party/afl/src/libtokencap/libtokencap.so.c
@@ -102,7 +102,8 @@
   u32 i;
   u32 pos = 0;
 
-  if (len < MIN_AUTO_EXTRA || len > MAX_AUTO_EXTRA) return;
+  if (len < MIN_AUTO_EXTRA || len > MAX_AUTO_EXTRA || !__tokencap_out_file)
+    return;
 
   for (i = 0; i < len; i++) {
 
@@ -241,6 +242,57 @@
 }
 
 
+#undef strstr
+
+char* strstr(const char* haystack, const char* needle) {
+
+  if (__tokencap_is_ro(haystack))
+    __tokencap_dump(haystack, strlen(haystack), 1);
+
+  if (__tokencap_is_ro(needle))
+    __tokencap_dump(needle, strlen(needle), 1);
+
+  do {
+    const char* n = needle;
+    const char* h = haystack;
+
+    while(*n && *h && *n == *h) n++, h++;
+
+    if(!*n) return (char*)haystack;
+
+  } while (*(haystack++));
+
+  return 0;
+
+}
+
+
+#undef strcasestr
+
+char* strcasestr(const char* haystack, const char* needle) {
+
+  if (__tokencap_is_ro(haystack))
+    __tokencap_dump(haystack, strlen(haystack), 1);
+
+  if (__tokencap_is_ro(needle))
+    __tokencap_dump(needle, strlen(needle), 1);
+
+  do {
+
+    const char* n = needle;
+    const char* h = haystack;
+
+    while(*n && *h && tolower(*n) == tolower(*h)) n++, h++;
+
+    if(!*n) return (char*)haystack;
+
+  } while(*(haystack++));
+
+  return 0;
+
+}
+
+
 /* Init code to open the output file (or default to stderr). */
 
 __attribute__((constructor)) void __tokencap_init(void) {
diff --git a/third_party/afl/src/llvm_mode/README.llvm b/third_party/afl/src/llvm_mode/README.llvm
index d96d8c31..349d0e2 100644
--- a/third_party/afl/src/llvm_mode/README.llvm
+++ b/third_party/afl/src/llvm_mode/README.llvm
@@ -182,7 +182,9 @@
 
   AFL_TRACE_PC=1 make clean all
 
-Note that this mode is currently about 20-30% slower than "vanilla"
-afl-clang-fast, and about 5-10% slower than afl-clang. I am not entirely sure
-why.
+Note that this mode is currently about 20% slower than "vanilla" afl-clang-fast,
+and about 5-10% slower than afl-clang. This is likely because the
+instrumentation is not inlined, and instead involves a function call. On systems
+that support it, compiling your target with -flto should help.
+
 
diff --git a/third_party/afl/src/llvm_mode/afl-clang-fast.c b/third_party/afl/src/llvm_mode/afl-clang-fast.c
index 4f7fe475..d4202a63 100644
--- a/third_party/afl/src/llvm_mode/afl-clang-fast.c
+++ b/third_party/afl/src/llvm_mode/afl-clang-fast.c
@@ -315,7 +315,11 @@
 
   if (isatty(2) && !getenv("AFL_QUIET")) {
 
+#ifdef USE_TRACE_PC
+    SAYF(cCYA "afl-clang-fast [tpcg] " cBRI VERSION  cRST " by <lszekeres@google.com>\n");
+#else
     SAYF(cCYA "afl-clang-fast " cBRI VERSION  cRST " by <lszekeres@google.com>\n");
+#endif /* ^USE_TRACE_PC */
 
   }
 
diff --git a/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c b/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c
index 905c76f..ed3a664 100644
--- a/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c
+++ b/third_party/afl/src/llvm_mode/afl-llvm-rt.o.c
@@ -278,6 +278,8 @@
   u32 inst_ratio = 100;
   u8* x;
 
+  if (start == stop || *start) return;
+
   x = getenv("AFL_INST_RATIO");
   if (x) inst_ratio = atoi(x);
 
@@ -286,6 +288,12 @@
     abort();
   }
 
+  /* Make sure that the first element in the range is always set - we use that
+     to avoid duplicate calls (which can happen as an artifact of the underlying
+     implementation in LLVM). */
+
+  *(start++) = R(MAP_SIZE - 1) + 1;
+
   while (start < stop) {
 
     if (R(100) < inst_ratio) *start = R(MAP_SIZE - 1) + 1;
diff --git a/third_party/afl/src/qemu_mode/README.qemu b/third_party/afl/src/qemu_mode/README.qemu
index f9dce99..cf29088 100644
--- a/third_party/afl/src/qemu_mode/README.qemu
+++ b/third_party/afl/src/qemu_mode/README.qemu
@@ -21,7 +21,7 @@
 2) How to use
 -------------
 
-The feature is implemented with a fairly simple patch to QEMU 2.3.0. The
+The feature is implemented with a fairly simple patch to QEMU 2.10.0. The
 simplest way to build it is to run ./build_qemu_support.sh. The script will
 download, configure, and compile the QEMU binary for you.
 
diff --git a/third_party/afl/src/qemu_mode/build_qemu_support.sh b/third_party/afl/src/qemu_mode/build_qemu_support.sh
index 7224671..827c93d7 100755
--- a/third_party/afl/src/qemu_mode/build_qemu_support.sh
+++ b/third_party/afl/src/qemu_mode/build_qemu_support.sh
@@ -6,7 +6,7 @@
 # Written by Andrew Griffiths <agriffiths@google.com> and
 #            Michal Zalewski <lcamtuf@google.com>
 #
-# Copyright 2015, 2016 Google Inc. All rights reserved.
+# Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -22,8 +22,10 @@
 # will be written to ../afl-qemu-trace.
 #
 
-QEMU_URL="http://wiki.qemu-project.org/download/qemu-2.3.0.tar.bz2"
-QEMU_SHA384="7a0f0c900f7e2048463cc32ff3e904965ab466c8428847400a0f2dcfe458108a68012c4fddb2a7e7c822b4fd1a49639b"
+
+VERSION="2.10.0"
+QEMU_URL="http://download.qemu-project.org/qemu-${VERSION}.tar.xz"
+QEMU_SHA384="68216c935487bc8c0596ac309e1e3ee75c2c4ce898aab796faa321db5740609ced365fedda025678d072d09ac8928105"
 
 echo "================================================="
 echo "AFL binary-only instrumentation QEMU build script"
@@ -89,7 +91,7 @@
 
 if [ ! "$CKSUM" = "$QEMU_SHA384" ]; then
 
-  echo "[*] Downloading QEMU 2.3.0 from the web..."
+  echo "[*] Downloading QEMU ${VERSION} from the web..."
   rm -f "$ARCHIVE"
   wget -O "$ARCHIVE" -- "$QEMU_URL" || exit 1
 
@@ -110,32 +112,34 @@
 
 echo "[*] Uncompressing archive (this will take a while)..."
 
-rm -rf "qemu-2.3.0" || exit 1
+rm -rf "qemu-${VERSION}" || exit 1
 tar xf "$ARCHIVE" || exit 1
 
 echo "[+] Unpacking successful."
 
-echo "[*] Applying patches..."
-
-patch -p0 <patches/elfload.diff || exit 1
-patch -p0 <patches/cpu-exec.diff || exit 1
-patch -p0 <patches/translate-all.diff || exit 1
-patch -p0 <patches/syscall.diff || exit 1
-
-echo "[+] Patching done."
+echo "[*] Configuring QEMU for $CPU_TARGET..."
 
 ORIG_CPU_TARGET="$CPU_TARGET"
 
 test "$CPU_TARGET" = "" && CPU_TARGET="`uname -m`"
 test "$CPU_TARGET" = "i686" && CPU_TARGET="i386"
 
-echo "[*] Configuring QEMU for $CPU_TARGET..."
+cd qemu-$VERSION || exit 1
 
-cd qemu-2.3.0 || exit 1
+echo "[*] Applying patches..."
 
-CFLAGS="-O3" ./configure --disable-system --enable-linux-user \
-  --enable-guest-base --disable-gtk --disable-sdl --disable-vnc \
-  --target-list="${CPU_TARGET}-linux-user" || exit 1
+patch -p1 <../patches/elfload.diff || exit 1
+patch -p1 <../patches/cpu-exec.diff || exit 1
+patch -p1 <../patches/syscall.diff || exit 1
+
+echo "[+] Patching done."
+
+# --enable-pie seems to give a couple of exec's a second performance
+# improvement, much to my surprise. Not sure how universal this is..
+
+CFLAGS="-O3 -ggdb" ./configure --disable-system \
+  --enable-linux-user --disable-gtk --disable-sdl --disable-vnc \
+  --target-list="${CPU_TARGET}-linux-user" --enable-pie --enable-kvm || exit 1
 
 echo "[+] Configuration complete."
 
diff --git a/third_party/afl/src/qemu_mode/patches/afl-qemu-cpu-inl.h b/third_party/afl/src/qemu_mode/patches/afl-qemu-cpu-inl.h
index eaa0e67..8d3133a 100644
--- a/third_party/afl/src/qemu_mode/patches/afl-qemu-cpu-inl.h
+++ b/third_party/afl/src/qemu_mode/patches/afl-qemu-cpu-inl.h
@@ -7,7 +7,7 @@
 
    Idea & design very much by Andrew Griffiths.
 
-   Copyright 2015, 2016 Google Inc. All rights reserved.
+   Copyright 2015, 2016, 2017 Google Inc. All rights reserved.
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
      http://www.apache.org/licenses/LICENSE-2.0
 
    This code is a shim patched into the separately-distributed source
-   code of QEMU 2.2.0. It leverages the built-in QEMU tracing functionality
+   code of QEMU 2.10.0. It leverages the built-in QEMU tracing functionality
    to implement AFL-style instrumentation and to take care of the remaining
    parts of the AFL fork server logic.
 
@@ -47,11 +47,11 @@
    regular instrumentation injected via afl-as.h. */
 
 #define AFL_QEMU_CPU_SNIPPET2 do { \
-    if(tb->pc == afl_entry_point) { \
+    if(itb->pc == afl_entry_point) { \
       afl_setup(); \
-      afl_forkserver(env); \
+      afl_forkserver(cpu); \
     } \
-    afl_maybe_log(tb->pc); \
+    afl_maybe_log(itb->pc); \
   } while (0)
 
 /* We use one additional file descriptor to relay "needs translation"
@@ -81,16 +81,12 @@
 /* Function declarations. */
 
 static void afl_setup(void);
-static void afl_forkserver(CPUArchState*);
+static void afl_forkserver(CPUState*);
 static inline void afl_maybe_log(abi_ulong);
 
-static void afl_wait_tsl(CPUArchState*, int);
+static void afl_wait_tsl(CPUState*, int);
 static void afl_request_tsl(target_ulong, target_ulong, uint64_t);
 
-static TranslationBlock *tb_find_slow(CPUArchState*, target_ulong,
-                                      target_ulong, uint64_t);
-
-
 /* Data structure passed around by the translate handlers: */
 
 struct afl_tsl {
@@ -99,12 +95,15 @@
   uint64_t flags;
 };
 
+/* Some forward decls: */
+
+TranslationBlock *tb_htable_lookup(CPUState*, target_ulong, target_ulong, uint32_t);
+static inline TranslationBlock *tb_find(CPUState*, TranslationBlock*, int);
 
 /*************************
  * ACTUAL IMPLEMENTATION *
  *************************/
 
-
 /* Set up SHM region and initialize other stuff. */
 
 static void afl_setup(void) {
@@ -149,12 +148,18 @@
 
   }
 
+  /* pthread_atfork() seems somewhat broken in util/rcu.c, and I'm
+     not entirely sure what is the cause. This disables that
+     behaviour, and seems to work alright? */
+
+  rcu_disable_atfork();
+
 }
 
 
 /* Fork server logic, invoked once we hit _start. */
 
-static void afl_forkserver(CPUArchState *env) {
+static void afl_forkserver(CPUState *cpu) {
 
   static unsigned char tmp[4];
 
@@ -178,7 +183,7 @@
 
     if (read(FORKSRV_FD, tmp, 4) != 4) exit(2);
 
-    /* Establish a channel with child to grab translation commands. We'll 
+    /* Establish a channel with child to grab translation commands. We'll
        read from t_fd[0], child will write to TSL_FD. */
 
     if (pipe(t_fd) || dup2(t_fd[1], TSL_FD) < 0) exit(3);
@@ -207,7 +212,7 @@
 
     /* Collect translation requests until child dies and closes the pipe. */
 
-    afl_wait_tsl(env, t_fd[0]);
+    afl_wait_tsl(cpu, t_fd[0]);
 
     /* Get and relay exit status to parent. */
 
@@ -269,13 +274,13 @@
 
 }
 
-
 /* This is the other side of the same channel. Since timeouts are handled by
    afl-fuzz simply killing the child, we can just wait until the pipe breaks. */
 
-static void afl_wait_tsl(CPUArchState *env, int fd) {
+static void afl_wait_tsl(CPUState *cpu, int fd) {
 
   struct afl_tsl t;
+  TranslationBlock *tb;
 
   while (1) {
 
@@ -284,11 +289,18 @@
     if (read(fd, &t, sizeof(struct afl_tsl)) != sizeof(struct afl_tsl))
       break;
 
-    tb_find_slow(env, t.pc, t.cs_base, t.flags);
+    tb = tb_htable_lookup(cpu, t.pc, t.cs_base, t.flags);
+
+    if(!tb) {
+      mmap_lock();
+      tb_lock();
+      tb_gen_code(cpu, t.pc, t.cs_base, t.flags, 0);
+      mmap_unlock();
+      tb_unlock();
+    }
 
   }
 
   close(fd);
 
 }
-
diff --git a/third_party/afl/src/qemu_mode/patches/cpu-exec.diff b/third_party/afl/src/qemu_mode/patches/cpu-exec.diff
index f7085cd2..9c69d0c 100644
--- a/third_party/afl/src/qemu_mode/patches/cpu-exec.diff
+++ b/third_party/afl/src/qemu_mode/patches/cpu-exec.diff
@@ -1,33 +1,28 @@
---- qemu-2.3.0/cpu-exec.c.orig     2014-12-09 14:45:40.000000000 +0000
-+++ qemu-2.3.0/cpu-exec.c  2015-02-20 22:07:02.966000000 +0000
-@@ -28,6 +28,8 @@
- #include "exec/memory-internal.h"
- #include "qemu/rcu.h"
-
+--- qemu-2.10.0-rc3-clean/accel/tcg/cpu-exec.c	2017-08-15 11:39:41.000000000 -0700
++++ qemu-2.10.0-rc3/accel/tcg/cpu-exec.c	2017-08-22 14:34:55.868730680 -0700
+@@ -36,6 +36,8 @@
+ #include "sysemu/cpus.h"
+ #include "sysemu/replay.h"
+ 
 +#include "../patches/afl-qemu-cpu-inl.h"
 +
  /* -icount align implementation. */
-
+ 
  typedef struct SyncClocks {
-@@ -296,8 +298,11 @@
-     }
-  not_found:
-    /* if no translated code available, then translate it now */
+@@ -144,6 +146,8 @@
+     int tb_exit;
+     uint8_t *tb_ptr = itb->tc_ptr;
+ 
++    AFL_QEMU_CPU_SNIPPET2;
 +
-     tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
-
-+    AFL_QEMU_CPU_SNIPPET1;
-+
-  found:
-     /* Move the last found TB to the head of the list */
-     if (likely(*ptb1)) {
-@@ -492,6 +497,9 @@
-                     next_tb = 0;
-                     tcg_ctx.tb_ctx.tb_invalidated_flag = 0;
-                 }
-+
-+                AFL_QEMU_CPU_SNIPPET2;
-+
-                 if (qemu_loglevel_mask(CPU_LOG_EXEC)) {
-                     qemu_log("Trace %p [" TARGET_FMT_lx "] %s\n",
-                              tb->tc_ptr, tb->pc, lookup_symbol(tb->pc));
+     qemu_log_mask_and_addr(CPU_LOG_EXEC, itb->pc,
+                            "Trace %p [%d: " TARGET_FMT_lx "] %s\n",
+                            itb->tc_ptr, cpu->cpu_index, itb->pc,
+@@ -365,6 +369,7 @@
+             if (!tb) {
+                 /* if no translated code available, then translate it now */
+                 tb = tb_gen_code(cpu, pc, cs_base, flags, 0);
++                AFL_QEMU_CPU_SNIPPET1;
+             }
+ 
+             mmap_unlock();
diff --git a/third_party/afl/src/qemu_mode/patches/elfload.diff b/third_party/afl/src/qemu_mode/patches/elfload.diff
index 325c917d..f4a53d6 100644
--- a/third_party/afl/src/qemu_mode/patches/elfload.diff
+++ b/third_party/afl/src/qemu_mode/patches/elfload.diff
@@ -1,6 +1,6 @@
---- qemu-2.3.0/linux-user/elfload.c.orig	2014-12-09 14:45:42.000000000 +0000
-+++ qemu-2.3.0/linux-user/elfload.c	2015-01-28 02:51:23.719000000 +0000
-@@ -28,6 +28,8 @@
+--- qemu-2.10.0-rc3-clean/linux-user/elfload.c	2017-08-15 11:39:41.000000000 -0700
++++ qemu-2.10.0-rc3/linux-user/elfload.c	2017-08-22 14:33:57.397127516 -0700
+@@ -20,6 +20,8 @@
  
  #define ELF_OSABI   ELFOSABI_SYSV
  
@@ -9,7 +9,7 @@
  /* from personality.h */
  
  /*
-@@ -1889,6 +1891,8 @@
+@@ -2085,6 +2087,8 @@
      info->brk = 0;
      info->elf_flags = ehdr->e_flags;
  
@@ -18,7 +18,7 @@
      for (i = 0; i < ehdr->e_phnum; i++) {
          struct elf_phdr *eppnt = phdr + i;
          if (eppnt->p_type == PT_LOAD) {
-@@ -1922,9 +1926,11 @@
+@@ -2118,9 +2122,11 @@
              if (elf_prot & PROT_EXEC) {
                  if (vaddr < info->start_code) {
                      info->start_code = vaddr;
diff --git a/third_party/afl/src/qemu_mode/patches/syscall.diff b/third_party/afl/src/qemu_mode/patches/syscall.diff
index 75d3938..55b2914 100644
--- a/third_party/afl/src/qemu_mode/patches/syscall.diff
+++ b/third_party/afl/src/qemu_mode/patches/syscall.diff
@@ -1,25 +1,35 @@
---- qemu-2.3.0/linux-user/syscall.c.orig	2014-12-09 14:45:43.000000000 +0000
-+++ qemu-2.3.0/linux-user/syscall.c	2015-03-27 06:33:00.736000000 +0000
-@@ -227,7 +227,21 @@
- _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo)
- _syscall3(int,sys_syslog,int,type,char*,bufp,int,len)
- #if defined(TARGET_NR_tgkill) && defined(__NR_tgkill)
--_syscall3(int,sys_tgkill,int,tgid,int,pid,int,sig)
-+
+--- qemu-2.10.0-rc3-clean/linux-user/syscall.c	2017-08-15 11:39:41.000000000 -0700
++++ qemu-2.10.0-rc3/linux-user/syscall.c	2017-08-22 14:34:03.193088186 -0700
+@@ -116,6 +116,8 @@
+ 
+ #include "qemu.h"
+ 
 +extern unsigned int afl_forksrv_pid;
 +
-+static int sys_tgkill(int tgid, int pid, int sig) {
-+
-+  /* Workaround for -lpthread to make abort() work properly, without
-+     killing the forkserver due to a prematurely cached PID. */
-+
-+  if (afl_forksrv_pid && afl_forksrv_pid == pid && sig == SIGABRT)
-+    pid = tgid = getpid();
-+
-+  return syscall(__NR_sys_tgkill, pid, tgid, sig);
-+
-+}
-+
+ #ifndef CLONE_IO
+ #define CLONE_IO                0x80000000      /* Clone io context */
  #endif
- #if defined(TARGET_NR_tkill) && defined(__NR_tkill)
- _syscall2(int,sys_tkill,int,tid,int,sig)
+@@ -11688,8 +11690,21 @@
+         break;
+ 
+     case TARGET_NR_tgkill:
+-        ret = get_errno(safe_tgkill((int)arg1, (int)arg2,
+-                        target_to_host_signal(arg3)));
++
++        {
++          int pid  = (int)arg1,
++              tgid = (int)arg2,
++              sig  = (int)arg3;
++
++          /* Not entirely sure if the below is correct for all architectures. */
++
++          if(afl_forksrv_pid && afl_forksrv_pid == pid && sig == SIGABRT)
++              pid = tgid = getpid();
++
++          ret = get_errno(safe_tgkill(pid, tgid, target_to_host_signal(sig)));
++
++        }
++
+         break;
+ 
+ #ifdef TARGET_NR_set_robust_list
diff --git a/third_party/afl/src/types.h b/third_party/afl/src/types.h
index 21d32da6..784d3a7 100644
--- a/third_party/afl/src/types.h
+++ b/third_party/afl/src/types.h
@@ -68,7 +68,11 @@
           ((_ret >> 8) & 0x0000FF00)); \
   })
 
-#define R(x) (random() % (x))
+#ifdef AFL_LLVM_PASS
+#  define AFL_R(x) (random() % (x))
+#else
+#  define R(x) (random() % (x))
+#endif /* ^AFL_LLVM_PASS */
 
 #define STRINGIFY_INTERNAL(x) #x
 #define STRINGIFY(x) STRINGIFY_INTERNAL(x)
diff --git a/third_party/closure_compiler/externs/developer_private.js b/third_party/closure_compiler/externs/developer_private.js
index f7f914f..78643ba 100644
--- a/third_party/closure_compiler/externs/developer_private.js
+++ b/third_party/closure_compiler/externs/developer_private.js
@@ -580,8 +580,7 @@
 
 /**
  * Runs auto update for extensions and apps immediately.
- * @param {function(boolean):void=} callback Called with the boolean result,
- *     true if autoUpdate is successful.
+ * @param {function():void=} callback Called after update check completes.
  * @see https://developer.chrome.com/extensions/developerPrivate#method-autoUpdate
  */
 chrome.developerPrivate.autoUpdate = function(callback) {};
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 5690b05b..c03be4a5 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -25076,6 +25076,7 @@
   <int value="-1174267639" label="ClientLoFi:disabled"/>
   <int value="-1172572865" label="NTPShowGoogleGInOmnibox:enabled"/>
   <int value="-1172204005" label="enable-offline-auto-reload-visible-only"/>
+  <int value="-1171900360" label="EnablePreventLayerSquashing:disabled"/>
   <int value="-1162944097" label="enable-color-correct-rendering"/>
   <int value="-1161409696" label="MediaRemotingEncrypted:enabled"/>
   <int value="-1160026273" label="enable-web-notification-custom-layouts"/>
@@ -26138,6 +26139,7 @@
   <int value="1719189460" label="EnablePasswordSelection:disabled"/>
   <int value="1723601083" label="enable-app-window-controls"/>
   <int value="1724800383" label="AsmJsToWebAssembly:disabled"/>
+  <int value="1725954299" label="EnablePreventLayerSquashing:enabled"/>
   <int value="1730094138" label="enable-md-storage-manager"/>
   <int value="1730236697" label="force-device-scale-factor"/>
   <int value="1730416578" label="NTPCondensedLayout:enabled"/>
diff --git a/ui/events/blink/input_handler_proxy.cc b/ui/events/blink/input_handler_proxy.cc
index 9d657c7..19b91b38 100644
--- a/ui/events/blink/input_handler_proxy.cc
+++ b/ui/events/blink/input_handler_proxy.cc
@@ -619,7 +619,6 @@
     // The first wheel event in the sequence should be cancellable.
     DCHECK(wheel_event.phase != WebMouseWheelEvent::kPhaseBegan);
 
-    DCHECK(mouse_wheel_result_ != kEventDispositionUndefined);
     result = static_cast<EventDisposition>(mouse_wheel_result_);
 
     if (wheel_event.phase == WebMouseWheelEvent::kPhaseEnded ||