Merge "Update for new kernel 5.11 headers."
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 65820bd..12d5d52 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <dirent.h>
#include <err.h>
#include <fcntl.h>
#include <malloc.h>
@@ -1444,9 +1445,16 @@
std::this_thread::sleep_for(100ms);
// Find the tombstone.
- std::optional<int> tombstone_index;
- for (int i = 0; i < 50; ++i) {
- std::string path = android::base::StringPrintf("/data/tombstones/tombstone_%02d", i);
+ std::optional<std::string> tombstone_file;
+ std::unique_ptr<DIR, decltype(&closedir)> dir_h(opendir("/data/tombstones"), closedir);
+ ASSERT_TRUE(dir_h != nullptr);
+ std::regex tombstone_re("tombstone_\\d+");
+ dirent* entry;
+ while ((entry = readdir(dir_h.get())) != nullptr) {
+ if (!std::regex_match(entry->d_name, tombstone_re)) {
+ continue;
+ }
+ std::string path = android::base::StringPrintf("/data/tombstones/%s", entry->d_name);
struct stat st;
if (TEMP_FAILURE_RETRY(stat(path.c_str(), &st)) != 0) {
@@ -1454,14 +1462,13 @@
}
if (st.st_dev == text_st.st_dev && st.st_ino == text_st.st_ino) {
- tombstone_index = i;
+ tombstone_file = path;
break;
}
}
- ASSERT_TRUE(tombstone_index);
- std::string proto_path =
- android::base::StringPrintf("/data/tombstones/tombstone_%02d.pb", *tombstone_index);
+ ASSERT_TRUE(tombstone_file);
+ std::string proto_path = tombstone_file.value() + ".pb";
struct stat proto_fd_st;
struct stat proto_file_st;
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index 185bd6e..c1a59d8 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -619,7 +619,7 @@
log.tfd = output_fd.get();
log.amfd_data = amfd_data;
- bool translate_proto = GetBoolProperty("debug.debuggerd.translate_proto_to_text", false);
+ bool translate_proto = GetBoolProperty("debug.debuggerd.translate_proto_to_text", true);
if (translate_proto) {
tombstone_proto_to_text(tombstone, [&log](const std::string& line, bool should_log) {
_LOG(&log, should_log ? logtype::HEADER : logtype::LOGS, "%s\n", line.c_str());
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 388c296..1134f14 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -125,10 +125,38 @@
namespace {
+bool fs_mgr_in_recovery() {
+ // Check the existence of recovery binary instead of using the compile time
+ // macro, because first-stage-init is compiled with __ANDROID_RECOVERY__
+ // defined, albeit not in recovery. More details: system/core/init/README.md
+ return fs_mgr_access("/system/bin/recovery");
+}
+
+bool fs_mgr_is_dsu_running() {
+ // Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is
+ // never called in recovery, the return value of android::gsi::IsGsiRunning()
+ // is not well-defined. In this case, just return false as being in recovery
+ // implies not running a DSU system.
+ if (fs_mgr_in_recovery()) return false;
+ auto saved_errno = errno;
+ auto ret = android::gsi::IsGsiRunning();
+ errno = saved_errno;
+ return ret;
+}
+
// list of acceptable overlayfs backing storage
const auto kScratchMountPoint = "/mnt/scratch"s;
const auto kCacheMountPoint = "/cache"s;
-const std::vector<const std::string> kOverlayMountPoints = {kScratchMountPoint, kCacheMountPoint};
+
+std::vector<const std::string> OverlayMountPoints() {
+ // Never fallback to legacy cache mount point if within a DSU system,
+ // because running a DSU system implies the device supports dynamic
+ // partitions, which means legacy cache mustn't be used.
+ if (fs_mgr_is_dsu_running()) {
+ return {kScratchMountPoint};
+ }
+ return {kScratchMountPoint, kCacheMountPoint};
+}
// Return true if everything is mounted, but before adb is started. Right
// after 'trigger load_persist_props_action' is done.
@@ -166,26 +194,7 @@
static constexpr unsigned long kSizeThreshold = 8 * 1024 * 1024; // 8MB
return (vst.f_bfree >= (vst.f_blocks * kPercentThreshold / 100)) &&
- (vst.f_bfree * vst.f_bsize) >= kSizeThreshold;
-}
-
-bool fs_mgr_in_recovery() {
- // Check the existence of recovery binary instead of using the compile time
- // macro, because first-stage-init is compiled with __ANDROID_RECOVERY__
- // defined, albeit not in recovery. More details: system/core/init/README.md
- return fs_mgr_access("/system/bin/recovery");
-}
-
-bool fs_mgr_is_dsu_running() {
- // Since android::gsi::CanBootIntoGsi() or android::gsi::MarkSystemAsGsi() is
- // never called in recovery, the return value of android::gsi::IsGsiRunning()
- // is not well-defined. In this case, just return false as being in recovery
- // implies not running a DSU system.
- if (fs_mgr_in_recovery()) return false;
- auto saved_errno = errno;
- auto ret = android::gsi::IsGsiRunning();
- errno = saved_errno;
- return ret;
+ (static_cast<uint64_t>(vst.f_bfree) * vst.f_frsize) >= kSizeThreshold;
}
const auto kPhysicalDevice = "/dev/block/by-name/"s;
@@ -300,7 +309,7 @@
std::string fs_mgr_get_overlayfs_candidate(const std::string& mount_point) {
if (!fs_mgr_is_dir(mount_point)) return "";
const auto base = android::base::Basename(mount_point) + "/";
- for (const auto& overlay_mount_point : kOverlayMountPoints) {
+ for (const auto& overlay_mount_point : OverlayMountPoints()) {
auto dir = overlay_mount_point + kOverlayTopDir + "/" + base;
auto upper = dir + kUpperName;
if (!fs_mgr_is_dir(upper)) continue;
@@ -1344,7 +1353,7 @@
if (candidates.empty()) return ret;
std::string dir;
- for (const auto& overlay_mount_point : kOverlayMountPoints) {
+ 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;
@@ -1465,7 +1474,7 @@
}
}
bool should_destroy_scratch = false;
- for (const auto& overlay_mount_point : kOverlayMountPoints) {
+ for (const auto& overlay_mount_point : OverlayMountPoints()) {
ret &= fs_mgr_overlayfs_teardown_one(
overlay_mount_point, mount_point ? fs_mgr_mount_point(mount_point) : "", change,
overlay_mount_point == kScratchMountPoint ? &should_destroy_scratch : nullptr);
@@ -1569,7 +1578,7 @@
constexpr bool* ignore_change = nullptr;
// Teardown legacy overlay mount points that's not backed by a scratch device.
- for (const auto& overlay_mount_point : kOverlayMountPoints) {
+ for (const auto& overlay_mount_point : OverlayMountPoints()) {
if (overlay_mount_point == kScratchMountPoint) {
continue;
}
diff --git a/fs_mgr/libfiemap/fiemap_writer.cpp b/fs_mgr/libfiemap/fiemap_writer.cpp
index 621031a..8acb885 100644
--- a/fs_mgr/libfiemap/fiemap_writer.cpp
+++ b/fs_mgr/libfiemap/fiemap_writer.cpp
@@ -52,7 +52,7 @@
static constexpr const uint32_t kUnsupportedExtentFlags =
FIEMAP_EXTENT_UNKNOWN | FIEMAP_EXTENT_UNWRITTEN | FIEMAP_EXTENT_DELALLOC |
FIEMAP_EXTENT_NOT_ALIGNED | FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_DATA_TAIL |
- FIEMAP_EXTENT_UNWRITTEN | FIEMAP_EXTENT_SHARED | FIEMAP_EXTENT_MERGED;
+ FIEMAP_EXTENT_UNWRITTEN | FIEMAP_EXTENT_SHARED;
// Large file support must be enabled.
static_assert(sizeof(off_t) == sizeof(uint64_t));
diff --git a/gatekeeperd/gatekeeperd.cpp b/gatekeeperd/gatekeeperd.cpp
index 781b4af..f9c0cdd 100644
--- a/gatekeeperd/gatekeeperd.cpp
+++ b/gatekeeperd/gatekeeperd.cpp
@@ -318,6 +318,7 @@
authToken.timestamp.milliSeconds = betoh64(hwAuthToken->timestamp);
authToken.challenge = hwAuthToken->challenge;
+ authToken.userId = hwAuthToken->user_id;
authToken.authenticatorId = hwAuthToken->authenticator_id;
authToken.authenticatorType = static_cast<HardwareAuthenticatorType>(
betoh32(hwAuthToken->authenticator_type));
diff --git a/init/Android.bp b/init/Android.bp
index b0a59b1..5da8e36 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -235,6 +235,119 @@
visibility: ["//packages/modules/Virtualization/microdroid"],
}
+// This currently is only for the VM usecase.
+// TODO(jiyong): replace init_first_stage in Android.mk with this
+cc_binary {
+ name: "init_first_stage_soong",
+ stem: "init_vendor",
+
+ srcs: [
+ "block_dev_initializer.cpp",
+ "devices.cpp",
+ "first_stage_console.cpp",
+ "first_stage_init.cpp",
+ "first_stage_main.cpp",
+ "first_stage_mount.cpp",
+ "reboot_utils.cpp",
+ "selabel.cpp",
+ "selinux.cpp",
+ "service_utils.cpp",
+ "snapuserd_transition.cpp",
+ "switch_root.cpp",
+ "uevent_listener.cpp",
+ "util.cpp",
+ ],
+
+ static_libs: [
+ "libc++fs",
+ "libfs_avb",
+ "libfs_mgr",
+ "libfec",
+ "libfec_rs",
+ "libsquashfs_utils",
+ "liblogwrap",
+ "libext4_utils",
+ "libcrypto_utils",
+ "libsparse",
+ "libavb",
+ "libkeyutils",
+ "liblp",
+ "libcutils",
+ "libbase",
+ "liblog",
+ "libcrypto_static",
+ "libdl",
+ "libz",
+ "libselinux",
+ "libcap",
+ "libgsi",
+ "libcom.android.sysprop.apex",
+ "liblzma",
+ "libunwindstack_no_dex",
+ "libbacktrace_no_dex",
+ "libmodprobe",
+ "libext2_uuid",
+ "libprotobuf-cpp-lite",
+ "libsnapshot_cow",
+ "libsnapshot_init",
+ "update_metadata-protos",
+ ],
+
+ static_executable: true,
+
+ cflags: [
+ "-Wall",
+ "-Wextra",
+ "-Wno-unused-parameter",
+ "-Werror",
+ "-DALLOW_FIRST_STAGE_CONSOLE=0",
+ "-DALLOW_LOCAL_PROP_OVERRIDE=0",
+ "-DALLOW_PERMISSIVE_SELINUX=0",
+ "-DREBOOT_BOOTLOADER_ON_PANIC=0",
+ "-DWORLD_WRITABLE_KMSG=0",
+ "-DDUMP_ON_UMOUNT_FAILURE=0",
+ "-DSHUTDOWN_ZERO_TIMEOUT=0",
+ "-DLOG_UEVENTS=0",
+ "-DSEPOLICY_VERSION=30", // TODO(jiyong): externalize the version number
+ ],
+
+ product_variables: {
+ debuggable: {
+ cflags: [
+ "-UALLOW_FIRST_STAGE_CONSOLE",
+ "-DALLOW_FIRST_STAGE_CONSOLE=1",
+
+ "-UALLOW_LOCAL_PROP_OVERRIDE",
+ "-DALLOW_LOCAL_PROP_OVERRIDE=1",
+
+ "-UALLOW_PERMISSIVE_SELINUX",
+ "-DALLOW_PERMISSIVE_SELINUX=1",
+
+ "-UREBOOT_BOOTLOADER_ON_PANIC",
+ "-DREBOOT_BOOTLOADER_ON_PANIC=1",
+
+ "-UWORLD_WRITABLE_KMSG",
+ "-DWORLD_WRITABLE_KMSG=1",
+
+ "-UDUMP_ON_UMOUNT_FAILURE",
+ "-DDUMP_ON_UMOUNT_FAILURE=1",
+ ],
+ },
+
+ eng: {
+ cflags: [
+ "-USHUTDOWN_ZERO_TIMEOUT",
+ "-DSHUTDOWN_ZERO_TIMEOUT=1",
+ ],
+ },
+ },
+
+ sanitize: {
+ misc_undefined: ["signed-integer-overflow"],
+ hwaddress: false,
+ },
+}
+
// Tests
// ------------------------------------------------------------------------------
diff --git a/libcutils/include/cutils/trace.h b/libcutils/include/cutils/trace.h
index 793e2ce..ef426ff 100644
--- a/libcutils/include/cutils/trace.h
+++ b/libcutils/include/cutils/trace.h
@@ -104,14 +104,6 @@
void atrace_update_tags();
/**
- * Set whether the process is debuggable. By default the process is not
- * considered debuggable. If the process is not debuggable then application-
- * level tracing is not allowed unless the ro.debuggable system property is
- * set to '1'.
- */
-void atrace_set_debuggable(bool debuggable);
-
-/**
* Set whether tracing is enabled for the current process. This is used to
* prevent tracing within the Zygote process.
*/
diff --git a/libcutils/trace-dev.inc b/libcutils/trace-dev.inc
index 80205bc..3b459e0 100644
--- a/libcutils/trace-dev.inc
+++ b/libcutils/trace-dev.inc
@@ -52,7 +52,6 @@
atomic_bool atrace_is_ready = ATOMIC_VAR_INIT(false);
int atrace_marker_fd = -1;
uint64_t atrace_enabled_tags = ATRACE_TAG_NOT_READY;
-static bool atrace_is_debuggable = false;
static atomic_bool atrace_is_enabled = ATOMIC_VAR_INIT(true);
static pthread_mutex_t atrace_tags_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -96,15 +95,6 @@
return atrace_enabled_tags;
}
-// Set whether this process is debuggable, which determines whether
-// application-level tracing is allowed when the ro.debuggable system property
-// is not set to '1'.
-void atrace_set_debuggable(bool debuggable)
-{
- atrace_is_debuggable = debuggable;
- atrace_update_tags();
-}
-
// Check whether the given command line matches one of the comma-separated
// values listed in the app_cmdlines property.
static bool atrace_is_cmdline_match(const char* cmdline)
@@ -128,24 +118,21 @@
// Determine whether application-level tracing is enabled for this process.
static bool atrace_is_app_tracing_enabled()
{
- bool sys_debuggable = property_get_bool("ro.debuggable", 0);
bool result = false;
- if (sys_debuggable || atrace_is_debuggable) {
- // Check whether tracing is enabled for this process.
- FILE * file = fopen("/proc/self/cmdline", "re");
- if (file) {
- char cmdline[4096];
- if (fgets(cmdline, sizeof(cmdline), file)) {
- result = atrace_is_cmdline_match(cmdline);
- } else {
- ALOGE("Error reading cmdline: %s (%d)", strerror(errno), errno);
- }
- fclose(file);
+ // Check whether tracing is enabled for this process.
+ FILE * file = fopen("/proc/self/cmdline", "re");
+ if (file) {
+ char cmdline[4096];
+ if (fgets(cmdline, sizeof(cmdline), file)) {
+ result = atrace_is_cmdline_match(cmdline);
} else {
- ALOGE("Error opening /proc/self/cmdline: %s (%d)", strerror(errno),
- errno);
+ ALOGE("Error reading cmdline: %s (%d)", strerror(errno), errno);
}
+ fclose(file);
+ } else {
+ ALOGE("Error opening /proc/self/cmdline: %s (%d)", strerror(errno),
+ errno);
}
return result;
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 863cf6c..68a76f1 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -738,6 +738,8 @@
mkdir /data/misc/snapshotctl_log 0755 root root
# create location to store pre-reboot information
mkdir /data/misc/prereboot 0700 system system
+ # directory used for on-device signing key blob
+ mkdir /data/misc/odsign 0700 root root
mkdir /data/preloads 0775 system system encryption=None
@@ -877,6 +879,10 @@
# Set SELinux security contexts on upgrade or policy update.
restorecon --recursive --skip-ce /data
+ # Start the on-device signing daemon, and wait for it to finish, to ensure
+ # ART artifacts are generated if needed.
+ exec_start odsign
+
# After apexes are mounted, tell keymaster early boot has ended, so it will
# stop allowing use of early-boot keys
exec - system system -- /system/bin/vdc keymaster earlyBootEnded
diff --git a/trusty/confirmationui/Android.bp b/trusty/confirmationui/Android.bp
index 60e0e71..09d48ad 100644
--- a/trusty/confirmationui/Android.bp
+++ b/trusty/confirmationui/Android.bp
@@ -54,6 +54,7 @@
"android.hardware.confirmationui@1.0",
"android.hardware.keymaster@4.0",
"libbase",
+ "libdmabufheap",
"libhidlbase",
"libteeui_hal_support",
"libtrusty",
@@ -92,4 +93,4 @@
"-Werror",
"-DTEEUI_USE_STD_VECTOR",
],
-}
\ No newline at end of file
+}
diff --git a/trusty/confirmationui/TrustyApp.cpp b/trusty/confirmationui/TrustyApp.cpp
index e4c68f9..0e84b19 100644
--- a/trusty/confirmationui/TrustyApp.cpp
+++ b/trusty/confirmationui/TrustyApp.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2020, The Android Open Source Project
+ * Copyright 2021, 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.
@@ -15,140 +15,155 @@
*/
#include "TrustyApp.h"
+#include "TrustyIpc.h"
+#include <BufferAllocator/BufferAllocator.h>
#include <android-base/logging.h>
+#include <sys/mman.h>
#include <sys/uio.h>
#include <trusty/tipc.h>
+#define countof(arr) (sizeof(arr) / sizeof(arr[0]))
+
namespace android {
namespace trusty {
-// 0x1000 is the message buffer size but we need to leave some space for a protocol header.
-// This assures that packets can always be read/written in one read/write operation.
-static constexpr const uint32_t kPacketSize = 0x1000 - 32;
+using ::android::base::unique_fd;
-enum class PacketType : uint32_t {
- SND,
- RCV,
- ACK,
-};
-
-struct PacketHeader {
- PacketType type;
- uint32_t remaining;
-};
-
-const char* toString(PacketType t) {
- switch (t) {
- case PacketType::SND:
- return "SND";
- case PacketType::RCV:
- return "RCV";
- case PacketType::ACK:
- return "ACK";
- default:
- return "UNKNOWN";
- }
+static inline uintptr_t RoundPageUp(uintptr_t val) {
+ return (val + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
}
-static constexpr const uint32_t kHeaderSize = sizeof(PacketHeader);
-static constexpr const uint32_t kPayloadSize = kPacketSize - kHeaderSize;
+ssize_t TrustyApp::TrustyRpc(const uint8_t* obegin, const uint8_t* oend, uint8_t* ibegin,
+ uint8_t* iend) {
+ uint32_t olen = oend - obegin;
-ssize_t TrustyRpc(int handle, const uint8_t* obegin, const uint8_t* oend, uint8_t* ibegin,
- uint8_t* iend) {
- while (obegin != oend) {
- PacketHeader header = {
- .type = PacketType::SND,
- .remaining = uint32_t(oend - obegin),
- };
- uint32_t body_size = std::min(kPayloadSize, header.remaining);
- iovec iov[] = {
- {
- .iov_base = &header,
- .iov_len = kHeaderSize,
- },
- {
- .iov_base = const_cast<uint8_t*>(obegin),
- .iov_len = body_size,
- },
- };
- int rc = writev(handle, iov, 2);
- if (!rc) {
- PLOG(ERROR) << "Error sending SND message. " << rc;
- return rc;
- }
-
- obegin += body_size;
-
- rc = read(handle, &header, kHeaderSize);
- if (!rc) {
- PLOG(ERROR) << "Error reading ACK. " << rc;
- return rc;
- }
-
- if (header.type != PacketType::ACK || header.remaining != oend - obegin) {
- LOG(ERROR) << "malformed ACK";
- return -1;
- }
+ if (olen > shm_len_) {
+ LOG(ERROR) << AT << "request message too long to fit in shared memory";
+ return -1;
}
- ssize_t remaining = 0;
- auto begin = ibegin;
- do {
- PacketHeader header = {
- .type = PacketType::RCV,
- .remaining = 0,
- };
+ memcpy(shm_base_, obegin, olen);
- iovec iov[] = {
- {
- .iov_base = &header,
- .iov_len = kHeaderSize,
- },
- {
- .iov_base = begin,
- .iov_len = uint32_t(iend - begin),
- },
- };
+ confirmationui_hdr hdr = {
+ .cmd = CONFIRMATIONUI_CMD_MSG,
+ };
+ confirmationui_msg_args args = {
+ .msg_len = olen,
+ };
+ iovec iov[] = {
+ {
+ .iov_base = &hdr,
+ .iov_len = sizeof(hdr),
+ },
+ {
+ .iov_base = &args,
+ .iov_len = sizeof(args),
+ },
+ };
- ssize_t rc = writev(handle, iov, 1);
- if (!rc) {
- PLOG(ERROR) << "Error sending RCV message. " << rc;
- return rc;
- }
+ int rc = tipc_send(handle_, iov, countof(iov), NULL, 0);
+ if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
+ LOG(ERROR) << AT << "failed to send MSG request";
+ return -1;
+ }
- rc = readv(handle, iov, 2);
- if (rc < 0) {
- PLOG(ERROR) << "Error reading response. " << rc;
- return rc;
- }
+ rc = readv(handle_, iov, countof(iov));
+ if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
+ LOG(ERROR) << AT << "failed to receive MSG response";
+ return -1;
+ }
- uint32_t body_size = std::min(kPayloadSize, header.remaining);
- if (body_size != rc - kHeaderSize) {
- LOG(ERROR) << "Unexpected amount of data: " << rc;
- return -1;
- }
+ if (hdr.cmd != (CONFIRMATIONUI_CMD_MSG | CONFIRMATIONUI_RESP_BIT)) {
+ LOG(ERROR) << AT << "unknown response command: " << hdr.cmd;
+ return -1;
+ }
- remaining = header.remaining - body_size;
- begin += body_size;
- } while (remaining);
+ uint32_t ilen = iend - ibegin;
+ if (args.msg_len > ilen) {
+ LOG(ERROR) << AT << "response message too long to fit in return buffer";
+ return -1;
+ }
- return begin - ibegin;
+ memcpy(ibegin, shm_base_, args.msg_len);
+
+ return args.msg_len;
}
TrustyApp::TrustyApp(const std::string& path, const std::string& appname)
: handle_(kInvalidHandle) {
- handle_ = tipc_connect(path.c_str(), appname.c_str());
- if (handle_ == kInvalidHandle) {
+ unique_fd tipc_handle(tipc_connect(path.c_str(), appname.c_str()));
+ if (tipc_handle < 0) {
LOG(ERROR) << AT << "failed to connect to Trusty TA \"" << appname << "\" using dev:"
<< "\"" << path << "\"";
+ return;
}
+
+ uint32_t shm_len = RoundPageUp(CONFIRMATIONUI_MAX_MSG_SIZE);
+ BufferAllocator allocator;
+ unique_fd dma_buf(allocator.Alloc("system", shm_len));
+ if (dma_buf < 0) {
+ LOG(ERROR) << AT << "failed to allocate shared memory buffer";
+ return;
+ }
+
+ if (dma_buf < 0) {
+ LOG(ERROR) << AT << "failed to allocate shared memory buffer";
+ return;
+ }
+
+ confirmationui_hdr hdr = {
+ .cmd = CONFIRMATIONUI_CMD_INIT,
+ };
+ confirmationui_init_req args = {
+ .shm_len = shm_len,
+ };
+ iovec iov[] = {
+ {
+ .iov_base = &hdr,
+ .iov_len = sizeof(hdr),
+ },
+ {
+ .iov_base = &args,
+ .iov_len = sizeof(args),
+ },
+ };
+ trusty_shm shm = {
+ .fd = dma_buf,
+ .transfer = TRUSTY_SHARE,
+ };
+
+ int rc = tipc_send(tipc_handle, iov, 2, &shm, 1);
+ if (rc != static_cast<int>(sizeof(hdr) + sizeof(args))) {
+ LOG(ERROR) << AT << "failed to send INIT request";
+ return;
+ }
+
+ rc = read(tipc_handle, &hdr, sizeof(hdr));
+ if (rc != static_cast<int>(sizeof(hdr))) {
+ LOG(ERROR) << AT << "failed to receive INIT response";
+ return;
+ }
+
+ if (hdr.cmd != (CONFIRMATIONUI_CMD_INIT | CONFIRMATIONUI_RESP_BIT)) {
+ LOG(ERROR) << AT << "unknown response command: " << hdr.cmd;
+ return;
+ }
+
+ void* shm_base = mmap(0, shm_len, PROT_READ | PROT_WRITE, MAP_SHARED, dma_buf, 0);
+ if (shm_base == MAP_FAILED) {
+ LOG(ERROR) << AT << "failed to mmap() shared memory buffer";
+ return;
+ }
+
+ handle_ = std::move(tipc_handle);
+ shm_base_ = shm_base;
+ shm_len_ = shm_len;
+
LOG(INFO) << AT << "succeeded to connect to Trusty TA \"" << appname << "\"";
}
+
TrustyApp::~TrustyApp() {
- if (handle_ != kInvalidHandle) {
- tipc_close(handle_);
- }
LOG(INFO) << "Done shutting down TrustyApp";
}
diff --git a/trusty/confirmationui/TrustyApp.h b/trusty/confirmationui/TrustyApp.h
index 05a25f6..406f439 100644
--- a/trusty/confirmationui/TrustyApp.h
+++ b/trusty/confirmationui/TrustyApp.h
@@ -16,7 +16,10 @@
#pragma once
+#include "TrustyIpc.h"
+
#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
#include <errno.h>
#include <poll.h>
#include <stdio.h>
@@ -60,19 +63,11 @@
MSG_TOO_LONG = -2,
};
-/*
- * There is a hard limitation of 0x1800 bytes for the to-be-signed message size. The protocol
- * overhead is limited, so that 0x2000 is a buffer size that will be sufficient in any benign
- * mode of operation.
- */
-static constexpr const size_t kSendBufferSize = 0x2000;
-
-ssize_t TrustyRpc(int handle, const uint8_t* obegin, const uint8_t* oend, uint8_t* ibegin,
- uint8_t* iend);
-
class TrustyApp {
private:
- int handle_;
+ android::base::unique_fd handle_;
+ void* shm_base_;
+ size_t shm_len_;
static constexpr const int kInvalidHandle = -1;
/*
* This mutex serializes communication with the trusted app, not handle_.
@@ -84,6 +79,8 @@
TrustyApp(const std::string& path, const std::string& appname);
~TrustyApp();
+ ssize_t TrustyRpc(const uint8_t* obegin, const uint8_t* oend, uint8_t* ibegin, uint8_t* iend);
+
template <typename Request, typename Response, typename... T>
std::tuple<TrustyAppError, msg2tuple_t<Response>> issueCmd(const T&... args) {
std::lock_guard<std::mutex> lock(mutex_);
@@ -93,7 +90,7 @@
return {TrustyAppError::ERROR, {}};
}
- uint8_t buffer[kSendBufferSize];
+ uint8_t buffer[CONFIRMATIONUI_MAX_MSG_SIZE];
WriteStream out(buffer);
out = write(Request(), out, args...);
@@ -102,8 +99,8 @@
return {TrustyAppError::MSG_TOO_LONG, {}};
}
- auto rc = TrustyRpc(handle_, &buffer[0], const_cast<const uint8_t*>(out.pos()), &buffer[0],
- &buffer[kSendBufferSize]);
+ auto rc = TrustyRpc(&buffer[0], const_cast<const uint8_t*>(out.pos()), &buffer[0],
+ &buffer[CONFIRMATIONUI_MAX_MSG_SIZE]);
if (rc < 0) return {TrustyAppError::ERROR, {}};
ReadStream in(&buffer[0], rc);
@@ -125,7 +122,7 @@
return TrustyAppError::ERROR;
}
- uint8_t buffer[kSendBufferSize];
+ uint8_t buffer[CONFIRMATIONUI_MAX_MSG_SIZE];
WriteStream out(buffer);
out = write(Request(), out, args...);
@@ -134,8 +131,8 @@
return TrustyAppError::MSG_TOO_LONG;
}
- auto rc = TrustyRpc(handle_, &buffer[0], const_cast<const uint8_t*>(out.pos()), &buffer[0],
- &buffer[kSendBufferSize]);
+ auto rc = TrustyRpc(&buffer[0], const_cast<const uint8_t*>(out.pos()), &buffer[0],
+ &buffer[CONFIRMATIONUI_MAX_MSG_SIZE]);
if (rc < 0) {
LOG(ERROR) << "send command failed: " << strerror(errno) << " (" << errno << ")";
return TrustyAppError::ERROR;
diff --git a/trusty/confirmationui/TrustyConfirmationUI.cpp b/trusty/confirmationui/TrustyConfirmationUI.cpp
index 6b25893..c8b24e3 100644
--- a/trusty/confirmationui/TrustyConfirmationUI.cpp
+++ b/trusty/confirmationui/TrustyConfirmationUI.cpp
@@ -71,7 +71,7 @@
using TeeuiRc = ::teeui::ResponseCode;
constexpr const char kTrustyDeviceName[] = "/dev/trusty-ipc-dev0";
-constexpr const char kConfirmationuiAppName[] = "com.android.trusty.confirmationui";
+constexpr const char kConfirmationuiAppName[] = CONFIRMATIONUI_PORT;
namespace {
diff --git a/trusty/confirmationui/TrustyIpc.h b/trusty/confirmationui/TrustyIpc.h
new file mode 100644
index 0000000..eb764bc
--- /dev/null
+++ b/trusty/confirmationui/TrustyIpc.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2021 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.
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+/*
+ * This interface is shared between Android and Trusty. There is a copy in each
+ * repository. They must be kept in sync.
+ */
+
+#define CONFIRMATIONUI_PORT "com.android.trusty.confirmationui"
+
+/**
+ * enum confirmationui_cmd - command identifiers for ConfirmationUI interface
+ * @CONFIRMATIONUI_RESP_BIT: response bit set as part of response
+ * @CONFIRMATIONUI_REQ_SHIFT: number of bits used by response bit
+ * @CONFIRMATIONUI_CMD_INIT: command to initialize session
+ * @CONFIRMATIONUI_CMD_MSG: command to send ConfirmationUI messages
+ */
+enum confirmationui_cmd : uint32_t {
+ CONFIRMATIONUI_RESP_BIT = 1,
+ CONFIRMATIONUI_REQ_SHIFT = 1,
+
+ CONFIRMATIONUI_CMD_INIT = (1 << CONFIRMATIONUI_REQ_SHIFT),
+ CONFIRMATIONUI_CMD_MSG = (2 << CONFIRMATIONUI_REQ_SHIFT),
+};
+
+/**
+ * struct confirmationui_hdr - header for ConfirmationUI messages
+ * @cmd: command identifier
+ *
+ * Note that no messages return a status code. Any error on the server side
+ * results in the connection being closed. So, operations can be assumed to be
+ * successful if they return a response.
+ */
+struct confirmationui_hdr {
+ uint32_t cmd;
+};
+
+/**
+ * struct confirmationui_init_req - arguments for request to initialize a
+ * session
+ * @shm_len: length of memory region being shared
+ *
+ * A handle to a memory region must be sent along with this message. This memory
+ * is send to ConfirmationUI messages.
+ */
+struct confirmationui_init_req {
+ uint32_t shm_len;
+};
+
+/**
+ * struct confirmationui_msg_args - arguments for sending a message
+ * @msg_len: length of message being sent
+ *
+ * Contents of the message are located in the shared memory region that is
+ * established using %CONFIRMATIONUI_CMD_INIT.
+ *
+ * ConfirmationUI messages can travel both ways.
+ */
+struct confirmationui_msg_args {
+ uint32_t msg_len;
+};
+
+#define CONFIRMATIONUI_MAX_MSG_SIZE 0x2000
diff --git a/trusty/confirmationui/android.hardware.confirmationui@1.0-service.trusty.rc b/trusty/confirmationui/android.hardware.confirmationui@1.0-service.trusty.rc
index dc7a03b..3ba6fc0 100644
--- a/trusty/confirmationui/android.hardware.confirmationui@1.0-service.trusty.rc
+++ b/trusty/confirmationui/android.hardware.confirmationui@1.0-service.trusty.rc
@@ -1,4 +1,4 @@
service confirmationui-1-0 /vendor/bin/hw/android.hardware.confirmationui@1.0-service.trusty
class hal
- user nobody
- group drmrpc input
+ user system
+ group drmrpc input system