From 14e9504d2ea495a93dae9ccb9bf9bfba73691165 Mon Sep 17 00:00:00 2001 From: Akilesh Kailash Date: Wed, 1 Dec 2021 12:06:51 +0000 Subject: [PATCH] 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 Change-Id: I63c0d862057ebf138c9d1696a942030e30598739 --- .../snapuserd/dm-snapshot-merge/snapuserd_readahead.cpp | 8 +++++++- .../snapuserd/user-space-merge/snapuserd_readahead.cpp | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_readahead.cpp b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_readahead.cpp index 3bb7a0a07..c201b23dc 100644 --- a/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_readahead.cpp +++ b/fs_mgr/libsnapshot/snapuserd/dm-snapshot-merge/snapuserd_readahead.cpp @@ -246,9 +246,15 @@ bool ReadAheadThread::ReconstructDataFromCow() { 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 metadata_buffer = + std::make_unique(snapuserd_->GetBufferMetadataSize()); + memcpy(metadata_buffer.get(), metadata_buffer_, snapuserd_->GetBufferMetadataSize()); + while (true) { struct ScratchMetadata* bm = reinterpret_cast( - (char*)metadata_buffer_ + metadata_offset); + (char*)metadata_buffer.get() + metadata_offset); // Done reading metadata if (bm->new_block == 0 && bm->file_offset == 0) { diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp index 40e7242cd..9e8ccfb1e 100644 --- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp +++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp @@ -121,9 +121,15 @@ bool ReadAhead::ReconstructDataFromCow() { 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 metadata_buffer = + std::make_unique(snapuserd_->GetBufferMetadataSize()); + memcpy(metadata_buffer.get(), metadata_buffer_, snapuserd_->GetBufferMetadataSize()); + while (true) { struct ScratchMetadata* bm = reinterpret_cast( - (char*)metadata_buffer_ + metadata_offset); + (char*)metadata_buffer.get() + metadata_offset); // Done reading metadata if (bm->new_block == 0 && bm->file_offset == 0) {