snapuserd: Address alignment fault on 32-bit systems

When the scratch space is mmap'ed, the metadata buffer
will be un-aligned. This may lead to alignment fault
on 32-bit systems. Address this by temporarily copying
it to buffer.

No perf impact as this code path is not in I/O path
and the copy is a for the size of metadata buffer which
is 8k.

Bug: 206426215
Test: Full and Incremental OTA on pixel
1: Compile snapuserd as 32 bit and reproduced the bug on pixel.
2: With fix - OTA applied successfully.
3: Reboot the device when merge was in-flight as the fix is primarily
in that path.
4: Verify merge completion and data integrity post merge.

Signed-off-by: Akilesh Kailash <akailash@google.com>
Change-Id: Icd4a21d6a61f1ab36e65994c06a4d049a2ee741c
Merged-In: I63c0d862057ebf138c9d1696a942030e30598739
diff --git a/fs_mgr/libsnapshot/snapuserd_readahead.cpp b/fs_mgr/libsnapshot/snapuserd_readahead.cpp
index 16d5919..e55fea3 100644
--- a/fs_mgr/libsnapshot/snapuserd_readahead.cpp
+++ b/fs_mgr/libsnapshot/snapuserd_readahead.cpp
@@ -226,9 +226,15 @@
     int num_ops = 0;
     int total_blocks_merged = 0;
 
+    // This memcpy is important as metadata_buffer_ will be an unaligned address and will fault
+    // on 32-bit systems
+    std::unique_ptr<uint8_t[]> metadata_buffer =
+            std::make_unique<uint8_t[]>(snapuserd_->GetBufferMetadataSize());
+    memcpy(metadata_buffer.get(), metadata_buffer_, snapuserd_->GetBufferMetadataSize());
+
     while (true) {
         struct ScratchMetadata* bm = reinterpret_cast<struct ScratchMetadata*>(
-                (char*)metadata_buffer_ + metadata_offset);
+                (char*)metadata_buffer.get() + metadata_offset);
 
         // Done reading metadata
         if (bm->new_block == 0 && bm->file_offset == 0) {