summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-10-29 07:21:32 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-10-29 07:21:32 +0000
commit9ce7901cda5d02d9083d644f683dd72029efad46 (patch)
tree671fe7b1342730aa93614125c670bcbdfa4041c4
parent103208bd1f48087e65b93e0dce0623f48e24b65d (diff)
parent4d51991a5852a4374cb34ea27ae8e624133f87b4 (diff)
downloadcore-android14-mainline-healthfitness-release.tar.gz
Snap for 11018792 from 4d51991a5852a4374cb34ea27ae8e624133f87b4 to mainline-healthfitness-releaseaml_hef_341512030aml_hef_341415040aml_hef_341311010android14-mainline-healthfitness-release
Change-Id: I7c8e221ce2c3cbb5a850adc5dad79a1506bb6a73
-rw-r--r--fs_mgr/fs_mgr.cpp25
-rw-r--r--fs_mgr/tests/vts_fs_test.cpp21
-rw-r--r--libcutils/ashmem-dev.cpp29
3 files changed, 69 insertions, 6 deletions
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 742cdfab0..8b9bce1db 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -700,6 +700,29 @@ static void SetReadAheadSize(const std::string& entry_block_device, off64_t size
}
//
+// Mechanism to allow fsck to be triggered by setting ro.preventative_fsck
+// Introduced to address b/305658663
+// If the property value is not equal to the flag file contents, trigger
+// fsck and store the property value in the flag file
+// If we want to trigger again, simply change the property value
+//
+static bool check_if_preventative_fsck_needed(const FstabEntry& entry) {
+ const char* flag_file = "/metadata/vold/preventative_fsck";
+ if (entry.mount_point != "/data") return false;
+
+ // Don't error check - both default to empty string, which is OK
+ std::string prop = android::base::GetProperty("ro.preventative_fsck", "");
+ std::string flag;
+ android::base::ReadFileToString(flag_file, &flag);
+ if (prop == flag) return false;
+ // fsck is run immediately, so assume it runs or there is some deeper problem
+ if (!android::base::WriteStringToFile(prop, flag_file))
+ PERROR << "Failed to write file " << flag_file;
+ LINFO << "Run preventative fsck on /data";
+ return true;
+}
+
+//
// Prepare the filesystem on the given block device to be mounted.
//
// If the "check" option was given in the fstab record, or it seems that the
@@ -749,7 +772,7 @@ static int prepare_fs_for_mount(const std::string& blk_device, const FstabEntry&
}
}
- if (entry.fs_mgr_flags.check ||
+ if (check_if_preventative_fsck_needed(entry) || entry.fs_mgr_flags.check ||
(fs_stat & (FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED))) {
check_fs(blk_device, entry.fs_type, mount_point, &fs_stat);
}
diff --git a/fs_mgr/tests/vts_fs_test.cpp b/fs_mgr/tests/vts_fs_test.cpp
index 4d771fa04..bf003eef7 100644
--- a/fs_mgr/tests/vts_fs_test.cpp
+++ b/fs_mgr/tests/vts_fs_test.cpp
@@ -30,6 +30,24 @@ static int GetVsrLevel() {
return android::base::GetIntProperty("ro.vendor.api_level", -1);
}
+// Returns true iff the device has the specified feature.
+bool DeviceSupportsFeature(const char* feature) {
+ bool device_supports_feature = false;
+ FILE* p = popen("pm list features", "re");
+ if (p) {
+ char* line = NULL;
+ size_t len = 0;
+ while (getline(&line, &len, p) > 0) {
+ if (strstr(line, feature)) {
+ device_supports_feature = true;
+ break;
+ }
+ }
+ pclose(p);
+ }
+ return device_supports_feature;
+}
+
TEST(fs, ErofsSupported) {
// T-launch GKI kernels and higher must support EROFS.
if (GetVsrLevel() < __ANDROID_API_T__) {
@@ -80,7 +98,8 @@ TEST(fs, PartitionTypes) {
ASSERT_TRUE(android::base::Readlink("/dev/block/by-name/userdata", &userdata_bdev));
std::vector<std::string> must_be_f2fs = {"/data"};
- if (vsr_level >= __ANDROID_API_U__) {
+ if (vsr_level >= __ANDROID_API_U__ &&
+ !DeviceSupportsFeature("android.hardware.type.automotive")) {
must_be_f2fs.emplace_back("/metadata");
}
diff --git a/libcutils/ashmem-dev.cpp b/libcutils/ashmem-dev.cpp
index 6a27f9a20..56d68759f 100644
--- a/libcutils/ashmem-dev.cpp
+++ b/libcutils/ashmem-dev.cpp
@@ -349,6 +349,12 @@ static int memfd_create_region(const char* name, size_t size) {
return -1;
}
+ // forbid size changes to match ashmem behaviour
+ if (fcntl(fd, F_ADD_SEALS, F_SEAL_GROW | F_SEAL_SHRINK) == -1) {
+ ALOGE("memfd_create(%s, %zd) F_ADD_SEALS failed: %m", name, size);
+ return -1;
+ }
+
if (debug_log) {
ALOGE("memfd_create(%s, %zd) success. fd=%d\n", name, size, fd.get());
}
@@ -400,14 +406,29 @@ error:
}
static int memfd_set_prot_region(int fd, int prot) {
- /* Only proceed if an fd needs to be write-protected */
+ int seals = fcntl(fd, F_GET_SEALS);
+ if (seals == -1) {
+ ALOGE("memfd_set_prot_region(%d, %d): F_GET_SEALS failed: %s\n", fd, prot, strerror(errno));
+ return -1;
+ }
+
if (prot & PROT_WRITE) {
+ /* Now we want the buffer to be read-write, let's check if the buffer
+ * has been previously marked as read-only before, if so return error
+ */
+ if (seals & F_SEAL_FUTURE_WRITE) {
+ ALOGE("memfd_set_prot_region(%d, %d): region is write protected\n", fd, prot);
+ errno = EINVAL; // inline with ashmem error code, if already in
+ // read-only mode
+ return -1;
+ }
return 0;
}
- if (fcntl(fd, F_ADD_SEALS, F_SEAL_FUTURE_WRITE) == -1) {
- ALOGE("memfd_set_prot_region(%d, %d): F_SEAL_FUTURE_WRITE seal failed: %s\n", fd, prot,
- strerror(errno));
+ /* We would only allow read-only for any future file operations */
+ if (fcntl(fd, F_ADD_SEALS, F_SEAL_FUTURE_WRITE | F_SEAL_SEAL) == -1) {
+ ALOGE("memfd_set_prot_region(%d, %d): F_SEAL_FUTURE_WRITE | F_SEAL_SEAL seal failed: %s\n",
+ fd, prot, strerror(errno));
return -1;
}