Merge "[MTE] Print cause and alloc/dealloc traces to logcat."
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index ea9d333..af71fe6 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -2265,3 +2265,81 @@
}
return LP_METADATA_DEFAULT_PARTITION_NAME;
}
+
+bool fs_mgr_create_canonical_mount_point(const std::string& mount_point) {
+ auto saved_errno = errno;
+ auto ok = true;
+ auto created_mount_point = !mkdir(mount_point.c_str(), 0755);
+ std::string real_mount_point;
+ if (!Realpath(mount_point, &real_mount_point)) {
+ ok = false;
+ PERROR << "failed to realpath(" << mount_point << ")";
+ } else if (mount_point != real_mount_point) {
+ ok = false;
+ LERROR << "mount point is not canonical: realpath(" << mount_point << ") -> "
+ << real_mount_point;
+ }
+ if (!ok && created_mount_point) {
+ rmdir(mount_point.c_str());
+ }
+ errno = saved_errno;
+ return ok;
+}
+
+bool fs_mgr_mount_overlayfs_fstab_entry(const FstabEntry& entry) {
+ auto overlayfs_valid_result = fs_mgr_overlayfs_valid();
+ if (overlayfs_valid_result == OverlayfsValidResult::kNotSupported) {
+ LERROR << __FUNCTION__ << "(): kernel does not support overlayfs";
+ return false;
+ }
+
+#if ALLOW_ADBD_DISABLE_VERITY == 0
+ // Allowlist the mount point if user build.
+ static const std::vector<const std::string> kAllowedPaths = {
+ "/odm", "/odm_dlkm", "/oem", "/product", "/system_ext", "/vendor", "/vendor_dlkm",
+ };
+ static const std::vector<const std::string> kAllowedPrefixes = {
+ "/mnt/product/",
+ "/mnt/vendor/",
+ };
+ if (std::none_of(kAllowedPaths.begin(), kAllowedPaths.end(),
+ [&entry](const auto& path) -> bool {
+ return entry.mount_point == path ||
+ StartsWith(entry.mount_point, path + "/");
+ }) &&
+ std::none_of(kAllowedPrefixes.begin(), kAllowedPrefixes.end(),
+ [&entry](const auto& prefix) -> bool {
+ return entry.mount_point != prefix &&
+ StartsWith(entry.mount_point, prefix);
+ })) {
+ LERROR << __FUNCTION__
+ << "(): mount point is forbidden on user build: " << entry.mount_point;
+ return false;
+ }
+#endif // ALLOW_ADBD_DISABLE_VERITY == 0
+
+ if (!fs_mgr_create_canonical_mount_point(entry.mount_point)) {
+ return false;
+ }
+
+ auto options = "lowerdir=" + entry.lowerdir;
+ if (overlayfs_valid_result == OverlayfsValidResult::kOverrideCredsRequired) {
+ options += ",override_creds=off";
+ }
+
+ // Use "overlay-" + entry.blk_device as the mount() source, so that adb-remout-test don't
+ // confuse this with adb remount overlay, whose device name is "overlay".
+ // Overlayfs is a pseudo filesystem, so the source device is a symbolic value and isn't used to
+ // back the filesystem. However the device name would be shown in /proc/mounts.
+ auto source = "overlay-" + entry.blk_device;
+ auto report = "__mount(source=" + source + ",target=" + entry.mount_point + ",type=overlay," +
+ options + ")=";
+ auto ret = mount(source.c_str(), entry.mount_point.c_str(), "overlay", MS_RDONLY | MS_NOATIME,
+ options.c_str());
+ if (ret) {
+ PERROR << report << ret;
+ return false;
+ }
+ LINFO << report << ret;
+ return true;
+}
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 853b24d..d0c89b9 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -127,15 +127,16 @@
}
fs_options.append(flag);
- if (entry->fs_type == "f2fs" && StartsWith(flag, "reserve_root=")) {
- std::string arg;
- if (auto equal_sign = flag.find('='); equal_sign != std::string::npos) {
- arg = flag.substr(equal_sign + 1);
- }
- if (!ParseInt(arg, &entry->reserved_size)) {
- LWARNING << "Warning: reserve_root= flag malformed: " << arg;
- } else {
- entry->reserved_size <<= 12;
+ if (auto equal_sign = flag.find('='); equal_sign != std::string::npos) {
+ const auto arg = flag.substr(equal_sign + 1);
+ if (entry->fs_type == "f2fs" && StartsWith(flag, "reserve_root=")) {
+ if (!ParseInt(arg, &entry->reserved_size)) {
+ LWARNING << "Warning: reserve_root= flag malformed: " << arg;
+ } else {
+ entry->reserved_size <<= 12;
+ }
+ } else if (StartsWith(flag, "lowerdir=")) {
+ entry->lowerdir = std::move(arg);
}
}
}
@@ -298,8 +299,6 @@
if (!ParseByteCount(arg, &entry->zram_backingdev_size)) {
LWARNING << "Warning: zram_backingdev_size= flag malformed: " << arg;
}
- } else if (StartsWith(flag, "lowerdir=")) {
- entry->lowerdir = arg;
} else {
LWARNING << "Warning: unknown flag: " << flag;
}
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 9fb658e..4d32bda 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -92,14 +92,6 @@
return false;
}
-bool fs_mgr_overlayfs_mount_fstab_entry(const android::fs_mgr::FstabEntry&) {
- return false;
-}
-
-std::vector<std::string> fs_mgr_overlayfs_required_devices(Fstab*) {
- return {};
-}
-
bool fs_mgr_overlayfs_setup(const char*, const char*, bool* change, bool) {
if (change) *change = false;
return false;
@@ -1299,34 +1291,6 @@
}
}
-bool fs_mgr_overlayfs_mount_fstab_entry(const android::fs_mgr::FstabEntry& entry) {
- if (fs_mgr_overlayfs_invalid()) return false;
-
- // Create the mount point in case it doesn't exist.
- mkdir(entry.mount_point.c_str(), 0755);
-
- auto options = kLowerdirOption + entry.lowerdir;
- if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kOverrideCredsRequired) {
- options += ",override_creds=off";
- }
-
- // Use "overlay-" + entry.blk_device as the mount() source, so that adb-remout-test don't
- // confuse this with adb remount overlay, whose device name is "overlay".
- // Overlayfs is a pseudo filesystem, so the source device is a symbolic value and isn't used to
- // back the filesystem. However the device name would be shown in /proc/mounts.
- auto source = "overlay-" + entry.blk_device;
- auto report = "__mount(source=" + source + ",target=" + entry.mount_point + ",type=overlay," +
- options + ")=";
- auto ret = mount(source.c_str(), entry.mount_point.c_str(), "overlay", MS_RDONLY | MS_NOATIME,
- options.c_str());
- if (ret) {
- PERROR << report << ret;
- return false;
- }
- LINFO << report << ret;
- return true;
-}
-
bool fs_mgr_overlayfs_mount_all(Fstab* fstab) {
auto ret = false;
if (fs_mgr_overlayfs_invalid()) return ret;
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 22c02cc..4d3ecc9 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -131,3 +131,12 @@
// Finds the dm_bow device on which this block device is stacked, or returns
// empty string
std::string fs_mgr_find_bow_device(const std::string& block_device);
+
+// Creates mount point if not already existed, and checks that mount point is a
+// canonical path that doesn't contain any symbolic link or /../.
+bool fs_mgr_create_canonical_mount_point(const std::string& mount_point);
+
+// Like fs_mgr_do_mount_one() but for overlayfs fstab entries.
+// Unlike fs_mgr_overlayfs, mount overlayfs without upperdir and workdir, so the
+// filesystem cannot be remount read-write.
+bool fs_mgr_mount_overlayfs_fstab_entry(const android::fs_mgr::FstabEntry& entry);
diff --git a/fs_mgr/include/fs_mgr_overlayfs.h b/fs_mgr/include/fs_mgr_overlayfs.h
index 22d12e7..6caab1f 100644
--- a/fs_mgr/include/fs_mgr_overlayfs.h
+++ b/fs_mgr/include/fs_mgr_overlayfs.h
@@ -27,8 +27,6 @@
android::fs_mgr::Fstab fs_mgr_overlayfs_candidate_list(const android::fs_mgr::Fstab& fstab);
bool fs_mgr_overlayfs_mount_all(android::fs_mgr::Fstab* fstab);
-bool fs_mgr_overlayfs_mount_fstab_entry(const android::fs_mgr::FstabEntry& entry);
-std::vector<std::string> fs_mgr_overlayfs_required_devices(android::fs_mgr::Fstab* fstab);
bool fs_mgr_overlayfs_setup(const char* backing = nullptr, const char* mount_point = nullptr,
bool* change = nullptr, bool force = true);
bool fs_mgr_overlayfs_teardown(const char* mount_point = nullptr, bool* change = nullptr);
diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp
index d5b8a61..c4874b8 100644
--- a/fs_mgr/libdm/dm.cpp
+++ b/fs_mgr/libdm/dm.cpp
@@ -35,6 +35,10 @@
#include "utility.h"
+#ifndef DM_DEFERRED_REMOVE
+#define DM_DEFERRED_REMOVE (1 << 17)
+#endif
+
namespace android {
namespace dm {
@@ -133,6 +137,25 @@
return DeleteDevice(name, 0ms);
}
+bool DeviceMapper::DeleteDeviceDeferred(const std::string& name) {
+ struct dm_ioctl io;
+ InitIo(&io, name);
+
+ io.flags |= DM_DEFERRED_REMOVE;
+ if (ioctl(fd_, DM_DEV_REMOVE, &io)) {
+ PLOG(ERROR) << "DM_DEV_REMOVE with DM_DEFERRED_REMOVE failed for [" << name << "]";
+ return false;
+ }
+ return true;
+}
+
+bool DeviceMapper::DeleteDeviceIfExistsDeferred(const std::string& name) {
+ if (GetState(name) == DmDeviceState::INVALID) {
+ return true;
+ }
+ return DeleteDeviceDeferred(name);
+}
+
static std::string GenerateUuid() {
uuid_t uuid_bytes;
uuid_generate(uuid_bytes);
diff --git a/fs_mgr/libdm/dm_test.cpp b/fs_mgr/libdm/dm_test.cpp
index 41d3145..8006db2 100644
--- a/fs_mgr/libdm/dm_test.cpp
+++ b/fs_mgr/libdm/dm_test.cpp
@@ -35,6 +35,7 @@
#include <libdm/dm.h>
#include <libdm/loop_control.h>
#include "test_util.h"
+#include "utility.h"
using namespace std;
using namespace std::chrono_literals;
@@ -617,3 +618,64 @@
auto sub_block_device = dm.GetParentBlockDeviceByPath(dev.path());
ASSERT_EQ(loop.device(), *sub_block_device);
}
+
+TEST(libdm, DeleteDeviceDeferredNoReferences) {
+ unique_fd tmp(CreateTempFile("file_1", 4096));
+ ASSERT_GE(tmp, 0);
+ LoopDevice loop(tmp, 10s);
+ ASSERT_TRUE(loop.valid());
+
+ DmTable table;
+ ASSERT_TRUE(table.Emplace<DmTargetLinear>(0, 1, loop.device(), 0));
+ ASSERT_TRUE(table.valid());
+ TempDevice dev("libdm-test-dm-linear", table);
+ ASSERT_TRUE(dev.valid());
+
+ DeviceMapper& dm = DeviceMapper::Instance();
+
+ std::string path;
+ ASSERT_TRUE(dm.GetDmDevicePathByName("libdm-test-dm-linear", &path));
+ ASSERT_EQ(0, access(path.c_str(), F_OK));
+
+ ASSERT_TRUE(dm.DeleteDeviceDeferred("libdm-test-dm-linear"));
+
+ ASSERT_TRUE(WaitForFileDeleted(path, 5s));
+ ASSERT_EQ(DmDeviceState::INVALID, dm.GetState("libdm-test-dm-linear"));
+ ASSERT_NE(0, access(path.c_str(), F_OK));
+ ASSERT_EQ(ENOENT, errno);
+}
+
+TEST(libdm, DeleteDeviceDeferredWaitsForLastReference) {
+ unique_fd tmp(CreateTempFile("file_1", 4096));
+ ASSERT_GE(tmp, 0);
+ LoopDevice loop(tmp, 10s);
+ ASSERT_TRUE(loop.valid());
+
+ DmTable table;
+ ASSERT_TRUE(table.Emplace<DmTargetLinear>(0, 1, loop.device(), 0));
+ ASSERT_TRUE(table.valid());
+ TempDevice dev("libdm-test-dm-linear", table);
+ ASSERT_TRUE(dev.valid());
+
+ DeviceMapper& dm = DeviceMapper::Instance();
+
+ std::string path;
+ ASSERT_TRUE(dm.GetDmDevicePathByName("libdm-test-dm-linear", &path));
+ ASSERT_EQ(0, access(path.c_str(), F_OK));
+
+ {
+ // Open a reference to block device.
+ unique_fd fd(TEMP_FAILURE_RETRY(open(dev.path().c_str(), O_RDONLY | O_CLOEXEC)));
+ ASSERT_GE(fd.get(), 0);
+
+ ASSERT_TRUE(dm.DeleteDeviceDeferred("libdm-test-dm-linear"));
+
+ ASSERT_EQ(0, access(path.c_str(), F_OK));
+ }
+
+ // After release device will be removed.
+ ASSERT_TRUE(WaitForFileDeleted(path, 5s));
+ ASSERT_EQ(DmDeviceState::INVALID, dm.GetState("libdm-test-dm-linear"));
+ ASSERT_NE(0, access(path.c_str(), F_OK));
+ ASSERT_EQ(ENOENT, errno);
+}
diff --git a/fs_mgr/libdm/include/libdm/dm.h b/fs_mgr/libdm/include/libdm/dm.h
index 5d6db46..70b14fa 100644
--- a/fs_mgr/libdm/include/libdm/dm.h
+++ b/fs_mgr/libdm/include/libdm/dm.h
@@ -95,6 +95,12 @@
bool DeleteDevice(const std::string& name, const std::chrono::milliseconds& timeout_ms);
bool DeleteDeviceIfExists(const std::string& name, const std::chrono::milliseconds& timeout_ms);
+ // Enqueues a deletion of device mapper device with the given name once last reference is
+ // closed.
+ // Returns 'true' on success, false otherwise.
+ bool DeleteDeviceDeferred(const std::string& name);
+ bool DeleteDeviceIfExistsDeferred(const std::string& name);
+
// Fetches and returns the complete state of the underlying device mapper
// device with given name.
std::optional<Info> GetDetailedInfo(const std::string& name) const;
diff --git a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
index 92aa55c..77ed92c 100644
--- a/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
+++ b/fs_mgr/libsnapshot/android/snapshot/snapshot.proto
@@ -213,6 +213,7 @@
// Time from sys.boot_completed to merge start, in milliseconds.
uint32 boot_complete_to_merge_start_time_ms = 8;
- // Merge failure code, filled if state == MergeFailed.
+ // Merge failure code, filled if the merge failed at any time (regardless
+ // of whether it succeeded at a later time).
MergeFailureCode merge_failure_code = 9;
}
diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh
index 0c5fe3d..9542bc1 100755
--- a/fs_mgr/tests/adb-remount-test.sh
+++ b/fs_mgr/tests/adb-remount-test.sh
@@ -762,15 +762,15 @@
"ramdumpfs" "binder" "securityfs" "functionfs" "rootfs"
)
local exclude_devices=(
- "[/]sys[/]kernel[/]debug" "[/]data[/]media" "[/]dev[/]block[/]loop[0-9]*"
+ "\/sys\/kernel\/debug" "\/data\/media" "\/dev\/block\/loop[0-9]*"
"${exclude_filesystems[@]}"
)
local exclude_mount_points=(
- "[/]cache" "[/]mnt[/]scratch" "[/]mnt[/]vendor[/]persist" "[/]persist"
- "[/]metadata"
+ "\/cache" "\/mnt\/scratch" "\/mnt\/vendor\/persist" "\/persist"
+ "\/metadata"
)
if [ "data" = "${1}" ]; then
- exclude_mount_points+=("[/]data")
+ exclude_mount_points+=("\/data")
fi
awk '$1 !~ /^('"$(join_with "|" "${exclude_devices[@]}")"')$/ &&
$2 !~ /^('"$(join_with "|" "${exclude_mount_points[@]}")"')$/ &&
@@ -934,7 +934,7 @@
PARTITIONS=`adb_su cat /vendor/etc/fstab* </dev/null |
grep -v "^[#${SPACE}${TAB}]" |
skip_administrative_mounts |
- awk '$1 ~ /^[^/]+$/ && "/"$1 == $2 && $4 ~ /(^|,)ro(,|$)/ { print $1 }' |
+ awk '$1 ~ /^[^\/]+$/ && "/"$1 == $2 && $4 ~ /(^|,)ro(,|$)/ { print $1 }' |
sort -u |
tr '\n' ' '`
PARTITIONS="${PARTITIONS:-system vendor}"
diff --git a/fs_mgr/tests/fs_mgr_test.cpp b/fs_mgr/tests/fs_mgr_test.cpp
index eb2919b..a1b020a 100644
--- a/fs_mgr/tests/fs_mgr_test.cpp
+++ b/fs_mgr/tests/fs_mgr_test.cpp
@@ -120,7 +120,7 @@
};
const std::string bootconfig =
- "androidboot.bootdevice = \" \"1d84000.ufshc\"\n"
+ "androidboot.bootdevice = \"1d84000.ufshc\"\n"
"androidboot.boot_devices = \"dev1\", \"dev2,withcomma\", \"dev3\"\n"
"androidboot.baseband = \"sdy\"\n"
"androidboot.keymaster = \"1\"\n"
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 616d285..f5c10bb 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -420,6 +420,10 @@
*end = begin + 1;
}
+ if (!fs_mgr_create_canonical_mount_point(begin->mount_point)) {
+ return false;
+ }
+
if (begin->fs_mgr_flags.logical) {
if (!fs_mgr_update_logical_partition(&(*begin))) {
return false;
@@ -574,7 +578,7 @@
for (const auto& entry : fstab_) {
if (entry.fs_type == "overlay") {
- fs_mgr_overlayfs_mount_fstab_entry(entry);
+ fs_mgr_mount_overlayfs_fstab_entry(entry);
}
}
diff --git a/libcutils/include/private/android_filesystem_config.h b/libcutils/include/private/android_filesystem_config.h
index 8f22d89..c471fa0 100644
--- a/libcutils/include/private/android_filesystem_config.h
+++ b/libcutils/include/private/android_filesystem_config.h
@@ -127,7 +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 */
+#define AID_VIRTUALIZATIONSERVICE 1081 /* VirtualizationService daemon */
#define AID_ARTD 1082 /* ART Service daemon */
#define AID_UWB 1083 /* UWB subsystem */
/* Changes to this file must be made in AOSP, *not* in internal branches. */
diff --git a/rootdir/etc/linker.config.json b/rootdir/etc/linker.config.json
index 6b03a1d..c58f298 100644
--- a/rootdir/etc/linker.config.json
+++ b/rootdir/etc/linker.config.json
@@ -19,7 +19,6 @@
"libnetd_resolv.so",
// nn
"libneuralnetworks.so",
- "libneuralnetworks_shim.so",
// statsd
"libstatspull.so",
"libstatssocket.so",
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 6e85da5..c6b74bc 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -776,6 +776,9 @@
mkdir /data/misc/odrefresh 0777 system system
# directory used for on-device signing key blob
mkdir /data/misc/odsign 0700 root root
+ # Directory for VirtualizationService temporary image files. Ensure that it is empty.
+ exec -- /bin/rm -rf /data/misc/virtualizationservice
+ mkdir /data/misc/virtualizationservice 0700 virtualizationservice virtualizationservice
mkdir /data/preloads 0775 system system encryption=None
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 56e774b..3101974 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -67,9 +67,9 @@
# CDMA radio interface MUX
/dev/ppp 0660 radio vpn
-# Virtualisation is managed by Virt Manager
-/dev/kvm 0600 virtmanager root
-/dev/vhost-vsock 0600 virtmanager root
+# Virtualization is managed by VirtualizationService.
+/dev/kvm 0600 virtualizationservice root
+/dev/vhost-vsock 0600 virtualizationservice root
# sysfs properties
/sys/devices/platform/trusty.* trusty_version 0440 root log
diff --git a/trusty/apploader/apploader.cpp b/trusty/apploader/apploader.cpp
index 4aca375..e4d9b39 100644
--- a/trusty/apploader/apploader.cpp
+++ b/trusty/apploader/apploader.cpp
@@ -220,6 +220,9 @@
case APPLOADER_ERR_INTERNAL:
LOG(ERROR) << "Error: internal apploader error";
break;
+ case APPLOADER_ERR_INVALID_VERSION:
+ LOG(ERROR) << "Error: invalid application version";
+ break;
default:
LOG(ERROR) << "Unrecognized error: " << resp.error;
break;
diff --git a/trusty/apploader/apploader_ipc.h b/trusty/apploader/apploader_ipc.h
index d8c915e..6cda7c1 100644
--- a/trusty/apploader/apploader_ipc.h
+++ b/trusty/apploader/apploader_ipc.h
@@ -44,6 +44,7 @@
* @APPLOADER_ERR_ALREADY_EXISTS: application has already been loaded
* @APPLOADER_ERR_INTERNAL: miscellaneous or internal apploader
* error not covered by the above
+ * @APPLOADER_ERR_INVALID_VERSION: invalid application version
*/
enum apploader_error : uint32_t {
APPLOADER_NO_ERROR = 0,
@@ -54,6 +55,7 @@
APPLOADER_ERR_LOADING_FAILED,
APPLOADER_ERR_ALREADY_EXISTS,
APPLOADER_ERR_INTERNAL,
+ APPLOADER_ERR_INVALID_VERSION,
};
/**