libsnapshot: Fix footer values and verification

A few values in the footer were being set inconsistently. We weren't
verifying them, so it didn't matter. This adds verification and sets
them properly.

Change-Id: I669a03a6e1e87ace31775aba5b67dde9b6e5ecf5
Bug: 168829493
Test: cow_api_test
diff --git a/fs_mgr/libsnapshot/cow_reader.cpp b/fs_mgr/libsnapshot/cow_reader.cpp
index f10ccb6..452a5f3 100644
--- a/fs_mgr/libsnapshot/cow_reader.cpp
+++ b/fs_mgr/libsnapshot/cow_reader.cpp
@@ -154,7 +154,8 @@
             }
         } else if (current_op.type == kCowFooterOp) {
             memcpy(&footer_.op, &current_op, sizeof(footer_.op));
-
+            // we don't consider this an operation for the checksum
+            current_op_num--;
             if (android::base::ReadFully(fd_, &footer_.data, sizeof(footer_.data))) {
                 has_footer_ = true;
                 if (next_last_label) {
@@ -170,6 +171,19 @@
     memset(csum, 0, sizeof(uint8_t) * 32);
 
     if (has_footer_) {
+        if (ops_buffer->size() != footer_.op.num_ops) {
+            LOG(ERROR) << "num ops does not match";
+            return false;
+        }
+        if (ops_buffer->size() * sizeof(CowOperation) != footer_.op.ops_size) {
+            LOG(ERROR) << "ops size does not match ";
+            return false;
+        }
+        SHA256(&footer_.op, sizeof(footer_.op), footer_.data.footer_checksum);
+        if (memcmp(csum, footer_.data.ops_checksum, sizeof(csum)) != 0) {
+            LOG(ERROR) << "ops checksum does not match";
+            return false;
+        }
         SHA256(ops_buffer.get()->data(), footer_.op.ops_size, csum);
         if (memcmp(csum, footer_.data.ops_checksum, sizeof(csum)) != 0) {
             LOG(ERROR) << "ops checksum does not match";
diff --git a/fs_mgr/libsnapshot/cow_writer.cpp b/fs_mgr/libsnapshot/cow_writer.cpp
index f2692dc..b3e75a0 100644
--- a/fs_mgr/libsnapshot/cow_writer.cpp
+++ b/fs_mgr/libsnapshot/cow_writer.cpp
@@ -185,6 +185,7 @@
     // Reset this, since we're going to reimport all operations.
     footer_.op.num_ops = 0;
     next_op_pos_ = sizeof(header_);
+    ops_.resize(0);
 
     auto iter = reader->GetOpIter();
     while (!iter->Done()) {
@@ -233,6 +234,7 @@
     // Reset this, since we're going to reimport all operations.
     footer_.op.num_ops = 0;
     next_op_pos_ = sizeof(header_);
+    ops_.resize(0);
 
     auto iter = reader->GetOpIter();
     while (!iter->Done()) {
@@ -384,7 +386,7 @@
 }
 
 bool CowWriter::Finalize() {
-    footer_.op.ops_size = ops_.size() + sizeof(footer_.op);
+    footer_.op.ops_size = ops_.size();
     uint64_t pos;
 
     if (!GetDataPos(&pos)) {