Merge "libsnapshot: fix -Wdefaulted-function-delete warnings."
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index ad0231d..c15146b 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -204,6 +204,7 @@
header_libs: [
"bionic_libc_platform_headers",
"gwp_asan_headers",
+ "liblog_headers",
],
static_libs: [
@@ -212,7 +213,6 @@
"liblzma",
"libbase",
"libcutils",
- "liblog",
],
runtime_libs: [
"libdexfile", // libdexfile_support dependency
diff --git a/fastboot/Android.bp b/fastboot/Android.bp
index 26e6e00..b478e6e 100644
--- a/fastboot/Android.bp
+++ b/fastboot/Android.bp
@@ -154,6 +154,7 @@
"device/flashing.cpp",
"device/main.cpp",
"device/usb.cpp",
+ "device/usb_iouring.cpp",
"device/usb_client.cpp",
"device/tcp_client.cpp",
"device/utility.cpp",
@@ -195,7 +196,9 @@
"liblz4",
"libsnapshot_nobinder",
"update_metadata-protos",
+ "liburing",
],
+ include_dirs: ["bionic/libc/kernel"],
header_libs: [
"avb_headers",
@@ -346,9 +349,7 @@
target: {
not_windows: {
required: [
- "e2fsdroid",
"mke2fs.conf",
- "sload_f2fs",
],
},
windows: {
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 10bed6d..cde0cb2 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -19,9 +19,7 @@
#
my_dist_files := $(HOST_OUT_EXECUTABLES)/mke2fs
-my_dist_files += $(HOST_OUT_EXECUTABLES)/e2fsdroid
my_dist_files += $(HOST_OUT_EXECUTABLES)/make_f2fs
my_dist_files += $(HOST_OUT_EXECUTABLES)/make_f2fs_casefold
-my_dist_files += $(HOST_OUT_EXECUTABLES)/sload_f2fs
$(call dist-for-goals,dist_files sdk,$(my_dist_files))
my_dist_files :=
diff --git a/fastboot/device/usb.cpp b/fastboot/device/usb.cpp
index 4115a6d..b77d772 100644
--- a/fastboot/device/usb.cpp
+++ b/fastboot/device/usb.cpp
@@ -15,6 +15,7 @@
*/
#include "usb.h"
+#include "usb_iouring.h"
#include <dirent.h>
#include <errno.h>
@@ -28,6 +29,7 @@
#include <linux/usb/ch9.h>
#include <linux/usb/functionfs.h>
+#include <sys/utsname.h>
#include <algorithm>
#include <atomic>
@@ -38,6 +40,7 @@
#include <android-base/logging.h>
#include <android-base/properties.h>
+#include <liburing.h>
using namespace std::chrono_literals;
@@ -65,8 +68,8 @@
}
}
-static int getMaxPacketSize(int ffs_fd) {
- usb_endpoint_descriptor desc;
+int getMaxPacketSize(int ffs_fd) {
+ usb_endpoint_descriptor desc{};
if (ioctl(ffs_fd, FUNCTIONFS_ENDPOINT_DESC, reinterpret_cast<unsigned long>(&desc))) {
D("[ could not get endpoint descriptor! (%d) ]", errno);
return MAX_PACKET_SIZE_HS;
@@ -128,11 +131,9 @@
static int usb_ffs_do_aio(usb_handle* h, const void* data, int len, bool read) {
aio_block* aiob = read ? &h->read_aiob : &h->write_aiob;
- bool zero_packet = false;
int num_bufs = len / h->io_size + (len % h->io_size == 0 ? 0 : 1);
const char* cur_data = reinterpret_cast<const char*>(data);
- int packet_size = getMaxPacketSize(aiob->fd);
if (posix_madvise(const_cast<void*>(data), len, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED) <
0) {
@@ -145,17 +146,6 @@
len -= buf_len;
cur_data += buf_len;
-
- if (len == 0 && buf_len % packet_size == 0 && read) {
- // adb does not expect the device to send a zero packet after data transfer,
- // but the host *does* send a zero packet for the device to read.
- zero_packet = h->reads_zero_packets;
- }
- }
- if (zero_packet) {
- io_prep(&aiob->iocb[num_bufs], aiob->fd, reinterpret_cast<const void*>(cur_data),
- packet_size, 0, read);
- num_bufs += 1;
}
while (true) {
@@ -204,21 +194,46 @@
h->open_new_connection = true;
h->lock.unlock();
h->notify.notify_one();
+ if (h->aio_type == AIOType::IO_URING) {
+ exit_io_uring_ffs(h);
+ }
}
-usb_handle* create_usb_handle(unsigned num_bufs, unsigned io_size) {
- usb_handle* h = new usb_handle();
+bool DoesKernelSupportIouring() {
+ struct utsname uts {};
+ unsigned int major = 0, minor = 0;
+ if ((uname(&uts) != 0) || (sscanf(uts.release, "%u.%u", &major, &minor) != 2)) {
+ return false;
+ }
+ if (major > 5) {
+ return true;
+ }
+ // We will only support kernels from 5.6 onwards as IOSQE_ASYNC flag and
+ // IO_URING_OP_READ/WRITE opcodes were introduced only on 5.6 kernel
+ return minor >= 6;
+}
- if (android::base::GetBoolProperty("sys.usb.ffs.aio_compat", false)) {
+std::unique_ptr<usb_handle> create_usb_handle(unsigned num_bufs, unsigned io_size) {
+ auto h = std::make_unique<usb_handle>();
+ if (DoesKernelSupportIouring() &&
+ android::base::GetBoolProperty("sys.usb.ffs.io_uring_enabled", false)) {
+ init_io_uring_ffs(h.get(), num_bufs);
+ h->aio_type = AIOType::IO_URING;
+ LOG(INFO) << "Using io_uring for usb ffs";
+ } else if (android::base::GetBoolProperty("sys.usb.ffs.aio_compat", false)) {
// Devices on older kernels (< 3.18) will not have aio support for ffs
// unless backported. Fall back on the non-aio functions instead.
h->write = usb_ffs_write;
h->read = usb_ffs_read;
+ h->aio_type = AIOType::SYNC_IO;
+ LOG(INFO) << "Using sync io for usb ffs";
} else {
h->write = usb_ffs_aio_write;
h->read = usb_ffs_aio_read;
aio_block_init(&h->read_aiob, num_bufs);
aio_block_init(&h->write_aiob, num_bufs);
+ h->aio_type = AIOType::AIO;
+ LOG(INFO) << "Using aio for usb ffs";
}
h->io_size = io_size;
h->close = usb_ffs_close;
diff --git a/fastboot/device/usb.h b/fastboot/device/usb.h
index 6c3f542..8996c31 100644
--- a/fastboot/device/usb.h
+++ b/fastboot/device/usb.h
@@ -18,8 +18,10 @@
#include <linux/usb/functionfs.h>
+#include <liburing.h>
#include <atomic>
#include <condition_variable>
+#include <memory>
#include <mutex>
#include <vector>
@@ -35,9 +37,11 @@
int fd;
};
-struct usb_handle {
- usb_handle() {}
+int getMaxPacketSize(int ffs_fd);
+enum class AIOType { SYNC_IO, AIO, IO_URING };
+
+struct usb_handle {
std::condition_variable notify;
std::mutex lock;
bool open_new_connection = true;
@@ -56,8 +60,9 @@
struct aio_block read_aiob;
struct aio_block write_aiob;
- bool reads_zero_packets;
+ io_uring ring;
size_t io_size;
+ AIOType aio_type;
};
-usb_handle* create_usb_handle(unsigned num_bufs, unsigned io_size);
+std::unique_ptr<usb_handle> create_usb_handle(unsigned num_bufs, unsigned io_size);
diff --git a/fastboot/device/usb_client.cpp b/fastboot/device/usb_client.cpp
index 3f9b0f0..d1b38d4 100644
--- a/fastboot/device/usb_client.cpp
+++ b/fastboot/device/usb_client.cpp
@@ -232,7 +232,6 @@
h->read_aiob.fd = h->bulk_out.get();
h->write_aiob.fd = h->bulk_in.get();
- h->reads_zero_packets = false;
return true;
err:
diff --git a/fastboot/device/usb_iouring.cpp b/fastboot/device/usb_iouring.cpp
new file mode 100644
index 0000000..d987712
--- /dev/null
+++ b/fastboot/device/usb_iouring.cpp
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android-base/logging.h>
+#include <liburing.h>
+#include "liburing/io_uring.h"
+#include "usb.h"
+
+static int prep_async_read(struct io_uring* ring, int fd, void* data, size_t len, int64_t offset) {
+ if (io_uring_sq_space_left(ring) <= 0) {
+ LOG(ERROR) << "Submission queue run out of space.";
+ return -1;
+ }
+ auto sqe = io_uring_get_sqe(ring);
+ if (sqe == nullptr) {
+ return -1;
+ }
+ io_uring_sqe_set_flags(sqe, IOSQE_IO_LINK | IOSQE_ASYNC);
+ io_uring_prep_read(sqe, fd, data, len, offset);
+ return 0;
+}
+
+static int prep_async_write(struct io_uring* ring, int fd, const void* data, size_t len,
+ int64_t offset) {
+ if (io_uring_sq_space_left(ring) <= 0) {
+ LOG(ERROR) << "Submission queue run out of space.";
+ return -1;
+ }
+ auto sqe = io_uring_get_sqe(ring);
+ if (sqe == nullptr) {
+ return -1;
+ }
+ io_uring_sqe_set_flags(sqe, IOSQE_IO_LINK | IOSQE_ASYNC);
+ io_uring_prep_write(sqe, fd, data, len, offset);
+ return 0;
+}
+
+template <bool read, typename T>
+int prep_async_io(struct io_uring* ring, int fd, T* data, size_t len, int64_t offset) {
+ if constexpr (read) {
+ return prep_async_read(ring, fd, data, len, offset);
+ } else {
+ return prep_async_write(ring, fd, data, len, offset);
+ }
+}
+
+template <typename T>
+static constexpr T DivRoundup(T x, T y) {
+ return (x + y - 1) / y;
+}
+
+extern int getMaxPacketSize(int ffs_fd);
+
+template <bool read, typename T>
+static int usb_ffs_do_aio(usb_handle* h, T* const data, const int len) {
+ const aio_block* aiob = read ? &h->read_aiob : &h->write_aiob;
+ const int num_requests = DivRoundup<int>(len, h->io_size);
+ auto cur_data = data;
+ const auto packet_size = getMaxPacketSize(aiob->fd);
+
+ for (int bytes_remain = len; bytes_remain > 0;) {
+ const int buf_len = std::min(bytes_remain, static_cast<int>(h->io_size));
+ const auto ret = prep_async_io<read>(&h->ring, aiob->fd, cur_data, buf_len, 0);
+ if (ret < 0) {
+ PLOG(ERROR) << "Failed to queue io_uring request";
+ return -1;
+ }
+
+ bytes_remain -= buf_len;
+ cur_data = reinterpret_cast<T*>(reinterpret_cast<size_t>(cur_data) + buf_len);
+ }
+ const int ret = io_uring_submit(&h->ring);
+ if (ret <= 0 || ret != num_requests) {
+ PLOG(ERROR) << "io_uring: failed to submit SQE entries to kernel";
+ return -1;
+ }
+ int res = 0;
+ bool success = true;
+ for (int i = 0; i < num_requests; ++i) {
+ struct io_uring_cqe* cqe{};
+ const auto ret = TEMP_FAILURE_RETRY(io_uring_wait_cqe(&h->ring, &cqe));
+ if (ret < 0 || cqe == nullptr) {
+ PLOG(ERROR) << "Failed to get CQE from kernel";
+ success = false;
+ continue;
+ }
+ res += cqe->res;
+ if (cqe->res < 0) {
+ LOG(ERROR) << "io_uring request failed:, i = " << i
+ << ", num_requests = " << num_requests << ", res = " << cqe->res << ": "
+ << strerror(cqe->res) << (read ? " read" : " write")
+ << " request size: " << len << ", io_size: " << h->io_size
+ << " max packet size: " << packet_size << ", fd: " << aiob->fd;
+ success = false;
+ errno = -cqe->res;
+ }
+ io_uring_cqe_seen(&h->ring, cqe);
+ }
+ if (!success) {
+ return -1;
+ }
+ return res;
+}
+
+static int usb_ffs_io_uring_read(usb_handle* h, void* data, int len, bool /* allow_partial */) {
+ return usb_ffs_do_aio<true>(h, data, len);
+}
+
+static int usb_ffs_io_uring_write(usb_handle* h, const void* data, int len) {
+ return usb_ffs_do_aio<false>(h, data, len);
+}
+
+void exit_io_uring_ffs(usb_handle* h) {
+ io_uring_queue_exit(&h->ring);
+}
+
+bool init_io_uring_ffs(usb_handle* h, size_t queue_depth) {
+ const auto err = io_uring_queue_init(queue_depth, &h->ring, 0);
+ if (err) {
+ LOG(ERROR) << "Failed to initialize io_uring of depth " << queue_depth << ": "
+ << strerror(err);
+ return false;
+ }
+ h->write = usb_ffs_io_uring_write;
+ h->read = usb_ffs_io_uring_read;
+ return true;
+}
diff --git a/fastboot/device/usb_iouring.h b/fastboot/device/usb_iouring.h
new file mode 100644
index 0000000..7c14b81
--- /dev/null
+++ b/fastboot/device/usb_iouring.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "usb.h"
+
+bool init_io_uring_ffs(usb_handle* h, size_t queue_depth);
+
+void exit_io_uring_ffs(usb_handle* h);
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index c0e3161..1f54f5b 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -889,7 +889,7 @@
// attempted_idx: On return, will indicate which fstab entry
// succeeded. In case of failure, it will be the start_idx.
// Sets errno to match the 1st mount failure on failure.
-static bool mount_with_alternatives(const Fstab& fstab, int start_idx, int* end_idx,
+static bool mount_with_alternatives(Fstab& fstab, int start_idx, int* end_idx,
int* attempted_idx) {
unsigned long i;
int mount_errno = 0;
@@ -909,6 +909,14 @@
continue;
}
+ // fstab[start_idx].blk_device is already updated to /dev/dm-<N> by
+ // AVB related functions. Copy it from start_idx to the current index i.
+ if ((i != start_idx) && fstab[i].fs_mgr_flags.logical &&
+ fstab[start_idx].fs_mgr_flags.logical &&
+ (fstab[i].logical_partition_name == fstab[start_idx].logical_partition_name)) {
+ fstab[i].blk_device = fstab[start_idx].blk_device;
+ }
+
int fs_stat = prepare_fs_for_mount(fstab[i].blk_device, fstab[i]);
if (fs_stat & FS_STAT_INVALID_MAGIC) {
LERROR << __FUNCTION__
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index b1606d9..354d02a 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -81,6 +81,9 @@
return filesystems.find("\t" + filesystem + "\n") != std::string::npos;
}
+const auto kLowerdirOption = "lowerdir="s;
+const auto kUpperdirOption = "upperdir="s;
+
} // namespace
#if ALLOW_ADBD_DISABLE_VERITY == 0 // If we are a user build, provide stubs
@@ -97,7 +100,7 @@
return false;
}
-bool fs_mgr_overlayfs_setup(const char*, const char*, bool* change, bool) {
+bool fs_mgr_overlayfs_setup(const char*, bool* change, bool) {
if (change) *change = false;
return false;
}
@@ -328,9 +331,6 @@
return "";
}
-const auto kLowerdirOption = "lowerdir="s;
-const auto kUpperdirOption = "upperdir="s;
-
static inline bool KernelSupportsUserXattrs() {
struct utsname uts;
uname(&uts);
@@ -370,28 +370,6 @@
return ret;
}
-bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true) {
- Fstab fstab;
- auto save_errno = errno;
- if (!ReadFstabFromFile("/proc/mounts", &fstab)) {
- return false;
- }
- errno = save_errno;
- const auto lowerdir = kLowerdirOption + mount_point;
- for (const auto& entry : fstab) {
- if (overlay_only && "overlay" != entry.fs_type && "overlayfs" != entry.fs_type) continue;
- if (mount_point != entry.mount_point) continue;
- if (!overlay_only) return true;
- const auto options = android::base::Split(entry.fs_options, ",");
- for (const auto& opt : options) {
- if (opt == lowerdir) {
- return true;
- }
- }
- }
- return false;
-}
-
constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0";
bool fs_mgr_overlayfs_setup_dir(const std::string& dir, std::string* overlay, bool* change) {
@@ -1290,8 +1268,23 @@
}
Fstab fs_mgr_overlayfs_candidate_list(const Fstab& fstab) {
+ android::fs_mgr::Fstab mounts;
+ if (!android::fs_mgr::ReadFstabFromFile("/proc/mounts", &mounts)) {
+ PLOG(ERROR) << "Failed to read /proc/mounts";
+ return {};
+ }
+
Fstab candidates;
for (const auto& entry : fstab) {
+ // Filter out partitions whose type doesn't match what's mounted.
+ // This avoids spammy behavior on devices which can mount different
+ // filesystems for each partition.
+ auto proc_mount_point = (entry.mount_point == "/system") ? "/" : entry.mount_point;
+ auto mounted = GetEntryForMountPoint(&mounts, proc_mount_point);
+ if (!mounted || mounted->fs_type != entry.fs_type) {
+ continue;
+ }
+
FstabEntry new_entry = entry;
if (!fs_mgr_overlayfs_already_mounted(entry.mount_point) &&
!fs_mgr_wants_overlayfs(&new_entry)) {
@@ -1364,8 +1357,7 @@
// Returns false if setup not permitted, errno set to last error.
// If something is altered, set *change.
-bool fs_mgr_overlayfs_setup(const char* backing, const char* mount_point, bool* change,
- bool force) {
+bool fs_mgr_overlayfs_setup(const char* mount_point, bool* change, bool force) {
if (change) *change = false;
auto ret = false;
if (fs_mgr_overlayfs_valid() == OverlayfsValidResult::kNotSupported) return ret;
@@ -1402,7 +1394,6 @@
std::string dir;
for (const auto& overlay_mount_point : OverlayMountPoints()) {
- if (backing && backing[0] && (overlay_mount_point != backing)) continue;
if (overlay_mount_point == kScratchMountPoint) {
if (!fs_mgr_overlayfs_setup_scratch(fstab, change)) continue;
} else {
@@ -1698,6 +1689,28 @@
#endif // ALLOW_ADBD_DISABLE_VERITY != 0
+bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only) {
+ Fstab fstab;
+ auto save_errno = errno;
+ if (!ReadFstabFromFile("/proc/mounts", &fstab)) {
+ return false;
+ }
+ errno = save_errno;
+ const auto lowerdir = kLowerdirOption + mount_point;
+ for (const auto& entry : fstab) {
+ if (overlay_only && "overlay" != entry.fs_type && "overlayfs" != entry.fs_type) continue;
+ if (mount_point != entry.mount_point) continue;
+ if (!overlay_only) return true;
+ const auto options = android::base::Split(entry.fs_options, ",");
+ for (const auto& opt : options) {
+ if (opt == lowerdir) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
bool fs_mgr_has_shared_blocks(const std::string& mount_point, const std::string& dev) {
struct statfs fs;
if ((statfs((mount_point + "/lost+found").c_str(), &fs) == -1) ||
diff --git a/fs_mgr/fs_mgr_remount.cpp b/fs_mgr/fs_mgr_remount.cpp
index c47d110..4a927d0 100644
--- a/fs_mgr/fs_mgr_remount.cpp
+++ b/fs_mgr/fs_mgr_remount.cpp
@@ -91,12 +91,8 @@
logd(id, severity, tag, file, line, message);
}
-[[noreturn]] void reboot(bool overlayfs = false) {
- if (overlayfs) {
- LOG(INFO) << "Successfully setup overlayfs\nrebooting device";
- } else {
- LOG(INFO) << "Successfully disabled verity\nrebooting device";
- }
+[[noreturn]] void reboot() {
+ LOG(INFO) << "Rebooting device for new settings to take effect";
::sync();
android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot,remount");
::sleep(60);
@@ -132,11 +128,9 @@
BAD_OVERLAY,
NO_MOUNTS,
REMOUNT_FAILED,
- MUST_REBOOT,
BINDER_ERROR,
CHECKPOINTING,
GSID_ERROR,
- CLEAN_SCRATCH_FILES,
};
static bool ReadFstab(const char* fstab_file, android::fs_mgr::Fstab* fstab) {
@@ -191,8 +185,8 @@
if (entry.fs_type == "vfat") {
return false;
}
- if (GetEntryForMountPoint(&candidates, entry.mount_point)) {
- return true;
+ if (auto candidate_entry = GetEntryForMountPoint(&candidates, entry.mount_point)) {
+ return candidate_entry->fs_type == entry.fs_type;
}
if (GetWrappedEntry(candidates, entry)) {
return false;
@@ -201,13 +195,22 @@
}
static Fstab::const_iterator FindPartition(const Fstab& fstab, const std::string& partition) {
+ Fstab mounts;
+ if (!android::fs_mgr::ReadFstabFromFile("/proc/mounts", &mounts)) {
+ LOG(ERROR) << "Failed to read /proc/mounts";
+ return fstab.end();
+ }
+
for (auto iter = fstab.begin(); iter != fstab.end(); iter++) {
const auto mount_point = system_mount_point(*iter);
- if (partition == mount_point) {
- return iter;
- }
- if (partition == android::base::Basename(mount_point)) {
- return iter;
+ if (partition == mount_point || partition == android::base::Basename(mount_point)) {
+ // In case fstab has multiple entries, pick the one that matches the
+ // actual mounted filesystem type.
+ auto proc_mount_point = (iter->mount_point == "/system") ? "/" : iter->mount_point;
+ auto mounted = GetEntryForMountPoint(&mounts, proc_mount_point);
+ if (mounted && mounted->fs_type == iter->fs_type) {
+ return iter;
+ }
}
}
return fstab.end();
@@ -248,7 +251,10 @@
entry = wrap;
}
- if (!IsRemountable(candidates, *entry)) {
+ // If it's already remounted, include it so it gets gracefully skipped
+ // later on.
+ if (!fs_mgr_overlayfs_already_mounted(entry->mount_point) &&
+ !IsRemountable(candidates, *entry)) {
LOG(ERROR) << "Invalid partition " << arg;
return INVALID_PARTITION;
}
@@ -266,6 +272,7 @@
bool setup_overlayfs = false;
bool disabled_verity = false;
bool verity_error = false;
+ bool remounted_anything = false;
};
static RemountStatus CheckVerity(const FstabEntry& entry, RemountCheckResult* result) {
@@ -312,7 +319,7 @@
if (fs_mgr_wants_overlayfs(&entry)) {
bool change = false;
bool force = result->disabled_verity;
- if (!fs_mgr_overlayfs_setup(nullptr, mount_point.c_str(), &change, force)) {
+ if (!fs_mgr_overlayfs_setup(mount_point.c_str(), &change, force)) {
LOG(ERROR) << "Overlayfs setup for " << mount_point << " failed, skipping";
status = BAD_OVERLAY;
it = partitions->erase(it);
@@ -422,75 +429,8 @@
return REMOUNT_FAILED;
}
-static int do_remount(int argc, char* argv[]) {
- // If somehow this executable is delivered on a "user" build, it can
- // not function, so providing a clear message to the caller rather than
- // letting if fall through and provide a lot of confusing failure messages.
- if (!ALLOW_ADBD_DISABLE_VERITY || (android::base::GetProperty("ro.debuggable", "0") != "1")) {
- LOG(ERROR) << "only functions on userdebug or eng builds";
- return NOT_USERDEBUG;
- }
-
- const char* fstab_file = nullptr;
- auto can_reboot = false;
- std::vector<std::string> partition_args;
-
- struct option longopts[] = {
- {"fstab", required_argument, nullptr, 'T'},
- {"help", no_argument, nullptr, 'h'},
- {"reboot", no_argument, nullptr, 'R'},
- {"verbose", no_argument, nullptr, 'v'},
- {"clean_scratch_files", no_argument, nullptr, 'C'},
- {0, 0, nullptr, 0},
- };
- for (int opt; (opt = ::getopt_long(argc, argv, "hRT:v", longopts, nullptr)) != -1;) {
- switch (opt) {
- case 'h':
- usage(SUCCESS);
- break;
- case 'R':
- can_reboot = true;
- break;
- case 'T':
- if (fstab_file) {
- LOG(ERROR) << "Cannot supply two fstabs: -T " << fstab_file << " -T" << optarg;
- usage(BADARG);
- }
- fstab_file = optarg;
- break;
- case 'v':
- verbose = true;
- break;
- case 'C':
- return CLEAN_SCRATCH_FILES;
- default:
- LOG(ERROR) << "Bad Argument -" << char(opt);
- usage(BADARG);
- break;
- }
- }
-
- for (; argc > optind; ++optind) {
- partition_args.emplace_back(argv[optind]);
- }
-
- // Make sure we are root.
- if (::getuid() != 0) {
- LOG(ERROR) << "Not running as root. Try \"adb root\" first.";
- return NOT_ROOT;
- }
-
- // Read the selected fstab.
- Fstab fstab;
- if (!ReadFstab(fstab_file, &fstab) || fstab.empty()) {
- PLOG(ERROR) << "Failed to read fstab";
- return NO_FSTAB;
- }
-
- if (auto rv = VerifyCheckpointing(); rv != REMOUNT_SUCCESS) {
- return rv;
- }
-
+static int do_remount(Fstab& fstab, const std::vector<std::string>& partition_args,
+ RemountCheckResult* check_result) {
Fstab partitions;
if (partition_args.empty()) {
partitions = GetAllRemountablePartitions(fstab);
@@ -501,29 +441,12 @@
}
// Check verity and optionally setup overlayfs backing.
- RemountCheckResult check_result;
- auto retval = CheckVerityAndOverlayfs(&partitions, &check_result);
+ auto retval = CheckVerityAndOverlayfs(&partitions, check_result);
- bool auto_reboot = check_result.reboot_later && can_reboot;
-
- // If (1) remount requires a reboot to take effect, (2) system is currently
- // running a DSU guest and (3) DSU is disabled, then enable DSU so that the
- // next reboot would not take us back to the host system but stay within
- // the guest system.
- if (auto_reboot) {
- if (auto rv = EnableDsuIfNeeded(); rv != REMOUNT_SUCCESS) {
- return rv;
+ if (partitions.empty() || check_result->disabled_verity) {
+ if (partitions.empty()) {
+ LOG(WARNING) << "No remountable partitions were found.";
}
- }
-
- if (partitions.empty() || check_result.disabled_verity) {
- if (auto_reboot) {
- reboot(check_result.setup_overlayfs);
- }
- if (check_result.reboot_later) {
- return MUST_REBOOT;
- }
- LOG(WARNING) << "No partitions to remount";
return retval;
}
@@ -545,34 +468,118 @@
for (auto& entry : partitions) {
if (auto rv = RemountPartition(fstab, mounts, entry); rv != REMOUNT_SUCCESS) {
retval = rv;
+ } else {
+ check_result->remounted_anything = true;
}
}
-
- if (auto_reboot) reboot(check_result.setup_overlayfs);
- if (check_result.reboot_later) {
- LOG(INFO) << "Now reboot your device for settings to take effect";
- }
return retval;
}
-static int do_clean_scratch_files() {
- android::fs_mgr::CleanupOldScratchFiles();
- return 0;
-}
-
int main(int argc, char* argv[]) {
- android::base::InitLogging(argv, MyLogger);
+ // Do not use MyLogger() when running as clean_scratch_files, as stdout/stderr of daemon process
+ // are discarded.
if (argc > 0 && android::base::Basename(argv[0]) == "clean_scratch_files"s) {
- return do_clean_scratch_files();
+ android::fs_mgr::CleanupOldScratchFiles();
+ return 0;
}
- int result = do_remount(argc, argv);
- if (result == MUST_REBOOT) {
- LOG(INFO) << "Now reboot your device for settings to take effect";
- result = 0;
- } else if (result == REMOUNT_SUCCESS) {
+
+ android::base::InitLogging(argv, MyLogger);
+
+ // Make sure we are root.
+ if (::getuid() != 0) {
+ LOG(ERROR) << "Not running as root. Try \"adb root\" first.";
+ return NOT_ROOT;
+ }
+
+ // If somehow this executable is delivered on a "user" build, it can
+ // not function, so providing a clear message to the caller rather than
+ // letting if fall through and provide a lot of confusing failure messages.
+ if (!ALLOW_ADBD_DISABLE_VERITY || (android::base::GetProperty("ro.debuggable", "0") != "1")) {
+ LOG(ERROR) << "only functions on userdebug or eng builds";
+ return NOT_USERDEBUG;
+ }
+
+ const char* fstab_file = nullptr;
+ auto auto_reboot = false;
+ std::vector<std::string> partition_args;
+
+ struct option longopts[] = {
+ {"fstab", required_argument, nullptr, 'T'},
+ {"help", no_argument, nullptr, 'h'},
+ {"reboot", no_argument, nullptr, 'R'},
+ {"verbose", no_argument, nullptr, 'v'},
+ {0, 0, nullptr, 0},
+ };
+ for (int opt; (opt = ::getopt_long(argc, argv, "hRT:v", longopts, nullptr)) != -1;) {
+ switch (opt) {
+ case 'h':
+ usage(SUCCESS);
+ break;
+ case 'R':
+ auto_reboot = true;
+ break;
+ case 'T':
+ if (fstab_file) {
+ LOG(ERROR) << "Cannot supply two fstabs: -T " << fstab_file << " -T" << optarg;
+ usage(BADARG);
+ }
+ fstab_file = optarg;
+ break;
+ case 'v':
+ verbose = true;
+ break;
+ default:
+ LOG(ERROR) << "Bad Argument -" << char(opt);
+ usage(BADARG);
+ break;
+ }
+ }
+
+ for (; argc > optind; ++optind) {
+ partition_args.emplace_back(argv[optind]);
+ }
+
+ // Make sure checkpointing is disabled if necessary.
+ if (auto rv = VerifyCheckpointing(); rv != REMOUNT_SUCCESS) {
+ return rv;
+ }
+
+ // Read the selected fstab.
+ Fstab fstab;
+ if (!ReadFstab(fstab_file, &fstab) || fstab.empty()) {
+ PLOG(ERROR) << "Failed to read fstab";
+ return NO_FSTAB;
+ }
+
+ RemountCheckResult check_result;
+ int result = do_remount(fstab, partition_args, &check_result);
+
+ if (check_result.disabled_verity && check_result.setup_overlayfs) {
+ LOG(INFO) << "Verity disabled; overlayfs enabled.";
+ } else if (check_result.disabled_verity) {
+ LOG(INFO) << "Verity disabled.";
+ } else if (check_result.setup_overlayfs) {
+ LOG(INFO) << "Overlayfs enabled.";
+ }
+
+ if (check_result.reboot_later) {
+ if (auto_reboot) {
+ // If (1) remount requires a reboot to take effect, (2) system is currently
+ // running a DSU guest and (3) DSU is disabled, then enable DSU so that the
+ // next reboot would not take us back to the host system but stay within
+ // the guest system.
+ if (auto rv = EnableDsuIfNeeded(); rv != REMOUNT_SUCCESS) {
+ LOG(ERROR) << "Unable to automatically enable DSU";
+ return rv;
+ }
+ reboot();
+ } else {
+ LOG(INFO) << "Now reboot your device for settings to take effect";
+ }
+ return REMOUNT_SUCCESS;
+ }
+ if (result == REMOUNT_SUCCESS) {
printf("remount succeeded\n");
- } else if (result == CLEAN_SCRATCH_FILES) {
- return do_clean_scratch_files();
} else {
printf("remount failed\n");
}
diff --git a/fs_mgr/include/fs_mgr_overlayfs.h b/fs_mgr/include/fs_mgr_overlayfs.h
index 21d7cd9..ec1d78f 100644
--- a/fs_mgr/include/fs_mgr_overlayfs.h
+++ b/fs_mgr/include/fs_mgr_overlayfs.h
@@ -28,11 +28,12 @@
bool fs_mgr_wants_overlayfs(android::fs_mgr::FstabEntry* entry);
bool fs_mgr_overlayfs_mount_all(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_setup(const char* mount_point = nullptr, bool* change = nullptr,
+ bool force = true);
bool fs_mgr_overlayfs_teardown(const char* mount_point = nullptr, bool* change = nullptr);
bool fs_mgr_overlayfs_is_setup();
bool fs_mgr_has_shared_blocks(const std::string& mount_point, const std::string& dev);
+bool fs_mgr_overlayfs_already_mounted(const std::string& mount_point, bool overlay_only = true);
std::string fs_mgr_get_context(const std::string& mount_point);
enum class OverlayfsValidResult {
diff --git a/fs_mgr/libsnapshot/cow_reader.cpp b/fs_mgr/libsnapshot/cow_reader.cpp
index c8a0249..45be191 100644
--- a/fs_mgr/libsnapshot/cow_reader.cpp
+++ b/fs_mgr/libsnapshot/cow_reader.cpp
@@ -34,12 +34,13 @@
namespace android {
namespace snapshot {
-CowReader::CowReader(ReaderFlags reader_flag)
+CowReader::CowReader(ReaderFlags reader_flag, bool is_merge)
: fd_(-1),
header_(),
fd_size_(0),
block_pos_index_(std::make_shared<std::vector<int>>()),
- reader_flag_(reader_flag) {}
+ reader_flag_(reader_flag),
+ is_merge_(is_merge) {}
static void SHA256(const void*, size_t, uint8_t[]) {
#if 0
@@ -64,6 +65,7 @@
cow->has_seq_ops_ = has_seq_ops_;
cow->data_loc_ = data_loc_;
cow->block_pos_index_ = block_pos_index_;
+ cow->is_merge_ = is_merge_;
return cow;
}
@@ -476,15 +478,28 @@
merge_op_blocks->insert(merge_op_blocks->end(), other_ops.begin(), other_ops.end());
- for (auto block : *merge_op_blocks) {
- block_pos_index_->push_back(block_map->at(block));
- }
-
num_total_data_ops_ = merge_op_blocks->size();
if (header_.num_merge_ops > 0) {
merge_op_start_ = header_.num_merge_ops;
}
+ if (is_merge_) {
+ // Metadata ops are not required for merge. Thus, just re-arrange
+ // the ops vector as required for merge operations.
+ auto merge_ops_buffer = std::make_shared<std::vector<CowOperation>>();
+ merge_ops_buffer->reserve(num_total_data_ops_);
+ for (auto block : *merge_op_blocks) {
+ merge_ops_buffer->emplace_back(ops_->data()[block_map->at(block)]);
+ }
+ ops_->clear();
+ ops_ = merge_ops_buffer;
+ ops_->shrink_to_fit();
+ } else {
+ for (auto block : *merge_op_blocks) {
+ block_pos_index_->push_back(block_map->at(block));
+ }
+ }
+
block_map->clear();
merge_op_blocks->clear();
@@ -548,7 +563,7 @@
class CowOpIter final : public ICowOpIter {
public:
- CowOpIter(std::shared_ptr<std::vector<CowOperation>>& ops);
+ CowOpIter(std::shared_ptr<std::vector<CowOperation>>& ops, uint64_t start);
bool Done() override;
const CowOperation& Get() override;
@@ -562,9 +577,9 @@
std::vector<CowOperation>::iterator op_iter_;
};
-CowOpIter::CowOpIter(std::shared_ptr<std::vector<CowOperation>>& ops) {
+CowOpIter::CowOpIter(std::shared_ptr<std::vector<CowOperation>>& ops, uint64_t start) {
ops_ = ops;
- op_iter_ = ops_->begin();
+ op_iter_ = ops_->begin() + start;
}
bool CowOpIter::RDone() {
@@ -691,8 +706,8 @@
return ops_->data()[*block_riter_];
}
-std::unique_ptr<ICowOpIter> CowReader::GetOpIter() {
- return std::make_unique<CowOpIter>(ops_);
+std::unique_ptr<ICowOpIter> CowReader::GetOpIter(bool merge_progress) {
+ return std::make_unique<CowOpIter>(ops_, merge_progress ? merge_op_start_ : 0);
}
std::unique_ptr<ICowOpIter> CowReader::GetRevMergeOpIter(bool ignore_progress) {
diff --git a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
index fbdd6b9..e8e4d72 100644
--- a/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
+++ b/fs_mgr/libsnapshot/include/libsnapshot/cow_reader.h
@@ -74,7 +74,7 @@
virtual bool GetLastLabel(uint64_t* label) = 0;
// Return an iterator for retrieving CowOperation entries.
- virtual std::unique_ptr<ICowOpIter> GetOpIter() = 0;
+ virtual std::unique_ptr<ICowOpIter> GetOpIter(bool merge_progress) = 0;
// Return an iterator for retrieving CowOperation entries in reverse merge order
virtual std::unique_ptr<ICowOpIter> GetRevMergeOpIter(bool ignore_progress) = 0;
@@ -115,7 +115,7 @@
USERSPACE_MERGE = 1,
};
- CowReader(ReaderFlags reader_flag = ReaderFlags::DEFAULT);
+ CowReader(ReaderFlags reader_flag = ReaderFlags::DEFAULT, bool is_merge = false);
~CowReader() { owned_fd_ = {}; }
// Parse the COW, optionally, up to the given label. If no label is
@@ -135,7 +135,7 @@
// CowOperation objects. Get() returns a unique CowOperation object
// whose lifetime depends on the CowOpIter object; the return
// value of these will never be null.
- std::unique_ptr<ICowOpIter> GetOpIter() override;
+ std::unique_ptr<ICowOpIter> GetOpIter(bool merge_progress = false) override;
std::unique_ptr<ICowOpIter> GetRevMergeOpIter(bool ignore_progress = false) override;
std::unique_ptr<ICowOpIter> GetMergeOpIter(bool ignore_progress = false) override;
@@ -177,6 +177,7 @@
bool has_seq_ops_{};
std::shared_ptr<std::unordered_map<uint64_t, uint64_t>> data_loc_;
ReaderFlags reader_flag_;
+ bool is_merge_{};
};
} // namespace snapshot
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index 91f31b0..2233a38 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -349,7 +349,7 @@
}
AssertionResult DeleteDevice(const std::string& device) {
- if (!dm_.DeleteDeviceIfExists(device)) {
+ if (!sm->DeleteDeviceIfExists(device, 1s)) {
return AssertionFailure() << "Can't delete " << device;
}
return AssertionSuccess();
@@ -2660,7 +2660,6 @@
}
void TearDown() override {
RETURN_IF_NON_VIRTUAL_AB();
- return; // BUG(149738928)
EXPECT_TRUE(!image_manager_->BackingImageExists(kImageName) ||
image_manager_->DeleteBackingImage(kImageName));
@@ -2669,19 +2668,6 @@
std::unique_ptr<LowSpaceUserdata> userdata_;
};
-TEST_P(ImageManagerTest, CreateImageEnoughAvailSpace) {
- if (userdata_->available_space() == 0) {
- GTEST_SKIP() << "/data is full (" << userdata_->available_space()
- << " bytes available), skipping";
- }
- ASSERT_TRUE(image_manager_->CreateBackingImage(kImageName, userdata_->available_space(),
- IImageManager::CREATE_IMAGE_DEFAULT))
- << "Should be able to create image with size = " << userdata_->available_space()
- << " bytes";
- ASSERT_TRUE(image_manager_->DeleteBackingImage(kImageName))
- << "Should be able to delete created image";
-}
-
TEST_P(ImageManagerTest, CreateImageNoSpace) {
uint64_t to_allocate = userdata_->free_space() + userdata_->bsize();
auto res = image_manager_->CreateBackingImage(kImageName, to_allocate,
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
index 8939b78..492c43f 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_core.cpp
@@ -162,7 +162,7 @@
}
bool SnapshotHandler::ReadMetadata() {
- reader_ = std::make_unique<CowReader>(CowReader::ReaderFlags::USERSPACE_MERGE);
+ reader_ = std::make_unique<CowReader>(CowReader::ReaderFlags::USERSPACE_MERGE, true);
CowHeader header;
CowOptions options;
@@ -193,7 +193,7 @@
UpdateMergeCompletionPercentage();
// Initialize the iterator for reading metadata
- std::unique_ptr<ICowOpIter> cowop_iter = reader_->GetMergeOpIter();
+ std::unique_ptr<ICowOpIter> cowop_iter = reader_->GetOpIter(true);
int num_ra_ops_per_iter = ((GetBufferDataSize()) / BLOCK_SZ);
int ra_index = 0;
diff --git a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp
index 63f47d6..d57f434 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_merge.cpp
@@ -466,7 +466,7 @@
}
bool Worker::Merge() {
- cowop_iter_ = reader_->GetMergeOpIter();
+ cowop_iter_ = reader_->GetOpIter(true);
bool retry = false;
bool ordered_ops_merge_status;
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 b9e4255..fbe57d2 100644
--- a/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
+++ b/fs_mgr/libsnapshot/snapuserd/user-space-merge/snapuserd_readahead.cpp
@@ -772,7 +772,7 @@
}
void ReadAhead::InitializeRAIter() {
- cowop_iter_ = reader_->GetMergeOpIter();
+ cowop_iter_ = reader_->GetOpIter(true);
}
bool ReadAhead::RAIterDone() {
diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh
index 9542bc1..11e4790 100755
--- a/fs_mgr/tests/adb-remount-test.sh
+++ b/fs_mgr/tests/adb-remount-test.sh
@@ -1099,8 +1099,8 @@
D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay "` &&
echo "${H}" &&
echo "${D}" &&
- echo "${YELLOW}[ WARNING ]${NORMAL} overlays present before setup" >&2 ||
- echo "${GREEN}[ OK ]${NORMAL} no overlay present before setup" >&2
+ die "overlay takeover unexpected at this phase"
+echo "${GREEN}[ OK ]${NORMAL} no overlay present before setup" >&2
overlayfs_needed=true
D=`adb_sh cat /proc/mounts </dev/null |
skip_administrative_mounts data`
@@ -1133,73 +1133,38 @@
die "need overlayfs, but do not have it"
fi
-echo "${GREEN}[ RUN ]${NORMAL} disable verity" >&2
+echo "${GREEN}[ RUN ]${NORMAL} disable-verity -R" >&2
-T=`adb_date`
-H=`adb disable-verity 2>&1`
-err=${?}
L=
-D="${H%?Now reboot your device for settings to take effect*}"
-if [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ]; then
- echo "${GREEN}[ OK ]${NORMAL} using overlayfs" >&2
+T=$(adb_date)
+H=$(adb_su disable-verity -R 2>&1)
+err="${?}"
+echo "${H}"
+
+if [ "${err}" != 0 ]; then
+ die -t "${T}" "disable-verity -R"
fi
-if [ ${err} != 0 ]; then
- echo "${H}"
- ( [ -n "${L}" ] && echo "${L}" && false ) ||
- die -t "${T}" "disable-verity"
+
+# Fuzzy search for a line that contains "overlay" and "fail". Informational only.
+if echo "${H}" | grep -i "overlay" | grep -iq "fail"; then
+ echo "${YELLOW}[ WARNING ]${NORMAL} overlayfs setup whined" >&2
fi
-rebooted=false
-if [ X"${D}" != X"${H}" ]; then
- echo "${H}"
- if [ X"${D}" != X"${D##*setup failed}" ]; then
- echo "${YELLOW}[ WARNING ]${NORMAL} overlayfs setup whined" >&2
- fi
- D=`adb_sh df -k </dev/null` &&
- H=`echo "${D}" | head -1` &&
- D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay " || true` &&
- [ -z "${D}" ] ||
- ( echo "${H}" && echo "${D}" && false ) ||
- die -t ${T} "overlay takeover unexpected at this phase"
- echo "${GREEN}[ INFO ]${NORMAL} rebooting as requested" >&2
- L=`adb_logcat -b all -v nsec -t ${T} 2>&1`
- adb_reboot &&
- adb_wait ${ADB_WAIT} ||
- die "lost device after reboot requested `usb_status`"
+
+adb_wait "${ADB_WAIT}" &&
adb_root ||
- die "lost device after elevation to root `usb_status`"
- rebooted=true
- # re-disable verity to see the setup remarks expected
- T=`adb_date`
- H=`adb disable-verity 2>&1`
- err=${?}
- D="${H%?Now reboot your device for settings to take effect*}"
- if [ X"${D}" != X"${D##*[Uu]sing overlayfs}" ]; then
- echo "${GREEN}[ OK ]${NORMAL} using overlayfs" >&2
+ die "lost device after adb shell su root disable-verity -R $(usb_status)"
+
+if ${overlayfs_needed}; then
+ has_overlayfs_setup=false
+ for d in ${OVERLAYFS_BACKING}; do
+ if adb_test -d "/${d}/overlay"; then
+ has_overlayfs_setup=true
+ echo "${GREEN}[ OK ]${NORMAL} /${d}/overlay is setup" >&2
+ fi
+ done
+ if ! ${has_overlayfs_setup}; then
+ die "no overlay being setup after disable-verity -R"
fi
- if [ ${err} != 0 ]; then
- T=
- fi
-fi
-if ${overlayfs_supported} && ${overlayfs_needed} && [ X"${D}" != X"${D##*setup failed}" ]; then
- echo "${D}"
- ( [ -n "${L}" ] && echo "${L}" && false ) ||
- die -t "${T}" "setup for overlay"
-fi
-if [ X"${D}" != X"${D##*Successfully disabled verity}" ]; then
- echo "${H}"
- D=`adb_sh df -k </dev/null` &&
- H=`echo "${D}" | head -1` &&
- D=`echo "${D}" | grep -v " /vendor/..*$" | grep "^overlay " || true` &&
- [ -z "${D}" ] ||
- ( echo "${H}" && echo "${D}" && false ) ||
- ( [ -n "${L}" ] && echo "${L}" && false ) ||
- die -t "${T}" "overlay takeover unexpected"
- [ -n "${L}" ] && echo "${L}"
- die -t "${T}" "unexpected report of verity being disabled a second time"
-elif ${rebooted}; then
- echo "${GREEN}[ OK ]${NORMAL} verity already disabled" >&2
-else
- echo "${YELLOW}[ WARNING ]${NORMAL} verity already disabled" >&2
fi
echo "${GREEN}[ RUN ]${NORMAL} remount" >&2
@@ -1319,26 +1284,9 @@
B="`adb_cat /system/priv-app/hello`" ||
die "system priv-app hello"
check_eq "${A}" "${B}" /system/priv-app before reboot
-SYSTEM_DEVT=`adb_sh stat --format=%D /system/hello </dev/null`
-VENDOR_DEVT=`adb_sh stat --format=%D /vendor/hello </dev/null`
SYSTEM_INO=`adb_sh stat --format=%i /system/hello </dev/null`
VENDOR_INO=`adb_sh stat --format=%i /vendor/hello </dev/null`
-BASE_SYSTEM_DEVT=`adb_sh stat --format=%D /system/bin/stat </dev/null`
-BASE_VENDOR_DEVT=`adb_sh stat --format=%D /vendor/bin/stat </dev/null`
-check_eq "${SYSTEM_DEVT%[0-9a-fA-F][0-9a-fA-F]}" "${VENDOR_DEVT%[0-9a-fA-F][0-9a-fA-F]}" vendor and system devt
check_ne "${SYSTEM_INO}" "${VENDOR_INO}" vendor and system inode
-if ${overlayfs_needed}; then
- check_ne "${SYSTEM_DEVT}" "${BASE_SYSTEM_DEVT}" system devt
- check_ne "${VENDOR_DEVT}" "${BASE_VENDOR_DEVT}" vendor devt
-else
- check_eq "${SYSTEM_DEVT}" "${BASE_SYSTEM_DEVT}" system devt
- check_eq "${VENDOR_DEVT}" "${BASE_VENDOR_DEVT}" vendor devt
-fi
-check_ne "${BASE_SYSTEM_DEVT}" "${BASE_VENDOR_DEVT}" --warning system/vendor devt
-[ -n "${SYSTEM_DEVT%[0-9a-fA-F][0-9a-fA-F]}" ] ||
- echo "${YELLOW}[ WARNING ]${NORMAL} system devt ${SYSTEM_DEVT} major 0" >&2
-[ -n "${VENDOR_DEVT%[0-9a-fA-F][0-9a-fA-F]}" ] ||
- echo "${YELLOW}[ WARNING ]${NORMAL} vendor devt ${VENDOR_DEVT} major 0" >&2
# Download libc.so, append some garbage, push back, and check if the file
# is updated.
@@ -1411,13 +1359,8 @@
echo "${GREEN}[ OK ]${NORMAL} ${i} content remains after reboot" >&2
done
-check_eq "${SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/hello </dev/null`" system devt after reboot
-check_eq "${VENDOR_DEVT}" "`adb_sh stat --format=%D /vendor/hello </dev/null`" vendor devt after reboot
check_eq "${SYSTEM_INO}" "`adb_sh stat --format=%i /system/hello </dev/null`" system inode after reboot
check_eq "${VENDOR_INO}" "`adb_sh stat --format=%i /vendor/hello </dev/null`" vendor inode after reboot
-check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/bin/stat </dev/null`" --warning base system devt after reboot
-check_eq "${BASE_VENDOR_DEVT}" "`adb_sh stat --format=%D /vendor/bin/stat </dev/null`" --warning base vendor devt after reboot
-check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/xbin/su </dev/null`" --warning devt for su after reboot
# Feed log with selinux denials as a result of overlays
adb_sh find ${MOUNTS} </dev/null >/dev/null 2>/dev/null || true
@@ -1542,10 +1485,7 @@
--warning vendor content after flash vendor
fi
- check_eq "${SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/hello </dev/null`" system devt after reboot
check_eq "${SYSTEM_INO}" "`adb_sh stat --format=%i /system/hello </dev/null`" system inode after reboot
- check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/bin/stat </dev/null`" --warning base system devt after reboot
- check_eq "${BASE_SYSTEM_DEVT}" "`adb_sh stat --format=%D /system/xbin/su </dev/null`" --warning devt for su after reboot
fi
diff --git a/init/Android.bp b/init/Android.bp
index 2dd9683..856fe3e 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -222,8 +222,8 @@
],
whole_static_libs: [
"libcap",
- "com.android.sysprop.apex",
- "com.android.sysprop.init",
+ "libcom.android.sysprop.apex",
+ "libcom.android.sysprop.init",
],
header_libs: ["bootimg_headers"],
proto: {
diff --git a/init/TEST_MAPPING b/init/TEST_MAPPING
index 36ca379..402b501 100644
--- a/init/TEST_MAPPING
+++ b/init/TEST_MAPPING
@@ -8,6 +8,14 @@
},
{
"name": "MicrodroidHostTestCases"
+ },
+ {
+ "name": "CtsSecurityHostTestCases",
+ "options": [
+ {
+ "include-filter": "android.security.cts.SeamendcHostTest"
+ }
+ ]
}
],
"hwasan-presubmit": [
@@ -19,6 +27,14 @@
},
{
"name": "MicrodroidHostTestCases"
+ },
+ {
+ "name": "CtsSecurityHostTestCases",
+ "options": [
+ {
+ "include-filter": "android.security.cts.SeamendcHostTest"
+ }
+ ]
}
]
}
diff --git a/init/epoll.cpp b/init/epoll.cpp
index 74d8aac..0580f86 100644
--- a/init/epoll.cpp
+++ b/init/epoll.cpp
@@ -23,6 +23,8 @@
#include <functional>
#include <map>
+#include <android-base/logging.h>
+
namespace android {
namespace init {
@@ -42,8 +44,11 @@
if (!events) {
return Error() << "Must specify events";
}
- auto sp = std::make_shared<decltype(handler)>(std::move(handler));
- auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(sp));
+
+ Info info;
+ info.events = events;
+ info.handler = std::make_shared<decltype(handler)>(std::move(handler));
+ auto [it, inserted] = epoll_handlers_.emplace(fd, std::move(info));
if (!inserted) {
return Error() << "Cannot specify two epoll handlers for a given FD";
}
@@ -84,8 +89,14 @@
}
std::vector<std::shared_ptr<Handler>> pending_functions;
for (int i = 0; i < num_events; ++i) {
- auto sp = *reinterpret_cast<std::shared_ptr<Handler>*>(ev[i].data.ptr);
- pending_functions.emplace_back(std::move(sp));
+ auto& info = *reinterpret_cast<Info*>(ev[i].data.ptr);
+ if ((info.events & (EPOLLIN | EPOLLPRI)) == (EPOLLIN | EPOLLPRI) &&
+ (ev[i].events & EPOLLIN) != ev[i].events) {
+ // This handler wants to know about exception events, and just got one.
+ // Log something informational.
+ LOG(ERROR) << "Received unexpected epoll event set: " << ev[i].events;
+ }
+ pending_functions.emplace_back(info.handler);
}
return pending_functions;
diff --git a/init/epoll.h b/init/epoll.h
index 0df5289..f58ae8d 100644
--- a/init/epoll.h
+++ b/init/epoll.h
@@ -46,8 +46,13 @@
std::optional<std::chrono::milliseconds> timeout);
private:
+ struct Info {
+ std::shared_ptr<Handler> handler;
+ uint32_t events;
+ };
+
android::base::unique_fd epoll_fd_;
- std::map<int, std::shared_ptr<Handler>> epoll_handlers_;
+ std::map<int, Info> epoll_handlers_;
};
} // namespace init
diff --git a/init/init.cpp b/init/init.cpp
index 5f516b7..be99a1c 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -33,7 +33,10 @@
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <sys/_system_properties.h>
+#include <filesystem>
+#include <fstream>
#include <functional>
+#include <iostream>
#include <map>
#include <memory>
#include <mutex>
@@ -695,10 +698,10 @@
static constexpr std::chrono::milliseconds kDiagnosticTimeout = 10s;
-static void HandleSignalFd() {
+static void HandleSignalFd(bool one_off) {
signalfd_siginfo siginfo;
auto started = std::chrono::steady_clock::now();
- for (;;) {
+ do {
ssize_t bytes_read = TEMP_FAILURE_RETRY(read(signal_fd, &siginfo, sizeof(siginfo)));
if (bytes_read < 0 && errno == EAGAIN) {
auto now = std::chrono::steady_clock::now();
@@ -716,7 +719,7 @@
return;
}
break;
- }
+ } while (!one_off);
switch (siginfo.ssi_signo) {
case SIGCHLD:
@@ -776,7 +779,9 @@
PLOG(FATAL) << "failed to create signalfd";
}
- if (auto result = epoll->RegisterHandler(signal_fd, HandleSignalFd); !result.ok()) {
+ constexpr int flags = EPOLLIN | EPOLLPRI;
+ auto handler = std::bind(HandleSignalFd, false);
+ if (auto result = epoll->RegisterHandler(signal_fd, handler, flags); !result.ok()) {
LOG(FATAL) << result.error();
}
}
@@ -905,6 +910,32 @@
return {};
}
+static void DumpPidFds(const std::string& prefix, pid_t pid) {
+ std::error_code ec;
+ std::string proc_dir = "/proc/" + std::to_string(pid) + "/fd";
+ for (const auto& entry : std::filesystem::directory_iterator(proc_dir)) {
+ std::string target;
+ if (android::base::Readlink(entry.path(), &target)) {
+ LOG(ERROR) << prefix << target;
+ } else {
+ LOG(ERROR) << prefix << entry.path();
+ }
+ }
+}
+
+static void DumpFile(const std::string& prefix, const std::string& file) {
+ std::ifstream fp(file);
+ if (!fp) {
+ LOG(ERROR) << "Could not open " << file;
+ return;
+ }
+
+ std::string line;
+ while (std::getline(fp, line)) {
+ LOG(ERROR) << prefix << line;
+ }
+}
+
int SecondStageMain(int argc, char** argv) {
if (REBOOT_BOOTLOADER_ON_PANIC) {
InstallRebootSignalHandlers();
@@ -1114,11 +1145,23 @@
(*function)();
}
} else if (Service::is_exec_service_running()) {
+ static bool dumped_diagnostics = false;
std::chrono::duration<double> waited =
std::chrono::steady_clock::now() - Service::exec_service_started();
if (waited >= kDiagnosticTimeout) {
LOG(ERROR) << "Exec service is hung? Waited " << waited.count()
<< " without SIGCHLD";
+ if (!dumped_diagnostics) {
+ DumpPidFds("exec service opened: ", Service::exec_service_pid());
+
+ std::string status_file =
+ "/proc/" + std::to_string(Service::exec_service_pid()) + "/status";
+ DumpFile("exec service: ", status_file);
+ dumped_diagnostics = true;
+
+ LOG(INFO) << "Attempting to handle any stuck SIGCHLDs...";
+ HandleSignalFd(true);
+ }
}
}
if (!IsShuttingDown()) {
diff --git a/init/service.cpp b/init/service.cpp
index 730b6b6..b36584b 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -127,6 +127,7 @@
unsigned long Service::next_start_order_ = 1;
bool Service::is_exec_service_running_ = false;
+pid_t Service::exec_service_pid_ = -1;
std::chrono::time_point<std::chrono::steady_clock> Service::exec_service_started_;
Service::Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
@@ -395,6 +396,7 @@
flags_ |= SVC_EXEC;
is_exec_service_running_ = true;
+ exec_service_pid_ = pid_;
exec_service_started_ = std::chrono::steady_clock::now();
LOG(INFO) << "SVC_EXEC service '" << name_ << "' pid " << pid_ << " (uid " << proc_attr_.uid
diff --git a/init/service.h b/init/service.h
index f7f32d9..c14b312 100644
--- a/init/service.h
+++ b/init/service.h
@@ -103,6 +103,7 @@
size_t CheckAllCommands() const { return onrestart_.CheckAllCommands(); }
static bool is_exec_service_running() { return is_exec_service_running_; }
+ static pid_t exec_service_pid() { return exec_service_pid_; }
static std::chrono::time_point<std::chrono::steady_clock> exec_service_started() {
return exec_service_started_;
}
diff --git a/init/sigchld_handler.cpp b/init/sigchld_handler.cpp
index 9b2c7d9..6fc64df 100644
--- a/init/sigchld_handler.cpp
+++ b/init/sigchld_handler.cpp
@@ -95,7 +95,10 @@
LOG(INFO) << name << " received signal " << siginfo.si_status << wait_string;
}
- if (!service) return pid;
+ if (!service) {
+ LOG(INFO) << name << " did not have an associated service entry and will not be reaped";
+ return pid;
+ }
service->Reap(siginfo);
diff --git a/libmodprobe/libmodprobe.cpp b/libmodprobe/libmodprobe.cpp
index b2ace34..e071c96 100644
--- a/libmodprobe/libmodprobe.cpp
+++ b/libmodprobe/libmodprobe.cpp
@@ -444,6 +444,7 @@
// until all modules are loaded.
bool Modprobe::LoadModulesParallel(int num_threads) {
bool ret = true;
+ int count = -1;
std::map<std::string, std::set<std::string>> mod_with_deps;
// Get dependencies
@@ -471,18 +472,21 @@
}
}
- while (!mod_with_deps.empty()) {
+ while (!mod_with_deps.empty() && count != module_loaded_.size()) {
std::vector<std::thread> threads;
std::vector<std::string> mods_path_to_load;
std::mutex vector_lock;
+ count = module_loaded_.size();
// Find independent modules
for (const auto& [it_mod, it_dep] : mod_with_deps) {
if (it_dep.size() == 1) {
if (module_options_[it_mod].find("load_sequential=1") != std::string::npos) {
- LoadWithAliases(it_mod, true);
+ if (!LoadWithAliases(it_mod, true) && !IsBlocklisted(it_mod)) {
+ return false;
+ }
} else {
- mods_path_to_load.emplace_back(*(it_dep.begin()));
+ mods_path_to_load.emplace_back(it_mod);
}
}
}
@@ -491,12 +495,16 @@
auto thread_function = [&] {
std::unique_lock lk(vector_lock);
while (!mods_path_to_load.empty()) {
- auto mod_path_to_load = std::move(mods_path_to_load.back());
+ auto ret_load = true;
+ auto mod_to_load = std::move(mods_path_to_load.back());
mods_path_to_load.pop_back();
lk.unlock();
- ret &= Insmod(mod_path_to_load, "");
+ ret_load &= LoadWithAliases(mod_to_load, true);
lk.lock();
+ if (!ret_load && !IsBlocklisted(mod_to_load)) {
+ ret &= ret_load;
+ }
}
};
@@ -508,6 +516,8 @@
thread.join();
}
+ if (!ret) return ret;
+
std::lock_guard guard(module_loaded_lock_);
// Remove loaded module form mod_with_deps and soft dependencies of other modules
for (const auto& module_loaded : module_loaded_) {
diff --git a/libprocessgroup/Android.bp b/libprocessgroup/Android.bp
index 7b0e0d3..c6a0737 100644
--- a/libprocessgroup/Android.bp
+++ b/libprocessgroup/Android.bp
@@ -2,6 +2,17 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
+cc_defaults {
+ name: "libprocessgroup_defaults",
+ cpp_std: "gnu++20",
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wexit-time-destructors",
+ "-Wno-unused-parameter",
+ ],
+}
+
cc_library_headers {
name: "libprocessgroup_headers",
vendor_available: true,
@@ -62,11 +73,7 @@
export_header_lib_headers: [
"libprocessgroup_headers",
],
- cflags: [
- "-Wall",
- "-Werror",
- "-Wexit-time-destructors",
- ],
+ defaults: ["libprocessgroup_defaults"],
apex_available: [
"//apex_available:platform",
"//apex_available:anyapex",
@@ -77,12 +84,7 @@
cc_test {
name: "task_profiles_test",
host_supported: true,
- cflags: [
- "-Wall",
- "-Werror",
- "-Wexit-time-destructors",
- "-Wno-unused-parameter",
- ],
+ defaults: ["libprocessgroup_defaults"],
srcs: [
"task_profiles_test.cpp",
],
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h
index 39b9f3f..45a723f 100644
--- a/libprocessgroup/include/processgroup/processgroup.h
+++ b/libprocessgroup/include/processgroup/processgroup.h
@@ -18,7 +18,10 @@
#include <sys/cdefs.h>
#include <sys/types.h>
+#include <initializer_list>
+#include <span>
#include <string>
+#include <string_view>
#include <vector>
__BEGIN_DECLS
@@ -33,6 +36,19 @@
bool SetTaskProfiles(int tid, const std::vector<std::string>& profiles, bool use_fd_cache = false);
bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector<std::string>& profiles);
+__END_DECLS
+
+bool SetTaskProfiles(int tid, std::initializer_list<std::string_view> profiles,
+ bool use_fd_cache = false);
+bool SetProcessProfiles(uid_t uid, pid_t pid, std::initializer_list<std::string_view> profiles);
+#if _LIBCPP_STD_VER > 17
+bool SetTaskProfiles(int tid, std::span<const std::string_view> profiles,
+ bool use_fd_cache = false);
+bool SetProcessProfiles(uid_t uid, pid_t pid, std::span<const std::string_view> profiles);
+#endif
+
+__BEGIN_DECLS
+
#ifndef __ANDROID_VNDK__
bool SetProcessProfilesCached(uid_t uid, pid_t pid, const std::vector<std::string>& profiles);
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index 51c810e..bdda102 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -148,14 +148,35 @@
}
bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector<std::string>& profiles) {
+ return TaskProfiles::GetInstance().SetProcessProfiles(
+ uid, pid, std::span<const std::string>(profiles), false);
+}
+
+bool SetProcessProfiles(uid_t uid, pid_t pid, std::initializer_list<std::string_view> profiles) {
+ return TaskProfiles::GetInstance().SetProcessProfiles(
+ uid, pid, std::span<const std::string_view>(profiles), false);
+}
+
+bool SetProcessProfiles(uid_t uid, pid_t pid, std::span<const std::string_view> profiles) {
return TaskProfiles::GetInstance().SetProcessProfiles(uid, pid, profiles, false);
}
bool SetProcessProfilesCached(uid_t uid, pid_t pid, const std::vector<std::string>& profiles) {
- return TaskProfiles::GetInstance().SetProcessProfiles(uid, pid, profiles, true);
+ return TaskProfiles::GetInstance().SetProcessProfiles(
+ uid, pid, std::span<const std::string>(profiles), true);
}
bool SetTaskProfiles(int tid, const std::vector<std::string>& profiles, bool use_fd_cache) {
+ return TaskProfiles::GetInstance().SetTaskProfiles(tid, std::span<const std::string>(profiles),
+ use_fd_cache);
+}
+
+bool SetTaskProfiles(int tid, std::initializer_list<std::string_view> profiles, bool use_fd_cache) {
+ return TaskProfiles::GetInstance().SetTaskProfiles(
+ tid, std::span<const std::string_view>(profiles), use_fd_cache);
+}
+
+bool SetTaskProfiles(int tid, std::span<const std::string_view> profiles, bool use_fd_cache) {
return TaskProfiles::GetInstance().SetTaskProfiles(tid, profiles, use_fd_cache);
}
@@ -166,12 +187,12 @@
// https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3574427/5/src/linux/android.rs#12
extern "C" bool android_set_process_profiles(uid_t uid, pid_t pid, size_t num_profiles,
const char* profiles[]) {
- std::vector<std::string> profiles_;
+ std::vector<std::string_view> profiles_;
profiles_.reserve(num_profiles);
for (size_t i = 0; i < num_profiles; i++) {
profiles_.emplace_back(profiles[i]);
}
- return SetProcessProfiles(uid, pid, profiles_);
+ return SetProcessProfiles(uid, pid, std::span<const std::string_view>(profiles_));
}
static std::string ConvertUidToPath(const char* cgroup, uid_t uid) {
diff --git a/libprocessgroup/setup/cgroup_map_write.cpp b/libprocessgroup/setup/cgroup_map_write.cpp
index 3831ef2..304248a 100644
--- a/libprocessgroup/setup/cgroup_map_write.cpp
+++ b/libprocessgroup/setup/cgroup_map_write.cpp
@@ -410,7 +410,7 @@
// Make sure we do this only one time. No need for std::call_once because
// init is a single-threaded process
if (access(CGROUPS_RC_PATH, F_OK) == 0) {
- LOG(WARNING) << "Attempt to call SetupCgroups more than once";
+ LOG(WARNING) << "Attempt to call CgroupSetup() more than once";
return true;
}
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index e1c5934..744710f 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -786,7 +786,7 @@
return true;
}
-TaskProfile* TaskProfiles::GetProfile(const std::string& name) const {
+TaskProfile* TaskProfiles::GetProfile(std::string_view name) const {
auto iter = profiles_.find(name);
if (iter != profiles_.end()) {
@@ -795,7 +795,7 @@
return nullptr;
}
-const IProfileAttribute* TaskProfiles::GetAttribute(const std::string& name) const {
+const IProfileAttribute* TaskProfiles::GetAttribute(std::string_view name) const {
auto iter = attributes_.find(name);
if (iter != attributes_.end()) {
@@ -804,8 +804,9 @@
return nullptr;
}
-bool TaskProfiles::SetProcessProfiles(uid_t uid, pid_t pid,
- const std::vector<std::string>& profiles, bool use_fd_cache) {
+template <typename T>
+bool TaskProfiles::SetProcessProfiles(uid_t uid, pid_t pid, std::span<const T> profiles,
+ bool use_fd_cache) {
bool success = true;
for (const auto& name : profiles) {
TaskProfile* profile = GetProfile(name);
@@ -825,8 +826,8 @@
return success;
}
-bool TaskProfiles::SetTaskProfiles(int tid, const std::vector<std::string>& profiles,
- bool use_fd_cache) {
+template <typename T>
+bool TaskProfiles::SetTaskProfiles(int tid, std::span<const T> profiles, bool use_fd_cache) {
bool success = true;
for (const auto& name : profiles) {
TaskProfile* profile = GetProfile(name);
@@ -845,3 +846,14 @@
}
return success;
}
+
+template bool TaskProfiles::SetProcessProfiles(uid_t uid, pid_t pid,
+ std::span<const std::string> profiles,
+ bool use_fd_cache);
+template bool TaskProfiles::SetProcessProfiles(uid_t uid, pid_t pid,
+ std::span<const std::string_view> profiles,
+ bool use_fd_cache);
+template bool TaskProfiles::SetTaskProfiles(int tid, std::span<const std::string> profiles,
+ bool use_fd_cache);
+template bool TaskProfiles::SetTaskProfiles(int tid, std::span<const std::string_view> profiles,
+ bool use_fd_cache);
diff --git a/libprocessgroup/task_profiles.h b/libprocessgroup/task_profiles.h
index df08f65..85b3f91 100644
--- a/libprocessgroup/task_profiles.h
+++ b/libprocessgroup/task_profiles.h
@@ -18,9 +18,12 @@
#include <sys/cdefs.h>
#include <sys/types.h>
+#include <functional>
#include <map>
#include <mutex>
+#include <span>
#include <string>
+#include <string_view>
#include <vector>
#include <android-base/unique_fd.h>
@@ -206,18 +209,19 @@
// Should be used by all users
static TaskProfiles& GetInstance();
- TaskProfile* GetProfile(const std::string& name) const;
- const IProfileAttribute* GetAttribute(const std::string& name) const;
+ TaskProfile* GetProfile(std::string_view name) const;
+ const IProfileAttribute* GetAttribute(std::string_view name) const;
void DropResourceCaching(ProfileAction::ResourceCacheType cache_type) const;
- bool SetProcessProfiles(uid_t uid, pid_t pid, const std::vector<std::string>& profiles,
- bool use_fd_cache);
- bool SetTaskProfiles(int tid, const std::vector<std::string>& profiles, bool use_fd_cache);
+ template <typename T>
+ bool SetProcessProfiles(uid_t uid, pid_t pid, std::span<const T> profiles, bool use_fd_cache);
+ template <typename T>
+ bool SetTaskProfiles(int tid, std::span<const T> profiles, bool use_fd_cache);
private:
- std::map<std::string, std::shared_ptr<TaskProfile>> profiles_;
- std::map<std::string, std::unique_ptr<IProfileAttribute>> attributes_;
-
TaskProfiles();
bool Load(const CgroupMap& cg_map, const std::string& file_name);
+
+ std::map<std::string, std::shared_ptr<TaskProfile>, std::less<>> profiles_;
+ std::map<std::string, std::unique_ptr<IProfileAttribute>, std::less<>> attributes_;
};
diff --git a/libstats/pull_lazy/TEST_MAPPING b/libstats/pull_lazy/TEST_MAPPING
index 92f1e6a..0282a03 100644
--- a/libstats/pull_lazy/TEST_MAPPING
+++ b/libstats/pull_lazy/TEST_MAPPING
@@ -4,7 +4,7 @@
"name" : "libstatspull_lazy_test"
}
],
- "hwasan-postsubmit" : [
+ "hwasan-presubmit" : [
{
"name" : "libstatspull_lazy_test"
}
diff --git a/libutils/Android.bp b/libutils/Android.bp
index f663671..7939e82 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -68,6 +68,7 @@
"-Wall",
"-Werror",
"-Wno-exit-time-destructors",
+ "-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION",
],
header_libs: [
"libbase_headers",
@@ -173,6 +174,10 @@
min_sdk_version: "apex_inherit",
afdo: true,
+
+ header_abi_checker: {
+ diff_flags: ["-allow-adding-removing-weak-symbols"],
+ },
}
cc_library {
diff --git a/libutils/Looper.cpp b/libutils/Looper.cpp
index 292425a..1a3f34b 100644
--- a/libutils/Looper.cpp
+++ b/libutils/Looper.cpp
@@ -117,14 +117,15 @@
int result = pthread_once(& gTLSOnce, initTLSKey);
LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed");
- return (Looper*)pthread_getspecific(gTLSKey);
+ Looper* looper = (Looper*)pthread_getspecific(gTLSKey);
+ return sp<Looper>::fromExisting(looper);
}
sp<Looper> Looper::prepare(int opts) {
bool allowNonCallbacks = opts & PREPARE_ALLOW_NON_CALLBACKS;
sp<Looper> looper = Looper::getForThread();
if (looper == nullptr) {
- looper = new Looper(allowNonCallbacks);
+ looper = sp<Looper>::make(allowNonCallbacks);
Looper::setForThread(looper);
}
if (looper->getAllowNonCallbacks() != allowNonCallbacks) {
@@ -425,7 +426,11 @@
}
int Looper::addFd(int fd, int ident, int events, Looper_callbackFunc callback, void* data) {
- return addFd(fd, ident, events, callback ? new SimpleLooperCallback(callback) : nullptr, data);
+ sp<SimpleLooperCallback> looperCallback;
+ if (callback) {
+ looperCallback = sp<SimpleLooperCallback>::make(callback);
+ }
+ return addFd(fd, ident, events, looperCallback, data);
}
int Looper::addFd(int fd, int ident, int events, const sp<LooperCallback>& callback, void* data) {
diff --git a/libutils/NativeHandle.cpp b/libutils/NativeHandle.cpp
index d437a9f..819a603 100644
--- a/libutils/NativeHandle.cpp
+++ b/libutils/NativeHandle.cpp
@@ -20,7 +20,7 @@
namespace android {
sp<NativeHandle> NativeHandle::create(native_handle_t* handle, bool ownsHandle) {
- return handle ? new NativeHandle(handle, ownsHandle) : nullptr;
+ return handle ? sp<NativeHandle>::make(handle, ownsHandle) : nullptr;
}
NativeHandle::NativeHandle(native_handle_t* handle, bool ownsHandle)
diff --git a/libutils/Threads.cpp b/libutils/Threads.cpp
index 4dacdc6..e756fec 100644
--- a/libutils/Threads.cpp
+++ b/libutils/Threads.cpp
@@ -673,7 +673,7 @@
mThread = thread_id_t(-1);
// hold a strong reference on ourself
- mHoldSelf = this;
+ mHoldSelf = sp<Thread>::fromExisting(this);
mRunning = true;
diff --git a/libutils/include/utils/NativeHandle.h b/libutils/include/utils/NativeHandle.h
index 73fe804..f26a1a4 100644
--- a/libutils/include/utils/NativeHandle.h
+++ b/libutils/include/utils/NativeHandle.h
@@ -39,6 +39,8 @@
private:
// for access to the destructor
friend class LightRefBase<NativeHandle>;
+ // for access to the constructor
+ friend class sp<NativeHandle>;
NativeHandle(native_handle_t* handle, bool ownsHandle);
~NativeHandle();
diff --git a/rootdir/etc/linker.config.json b/rootdir/etc/linker.config.json
index 780ace5..c88c7ff 100644
--- a/rootdir/etc/linker.config.json
+++ b/rootdir/etc/linker.config.json
@@ -31,5 +31,9 @@
"libadb_pairing_auth.so",
"libadb_pairing_connection.so",
"libadb_pairing_server.so"
+ ],
+ "provideLibs": [
+ "libaptX_encoder.so",
+ "libaptXHD_encoder.so"
]
}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 660f18c..60bf57b 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -723,9 +723,13 @@
# Multi-installed APEXes are selected using persist props.
# Load persist properties and override properties (if enabled) from /data,
# before starting apexd.
+ # /data/property should be created before `load_persist_props`
+ mkdir /data/property 0700 root root encryption=Require
load_persist_props
+
start logd
start logd-reinit
+
# Some existing vendor rc files use 'on load_persist_props_action' to know
# when persist props are ready. These are difficult to change due to GRF,
# so continue triggering this action here even though props are already loaded
@@ -852,7 +856,6 @@
mkdir /data/app-asec 0700 root root encryption=Require
mkdir /data/app-lib 0771 system system encryption=Require
mkdir /data/app 0771 system system encryption=Require
- mkdir /data/property 0700 root root encryption=Require
# create directory for updated font files.
mkdir /data/fonts/ 0771 root root encryption=Require
diff --git a/set-verity-state/Android.bp b/set-verity-state/Android.bp
index f0df350..f40118b 100644
--- a/set-verity-state/Android.bp
+++ b/set-verity-state/Android.bp
@@ -9,17 +9,18 @@
srcs: ["set-verity-state.cpp"],
shared_libs: [
"libbase",
+ "libbinder",
"libcrypto",
"libcrypto_utils",
- "libcutils",
- "libfec",
"libfs_mgr_binder",
- "liblog",
"libutils",
],
static_libs: [
"libavb_user",
],
+ header_libs: [
+ "libcutils_headers",
+ ],
cflags: ["-Werror"],
cppflags: [
diff --git a/set-verity-state/set-verity-state.cpp b/set-verity-state/set-verity-state.cpp
index 52a7f74..de9a452 100644
--- a/set-verity-state/set-verity-state.cpp
+++ b/set-verity-state/set-verity-state.cpp
@@ -14,242 +14,230 @@
* limitations under the License.
*/
-#include <errno.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <libavb_user/libavb_user.h>
-#include <stdarg.h>
+#include <getopt.h>
#include <stdio.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <unistd.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
-#include <android-base/stringprintf.h>
-#include <android-base/unique_fd.h>
-#include <fs_mgr.h>
+#include <binder/ProcessState.h>
+#include <cutils/android_reboot.h>
#include <fs_mgr_overlayfs.h>
-#include <fstab/fstab.h>
-#include <log/log_properties.h>
+#include <libavb_user/libavb_user.h>
-#include "fec/io.h"
+using namespace std::string_literals;
+
+namespace {
+
+void print_usage() {
+ printf(
+ "Usage:\n"
+ "\tdisable-verity\n"
+ "\tenable-verity\n"
+ "\tset-verity-state [0|1]\n"
+ "Options:\n"
+ "\t-h --help\tthis help\n"
+ "\t-R --reboot\tautomatic reboot if needed for new settings to take effect\n"
+ "\t-v --verbose\tbe noisy\n");
+}
#ifdef ALLOW_DISABLE_VERITY
-static const bool kAllowDisableVerity = true;
+const bool kAllowDisableVerity = true;
#else
-static const bool kAllowDisableVerity = false;
+const bool kAllowDisableVerity = false;
#endif
-using android::base::unique_fd;
-
-static void suggest_run_adb_root() {
- if (getuid() != 0) printf("Maybe run adb root?\n");
-}
-
-static bool make_block_device_writable(const std::string& dev) {
- unique_fd fd(open(dev.c_str(), O_RDONLY | O_CLOEXEC));
- if (fd == -1) {
- return false;
- }
-
- int OFF = 0;
- bool result = (ioctl(fd.get(), BLKROSET, &OFF) != -1);
- return result;
-}
-
-/* Turn verity on/off */
-static bool set_verity_enabled_state(const char* block_device, const char* mount_point,
- bool enable) {
- if (!make_block_device_writable(block_device)) {
- printf("Could not make block device %s writable (%s).\n", block_device, strerror(errno));
- return false;
- }
-
- fec::io fh(block_device, O_RDWR);
-
- if (!fh) {
- printf("Could not open block device %s (%s).\n", block_device, strerror(errno));
- suggest_run_adb_root();
- return false;
- }
-
- fec_verity_metadata metadata;
-
- if (!fh.get_verity_metadata(metadata)) {
- printf("Couldn't find verity metadata!\n");
- return false;
- }
-
- if (!enable && metadata.disabled) {
- printf("Verity already disabled on %s\n", mount_point);
- return false;
- }
-
- if (enable && !metadata.disabled) {
- printf("Verity already enabled on %s\n", mount_point);
- return false;
- }
-
- if (!fh.set_verity_status(enable)) {
- printf("Could not set verity %s flag on device %s with error %s\n",
- enable ? "enabled" : "disabled", block_device, strerror(errno));
- return false;
- }
-
- auto change = false;
- errno = 0;
- if (enable ? fs_mgr_overlayfs_teardown(mount_point, &change)
- : fs_mgr_overlayfs_setup(nullptr, mount_point, &change)) {
- if (change) {
- printf("%s overlayfs for %s\n", enable ? "disabling" : "using", mount_point);
- }
- } else if (errno) {
- int expected_errno = enable ? EBUSY : ENOENT;
- if (errno != expected_errno) {
- printf("Overlayfs %s for %s failed with error %s\n", enable ? "teardown" : "setup",
- mount_point, strerror(errno));
- }
- }
- printf("Verity %s on %s\n", enable ? "enabled" : "disabled", mount_point);
- return true;
-}
-
/* Helper function to get A/B suffix, if any. If the device isn't
* using A/B the empty string is returned. Otherwise either "_a",
* "_b", ... is returned.
*/
-static std::string get_ab_suffix() {
+std::string get_ab_suffix() {
return android::base::GetProperty("ro.boot.slot_suffix", "");
}
-static bool is_avb_device_locked() {
+bool is_avb_device_locked() {
return android::base::GetProperty("ro.boot.vbmeta.device_state", "") == "locked";
}
-static bool overlayfs_setup(bool enable) {
+bool is_debuggable() {
+ return android::base::GetBoolProperty("ro.debuggable", false);
+}
+
+bool is_using_avb() {
+ // Figure out if we're using VB1.0 or VB2.0 (aka AVB) - by
+ // contract, androidboot.vbmeta.digest is set by the bootloader
+ // when using AVB).
+ return !android::base::GetProperty("ro.boot.vbmeta.digest", "").empty();
+}
+
+[[noreturn]] void reboot(const std::string& name) {
+ LOG(INFO) << "Rebooting device for new settings to take effect";
+ ::sync();
+ android::base::SetProperty(ANDROID_RB_PROPERTY, "reboot," + name);
+ ::sleep(60);
+ LOG(ERROR) << "Failed to reboot";
+ ::exit(1);
+}
+
+bool overlayfs_setup(bool enable) {
auto change = false;
errno = 0;
- if (enable ? fs_mgr_overlayfs_teardown(nullptr, &change)
- : fs_mgr_overlayfs_setup(nullptr, nullptr, &change)) {
+ if (enable ? fs_mgr_overlayfs_setup(nullptr, &change)
+ : fs_mgr_overlayfs_teardown(nullptr, &change)) {
if (change) {
- printf("%s overlayfs\n", enable ? "disabling" : "using");
+ LOG(INFO) << (enable ? "Enabled" : "Disabled") << " overlayfs";
}
- } else if (errno) {
- printf("Overlayfs %s failed with error %s\n", enable ? "teardown" : "setup", strerror(errno));
- suggest_run_adb_root();
+ } else {
+ LOG(ERROR) << "Failed to " << (enable ? "enable" : "disable") << " overlayfs";
}
return change;
}
+struct SetVerityStateResult {
+ bool success = false;
+ bool want_reboot = false;
+};
+
/* Use AVB to turn verity on/off */
-static bool set_avb_verity_enabled_state(AvbOps* ops, bool enable_verity) {
+SetVerityStateResult SetVerityState(bool enable_verity) {
std::string ab_suffix = get_ab_suffix();
- bool verity_enabled;
+ bool verity_enabled = false;
if (is_avb_device_locked()) {
- printf("Device is locked. Please unlock the device first\n");
- return false;
+ LOG(ERROR) << "Device must be bootloader unlocked to change verity state";
+ return {};
}
- if (!avb_user_verity_get(ops, ab_suffix.c_str(), &verity_enabled)) {
- printf("Error getting verity state. Try adb root first?\n");
- return false;
+ std::unique_ptr<AvbOps, decltype(&avb_ops_user_free)> ops(avb_ops_user_new(), &avb_ops_user_free);
+ if (!ops) {
+ LOG(ERROR) << "Error getting AVB ops";
+ return {};
+ }
+
+ if (!avb_user_verity_get(ops.get(), ab_suffix.c_str(), &verity_enabled)) {
+ LOG(ERROR) << "Error getting verity state";
+ return {};
}
if ((verity_enabled && enable_verity) || (!verity_enabled && !enable_verity)) {
- printf("verity is already %s\n", verity_enabled ? "enabled" : "disabled");
- return false;
+ LOG(INFO) << "Verity is already " << (verity_enabled ? "enabled" : "disabled");
+ return {.success = true, .want_reboot = false};
}
- if (!avb_user_verity_set(ops, ab_suffix.c_str(), enable_verity)) {
- printf("Error setting verity\n");
- return false;
+ if (!avb_user_verity_set(ops.get(), ab_suffix.c_str(), enable_verity)) {
+ LOG(ERROR) << "Error setting verity state";
+ return {};
}
- overlayfs_setup(enable_verity);
- printf("Successfully %s verity\n", enable_verity ? "enabled" : "disabled");
- return true;
+ LOG(INFO) << "Successfully " << (enable_verity ? "enabled" : "disabled") << " verity";
+ return {.success = true, .want_reboot = true};
}
+class MyLogger {
+ public:
+ explicit MyLogger(bool verbose) : verbose_(verbose) {}
+
+ void operator()(android::base::LogId id, android::base::LogSeverity severity, const char* tag,
+ const char* file, unsigned int line, const char* message) {
+ // Hide log starting with '[fs_mgr]' unless it's an error.
+ if (verbose_ || severity >= android::base::ERROR || message[0] != '[') {
+ fprintf(stderr, "%s\n", message);
+ }
+ logd_(id, severity, tag, file, line, message);
+ }
+
+ private:
+ android::base::LogdLogger logd_;
+ bool verbose_;
+};
+
+} // namespace
+
int main(int argc, char* argv[]) {
- if (argc == 0) {
- LOG(FATAL) << "set-verity-state called with empty argv";
- }
+ bool auto_reboot = false;
+ bool verbose = false;
- std::optional<bool> enable_opt;
- std::string procname = android::base::Basename(argv[0]);
- if (procname == "enable-verity") {
- enable_opt = true;
- } else if (procname == "disable-verity") {
- enable_opt = false;
- }
-
- if (!enable_opt.has_value()) {
- if (argc != 2) {
- printf("usage: %s [1|0]\n", argv[0]);
- return 1;
- }
-
- if (strcmp(argv[1], "1") == 0) {
- enable_opt = true;
- } else if (strcmp(argv[1], "0") == 0) {
- enable_opt = false;
- } else {
- printf("usage: %s [1|0]\n", argv[0]);
- return 1;
+ struct option longopts[] = {
+ {"help", no_argument, nullptr, 'h'},
+ {"reboot", no_argument, nullptr, 'R'},
+ {"verbose", no_argument, nullptr, 'v'},
+ {0, 0, nullptr, 0},
+ };
+ for (int opt; (opt = ::getopt_long(argc, argv, "hRv", longopts, nullptr)) != -1;) {
+ switch (opt) {
+ case 'h':
+ print_usage();
+ return 0;
+ case 'R':
+ auto_reboot = true;
+ break;
+ case 'v':
+ verbose = true;
+ break;
+ default:
+ print_usage();
+ return 1;
}
}
- bool enable = enable_opt.value();
+ android::base::InitLogging(argv, MyLogger(verbose));
- bool any_changed = false;
-
- // Figure out if we're using VB1.0 or VB2.0 (aka AVB) - by
- // contract, androidboot.vbmeta.digest is set by the bootloader
- // when using AVB).
- bool using_avb = !android::base::GetProperty("ro.boot.vbmeta.digest", "").empty();
-
- // If using AVB, dm-verity is used on any build so we want it to
- // be possible to disable/enable on any build (except USER). For
- // VB1.0 dm-verity is only enabled on certain builds.
- if (!using_avb) {
- if (!kAllowDisableVerity) {
- printf("%s only works for userdebug builds\n", argv[0]);
- }
-
- if (!android::base::GetBoolProperty("ro.secure", false)) {
- overlayfs_setup(enable);
- printf("verity not enabled - ENG build\n");
- return 0;
- }
+ bool enable_verity = false;
+ const std::string progname = getprogname();
+ if (progname == "enable-verity") {
+ enable_verity = true;
+ } else if (progname == "disable-verity") {
+ enable_verity = false;
+ } else if (optind < argc && (argv[optind] == "1"s || argv[optind] == "0"s)) {
+ // progname "set-verity-state"
+ enable_verity = (argv[optind] == "1"s);
+ } else {
+ print_usage();
+ return 1;
}
- // Should never be possible to disable dm-verity on a USER build
- // regardless of using AVB or VB1.0.
- if (!__android_log_is_debuggable()) {
- printf("verity cannot be disabled/enabled - USER build\n");
- return 0;
+ if (!kAllowDisableVerity || !is_debuggable()) {
+ errno = EPERM;
+ PLOG(ERROR) << "Cannot disable/enable verity on user build";
+ return 1;
}
- if (using_avb) {
- // Yep, the system is using AVB.
- AvbOps* ops = avb_ops_user_new();
- if (ops == nullptr) {
- printf("Error getting AVB ops\n");
- return 1;
+ if (getuid() != 0) {
+ errno = EACCES;
+ PLOG(ERROR) << "Must be running as root (adb root)";
+ return 1;
+ }
+
+ if (!is_using_avb()) {
+ LOG(ERROR) << "Expected AVB device, VB1.0 is no longer supported";
+ return 1;
+ }
+
+ int exit_code = 0;
+ bool want_reboot = false;
+
+ auto ret = SetVerityState(enable_verity);
+ if (ret.success) {
+ want_reboot |= ret.want_reboot;
+ } else {
+ exit_code = 1;
+ }
+
+ // Disable any overlayfs unconditionally if we want verity enabled.
+ // Enable overlayfs only if verity is successfully disabled or is already disabled.
+ if (enable_verity || ret.success) {
+ // Start a threadpool to service waitForService() callbacks as
+ // fs_mgr_overlayfs_* might call waitForService() to get the image service.
+ android::ProcessState::self()->startThreadPool();
+ want_reboot |= overlayfs_setup(!enable_verity);
+ }
+
+ if (want_reboot) {
+ if (auto_reboot) {
+ reboot(progname);
}
- if (set_avb_verity_enabled_state(ops, enable)) {
- any_changed = true;
- }
- avb_ops_user_free(ops);
- }
- if (!any_changed) any_changed = overlayfs_setup(enable);
-
- if (any_changed) {
- printf("Now reboot your device for settings to take effect\n");
+ printf("Reboot the device for new settings to take effect\n");
}
- return 0;
+ return exit_code;
}
diff --git a/trusty/apploader/apploader.cpp b/trusty/apploader/apploader.cpp
index 278499f..17d083c 100644
--- a/trusty/apploader/apploader.cpp
+++ b/trusty/apploader/apploader.cpp
@@ -226,6 +226,9 @@
case APPLOADER_ERR_POLICY_VIOLATION:
LOG(ERROR) << "Error: loading denied by policy engine";
break;
+ case APPLOADER_ERR_NOT_ENCRYPTED:
+ LOG(ERROR) << "Error: unmet application encryption requirement";
+ break;
default:
LOG(ERROR) << "Unrecognized error: " << resp.error;
break;
diff --git a/trusty/apploader/apploader_ipc.h b/trusty/apploader/apploader_ipc.h
index 306596e..f037692 100644
--- a/trusty/apploader/apploader_ipc.h
+++ b/trusty/apploader/apploader_ipc.h
@@ -45,6 +45,10 @@
* @APPLOADER_ERR_INTERNAL: miscellaneous or internal apploader
* error not covered by the above
* @APPLOADER_ERR_INVALID_VERSION: invalid application version
+ * @APPLOADER_ERR_POLICY_VIOLATION: signature verification succeeded but
+ * key+manifest combination not allowed
+ * by app loader policy engine
+ * @APPLOADER_ERR_NOT_ENCRYPTED: unmet application encryption requirement
*/
enum apploader_error : uint32_t {
APPLOADER_NO_ERROR = 0,
@@ -57,6 +61,7 @@
APPLOADER_ERR_INTERNAL,
APPLOADER_ERR_INVALID_VERSION,
APPLOADER_ERR_POLICY_VIOLATION,
+ APPLOADER_ERR_NOT_ENCRYPTED,
};
/**
diff --git a/trusty/utils/acvp/acvp_ipc.h b/trusty/utils/acvp/acvp_ipc.h
index 300e05a..fc1c9d7 100644
--- a/trusty/utils/acvp/acvp_ipc.h
+++ b/trusty/utils/acvp/acvp_ipc.h
@@ -45,7 +45,7 @@
* This must be at least as long as the longest reply from the ACVP service
* (currently the reply from getConfig()).
*/
-#define ACVP_MIN_SHARED_MEMORY 16384
+#define ACVP_MIN_SHARED_MEMORY 32768
/**
* acvp_req - Request for the Trusty ACVP app