Fix verity discarded bug

If update_engine opens CowWriterFileDescriptor w/o writing anything,
data past the resume label is readable while fd is open, but will
be discarded once the fd is closed. Such "phantom read" causes
inconsistency. This CL contains two changes to address the above bug:

1. When device reboots after update, all I/O are served by snapuserd.
update_engine should use snapuserd for verification to emulate bahvior
of device after reboot.

2. When a CowWriterFd is opened, don't call Finalize() if no verity is
written. Since past-the-end data is discarded when we call Finalize()

Test: th

Bug: 186196758

Change-Id: Ia1d31b671c16fded7319677fe0397f1288457201
diff --git a/common/hash_calculator.cc b/common/hash_calculator.cc
index d010a53..60812d5 100644
--- a/common/hash_calculator.cc
+++ b/common/hash_calculator.cc
@@ -95,6 +95,11 @@
   return RawHashOfBytes(data.data(), data.size(), out_hash);
 }
 
+bool HashCalculator::RawHashOfFile(const string& name, brillo::Blob* out_hash) {
+  const auto file_size = utils::FileSize(name);
+  return RawHashOfFile(name, file_size, out_hash) == file_size;
+}
+
 off_t HashCalculator::RawHashOfFile(const string& name,
                                     off_t length,
                                     brillo::Blob* out_hash) {
diff --git a/common/hash_calculator.h b/common/hash_calculator.h
index b7e4d86..4426128 100644
--- a/common/hash_calculator.h
+++ b/common/hash_calculator.h
@@ -75,6 +75,7 @@
   static off_t RawHashOfFile(const std::string& name,
                              off_t length,
                              brillo::Blob* out_hash);
+  static bool RawHashOfFile(const std::string& name, brillo::Blob* out_hash);
 
  private:
   // If non-empty, the final raw hash. Will only be set to non-empty when
diff --git a/common/utils.h b/common/utils.h
index 5f6e475..59f236e 100644
--- a/common/utils.h
+++ b/common/utils.h
@@ -399,13 +399,19 @@
 
   // If |open_fd| is true, a writable file descriptor will be opened for this
   // file.
-  explicit ScopedTempFile(const std::string& pattern, bool open_fd = false) {
+  // If |truncate_size| is non-zero, truncate file to that size on creation.
+  explicit ScopedTempFile(const std::string& pattern,
+                          bool open_fd = false,
+                          size_t truncate_size = 0) {
     CHECK(utils::MakeTempFile(pattern, &path_, open_fd ? &fd_ : nullptr));
     unlinker_.reset(new ScopedPathUnlinker(path_));
     if (open_fd) {
       CHECK_GE(fd_, 0);
       fd_closer_.reset(new ScopedFdCloser(&fd_));
     }
+    if (truncate_size > 0) {
+      CHECK_EQ(0, truncate(path_.c_str(), truncate_size));
+    }
   }
   virtual ~ScopedTempFile() = default;