Merge "init: Take wakelock on zygote restart"
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index c64de0e..37dbe86 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -187,27 +187,29 @@
* mutex is being held, so we don't want to use any libc functions that
* could allocate memory or hold a lock.
*/
-static void log_signal_summary(const siginfo_t* info) {
+static void log_signal_summary(const siginfo_t* si) {
char main_thread_name[MAX_TASK_NAME_LEN + 1];
if (!get_main_thread_name(main_thread_name, sizeof(main_thread_name))) {
strncpy(main_thread_name, "<unknown>", sizeof(main_thread_name));
}
- if (info->si_signo == BIONIC_SIGNAL_DEBUGGER) {
+ if (si->si_signo == BIONIC_SIGNAL_DEBUGGER) {
async_safe_format_log(ANDROID_LOG_INFO, "libc", "Requested dump for pid %d (%s)", __getpid(),
main_thread_name);
return;
}
- // Many signals don't have an address or sender.
- char addr_desc[32] = ""; // ", fault addr 0x1234"
- if (signal_has_si_addr(info)) {
- async_safe_format_buffer(addr_desc, sizeof(addr_desc), ", fault addr %p", info->si_addr);
- }
+ // Many signals don't have a sender or extra detail, but some do...
pid_t self_pid = __getpid();
char sender_desc[32] = {}; // " from pid 1234, uid 666"
- if (signal_has_sender(info, self_pid)) {
- get_signal_sender(sender_desc, sizeof(sender_desc), info);
+ if (signal_has_sender(si, self_pid)) {
+ get_signal_sender(sender_desc, sizeof(sender_desc), si);
+ }
+ char extra_desc[32] = {}; // ", fault addr 0x1234" or ", syscall 1234"
+ if (si->si_signo == SIGSYS && si->si_code == SYS_SECCOMP) {
+ async_safe_format_buffer(extra_desc, sizeof(extra_desc), ", syscall %d", si->si_syscall);
+ } else if (signal_has_si_addr(si)) {
+ async_safe_format_buffer(extra_desc, sizeof(extra_desc), ", fault addr %p", si->si_addr);
}
char thread_name[MAX_TASK_NAME_LEN + 1]; // one more for termination
@@ -221,8 +223,8 @@
async_safe_format_log(ANDROID_LOG_FATAL, "libc",
"Fatal signal %d (%s), code %d (%s%s)%s in tid %d (%s), pid %d (%s)",
- info->si_signo, get_signame(info), info->si_code, get_sigcode(info),
- sender_desc, addr_desc, __gettid(), thread_name, self_pid, main_thread_name);
+ si->si_signo, get_signame(si), si->si_code, get_sigcode(si), sender_desc,
+ extra_desc, __gettid(), thread_name, self_pid, main_thread_name);
}
/*
@@ -371,12 +373,29 @@
{.iov_base = thread_info->ucontext, .iov_len = sizeof(ucontext_t)},
};
+ constexpr size_t kHeaderSize = sizeof(version) + sizeof(siginfo_t) + sizeof(ucontext_t);
+
if (thread_info->process_info.fdsan_table) {
// Dynamic executables always use version 4. There is no need to increment the version number if
// the format changes, because the sender (linker) and receiver (crash_dump) are version locked.
version = 4;
expected = sizeof(CrashInfoHeader) + sizeof(CrashInfoDataDynamic);
+ static_assert(sizeof(CrashInfoHeader) + sizeof(CrashInfoDataDynamic) ==
+ kHeaderSize + sizeof(thread_info->process_info),
+ "Wire protocol structs do not match the data sent.");
+#define ASSERT_SAME_OFFSET(MEMBER1, MEMBER2) \
+ static_assert(sizeof(CrashInfoHeader) + offsetof(CrashInfoDataDynamic, MEMBER1) == \
+ kHeaderSize + offsetof(debugger_process_info, MEMBER2), \
+ "Wire protocol offset does not match data sent: " #MEMBER1);
+ ASSERT_SAME_OFFSET(fdsan_table_address, fdsan_table);
+ ASSERT_SAME_OFFSET(gwp_asan_state, gwp_asan_state);
+ ASSERT_SAME_OFFSET(gwp_asan_metadata, gwp_asan_metadata);
+ ASSERT_SAME_OFFSET(scudo_stack_depot, scudo_stack_depot);
+ ASSERT_SAME_OFFSET(scudo_region_info, scudo_region_info);
+ ASSERT_SAME_OFFSET(scudo_ring_buffer, scudo_ring_buffer);
+#undef ASSERT_SAME_OFFSET
+
iovs[3] = {.iov_base = &thread_info->process_info,
.iov_len = sizeof(thread_info->process_info)};
} else {
@@ -384,6 +403,10 @@
version = 1;
expected = sizeof(CrashInfoHeader) + sizeof(CrashInfoDataStatic);
+ static_assert(
+ sizeof(CrashInfoHeader) + sizeof(CrashInfoDataStatic) == kHeaderSize + sizeof(uintptr_t),
+ "Wire protocol structs do not match the data sent.");
+
iovs[3] = {.iov_base = &thread_info->process_info.abort_msg, .iov_len = sizeof(uintptr_t)};
}
errno = 0;
diff --git a/debuggerd/test_permissive_mte/Android.bp b/debuggerd/test_permissive_mte/Android.bp
index 1c09240..d3f7520 100644
--- a/debuggerd/test_permissive_mte/Android.bp
+++ b/debuggerd/test_permissive_mte/Android.bp
@@ -18,6 +18,7 @@
cc_binary {
name: "mte_crash",
+ tidy: false,
srcs: ["mte_crash.cpp"],
sanitize: {
memtag_heap: true,
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 0f2a75a..6349c20 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -116,8 +116,7 @@
// For non-A/B devices prefer cache backing storage if
// kPreferCacheBackingStorageProp property set.
- if (!IsABDevice() &&
- android::base::GetBoolProperty(kPreferCacheBackingStorageProp, false) &&
+ if (!IsABDevice() && android::base::GetBoolProperty(kPreferCacheBackingStorageProp, false) &&
android::base::GetIntProperty("ro.vendor.api_level", -1) < __ANDROID_API_T__) {
return {kCacheMountPoint, kScratchMountPoint};
}
@@ -332,8 +331,14 @@
return major > 5 || (major == 5 && minor >= 15);
}
+const std::string fs_mgr_mount_point(const std::string& mount_point) {
+ if ("/"s != mount_point) return mount_point;
+ return "/system";
+}
+
// default options for mount_point, returns empty string for none available.
-std::string fs_mgr_get_overlayfs_options(const std::string& mount_point) {
+std::string fs_mgr_get_overlayfs_options(const FstabEntry& entry) {
+ const auto mount_point = fs_mgr_mount_point(entry.mount_point);
auto candidate = fs_mgr_get_overlayfs_candidate(mount_point);
if (candidate.empty()) return "";
auto ret = kLowerdirOption + mount_point + "," + kUpperdirOption + candidate + kUpperName +
@@ -344,14 +349,14 @@
if (KernelSupportsUserXattrs()) {
ret += ",userxattr";
}
+ for (const auto& flag : android::base::Split(entry.fs_options, ",")) {
+ if (android::base::StartsWith(flag, "context=")) {
+ ret += "," + flag;
+ }
+ }
return ret;
}
-const std::string fs_mgr_mount_point(const std::string& mount_point) {
- if ("/"s != mount_point) return mount_point;
- return "/system";
-}
-
constexpr char kOverlayfsFileContext[] = "u:object_r:overlayfs_file:s0";
class AutoSetFsCreateCon final {
@@ -710,8 +715,9 @@
return info;
}
-bool fs_mgr_overlayfs_mount(const std::string& mount_point) {
- auto options = fs_mgr_get_overlayfs_options(mount_point);
+bool fs_mgr_overlayfs_mount(const FstabEntry& entry) {
+ const auto mount_point = fs_mgr_mount_point(entry.mount_point);
+ const auto options = fs_mgr_get_overlayfs_options(entry);
if (options.empty()) return false;
auto retval = true;
@@ -1346,7 +1352,7 @@
scratch_can_be_mounted = false;
TryMountScratch();
}
- ret &= fs_mgr_overlayfs_mount(mount_point);
+ ret &= fs_mgr_overlayfs_mount(entry);
}
return ret;
}
diff --git a/fs_mgr/libdm/dm.cpp b/fs_mgr/libdm/dm.cpp
index 0624fe0..deffae1 100644
--- a/fs_mgr/libdm/dm.cpp
+++ b/fs_mgr/libdm/dm.cpp
@@ -20,6 +20,7 @@
#include <sys/ioctl.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
+#include <sys/utsname.h>
#include <chrono>
#include <functional>
@@ -711,5 +712,28 @@
return dm_block_devices;
}
+bool DeviceMapper::CreatePlaceholderDevice(const std::string& name) {
+ if (!CreateEmptyDevice(name)) {
+ return false;
+ }
+
+ struct utsname uts;
+ unsigned int major, minor;
+ if (uname(&uts) != 0 || sscanf(uts.release, "%u.%u", &major, &minor) != 2) {
+ LOG(ERROR) << "Could not parse the kernel version from uname";
+ return true;
+ }
+
+ // On Linux 5.15+, there is no uevent until DM_TABLE_LOAD.
+ if (major > 5 || (major == 5 && minor >= 15)) {
+ DmTable table;
+ table.Emplace<DmTargetError>(0, 1);
+ if (!LoadTable(name, table)) {
+ return false;
+ }
+ }
+ return true;
+}
+
} // namespace dm
} // namespace android
diff --git a/fs_mgr/libdm/include/libdm/dm.h b/fs_mgr/libdm/include/libdm/dm.h
index f17ae13..dbef8f9 100644
--- a/fs_mgr/libdm/include/libdm/dm.h
+++ b/fs_mgr/libdm/include/libdm/dm.h
@@ -292,6 +292,12 @@
// Returns mapping <partition-name, /dev/block/dm-x>
std::map<std::string, std::string> FindDmPartitions();
+ // Create a placeholder device. This is useful for ensuring that a uevent is in the pipeline,
+ // to reduce the amount of time a future WaitForDevice will block. On kernels < 5.15, this
+ // simply calls CreateEmptyDevice. On 5.15 and higher, it also loads (but does not activate)
+ // a placeholder table containing dm-error.
+ bool CreatePlaceholderDevice(const std::string& name);
+
private:
// Maximum possible device mapper targets registered in the kernel.
// This is only used to read the list of targets from kernel so we allocate
diff --git a/fs_mgr/tests/vts_fs_test.cpp b/fs_mgr/tests/vts_fs_test.cpp
index b8b34e2..bb2ceb9 100644
--- a/fs_mgr/tests/vts_fs_test.cpp
+++ b/fs_mgr/tests/vts_fs_test.cpp
@@ -66,6 +66,14 @@
int vsr_level = GetVsrLevel();
+ std::vector<std::string> must_be_f2fs;
+ if (vsr_level >= __ANDROID_API_T__) {
+ must_be_f2fs.emplace_back("/data");
+ }
+ if (vsr_level >= __ANDROID_API_U__) {
+ must_be_f2fs.emplace_back("/metadata");
+ }
+
for (const auto& entry : fstab) {
std::string parent_bdev = entry.blk_device;
while (true) {
@@ -99,15 +107,15 @@
}
if (entry.flags & MS_RDONLY) {
- std::vector<std::string> allowed = {"erofs", "ext4"};
- if (vsr_level == __ANDROID_API_T__) {
- allowed.emplace_back("f2fs");
- }
+ std::vector<std::string> allowed = {"erofs", "ext4", "f2fs"};
EXPECT_NE(std::find(allowed.begin(), allowed.end(), entry.fs_type), allowed.end())
<< entry.mount_point;
} else {
- EXPECT_NE(entry.fs_type, "ext4") << entry.mount_point;
+ if (std::find(must_be_f2fs.begin(), must_be_f2fs.end(), entry.mount_point) !=
+ must_be_f2fs.end()) {
+ EXPECT_EQ(entry.fs_type, "f2fs") << entry.mount_point;
+ }
}
}
}
diff --git a/init/README.md b/init/README.md
index 6596528..957eb9e 100644
--- a/init/README.md
+++ b/init/README.md
@@ -162,6 +162,17 @@
setprop e 1
setprop f 2
+If the property `true` wasn't `true` when the `boot` was triggered, then the
+order of the commands executed will be:
+
+ setprop a 1
+ setprop b 2
+ setprop e 1
+ setprop f 2
+
+If the property `true` becomes `true` *AFTER* `boot` was triggered, nothing will
+be executed. The condition `boot && property:true=true` will be evaluated to
+false because the `boot` trigger is a past event.
Services
--------
@@ -184,8 +195,10 @@
capability without the "CAP\_" prefix, like "NET\_ADMIN" or "SETPCAP". See
http://man7.org/linux/man-pages/man7/capabilities.7.html for a list of Linux
capabilities.
- If no capabilities are provided, then all capabilities are removed from this service, even if it
- runs as root.
+ If no capabilities are provided, then behaviour depends on the user the service runs under:
+ * if it's root, then the service will run with all the capabitilies (note: whether the
+ service can actually use them is controlled by selinux);
+ * otherwise all capabilities will be dropped.
`class <name> [ <name>\* ]`
> Specify class names for the service. All services in a
@@ -399,7 +412,7 @@
using this new mechanism, processes can use the user option to
select their desired uid without ever running as root.
As of Android O, processes can also request capabilities directly in their .rc
- files. See the "capabilities" option below.
+ files. See the "capabilities" option above.
`writepid <file> [ <file>\* ]`
> Write the child's pid to the given files when it forks. Meant for
@@ -433,7 +446,9 @@
For example:
`on boot && property:a=b` defines an action that is only executed when
-the 'boot' event trigger happens and the property a equals b.
+the 'boot' event trigger happens and the property a equals b at the moment. This
+will NOT be executed when the property a transitions to value b after the `boot`
+event was triggered.
`on property:a=b && property:c=d` defines an action that is executed
at three times:
diff --git a/init/init_test.cpp b/init/init_test.cpp
index aea1cb3..18a08c7 100644
--- a/init/init_test.cpp
+++ b/init/init_test.cpp
@@ -194,13 +194,14 @@
}
TEST(init, StartConsole) {
- if (access("/dev/console", F_OK) < 0) {
- GTEST_SKIP() << "/dev/console not found";
+ if (GetProperty("ro.build.type", "") == "user") {
+ GTEST_SKIP() << "Must run on userdebug/eng builds. b/262090304";
+ return;
}
std::string init_script = R"init(
service console /system/bin/sh
class core
- console console
+ console null
disabled
user root
group root shell log readproc
diff --git a/init/service.cpp b/init/service.cpp
index 78bf42f..b9b3309 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -700,8 +700,9 @@
if (!result.ok()) {
return Error() << "Sending notification failed: " << result.error();
}
- return Error() << "createProcessGroup(" << proc_attr_.uid << ", " << pid_
- << ") failed for service '" << name_ << "'";
+ return Error() << "createProcessGroup(" << proc_attr_.uid << ", " << pid_ << ", "
+ << use_memcg << ") failed for service '" << name_
+ << "': " << strerror(errno);
}
// When the blkio controller is mounted in the v1 hierarchy, NormalIoPriority is
@@ -866,6 +867,8 @@
if ((how != SVC_DISABLED) && (how != SVC_RESET) && (how != SVC_RESTART)) {
// An illegal flag: default to SVC_DISABLED.
+ LOG(ERROR) << "service '" << name_ << "' requested unknown flag " << how
+ << ", defaulting to disabling it.";
how = SVC_DISABLED;
}
diff --git a/libcutils/ashmem_test.cpp b/libcutils/ashmem_test.cpp
index fb657f6..d158427 100644
--- a/libcutils/ashmem_test.cpp
+++ b/libcutils/ashmem_test.cpp
@@ -75,7 +75,7 @@
unique_fd fd;
ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ | PROT_WRITE));
- void *region1;
+ void* region1 = nullptr;
ASSERT_NO_FATAL_FAILURE(TestMmap(fd, size, PROT_READ | PROT_WRITE, ®ion1));
memcpy(region1, &data, size);
@@ -97,7 +97,7 @@
unique_fd fd;
ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd, PROT_READ | PROT_WRITE));
- void *region1;
+ void* region1 = nullptr;
ASSERT_NO_FATAL_FAILURE(TestMmap(fd, size, PROT_READ | PROT_WRITE, ®ion1));
memcpy(region1, &data, size);
@@ -131,7 +131,7 @@
TEST(AshmemTest, FileOperationsTest) {
unique_fd fd;
- void* region;
+ void* region = nullptr;
// Allocate a 4-page buffer, but leave page-sized holes on either side
constexpr size_t size = PAGE_SIZE * 4;
@@ -246,7 +246,7 @@
unique_fd fd[nRegions];
for (int i = 0; i < nRegions; i++) {
ASSERT_NO_FATAL_FAILURE(TestCreateRegion(size, fd[i], PROT_READ | PROT_WRITE));
- void *region;
+ void* region = nullptr;
ASSERT_NO_FATAL_FAILURE(TestMmap(fd[i], size, PROT_READ | PROT_WRITE, ®ion));
memcpy(region, &data, size);
ASSERT_EQ(0, memcmp(region, &data, size));
diff --git a/libcutils/include/cutils/qtaguid.h b/libcutils/include/cutils/qtaguid.h
index a5ffb03..8902c2b 100644
--- a/libcutils/include/cutils/qtaguid.h
+++ b/libcutils/include/cutils/qtaguid.h
@@ -33,12 +33,6 @@
*/
extern int qtaguid_untagSocket(int sockfd);
-/*
- * Enable/disable qtaguid functionnality at a lower level.
- * When pacified, the kernel will accept commands but do nothing.
- */
-extern int qtaguid_setPacifier(int on);
-
#ifdef __cplusplus
}
#endif
diff --git a/libprocessgroup/OWNERS b/libprocessgroup/OWNERS
index 8ebb8cc..d5aa721 100644
--- a/libprocessgroup/OWNERS
+++ b/libprocessgroup/OWNERS
@@ -1,2 +1,4 @@
-ccross@google.com
+# Bug component: 1293033
surenb@google.com
+tjmercier@google.com
+carlosgalo@google.com
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index 45ac99c..1da69ba 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -471,6 +471,11 @@
*max_processes = processes;
}
LOG(VERBOSE) << "Killed " << processes << " processes for processgroup " << initialPid;
+ if (!CgroupsAvailable()) {
+ // makes no sense to retry, because there are no cgroup_procs file
+ processes = 0; // no remaining processes
+ break;
+ }
if (retry > 0) {
std::this_thread::sleep_for(5ms);
--retry;
diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json
index c485097..e44d3bf 100644
--- a/libprocessgroup/profiles/task_profiles.json
+++ b/libprocessgroup/profiles/task_profiles.json
@@ -80,17 +80,20 @@
{
"Name": "BfqWeight",
"Controller": "io",
- "File": "io.bfq.weight"
+ "File": "blkio.bfq.weight",
+ "FileV2": "io.bfq.weight"
},
{
"Name": "CfqGroupIdle",
"Controller": "io",
- "File": "io.group_idle"
+ "File": "blkio.group_idle",
+ "FileV2": "io.group_idle"
},
{
"Name": "CfqWeight",
"Controller": "io",
- "File": "io.weight"
+ "File": "blkio.weight",
+ "FileV2": "io.weight"
}
],
@@ -459,7 +462,7 @@
{
"Controller": "blkio",
"Path": "background"
- }
+ }
},
{
"Name": "SetAttribute",
@@ -499,7 +502,7 @@
{
"Controller": "blkio",
"Path": ""
- }
+ }
},
{
"Name": "SetAttribute",
@@ -539,7 +542,7 @@
{
"Controller": "blkio",
"Path": ""
- }
+ }
},
{
"Name": "SetAttribute",
@@ -579,7 +582,7 @@
{
"Controller": "blkio",
"Path": ""
- }
+ }
},
{
"Name": "SetAttribute",
diff --git a/libutils/Android.bp b/libutils/Android.bp
index b07058a..162f0f4 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -21,11 +21,13 @@
vendor_ramdisk_available: true,
host_supported: true,
native_bridge_supported: true,
+ defaults: [
+ "apex-lowest-min-sdk-version",
+ ],
apex_available: [
"//apex_available:platform",
"//apex_available:anyapex",
],
- min_sdk_version: "apex_inherit",
header_libs: [
"libbase_headers",
@@ -124,7 +126,10 @@
cc_defaults {
name: "libutils_impl_defaults",
- defaults: ["libutils_defaults"],
+ defaults: [
+ "libutils_defaults",
+ "apex-lowest-min-sdk-version",
+ ],
native_bridge_supported: true,
srcs: [
@@ -167,7 +172,6 @@
"//apex_available:anyapex",
"//apex_available:platform",
],
- min_sdk_version: "apex_inherit",
afdo: true,
}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index d8e6b55..881564c 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -55,10 +55,11 @@
# Read more in b/136247322
write /sys/module/dm_verity/parameters/prefetch_cluster 0
- # Generate ld.config.txt for early executed processes
- exec -- /system/bin/bootstrap/linkerconfig --target /linkerconfig/bootstrap
+ # Generate empty ld.config.txt for early executed processes which rely on
+ # /system/lib libraries.
+ write /linkerconfig/bootstrap/ld.config.txt \#
+ write /linkerconfig/default/ld.config.txt \#
chmod 644 /linkerconfig/bootstrap/ld.config.txt
- copy /linkerconfig/bootstrap/ld.config.txt /linkerconfig/default/ld.config.txt
chmod 644 /linkerconfig/default/ld.config.txt
# Mount bootstrap linker configuration as current
@@ -489,18 +490,26 @@
service boringssl_self_test32 /system/bin/boringssl_self_test32
reboot_on_failure reboot,boringssl-self-check-failed
stdio_to_kmsg
+ # Explicitly specify that boringssl_self_test32 doesn't require any capabilities
+ capabilities
service boringssl_self_test64 /system/bin/boringssl_self_test64
reboot_on_failure reboot,boringssl-self-check-failed
stdio_to_kmsg
+ # Explicitly specify that boringssl_self_test64 doesn't require any capabilities
+ capabilities
service boringssl_self_test_apex32 /apex/com.android.conscrypt/bin/boringssl_self_test32
reboot_on_failure reboot,boringssl-self-check-failed
stdio_to_kmsg
+ # Explicitly specify that boringssl_self_test_apex32 doesn't require any capabilities
+ capabilities
service boringssl_self_test_apex64 /apex/com.android.conscrypt/bin/boringssl_self_test64
reboot_on_failure reboot,boringssl-self-check-failed
stdio_to_kmsg
+ # Explicitly specify that boringssl_self_test_apex64 doesn't require any capabilities
+ capabilities
# Healthd can trigger a full boot from charger mode by signaling this
@@ -838,7 +847,7 @@
# Delete any stale files owned by the old virtualizationservice uid (b/230056726).
chmod 0770 /data/misc/virtualizationservice
exec - virtualizationservice system -- /bin/rm -rf /data/misc/virtualizationservice
- mkdir /data/misc/virtualizationservice 0770 system system
+ mkdir /data/misc/virtualizationservice 0771 system system
# /data/preloads uses encryption=None because it only contains preloaded
# files that are public information, similar to the system image.
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 4ec59af..0b7ffb8 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -69,8 +69,8 @@
# CDMA radio interface MUX
/dev/ppp 0660 radio vpn
-/dev/kvm 0600 system system
-/dev/vhost-vsock 0600 system system
+/dev/kvm 0666 root root
+/dev/vhost-vsock 0666 root root
# sysfs properties
/sys/devices/platform/trusty.* trusty_version 0440 root log
diff --git a/trusty/keymint/src/keymint_hal_main.rs b/trusty/keymint/src/keymint_hal_main.rs
index d2d5f27..cfa859f 100644
--- a/trusty/keymint/src/keymint_hal_main.rs
+++ b/trusty/keymint/src/keymint_hal_main.rs
@@ -14,7 +14,9 @@
// limitations under the License.
//! This module implements the HAL service for Keymint (Rust) in Trusty.
-use kmr_hal::{keymint, rpc, secureclock, send_hal_info, sharedsecret, SerializedChannel};
+use kmr_hal::{
+ extract_rsp, keymint, rpc, secureclock, send_hal_info, sharedsecret, SerializedChannel,
+};
use log::{error, info};
use std::{
ffi::CString,
@@ -41,6 +43,7 @@
struct TipcChannel(trusty::TipcChannel);
impl SerializedChannel for TipcChannel {
+ const MAX_SIZE: usize = 4000;
fn execute(&mut self, serialized_req: &[u8]) -> binder::Result<Vec<u8>> {
self.0.send(serialized_req).map_err(|e| {
binder::Status::new_exception(
@@ -54,21 +57,27 @@
),
)
})?;
- let mut recv_buf = Vec::new();
- // TODO(b/253501976): cope with fragmentation of responses
- self.0.recv(&mut recv_buf).map_err(|e| {
- binder::Status::new_exception(
- binder::ExceptionCode::TRANSACTION_FAILED,
- Some(
- &CString::new(format!(
- "Failed to receive the response via tipc channel because of {:?}",
- e
- ))
- .unwrap(),
- ),
- )
- })?;
- Ok(recv_buf)
+ let mut expect_more_msgs = true;
+ let mut full_rsp = Vec::new();
+ while expect_more_msgs {
+ let mut recv_buf = Vec::new();
+ self.0.recv(&mut recv_buf).map_err(|e| {
+ binder::Status::new_exception(
+ binder::ExceptionCode::TRANSACTION_FAILED,
+ Some(
+ &CString::new(format!(
+ "Failed to receive the response via tipc channel because of {:?}",
+ e
+ ))
+ .unwrap(),
+ ),
+ )
+ })?;
+ let current_rsp_content;
+ (expect_more_msgs, current_rsp_content) = extract_rsp(&recv_buf)?;
+ full_rsp.extend_from_slice(current_rsp_content);
+ }
+ Ok(full_rsp)
}
}
diff --git a/trusty/trusty-base.mk b/trusty/trusty-base.mk
index 0609709..7b4aa26 100644
--- a/trusty/trusty-base.mk
+++ b/trusty/trusty-base.mk
@@ -22,8 +22,21 @@
# For gatekeeper, we include the generic -service and -impl to use legacy
# HAL loading of gatekeeper.trusty.
+# Allow the KeyMint HAL service implementation to be selected at build time. This needs to be
+# done in sync with the TA implementation included in Trusty. Possible values are:
+#
+# - Rust implementation: export TRUSTY_KEYMINT_IMPL=rust
+# - C++ implementation: (any other value of TRUSTY_KEYMINT_IMPL)
+
+ifeq ($(TRUSTY_KEYMINT_IMPL),rust)
+ LOCAL_KEYMINT_PRODUCT_PACKAGE := android.hardware.security.keymint-service.rust.trusty
+else
+ # Default to the C++ implementation
+ LOCAL_KEYMINT_PRODUCT_PACKAGE := android.hardware.security.keymint-service.trusty
+endif
+
PRODUCT_PACKAGES += \
- android.hardware.security.keymint-service.trusty \
+ $(LOCAL_KEYMINT_PRODUCT_PACKAGE) \
android.hardware.gatekeeper@1.0-service.trusty \
trusty_apploader \
RemoteProvisioner