summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fastboot/fastboot.cpp35
-rw-r--r--fs_mgr/libsnapshot/snapshot.cpp12
-rw-r--r--fs_mgr/libsnapshot/snapshot_test.cpp28
-rw-r--r--libcutils/include/private/android_filesystem_config.h1
-rw-r--r--rootdir/init.rc16
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.