diff --git a/core/includes/update.inc b/core/includes/update.inc
index fd02de09..4c18a20 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -238,13 +238,17 @@ function update_do_one($module, $number, $dependency_map, &$context) {
   $ret = array();
   if (function_exists($function)) {
     try {
+      \Drupal::moduleHandler()->lock();
       $ret['results']['query'] = $function($context['sandbox']);
       $ret['results']['success'] = TRUE;
+      \Drupal::moduleHandler()->unlock();
     }
     // @TODO We may want to do different error handling for different
     // exception types, but for now we'll just log the exception and
     // return the message for printing.
     catch (Exception $e) {
+      \Drupal::moduleHandler()->unlock();
+
       watchdog_exception('update', $e);
 
       $variables = Error::decodeException($e);
diff --git a/core/lib/Drupal/Core/DependencyInjection/UpdateServiceProvider.php b/core/lib/Drupal/Core/DependencyInjection/UpdateServiceProvider.php
index aa3c709..061ce6a 100644
--- a/core/lib/Drupal/Core/DependencyInjection/UpdateServiceProvider.php
+++ b/core/lib/Drupal/Core/DependencyInjection/UpdateServiceProvider.php
@@ -23,6 +23,10 @@ class UpdateServiceProvider implements ServiceProviderInterface, ServiceModifier
    * {@inheritdoc}
    */
   public function register(ContainerBuilder $container) {
+    $container
+      ->register('module_handler', 'Drupal\Core\Extension\UpdateModuleHandler')
+      ->addArgument('%container.modules%');
+
     if (!empty($GLOBALS['conf']['update_service_provider_overrides'])) {
       // Disable the Lock service.
       $container
@@ -33,8 +37,6 @@ public function register(ContainerBuilder $container) {
       $container
         ->register('config.storage', 'Drupal\Core\Config\FileStorage')
         ->addArgument(config_get_config_directory(CONFIG_ACTIVE_DIRECTORY));
-      $container->register('module_handler', 'Drupal\Core\Extension\UpdateModuleHandler')
-        ->addArgument('%container.modules%');
       $container
         ->register('cache_factory', 'Drupal\Core\Cache\MemoryBackendFactory');
       $container
diff --git a/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php b/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php
index 42fbd2a..00dcc92 100644
--- a/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/UpdateModuleHandler.php
@@ -18,9 +18,50 @@
 class UpdateModuleHandler extends ModuleHandler {
 
   /**
+   * Whether hook invocations are locked down to an explicit whitelist.
+   *
+   * @var bool
+   */
+  protected $locked = FALSE;
+
+  /**
+   * Returns whether hook invocations are locked down to an explicit whitelist.
+   *
+   * @return bool
+   */
+  public function isLocked() {
+    return $this->locked;
+  }
+
+  /**
+   * Locks down hook invocations to an explicit whitelist.
+   *
+   * Called right before update functions are executed.
+   */
+  public function lock() {
+    $this->locked = TRUE;
+    return $this;
+  }
+
+  /**
+   * Unlocks hook invocations.
+   *
+   * Called after update functions have been executed.
+   */
+  public function unlock() {
+    $this->locked = FALSE;
+    return $this;
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function getImplementations($hook) {
+    // If not executing an update function, all hooks can be invoked.
+    if (!$this->isLocked()) {
+      return parent::getImplementations($hook);
+    }
+
     if (substr($hook, -6) === '_alter') {
       return array();
     }
