Call fsync() when close file descriptor am: 3dd8397941 am: c7939fa8fe am: 1ec7764cae am: f4e3c28828

Original change: https://android-review.googlesource.com/c/platform/system/update_engine/+/1462862

Change-Id: I64a2bb305299ee2f0d545b9d3a31833b12879760
diff --git a/payload_consumer/delta_performer.cc b/payload_consumer/delta_performer.cc
index 9bf6d7e..9c13546 100644
--- a/payload_consumer/delta_performer.cc
+++ b/payload_consumer/delta_performer.cc
@@ -520,27 +520,24 @@
     if (!CanPerformInstallOperation(op))
       return true;
 
-    // Validate the operation only if the metadata signature is present.
-    // Otherwise, keep the old behavior. This serves as a knob to disable
-    // the validation logic in case we find some regression after rollout.
-    // NOTE: If hash checks are mandatory and if metadata_signature is empty,
-    // we would have already failed in ParsePayloadMetadata method and thus not
-    // even be here. So no need to handle that case again here.
-    if (!payload_->metadata_signature.empty()) {
-      // Note: Validate must be called only if CanPerformInstallOperation is
-      // called. Otherwise, we might be failing operations before even if there
-      // isn't sufficient data to compute the proper hash.
-      *error = ValidateOperationHash(op);
-      if (*error != ErrorCode::kSuccess) {
-        if (install_plan_->hash_checks_mandatory) {
-          LOG(ERROR) << "Mandatory operation hash check failed";
-          return false;
-        }
-
-        // For non-mandatory cases, just send a UMA stat.
-        LOG(WARNING) << "Ignoring operation validation errors";
-        *error = ErrorCode::kSuccess;
+    // Validate the operation unconditionally. This helps prevent the
+    // exploitation of vulnerabilities in the patching libraries, e.g. bspatch.
+    // The hash of the patch data for a given operation is embedded in the
+    // payload metadata; and thus has been verified against the public key on
+    // device.
+    // Note: Validate must be called only if CanPerformInstallOperation is
+    // called. Otherwise, we might be failing operations before even if there
+    // isn't sufficient data to compute the proper hash.
+    *error = ValidateOperationHash(op);
+    if (*error != ErrorCode::kSuccess) {
+      if (install_plan_->hash_checks_mandatory) {
+        LOG(ERROR) << "Mandatory operation hash check failed";
+        return false;
       }
+
+      // For non-mandatory cases, just send a UMA stat.
+      LOG(WARNING) << "Ignoring operation validation errors";
+      *error = ErrorCode::kSuccess;
     }
 
     // Makes sure we unblock exit when this operation completes.