diff options
-rw-r--r-- | fastboot/fastboot.cpp | 35 | ||||
-rw-r--r-- | fs_mgr/libsnapshot/snapshot.cpp | 12 | ||||
-rw-r--r-- | fs_mgr/libsnapshot/snapshot_test.cpp | 28 | ||||
-rw-r--r-- | libcutils/include/private/android_filesystem_config.h | 1 | ||||
-rw-r--r-- | rootdir/init.rc | 16 |
5 files changed, 70 insertions, 22 deletions
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp index c946ba95e..700d4bdeb 100644 --- a/fastboot/fastboot.cpp +++ b/fastboot/fastboot.cpp @@ -1007,6 +1007,11 @@ static bool has_vbmeta_partition() { fb->GetVar("partition-type:vbmeta_b", &partition_type) == fastboot::SUCCESS; } +static bool is_logical(const std::string& partition) { + std::string value; + return fb->GetVar("is-logical:" + partition, &value) == fastboot::SUCCESS && value == "yes"; +} + static std::string fb_fix_numeric_var(std::string var) { // Some bootloaders (angler, for example), send spurious leading whitespace. var = android::base::Trim(var); @@ -1019,12 +1024,18 @@ static std::string fb_fix_numeric_var(std::string var) { static uint64_t get_partition_size(const std::string& partition) { std::string partition_size_str; if (fb->GetVar("partition-size:" + partition, &partition_size_str) != fastboot::SUCCESS) { + if (!is_logical(partition)) { + return 0; + } die("cannot get partition size for %s", partition.c_str()); } partition_size_str = fb_fix_numeric_var(partition_size_str); uint64_t partition_size; if (!android::base::ParseUint(partition_size_str, &partition_size)) { + if (!is_logical(partition)) { + return 0; + } die("Couldn't parse partition size '%s'.", partition_size_str.c_str()); } return partition_size; @@ -1035,16 +1046,6 @@ static void copy_boot_avb_footer(const std::string& partition, struct fastboot_b return; } - // If overflows and negative, it should be < buf->sz. - int64_t partition_size = static_cast<int64_t>(get_partition_size(partition)); - - if (partition_size == buf->sz) { - return; - } - if (partition_size < buf->sz) { - die("boot partition is smaller than boot image"); - } - std::string data; if (!android::base::ReadFdToString(buf->fd, &data)) { die("Failed reading from boot"); @@ -1054,6 +1055,15 @@ static void copy_boot_avb_footer(const std::string& partition, struct fastboot_b if (0 != data.compare(footer_offset, AVB_FOOTER_MAGIC_LEN, AVB_FOOTER_MAGIC)) { return; } + // If overflows and negative, it should be < buf->sz. + int64_t partition_size = static_cast<int64_t>(get_partition_size(partition)); + + if (partition_size == buf->sz) { + return; + } + if (partition_size < buf->sz) { + die("boot partition is smaller than boot image"); + } unique_fd fd(make_temporary_fd("boot rewriting")); if (!android::base::WriteStringToFd(data, fd)) { @@ -1250,11 +1260,6 @@ static void do_for_partitions(const std::string& part, const std::string& slot, } } -static bool is_logical(const std::string& partition) { - std::string value; - return fb->GetVar("is-logical:" + partition, &value) == fastboot::SUCCESS && value == "yes"; -} - static bool is_retrofit_device() { std::string value; if (fb->GetVar("super-partition-name", &value) != fastboot::SUCCESS) { diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp index bd1e284da..2c5bf754c 100644 --- a/fs_mgr/libsnapshot/snapshot.cpp +++ b/fs_mgr/libsnapshot/snapshot.cpp @@ -1619,6 +1619,18 @@ bool SnapshotManager::RemoveAllSnapshots(LockedFile* lock) { // as dm-snapshot (for example, after merge completes). bool should_unmap = current_slot != Slot::Target; bool should_delete = ShouldDeleteSnapshot(flashing_status, current_slot, name); + if (should_unmap && android::base::EndsWith(name, device_->GetSlotSuffix())) { + // Something very unexpected has happened - we want to unmap this + // snapshot, but it's on the wrong slot. We can't unmap an active + // partition. If this is not really a snapshot, skip the unmap + // step. + auto& dm = DeviceMapper::Instance(); + if (dm.GetState(name) == DmDeviceState::INVALID || !IsSnapshotDevice(name)) { + LOG(ERROR) << "Detected snapshot " << name << " on " << current_slot << " slot" + << " for source partition; removing without unmap."; + should_unmap = false; + } + } bool partition_ok = true; if (should_unmap && !UnmapPartitionWithSnapshot(lock, name)) { diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp index 25500b5f3..6ed012941 100644 --- a/fs_mgr/libsnapshot/snapshot_test.cpp +++ b/fs_mgr/libsnapshot/snapshot_test.cpp @@ -2021,6 +2021,34 @@ TEST_F(SnapshotUpdateTest, MapAllSnapshots) { ASSERT_TRUE(IsPartitionUnchanged("sys_b")); } +TEST_F(SnapshotUpdateTest, CancelOnTargetSlot) { + AddOperationForPartitions(); + + // Execute the update from B->A. + test_device->set_slot_suffix("_b"); + ASSERT_TRUE(sm->BeginUpdate()); + ASSERT_TRUE(sm->CreateUpdateSnapshots(manifest_)); + + std::string path; + ASSERT_TRUE(CreateLogicalPartition( + CreateLogicalPartitionParams{ + .block_device = fake_super, + .metadata_slot = 0, + .partition_name = "sys_a", + .timeout_ms = 1s, + .partition_opener = opener_.get(), + }, + &path)); + + // Hold sys_a open so it can't be unmapped. + unique_fd fd(open(path.c_str(), O_RDONLY)); + + // Switch back to "A", make sure we can cancel. Instead of unmapping sys_a + // we should simply delete the old snapshots. + test_device->set_slot_suffix("_a"); + ASSERT_TRUE(sm->BeginUpdate()); +} + class FlashAfterUpdateTest : public SnapshotUpdateTest, public WithParamInterface<std::tuple<uint32_t, bool>> { public: diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h index b4fe2e687..748928187 100644 --- a/libcutils/include/private/android_filesystem_config.h +++ b/libcutils/include/private/android_filesystem_config.h @@ -127,6 +127,7 @@ #define AID_EXT_DATA_RW 1078 /* GID for app-private data directories on external storage */ #define AID_EXT_OBB_RW 1079 /* GID for OBB directories on external storage */ #define AID_CONTEXT_HUB 1080 /* GID for access to the Context Hub */ +#define AID_VIRTMANAGER 1081 /* VirtManager daemon */ /* Changes to this file must be made in AOSP, *not* in internal branches. */ #define AID_SHELL 2000 /* adb and debug shell user */ diff --git a/rootdir/init.rc b/rootdir/init.rc index 6f3807068..5df3125da 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -838,6 +838,9 @@ on post-fs-data mkdir /data/ss 0700 system system encryption=Require mkdir /data/system 0775 system system encryption=Require + mkdir /data/system/environ 0700 system system + # b/183861600 attempt to fix selinux label before running derive_classpath service + restorecon /data/system/environ mkdir /data/system/dropbox 0700 system system mkdir /data/system/heapdump 0700 system system mkdir /data/system/users 0775 system system @@ -901,13 +904,6 @@ on post-fs-data wait_for_prop apexd.status activated perform_apex_config - # Define and export *CLASSPATH variables - mkdir /data/system/environ 0700 system system - # Must start before 'odsign', as odsign depends on *CLASSPATH variables - exec_start derive_classpath - load_exports /data/system/environ/classpath - rm /data/system/environ/classpath - # Special-case /data/media/obb per b/64566063 mkdir /data/media 0770 media_rw media_rw encryption=None exec - media_rw media_rw -- /system/bin/chattr +F /data/media @@ -920,6 +916,12 @@ on post-fs-data # Set SELinux security contexts on upgrade or policy update. restorecon --recursive --skip-ce /data + # Define and export *CLASSPATH variables + # Must start before 'odsign', as odsign depends on *CLASSPATH variables + exec_start derive_classpath + load_exports /data/system/environ/classpath + rm /data/system/environ/classpath + # Start the on-device signing daemon, and wait for it to finish, to ensure # ART artifacts are generated if needed. # Must start after 'derive_classpath' to have *CLASSPATH variables set. |