Merge "libprocessgroup: Support memcg v1 per-app with PRODUCT_CGROUP_V2_SYS_APP_ISOLATION_ENABLED" into main
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 3257a2c..0e62ceb 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -505,6 +505,7 @@
"libbase",
"libdebuggerd_client",
"liblog",
+ "libprocessgroup",
"libprocinfo",
],
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index 15e8319..7d3830c 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -22,9 +22,14 @@
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/un.h>
+#include <sys/user.h>
#include <sys/wait.h>
#include <unistd.h>
+#if defined(__i386__)
+#include <asm/ldt.h>
+#endif
+
#include <cstdint>
#include <limits>
#include <map>
@@ -430,18 +435,12 @@
return true;
}
-static bool GetGuestRegistersFromCrashedProcess([[maybe_unused]] pid_t tid,
- NativeBridgeGuestRegs* guest_regs) {
+static bool GetGuestRegistersFromCrashedProcess(pid_t tid, NativeBridgeGuestRegs* guest_regs) {
auto process_memory = unwindstack::Memory::CreateProcessMemoryCached(tid);
uintptr_t header_ptr = 0;
uintptr_t base = 0;
-#if defined(__x86_64__)
- if (!PtracePeek(PTRACE_PEEKUSER, tid, offsetof(user_regs_struct, fs_base), nullptr,
- "failed to read thread register for thread " + std::to_string(tid), &base)) {
- return false;
- }
-#elif defined(__aarch64__)
+#if defined(__aarch64__)
// base is implicitly casted to uint64_t.
struct iovec pt_iov {
.iov_base = &base, .iov_len = sizeof(base),
@@ -451,6 +450,26 @@
PLOG(ERROR) << "failed to read thread register for thread " << tid;
return false;
}
+#elif defined(__arm__)
+ if (ptrace(PTRACE_GET_THREAD_AREA, tid, nullptr, &base) == 0) {
+ PLOG(ERROR) << "failed to get thread area for thread " << tid;
+ return false;
+ }
+#elif defined(__i386__)
+ struct user_regs_struct regs;
+ struct iovec pt_iov = {.iov_base = ®s, .iov_len = sizeof(regs)};
+ if (ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &pt_iov) != 0) {
+ PLOG(ERROR) << "failed to get registers for thread " << tid;
+ return false;
+ }
+
+ struct user_desc desc;
+ desc.entry_number = regs.xgs >> 3;
+ if (ptrace(PTRACE_GET_THREAD_AREA, tid, desc.entry_number, &desc) != 0) {
+ PLOG(ERROR) << "failed to get thread area for thread " << tid;
+ return false;
+ }
+ base = desc.base_addr;
#elif defined(__riscv)
struct user_regs_struct regs;
struct iovec pt_iov = {.iov_base = ®s, .iov_len = sizeof(regs)};
@@ -459,6 +478,11 @@
return false;
}
base = reinterpret_cast<uintptr_t>(regs.tp);
+#elif defined(__x86_64__)
+ if (!PtracePeek(PTRACE_PEEKUSER, tid, offsetof(user_regs_struct, fs_base), nullptr,
+ "failed to read thread register for thread " + std::to_string(tid), &base)) {
+ return false;
+ }
#else
// TODO(b/339287219): Add case for Riscv host.
return false;
@@ -487,9 +511,7 @@
return true;
}
-static void ReadGuestRegisters([[maybe_unused]] std::unique_ptr<unwindstack::Regs>* regs,
- pid_t tid) {
- // TODO: remove [[maybe_unused]], when the ARM32 case is removed from the native bridge support.
+static void ReadGuestRegisters(std::unique_ptr<unwindstack::Regs>* regs, pid_t tid) {
NativeBridgeGuestRegs guest_regs;
if (!GetGuestRegistersFromCrashedProcess(tid, &guest_regs)) {
return;
@@ -521,6 +543,17 @@
g_guest_arch = Architecture::RISCV64;
break;
}
+#else
+ case NATIVE_BRIDGE_ARCH_ARM: {
+ unwindstack::arm_user_regs arm_user_regs = {};
+ for (size_t i = 0; i < unwindstack::ARM_REG_LAST; i++) {
+ arm_user_regs.regs[i] = guest_regs.regs_arm.r[i];
+ }
+ regs->reset(unwindstack::RegsArm::Read(&arm_user_regs));
+
+ g_guest_arch = Architecture::ARM32;
+ break;
+ }
#endif
default:
break;
@@ -796,16 +829,17 @@
ATRACE_NAME("engrave_tombstone");
unwindstack::ArchEnum regs_arch = unwindstack::ARCH_UNKNOWN;
switch (g_guest_arch) {
- case Architecture::ARM64: {
+ case Architecture::ARM32:
+ regs_arch = unwindstack::ARCH_ARM;
+ break;
+ case Architecture::ARM64:
regs_arch = unwindstack::ARCH_ARM64;
break;
- }
- case Architecture::RISCV64: {
+ case Architecture::RISCV64:
regs_arch = unwindstack::ARCH_RISCV64;
break;
- }
- default: {
- }
+ default:
+ break;
}
if (regs_arch == unwindstack::ARCH_UNKNOWN) {
engrave_tombstone(std::move(g_output_fd), std::move(g_proto_fd), &unwinder, thread_info,
diff --git a/debuggerd/crasher/crasher.cpp b/debuggerd/crasher/crasher.cpp
index 05143ed..c3dd92b 100644
--- a/debuggerd/crasher/crasher.cpp
+++ b/debuggerd/crasher/crasher.cpp
@@ -402,6 +402,8 @@
return EXIT_SUCCESS;
}
+} // extern "C"
+
int main(int argc, char** argv) {
#if defined(STATIC_CRASHER)
debuggerd_callbacks_t callbacks = {
@@ -427,5 +429,3 @@
return usage();
}
-
-};
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 0d4b91f..7a2500c 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -23,11 +23,11 @@
#include <string_view>
#include <thread>
-#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/unique_fd.h>
#include <debuggerd/client.h>
+#include <processgroup/processgroup.h>
#include <procinfo/process.h>
#include "util.h"
@@ -92,13 +92,8 @@
}
// unfreeze if pid is frozen.
- const std::string freeze_file = android::base::StringPrintf(
- "/sys/fs/cgroup/uid_%d/pid_%d/cgroup.freeze", proc_info.uid, proc_info.pid);
- if (std::string freeze_status;
- android::base::ReadFileToString(freeze_file, &freeze_status) && freeze_status[0] == '1') {
- android::base::WriteStringToFile("0", freeze_file);
- // we don't restore the frozen state as this is considered a benign change.
- }
+ SetProcessProfiles(proc_info.uid, proc_info.pid, {"Unfrozen"});
+ // we don't restore the frozen state as this is considered a benign change.
unique_fd output_fd(fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 0));
if (output_fd.get() == -1) {
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 5bdc946..04a7df8 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -3303,8 +3303,44 @@
ASSERT_MATCH(result, ":\\s*This is on the next line.");
}
-TEST_F(CrasherTest, log_with_non_utf8) {
- StartProcess([]() { LOG(FATAL) << "Invalid UTF-8: \xA0\xB0\xC0\xD0 and some other data."; });
+TEST_F(CrasherTest, log_with_non_printable_ascii_verify_encoded) {
+ static const std::string kEncodedStr =
+ "\x5C\x31"
+ "\x5C\x32"
+ "\x5C\x33"
+ "\x5C\x34"
+ "\x5C\x35"
+ "\x5C\x36"
+ "\x5C\x37"
+ "\x5C\x31\x30"
+ "\x5C\x31\x36"
+ "\x5C\x31\x37"
+ "\x5C\x32\x30"
+ "\x5C\x32\x31"
+ "\x5C\x32\x32"
+ "\x5C\x32\x33"
+ "\x5C\x32\x34"
+ "\x5C\x32\x35"
+ "\x5C\x32\x36"
+ "\x5C\x32\x37"
+ "\x5C\x33\x30"
+ "\x5C\x33\x31"
+ "\x5C\x33\x32"
+ "\x5C\x33\x33"
+ "\x5C\x33\x34"
+ "\x5C\x33\x35"
+ "\x5C\x33\x36"
+ "\x5C\x33\x37"
+ "\x5C\x31\x37\x37"
+ "\x5C\x32\x34\x30"
+ "\x5C\x32\x36\x30"
+ "\x5C\x33\x30\x30"
+ "\x5C\x33\x32\x30";
+ StartProcess([]() {
+ LOG(FATAL) << "Encoded: "
+ "\x1\x2\x3\x4\x5\x6\x7\x8\xe\xf\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b"
+ "\x1c\x1d\x1e\x1f\x7f\xA0\xB0\xC0\xD0 after";
+ });
unique_fd output_fd;
StartIntercept(&output_fd);
@@ -3317,15 +3353,38 @@
std::string result;
ConsumeFd(std::move(output_fd), &result);
// Verify the abort message is sanitized properly.
- size_t pos = result.find(
- "Abort message: 'Invalid UTF-8: "
- "\x5C\x32\x34\x30\x5C\x32\x36\x30\x5C\x33\x30\x30\x5C\x33\x32\x30 and some other data.'");
+ size_t pos = result.find(std::string("Abort message: 'Encoded: ") + kEncodedStr + " after'");
EXPECT_TRUE(pos != std::string::npos) << "Couldn't find sanitized abort message: " << result;
// Make sure that the log message is sanitized properly too.
- EXPECT_TRUE(
- result.find("Invalid UTF-8: \x5C\x32\x34\x30\x5C\x32\x36\x30\x5C\x33\x30\x30\x5C\x33\x32\x30 "
- "and some other data.",
- pos + 30) != std::string::npos)
+ EXPECT_TRUE(result.find(std::string("Encoded: ") + kEncodedStr + " after", pos + 1) !=
+ std::string::npos)
+ << "Couldn't find sanitized log message: " << result;
+}
+
+TEST_F(CrasherTest, log_with_with_special_printable_ascii) {
+ static const std::string kMsg = "Not encoded: \t\v\f\r\n after";
+ StartProcess([]() { LOG(FATAL) << kMsg; });
+
+ unique_fd output_fd;
+ StartIntercept(&output_fd);
+ FinishCrasher();
+ AssertDeath(SIGABRT);
+ int intercept_result;
+ FinishIntercept(&intercept_result);
+ ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
+
+ std::string result;
+ ConsumeFd(std::move(output_fd), &result);
+ // Verify the abort message does not remove characters that are UTF8 but
+ // are, technically, not printable.
+ size_t pos = result.find(std::string("Abort message: '") + kMsg + "'");
+ EXPECT_TRUE(pos != std::string::npos) << "Couldn't find abort message: " << result;
+
+ // Make sure that the log message is handled properly too.
+ // The logger automatically splits a newline message into two pieces.
+ pos = result.find("Not encoded: \t\v\f\r", pos + kMsg.size());
+ EXPECT_TRUE(pos != std::string::npos) << "Couldn't find log message: " << result;
+ EXPECT_TRUE(result.find(" after", pos + 1) != std::string::npos)
<< "Couldn't find sanitized log message: " << result;
}
diff --git a/debuggerd/libdebuggerd/include/libdebuggerd/utility_host.h b/debuggerd/libdebuggerd/include/libdebuggerd/utility_host.h
index df22e01..819a99d 100644
--- a/debuggerd/libdebuggerd/include/libdebuggerd/utility_host.h
+++ b/debuggerd/libdebuggerd/include/libdebuggerd/utility_host.h
@@ -30,4 +30,7 @@
constexpr size_t kNumTagColumns = 16;
constexpr size_t kNumTagRows = 16;
-std::string oct_encode(const std::string& data);
+// Encode all non-ascii values and also ascii values that are not printable.
+std::string oct_encode_non_ascii_printable(const std::string& data);
+// Encode any value that fails isprint(), includes encoding chars like '\n' and '\t'.
+std::string oct_encode_non_printable(const std::string& data);
diff --git a/debuggerd/libdebuggerd/tombstone_proto.cpp b/debuggerd/libdebuggerd/tombstone_proto.cpp
index ef303f0..d3ac49a 100644
--- a/debuggerd/libdebuggerd/tombstone_proto.cpp
+++ b/debuggerd/libdebuggerd/tombstone_proto.cpp
@@ -467,7 +467,7 @@
msg.resize(index);
// Make sure only UTF8 characters are present since abort_message is a string.
- tombstone->set_abort_message(oct_encode(msg));
+ tombstone->set_abort_message(oct_encode_non_ascii_printable(msg));
}
static void dump_open_fds(Tombstone* tombstone, const OpenFilesList* open_files) {
@@ -776,7 +776,7 @@
log_msg->set_priority(prio);
log_msg->set_tag(tag);
// Make sure only UTF8 characters are present since message is a string.
- log_msg->set_message(oct_encode(msg));
+ log_msg->set_message(oct_encode_non_ascii_printable(msg));
} while ((msg = nl));
}
android_logger_list_free(logger_list);
diff --git a/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp b/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
index e885c5a..11841b2 100644
--- a/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
+++ b/debuggerd/libdebuggerd/tombstone_proto_to_text.cpp
@@ -17,6 +17,7 @@
#include <libdebuggerd/tombstone_proto_to_text.h>
#include <libdebuggerd/utility_host.h>
+#include <ctype.h>
#include <inttypes.h>
#include <algorithm>
@@ -463,8 +464,8 @@
}
for (const auto& crash_detail : tombstone.crash_details()) {
- std::string oct_encoded_name = oct_encode(crash_detail.name());
- std::string oct_encoded_data = oct_encode(crash_detail.data());
+ std::string oct_encoded_name = oct_encode_non_printable(crash_detail.name());
+ std::string oct_encoded_data = oct_encode_non_printable(crash_detail.data());
CBL("Extra crash detail: %s: '%s'", oct_encoded_name.c_str(), oct_encoded_data.c_str());
}
@@ -593,7 +594,7 @@
if (tombstone.page_size() != 4096) {
CBL("Page size: %d bytes", tombstone.page_size());
} else if (tombstone.has_been_16kb_mode()) {
- CBL("Has been in 16kb mode: yes");
+ CBL("Has been in 16 KB mode before: yes");
}
// Process header
diff --git a/debuggerd/libdebuggerd/utility_host.cpp b/debuggerd/libdebuggerd/utility_host.cpp
index 4efa03c..d87f4fb 100644
--- a/debuggerd/libdebuggerd/utility_host.cpp
+++ b/debuggerd/libdebuggerd/utility_host.cpp
@@ -16,6 +16,7 @@
#include "libdebuggerd/utility_host.h"
+#include <ctype.h>
#include <sys/prctl.h>
#include <charconv>
@@ -102,23 +103,31 @@
return describe_end(value, desc);
}
-std::string oct_encode(const std::string& data) {
+static std::string oct_encode(const std::string& data, bool (*should_encode_func)(int)) {
std::string oct_encoded;
oct_encoded.reserve(data.size());
// N.B. the unsigned here is very important, otherwise e.g. \255 would render as
// \-123 (and overflow our buffer).
for (unsigned char c : data) {
- if (isprint(c)) {
- oct_encoded += c;
- } else {
+ if (should_encode_func(c)) {
std::string oct_digits("\\\0\0\0", 4);
// char is encodable in 3 oct digits
static_assert(std::numeric_limits<unsigned char>::max() <= 8 * 8 * 8);
auto [ptr, ec] = std::to_chars(oct_digits.data() + 1, oct_digits.data() + 4, c, 8);
oct_digits.resize(ptr - oct_digits.data());
oct_encoded += oct_digits;
+ } else {
+ oct_encoded += c;
}
}
return oct_encoded;
}
+
+std::string oct_encode_non_ascii_printable(const std::string& data) {
+ return oct_encode(data, [](int c) { return !isgraph(c) && !isspace(c); });
+}
+
+std::string oct_encode_non_printable(const std::string& data) {
+ return oct_encode(data, [](int c) { return !isprint(c); });
+}
diff --git a/fastboot/OWNERS b/fastboot/OWNERS
index 3dec07e..2444081 100644
--- a/fastboot/OWNERS
+++ b/fastboot/OWNERS
@@ -1,5 +1,6 @@
dvander@google.com
elsk@google.com
enh@google.com
+sanglardf@google.com
zhangkelvin@google.com
diff --git a/fs_mgr/TEST_MAPPING b/fs_mgr/TEST_MAPPING
index 13af1e2..ccbb67e 100644
--- a/fs_mgr/TEST_MAPPING
+++ b/fs_mgr/TEST_MAPPING
@@ -36,9 +36,6 @@
],
"kernel-presubmit": [
{
- "name": "adb-remount-sh"
- },
- {
"name": "libdm_test"
},
{
diff --git a/fs_mgr/libfstab/fstab.cpp b/fs_mgr/libfstab/fstab.cpp
index 01e0e3d..010fbc8 100644
--- a/fs_mgr/libfstab/fstab.cpp
+++ b/fs_mgr/libfstab/fstab.cpp
@@ -75,6 +75,7 @@
{"slave", MS_SLAVE},
{"shared", MS_SHARED},
{"lazytime", MS_LAZYTIME},
+ {"nosymfollow", MS_NOSYMFOLLOW},
{"defaults", 0},
};
diff --git a/fs_mgr/libsnapshot/scratch_super.cpp b/fs_mgr/libsnapshot/scratch_super.cpp
index 93c4bbd..2036905 100644
--- a/fs_mgr/libsnapshot/scratch_super.cpp
+++ b/fs_mgr/libsnapshot/scratch_super.cpp
@@ -25,6 +25,13 @@
#include <sys/vfs.h>
#include <unistd.h>
+#include <algorithm>
+#include <filesystem>
+#include <memory>
+#include <optional>
+#include <string>
+#include <vector>
+
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/macros.h>
@@ -41,12 +48,6 @@
#include <fstab/fstab.h>
#include <liblp/builder.h>
#include <storage_literals/storage_literals.h>
-#include <algorithm>
-#include <filesystem>
-#include <memory>
-#include <optional>
-#include <string>
-#include <vector>
#include "device_info.h"
#include "scratch_super.h"
@@ -60,9 +61,18 @@
namespace snapshot {
static bool UmountScratch() {
- auto ota_dir = std::string(kOtaMetadataMount) + "/" + "ota";
- std::error_code ec;
+ Fstab fstab;
+ if (!ReadFstabFromProcMounts(&fstab)) {
+ LOG(ERROR) << "Cannot read /proc/mounts";
+ return false;
+ }
+ if (GetEntryForMountPoint(&fstab, kOtaMetadataMount) == nullptr) {
+ return true;
+ }
+ auto ota_dir = std::string(kOtaMetadataMount) + "/" + "ota";
+
+ std::error_code ec;
if (std::filesystem::remove_all(ota_dir, ec) == static_cast<std::uintmax_t>(-1)) {
LOG(ERROR) << "Failed to remove OTA directory: " << ec.message();
return false;
diff --git a/fs_mgr/libsnapshot/snapshot.cpp b/fs_mgr/libsnapshot/snapshot.cpp
index acabd67..ecf567e 100644
--- a/fs_mgr/libsnapshot/snapshot.cpp
+++ b/fs_mgr/libsnapshot/snapshot.cpp
@@ -2404,6 +2404,9 @@
PLOG(ERROR) << "Unable to write rollback indicator: " << path;
} else {
LOG(INFO) << "Rollback detected, writing rollback indicator to " << path;
+ if (device_->IsTempMetadata()) {
+ CleanupScratchOtaMetadataIfPresent();
+ }
}
}
LOG(INFO) << "Not booting from new slot. Will not mount snapshots.";
diff --git a/fs_mgr/libsnapshot/snapshot_test.cpp b/fs_mgr/libsnapshot/snapshot_test.cpp
index 1a0d559..931de89 100644
--- a/fs_mgr/libsnapshot/snapshot_test.cpp
+++ b/fs_mgr/libsnapshot/snapshot_test.cpp
@@ -1345,6 +1345,7 @@
TEST_F(SnapshotUpdateTest, SuperOtaMetadataTest) {
auto info = new TestDeviceInfo(fake_super);
+ ASSERT_TRUE(CleanupScratchOtaMetadataIfPresent(info));
ASSERT_TRUE(CreateScratchOtaMetadataOnSuper(info));
std::string scratch_device = GetScratchOtaMetadataPartition();
ASSERT_NE(scratch_device, "");
@@ -3071,6 +3072,18 @@
::testing::AddGlobalTestEnvironment(new ::android::snapshot::SnapshotTestEnvironment());
gflags::ParseCommandLineFlags(&argc, &argv, false);
+ // During incremental flashing, snapshot updates are in progress.
+ //
+ // When snapshot update is in-progress, snapuserd daemon
+ // will be up and running. These tests will start and stop the daemon
+ // thereby interfering with the update and snapshot-merge progress.
+ // Hence, wait until the update is complete.
+ auto sm = android::snapshot::SnapshotManager::New();
+ while (sm->IsUserspaceSnapshotUpdateInProgress()) {
+ LOG(INFO) << "Snapshot update is in progress. Waiting...";
+ std::this_thread::sleep_for(std::chrono::milliseconds(1000));
+ }
+
bool vab_legacy = false;
if (FLAGS_force_mode == "vab-legacy") {
vab_legacy = true;
diff --git a/fs_mgr/tests/fs_mgr_test.cpp b/fs_mgr/tests/fs_mgr_test.cpp
index 8004977..fc3d5dc 100644
--- a/fs_mgr/tests/fs_mgr_test.cpp
+++ b/fs_mgr/tests/fs_mgr_test.cpp
@@ -330,6 +330,7 @@
{"slave", MS_SLAVE},
{"shared", MS_SHARED},
{"lazytime", MS_LAZYTIME},
+ {"nosymfollow", MS_NOSYMFOLLOW},
{"defaults", 0},
{0, 0},
};
diff --git a/gatekeeperd/fuzzer/GateKeeperServiceFuzzer.cpp b/gatekeeperd/fuzzer/GateKeeperServiceFuzzer.cpp
index bc0d5fe..a3cc3f3 100644
--- a/gatekeeperd/fuzzer/GateKeeperServiceFuzzer.cpp
+++ b/gatekeeperd/fuzzer/GateKeeperServiceFuzzer.cpp
@@ -22,6 +22,8 @@
using android::GateKeeperProxy;
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ // TODO(b/183141167): need to rewrite 'dump' to avoid SIGPIPE.
+ signal(SIGPIPE, SIG_IGN);
auto gatekeeperService = new GateKeeperProxy();
fuzzService(gatekeeperService, FuzzedDataProvider(data, size));
return 0;
diff --git a/init/Android.bp b/init/Android.bp
index 4ee3be2..ed19b4b 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -268,7 +268,6 @@
cc_defaults {
name: "init_second_stage_defaults",
- recovery_available: true,
stem: "init",
defaults: ["init_defaults"],
srcs: ["main.cpp"],
@@ -280,37 +279,38 @@
defaults: ["init_second_stage_defaults"],
static_libs: ["libinit"],
visibility: ["//visibility:any_system_partition"],
- target: {
- platform: {
- required: [
- "init.rc",
- "ueventd.rc",
- "e2fsdroid",
- "extra_free_kbytes",
- "make_f2fs",
- "mke2fs",
- "sload_f2fs",
- ],
- },
- recovery: {
- cflags: ["-DRECOVERY"],
- exclude_static_libs: [
- "libxml2",
- ],
- exclude_shared_libs: [
- "libbinder",
- "libutils",
- ],
- required: [
- "init_recovery.rc",
- "ueventd.rc.recovery",
- "e2fsdroid.recovery",
- "make_f2fs.recovery",
- "mke2fs.recovery",
- "sload_f2fs.recovery",
- ],
- },
- },
+ required: [
+ "init.rc",
+ "ueventd.rc",
+ "e2fsdroid",
+ "extra_free_kbytes",
+ "make_f2fs",
+ "mke2fs",
+ "sload_f2fs",
+ ],
+}
+
+cc_binary {
+ name: "init_second_stage.recovery",
+ defaults: ["init_second_stage_defaults"],
+ static_libs: ["libinit"],
+ recovery: true,
+ cflags: ["-DRECOVERY"],
+ exclude_static_libs: [
+ "libxml2",
+ ],
+ exclude_shared_libs: [
+ "libbinder",
+ "libutils",
+ ],
+ required: [
+ "init_recovery.rc",
+ "ueventd.rc.recovery",
+ "e2fsdroid.recovery",
+ "make_f2fs.recovery",
+ "mke2fs.recovery",
+ "sload_f2fs.recovery",
+ ],
}
cc_binary {
@@ -319,7 +319,6 @@
"avf_build_flags_cc",
"init_second_stage_defaults",
],
- recovery_available: false,
static_libs: ["libinit.microdroid"],
cflags: ["-DMICRODROID=1"],
no_full_install: true,
diff --git a/init/README.md b/init/README.md
index 560c528..653dadd 100644
--- a/init/README.md
+++ b/init/README.md
@@ -369,6 +369,17 @@
`setenv <name> <value>`
> Set the environment variable _name_ to _value_ in the launched process.
+`shared_kallsyms`
+> If set, init will behave as if the service specified "file /proc/kallsyms r",
+ except the service will receive a duplicate of a single fd that init saved
+ during early second\_stage. This fd retains address visibility even after the
+ systemwide kptr\_restrict sysctl is set to its steady state on Android. The
+ ability to read from this fd is still constrained by selinux permissions,
+ which need to be granted separately and are gated by a neverallow.
+ Because of performance gotchas of concurrent use of this shared fd, all uses
+ need to coordinate via provisional flock(LOCK\_EX) locks on separately opened
+ /proc/kallsyms fds (since locking requires distinct open file descriptions).
+
`shutdown <shutdown_behavior>`
> Set shutdown behavior of the service process. When this is not specified,
the service is killed during shutdown process by using SIGTERM and SIGKILL.
diff --git a/init/builtins.cpp b/init/builtins.cpp
index c4af5b5..38aed9c 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -471,6 +471,7 @@
{ "private", MS_PRIVATE },
{ "slave", MS_SLAVE },
{ "shared", MS_SHARED },
+ { "nosymfollow", MS_NOSYMFOLLOW },
{ "defaults", 0 },
{ 0, 0 },
};
diff --git a/init/init.cpp b/init/init.cpp
index 5b0b0dd..b6ba6a8 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -1055,6 +1055,14 @@
}
}
+ // This needs to happen before SetKptrRestrictAction, as we are trying to
+ // open /proc/kallsyms while still being allowed to see the full addresses
+ // (since init holds CAP_SYSLOG, and Linux boots with kptr_restrict=0). The
+ // address visibility through the saved fd (more specifically, the backing
+ // open file description) will then be remembered by the kernel for the rest
+ // of its lifetime, even after we raise the kptr_restrict.
+ Service::OpenAndSaveStaticKallsymsFd();
+
am.QueueBuiltinAction(SetupCgroupsAction, "SetupCgroups");
am.QueueBuiltinAction(SetKptrRestrictAction, "SetKptrRestrict");
am.QueueBuiltinAction(TestPerfEventSelinuxAction, "TestPerfEventSelinux");
diff --git a/init/libprefetch/prefetch/src/arch/android.rs b/init/libprefetch/prefetch/src/arch/android.rs
index c765e38..3404e42 100644
--- a/init/libprefetch/prefetch/src/arch/android.rs
+++ b/init/libprefetch/prefetch/src/arch/android.rs
@@ -11,8 +11,8 @@
use rustutils::system_properties::error::PropertyWatcherError;
use rustutils::system_properties::PropertyWatcher;
-const PREFETCH_RECORD_PROPERTY: &str = "ro.prefetch_boot.record";
-const PREFETCH_REPLAY_PROPERTY: &str = "ro.prefetch_boot.replay";
+const PREFETCH_RECORD_PROPERTY: &str = "prefetch_boot.record";
+const PREFETCH_REPLAY_PROPERTY: &str = "prefetch_boot.replay";
const PREFETCH_RECORD_PROPERTY_STOP: &str = "ro.prefetch_boot.record_stop";
fn wait_for_property_true(
diff --git a/init/service.cpp b/init/service.cpp
index d76a5d5..5630020 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -34,6 +34,7 @@
#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <cutils/android_get_control_file.h>
#include <cutils/sockets.h>
#include <processgroup/processgroup.h>
#include <selinux/selinux.h>
@@ -672,6 +673,14 @@
}
}
+ if (shared_kallsyms_file_) {
+ if (auto result = CreateSharedKallsymsFd(); result.ok()) {
+ descriptors.emplace_back(std::move(*result));
+ } else {
+ LOG(INFO) << "Could not obtain a copy of /proc/kallsyms: " << result.error();
+ }
+ }
+
pid_t pid = -1;
if (namespaces_.flags) {
pid = clone(nullptr, nullptr, namespaces_.flags | SIGCHLD, nullptr);
@@ -835,6 +844,35 @@
return unique_fd(signalfd(-1, &mask, SFD_CLOEXEC));
}
+void Service::OpenAndSaveStaticKallsymsFd() {
+ Result<Descriptor> result = CreateSharedKallsymsFd();
+ if (!result.ok()) {
+ LOG(ERROR) << result.error();
+ }
+}
+
+// This function is designed to be called in two situations:
+// 1) early during second_stage init, to open and save the shared fd as a
+// static (see OpenAndSaveStaticKallsymsFd).
+// 2) whenever a service requesting a copy of the fd is being started, at which
+// point it will get a duplicated copy of the static fd.
+Result<Descriptor> Service::CreateSharedKallsymsFd() {
+ static constexpr char kallsyms_path[] = "/proc/kallsyms";
+ static int static_fd = open(kallsyms_path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
+ if (static_fd < 0) {
+ return ErrnoError() << "failed to open " << kallsyms_path;
+ }
+
+ unique_fd fd{fcntl(static_fd, F_DUPFD_CLOEXEC, /*min_fd=*/3)};
+ if (fd < 0) {
+ return ErrnoError() << "failed fcntl(F_DUPFD_CLOEXEC)";
+ }
+
+ // Use the same environment variable as if the service specified
+ // "file /proc/kallsyms r".
+ return Descriptor(std::string(ANDROID_FILE_ENV_PREFIX) + kallsyms_path, std::move(fd));
+}
+
void Service::SetStartedInFirstStage(pid_t pid) {
LOG(INFO) << "adding first-stage service '" << name_ << "'...";
diff --git a/init/service.h b/init/service.h
index ae75553..7193d7e 100644
--- a/init/service.h
+++ b/init/service.h
@@ -158,6 +158,7 @@
static int sigchld_fd = CreateSigchldFd().release();
return sigchld_fd;
}
+ static void OpenAndSaveStaticKallsymsFd();
private:
void NotifyStateChange(const std::string& new_state) const;
@@ -171,6 +172,7 @@
InterprocessFifo setsid_finished);
void SetMountNamespace();
static ::android::base::unique_fd CreateSigchldFd();
+ static Result<Descriptor> CreateSharedKallsymsFd();
static unsigned long next_start_order_;
static bool is_exec_service_running_;
@@ -188,6 +190,7 @@
std::optional<std::string> fatal_reboot_target_; // reboot target of fatal handler
bool was_last_exit_ok_ =
true; // true if the service never exited, or exited with status code 0
+ bool shared_kallsyms_file_ = false; // pass the service a pre-opened fd to /proc/kallsyms
std::optional<CapSet> capabilities_;
ProcessAttributes proc_attr_;
diff --git a/init/service_parser.cpp b/init/service_parser.cpp
index ec3b176..4c31718 100644
--- a/init/service_parser.cpp
+++ b/init/service_parser.cpp
@@ -309,6 +309,11 @@
return {};
}
+Result<void> ServiceParser::ParseSharedKallsyms(std::vector<std::string>&& args) {
+ service_->shared_kallsyms_file_ = true;
+ return {};
+}
+
Result<void> ServiceParser::ParseMemcgSwappiness(std::vector<std::string>&& args) {
if (!ParseInt(args[1], &service_->swappiness_, 0)) {
return Error() << "swappiness value must be equal or greater than 0";
@@ -603,6 +608,7 @@
{"rlimit", {3, 3, &ServiceParser::ParseProcessRlimit}},
{"seclabel", {1, 1, &ServiceParser::ParseSeclabel}},
{"setenv", {2, 2, &ServiceParser::ParseSetenv}},
+ {"shared_kallsyms", {0, 0, &ServiceParser::ParseSharedKallsyms}},
{"shutdown", {1, 1, &ServiceParser::ParseShutdown}},
{"sigstop", {0, 0, &ServiceParser::ParseSigstop}},
{"socket", {3, 6, &ServiceParser::ParseSocket}},
diff --git a/init/service_parser.h b/init/service_parser.h
index f06cfc4..e42b62b 100644
--- a/init/service_parser.h
+++ b/init/service_parser.h
@@ -67,6 +67,7 @@
Result<void> ParseRestartPeriod(std::vector<std::string>&& args);
Result<void> ParseSeclabel(std::vector<std::string>&& args);
Result<void> ParseSetenv(std::vector<std::string>&& args);
+ Result<void> ParseSharedKallsyms(std::vector<std::string>&& args);
Result<void> ParseShutdown(std::vector<std::string>&& args);
Result<void> ParseSigstop(std::vector<std::string>&& args);
Result<void> ParseSocket(std::vector<std::string>&& args);
diff --git a/janitors/OWNERS b/janitors/OWNERS
index c25d9e4..b317151 100644
--- a/janitors/OWNERS
+++ b/janitors/OWNERS
@@ -1,7 +1,19 @@
-# OWNERS file for projects that don't really have owners so much as volunteer janitors.
+# go/android-3p requires that all external projects have the "janitors" in
+# their OWNERS files.
+
+# These are also the "owners" for projects that don't really have owners
+# so much as volunteer janitors.
+
+# General maintenance.
+sadafebrahimi@google.com
+
+# C/C++.
ccross@google.com
cferris@google.com
-dwillemsen@google.com
enh@google.com
+
+# Java.
maco@google.com
-sadafebrahimi@google.com
+
+# Python.
+dwillemsen@google.com
diff --git a/libcutils/ashmem-dev.cpp b/libcutils/ashmem-dev.cpp
index 46b8ef2..cebfa5d 100644
--- a/libcutils/ashmem-dev.cpp
+++ b/libcutils/ashmem-dev.cpp
@@ -114,8 +114,14 @@
// Check if kernel support exists, otherwise fall back to ashmem.
// This code needs to build on old API levels, so we can't use the libc
// wrapper.
+ //
+ // MFD_NOEXEC_SEAL is used to match the semantics of the ashmem device,
+ // which did not have executable permissions. This also seals the executable
+ // permissions of the buffer (i.e. they cannot be changed by fchmod()).
+ //
+ // MFD_NOEXEC_SEAL implies MFD_ALLOW_SEALING.
android::base::unique_fd fd(
- syscall(__NR_memfd_create, "test_android_memfd", MFD_CLOEXEC | MFD_ALLOW_SEALING));
+ syscall(__NR_memfd_create, "test_android_memfd", MFD_CLOEXEC | MFD_NOEXEC_SEAL));
if (fd == -1) {
ALOGE("memfd_create failed: %s, no memfd support.\n", strerror(errno));
return false;
@@ -289,7 +295,13 @@
static int memfd_create_region(const char* name, size_t size) {
// This code needs to build on old API levels, so we can't use the libc
// wrapper.
- android::base::unique_fd fd(syscall(__NR_memfd_create, name, MFD_CLOEXEC | MFD_ALLOW_SEALING));
+ //
+ // MFD_NOEXEC_SEAL to match the semantics of the ashmem device, which did
+ // not have executable permissions. This also seals the executable
+ // permissions of the buffer (i.e. they cannot be changed by fchmod()).
+ //
+ // MFD_NOEXEC_SEAL implies MFD_ALLOW_SEALING.
+ android::base::unique_fd fd(syscall(__NR_memfd_create, name, MFD_CLOEXEC | MFD_NOEXEC_SEAL));
if (fd == -1) {
ALOGE("memfd_create(%s, %zd) failed: %s\n", name, size, strerror(errno));
diff --git a/libprocessgroup/cgrouprc/Android.bp b/libprocessgroup/cgrouprc/Android.bp
index 38b2fa3..d5214c1 100644
--- a/libprocessgroup/cgrouprc/Android.bp
+++ b/libprocessgroup/cgrouprc/Android.bp
@@ -18,10 +18,6 @@
cc_library {
name: "libcgrouprc",
- host_supported: true,
- ramdisk_available: true,
- vendor_ramdisk_available: true,
- recovery_available: true,
// Do not ever mark this as vendor_available; otherwise, vendor modules
// that links to the static library will behave unexpectedly. All on-device
// modules should use libprocessgroup which links to the LL-NDK library
diff --git a/libprocessgroup/cgrouprc/include/android/cgrouprc.h b/libprocessgroup/cgrouprc/include/android/cgrouprc.h
index e704a36..6fc2659 100644
--- a/libprocessgroup/cgrouprc/include/android/cgrouprc.h
+++ b/libprocessgroup/cgrouprc/include/android/cgrouprc.h
@@ -21,11 +21,6 @@
__BEGIN_DECLS
-// For host builds, __INTRODUCED_IN is not defined.
-#ifndef __INTRODUCED_IN
-#define __INTRODUCED_IN(x)
-#endif
-
struct ACgroupController;
typedef struct ACgroupController ACgroupController;
diff --git a/libprocessgroup/include/processgroup/processgroup.h b/libprocessgroup/include/processgroup/processgroup.h
index 6a026a7..98179e8 100644
--- a/libprocessgroup/include/processgroup/processgroup.h
+++ b/libprocessgroup/include/processgroup/processgroup.h
@@ -29,7 +29,11 @@
bool CgroupGetControllerPath(const std::string& cgroup_name, std::string* path);
bool CgroupGetControllerFromPath(const std::string& path, std::string* cgroup_name);
bool CgroupGetAttributePath(const std::string& attr_name, std::string* path);
+// Provides the path for an attribute in a specific process group
+// Returns false in case of error, true in case of success
bool CgroupGetAttributePathForTask(const std::string& attr_name, pid_t tid, std::string* path);
+bool CgroupGetAttributePathForProcess(std::string_view attr_name, uid_t uid, pid_t pid,
+ std::string &path);
bool SetTaskProfiles(pid_t tid, const std::vector<std::string>& profiles,
bool use_fd_cache = false);
@@ -81,10 +85,6 @@
void removeAllEmptyProcessGroups(void);
-// Provides the path for an attribute in a specific process group
-// Returns false in case of error, true in case of success
-bool getAttributePathForTask(const std::string& attr_name, pid_t tid, std::string* path);
-
// Check if a profile can be applied without failing.
// Returns true if it can be applied without failing, false otherwise
bool isProfileValidForProcess(const std::string& profile_name, uid_t uid, pid_t pid);
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index f83e042..a8fa50a 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -155,6 +155,23 @@
return true;
}
+bool CgroupGetAttributePathForProcess(std::string_view attr_name, uid_t uid, pid_t pid,
+ std::string &path) {
+ const TaskProfiles& tp = TaskProfiles::GetInstance();
+ const IProfileAttribute* attr = tp.GetAttribute(attr_name);
+
+ if (attr == nullptr) {
+ return false;
+ }
+
+ if (!attr->GetPathForProcess(uid, pid, &path)) {
+ LOG(ERROR) << "Failed to find cgroup for uid " << uid << " pid " << pid;
+ return false;
+ }
+
+ return true;
+}
+
bool UsePerAppMemcg() {
bool low_ram_device = GetBoolProperty("ro.config.low_ram", false);
return GetBoolProperty("ro.config.per_app_memcg", low_ram_device);
@@ -747,10 +764,6 @@
return SetProcessGroupValue(pid, "MemLimit", limit_in_bytes);
}
-bool getAttributePathForTask(const std::string& attr_name, pid_t tid, std::string* path) {
- return CgroupGetAttributePathForTask(attr_name, tid, path);
-}
-
bool isProfileValidForProcess(const std::string& profile_name, uid_t uid, pid_t pid) {
const TaskProfile* tp = TaskProfiles::GetInstance().GetProfile(profile_name);
diff --git a/libprocessgroup/profiles/cgroups.json b/libprocessgroup/profiles/cgroups.json
index 3e4393d..dbf736a 100644
--- a/libprocessgroup/profiles/cgroups.json
+++ b/libprocessgroup/profiles/cgroups.json
@@ -20,14 +20,6 @@
"Mode": "0755",
"UID": "system",
"GID": "system"
- },
- {
- "Controller": "memory",
- "Path": "/dev/memcg",
- "Mode": "0700",
- "UID": "root",
- "GID": "system",
- "Optional": true
}
],
"Cgroups2": {
@@ -39,6 +31,13 @@
{
"Controller": "freezer",
"Path": "."
+ },
+ {
+ "Controller": "memory",
+ "Path": ".",
+ "NeedsActivation": true,
+ "MaxActivationDepth": 0,
+ "Optional": true
}
]
}
diff --git a/libprocessgroup/profiles/cgroups.proto b/libprocessgroup/profiles/cgroups.proto
index d2fd472..1a78e9d 100644
--- a/libprocessgroup/profiles/cgroups.proto
+++ b/libprocessgroup/profiles/cgroups.proto
@@ -36,7 +36,7 @@
// https://developers.google.com/protocol-buffers/docs/proto3#default
bool needs_activation = 6 [json_name = "NeedsActivation"];
bool is_optional = 7 [json_name = "Optional"];
- uint32 max_activation_depth = 8 [json_name = "MaxActivationDepth"];
+ optional uint32 max_activation_depth = 8 [json_name = "MaxActivationDepth"];
}
// Next: 6
diff --git a/libprocessgroup/profiles/task_profiles.json b/libprocessgroup/profiles/task_profiles.json
index 28902ef..720cb30 100644
--- a/libprocessgroup/profiles/task_profiles.json
+++ b/libprocessgroup/profiles/task_profiles.json
@@ -81,6 +81,11 @@
"Name": "FreezerState",
"Controller": "freezer",
"File": "cgroup.freeze"
+ },
+ {
+ "Name": "CgroupProcs",
+ "Controller": "cgroup2",
+ "File": "cgroup.procs"
}
],
diff --git a/libsysutils/EventLogTags.logtags b/libsysutils/EventLogTags.logtags
index 713f8cd..bb06d34 100644
--- a/libsysutils/EventLogTags.logtags
+++ b/libsysutils/EventLogTags.logtags
@@ -1,4 +1,4 @@
-# See system/core/logcat/event.logtags for a description of the format of this file.
+# See system/logging/logcat/event.logtags for a description of the format of this file.
# FrameworkListener dispatchCommand overflow
78001 exp_det_dispatchCommand_overflow
diff --git a/libutils/OWNERS b/libutils/OWNERS
index 40164aa..4ce6893 100644
--- a/libutils/OWNERS
+++ b/libutils/OWNERS
@@ -1 +1,2 @@
+shayba@google.com
smoreland@google.com
diff --git a/reboot/Android.bp b/reboot/Android.bp
index 7b243bd..1cca824 100644
--- a/reboot/Android.bp
+++ b/reboot/Android.bp
@@ -4,10 +4,25 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
-cc_binary {
- name: "reboot",
+cc_defaults {
+ name: "reboot_defaults",
srcs: ["reboot.c"],
shared_libs: ["libcutils"],
cflags: ["-Werror"],
- recovery_available: true,
+}
+
+cc_binary {
+ name: "reboot",
+ defaults: [
+ "reboot_defaults",
+ ],
+}
+
+cc_binary {
+ name: "reboot.recovery",
+ defaults: [
+ "reboot_defaults",
+ ],
+ recovery: true,
+ stem: "reboot",
}
diff --git a/rootdir/Android.bp b/rootdir/Android.bp
index 44acbba..3204a9f 100644
--- a/rootdir/Android.bp
+++ b/rootdir/Android.bp
@@ -37,7 +37,6 @@
src: "init.rc",
sub_dir: "init/hw",
required: [
- "fsverity_init",
"platform-bootclasspath",
"init.boringssl.zygote64.rc",
"init.boringssl.zygote64_32.rc",
@@ -47,7 +46,13 @@
prebuilt_etc {
name: "ueventd.rc",
src: "ueventd.rc",
- recovery_available: true,
+}
+
+prebuilt_etc {
+ name: "ueventd.rc.recovery",
+ src: "ueventd.rc",
+ recovery: true,
+ filename: "ueventd.rc",
}
filegroup {
@@ -55,13 +60,6 @@
srcs: ["etc/linker.config.json"],
}
-// TODO(b/147210213) Generate list of libraries during build and fill in at build time
-linker_config {
- name: "system_linker_config",
- src: ":system_linker_config_json_file",
- installable: false,
-}
-
// TODO(b/185211376) Scope the native APIs that microdroid will provide to the app payload
prebuilt_etc {
name: "public.libraries.android.txt",
diff --git a/rootdir/create_root_structure.mk b/rootdir/create_root_structure.mk
index 1daf239..d0be897 100644
--- a/rootdir/create_root_structure.mk
+++ b/rootdir/create_root_structure.mk
@@ -27,7 +27,7 @@
#
# create some directories (some are mount points) and symlinks
LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
- dev proc sys system data data_mirror odm oem acct config storage mnt apex bootstrap-apex debug_ramdisk \
+ dev proc sys system data data_mirror odm oem config storage mnt apex bootstrap-apex debug_ramdisk \
linkerconfig second_stage_resources postinstall tmp $(BOARD_ROOT_EXTRA_FOLDERS)); \
ln -sf /system/bin $(TARGET_ROOT_OUT)/bin; \
ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \
diff --git a/rootdir/init.rc b/rootdir/init.rc
index f00479e..f1670ae 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -27,8 +27,6 @@
# Set the security context of /postinstall if present.
restorecon /postinstall
- mkdir /acct/uid
-
# memory.pressure_level used by lmkd
chown root system /dev/memcg/memory.pressure_level
chmod 0040 /dev/memcg/memory.pressure_level
@@ -54,6 +52,10 @@
mkdir /linkerconfig/bootstrap 0755
mkdir /linkerconfig/default 0755
+ # Greatly extend dm-verity's Merkle tree cache timeout. The default timeout
+ # is much too short and is unnecessary, given that there is also a shrinker.
+ write /sys/module/dm_bufio/parameters/max_age_seconds 86400
+
# Disable dm-verity hash prefetching, since it doesn't help performance
# Read more in b/136247322
write /sys/module/dm_verity/parameters/prefetch_cluster 0
@@ -567,6 +569,9 @@
chown root log /proc/vmallocinfo
chmod 0440 /proc/vmallocinfo
+ chown root log /proc/allocinfo
+ chmod 0440 /proc/allocinfo
+
chown root log /proc/slabinfo
chmod 0440 /proc/slabinfo
@@ -609,17 +614,6 @@
mkdir /metadata/staged-install 0770 root system
- mkdir /metadata/aconfig 0775 root system
- mkdir /metadata/aconfig/flags 0770 root system
- mkdir /metadata/aconfig/maps 0775 root system
- mkdir /metadata/aconfig/boot 0775 root system
-
- mkdir /metadata/aconfig_test_missions 0775 root system
-
- # See flag enable_system_aconfigd_rust, which toggles these processes.
- exec_start system_aconfigd_platform_init
- exec_start aconfigd-platform-init
-
on late-fs
# Ensure that tracefs has the correct permissions.
# This does not work correctly if it is called in post-fs.
@@ -629,9 +623,6 @@
# HALs required before storage encryption can get unlocked (FBE)
class_start early_hal
- # Load trusted keys from dm-verity protected partitions
- exec -- /system/bin/fsverity_init --load-verified-keys
-
# Only enable the bootreceiver tracing instance for kernels 5.10 and above.
on late-fs && property:ro.kernel.version=4.19
setprop bootreceiver.enable 0
@@ -1008,16 +999,13 @@
wait_for_prop apexd.status activated
perform_apex_config
- # See flag enable_system_aconfigd_rust, which toggles these processes.
- exec_start aconfigd-mainline-init
exec_start system_aconfigd_mainline_init
-
- # system_aconfigd_socket_service is replacing aconfigd:
- # - A flag (enable_system_aconfigd_rust) toggles which socket executes.
- # - When enabled, aconfigd is a no-op, system_aconfigd_socket_service executes.
- # - Conversely, when disabled, aconfigd executes, and system_aconfigd_socket_service is a no-op.
start system_aconfigd_socket_service
- start aconfigd
+
+ # start mainline aconfigd init, after transition, the above system_aconfigd_mainline_init
+ # will be deprecated
+ exec_start mainline_aconfigd_init
+ start mainline_aconfigd_socket_service
# Create directories for boot animation.
mkdir /data/misc/bootanim 0755 system system
diff --git a/shell_and_utilities/Android.bp b/shell_and_utilities/Android.bp
index 1f5c179..0a1f7c5 100644
--- a/shell_and_utilities/Android.bp
+++ b/shell_and_utilities/Android.bp
@@ -43,9 +43,10 @@
required: [
"sh.recovery",
"toolbox.recovery",
- "toybox.recovery",
+ "toybox_recovery",
"ziptool.recovery",
],
+ recovery: true,
}
phony {
diff --git a/toolbox/Android.bp b/toolbox/Android.bp
index 120cc6e..3142542 100644
--- a/toolbox/Android.bp
+++ b/toolbox/Android.bp
@@ -68,11 +68,17 @@
cc_binary {
name: "toolbox",
defaults: ["toolbox_binary_defaults"],
- recovery_available: true,
vendor_ramdisk_available: true,
}
cc_binary {
+ name: "toolbox.recovery",
+ defaults: ["toolbox_binary_defaults"],
+ recovery: true,
+ stem: "toolbox",
+}
+
+cc_binary {
name: "toolbox_vendor",
stem: "toolbox",
vendor: true,
diff --git a/trusty/keymaster/Android.bp b/trusty/keymaster/Android.bp
index 5a1e420..8ebfc1a 100644
--- a/trusty/keymaster/Android.bp
+++ b/trusty/keymaster/Android.bp
@@ -106,11 +106,11 @@
"keymint/service.cpp",
],
shared_libs: [
- "android.hardware.security.keymint-V3-ndk",
+ "android.hardware.security.keymint-V4-ndk",
"android.hardware.security.rkp-V3-ndk",
"android.hardware.security.secureclock-V1-ndk",
"android.hardware.security.sharedsecret-V1-ndk",
- "lib_android_keymaster_keymint_utils_V3",
+ "lib_android_keymaster_keymint_utils",
"libbase",
"libbinder_ndk",
"libhardware",
@@ -120,9 +120,10 @@
"libtrusty",
"libutils",
],
- required: [
- "android.hardware.hardware_keystore_V3.xml",
- ],
+ required: select(release_flag("RELEASE_AIDL_USE_UNFROZEN"), {
+ true: ["android.hardware.hardware_keystore.xml"],
+ default: ["android.hardware.hardware_keystore_V3.xml"],
+ }),
}
prebuilt_etc {
diff --git a/trusty/keymaster/TrustyKeymaster.cpp b/trusty/keymaster/TrustyKeymaster.cpp
index b118a20..723229d 100644
--- a/trusty/keymaster/TrustyKeymaster.cpp
+++ b/trusty/keymaster/TrustyKeymaster.cpp
@@ -295,6 +295,13 @@
return response;
}
+SetAdditionalAttestationInfoResponse TrustyKeymaster::SetAdditionalAttestationInfo(
+ const SetAdditionalAttestationInfoRequest& request) {
+ SetAdditionalAttestationInfoResponse response(message_version());
+ ForwardCommand(KM_SET_ADDITIONAL_ATTESTATION_INFO, request, &response);
+ return response;
+}
+
GetHwInfoResponse TrustyKeymaster::GetHwInfo() {
GetHwInfoResponse response(message_version());
ForwardCommand(KM_GET_HW_INFO, GetHwInfoRequest(message_version()), &response);
diff --git a/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintDevice.h b/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintDevice.h
index c8d8932..5e876d3 100644
--- a/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintDevice.h
+++ b/trusty/keymaster/include/trusty_keymaster/TrustyKeyMintDevice.h
@@ -85,6 +85,7 @@
ScopedAStatus getRootOfTrust(const array<uint8_t, 16>& challenge,
vector<uint8_t>* rootOfTrust) override;
ScopedAStatus sendRootOfTrust(const vector<uint8_t>& rootOfTrust) override;
+ ScopedAStatus setAdditionalAttestationInfo(const vector<KeyParameter>& info) override;
protected:
std::shared_ptr<TrustyKeymaster> impl_;
diff --git a/trusty/keymaster/include/trusty_keymaster/TrustyKeymaster.h b/trusty/keymaster/include/trusty_keymaster/TrustyKeymaster.h
index c50178b..65d7217 100644
--- a/trusty/keymaster/include/trusty_keymaster/TrustyKeymaster.h
+++ b/trusty/keymaster/include/trusty_keymaster/TrustyKeymaster.h
@@ -70,6 +70,8 @@
ConfigureVendorPatchlevelResponse ConfigureVendorPatchlevel(
const ConfigureVendorPatchlevelRequest& request);
GetRootOfTrustResponse GetRootOfTrust(const GetRootOfTrustRequest& request);
+ SetAdditionalAttestationInfoResponse SetAdditionalAttestationInfo(
+ const SetAdditionalAttestationInfoRequest& request);
GetHwInfoResponse GetHwInfo();
uint32_t message_version() const { return message_version_; }
diff --git a/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h b/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h
index 822e933..721315d 100644
--- a/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h
+++ b/trusty/keymaster/include/trusty_keymaster/ipc/keymaster_ipc.h
@@ -62,6 +62,7 @@
KM_GET_ROOT_OF_TRUST = (34 << KEYMASTER_REQ_SHIFT),
KM_GET_HW_INFO = (35 << KEYMASTER_REQ_SHIFT),
KM_GENERATE_CSR_V2 = (36 << KEYMASTER_REQ_SHIFT),
+ KM_SET_ADDITIONAL_ATTESTATION_INFO = (37 << KEYMASTER_REQ_SHIFT),
// Bootloader/provisioning calls.
KM_SET_BOOT_PARAMS = (0x1000 << KEYMASTER_REQ_SHIFT),
diff --git a/trusty/keymaster/keymint/TrustyKeyMintDevice.cpp b/trusty/keymaster/keymint/TrustyKeyMintDevice.cpp
index fec4c60..154597f 100644
--- a/trusty/keymaster/keymint/TrustyKeyMintDevice.cpp
+++ b/trusty/keymaster/keymint/TrustyKeyMintDevice.cpp
@@ -349,4 +349,18 @@
return kmError2ScopedAStatus(KM_ERROR_UNIMPLEMENTED);
}
+ScopedAStatus TrustyKeyMintDevice::setAdditionalAttestationInfo(const vector<KeyParameter>& info) {
+ keymaster::SetAdditionalAttestationInfoRequest request(impl_->message_version());
+ request.info.Reinitialize(KmParamSet(info));
+
+ keymaster::SetAdditionalAttestationInfoResponse response =
+ impl_->SetAdditionalAttestationInfo(request);
+
+ if (response.error != KM_ERROR_OK) {
+ return kmError2ScopedAStatus(response.error);
+ } else {
+ return ScopedAStatus::ok();
+ }
+}
+
} // namespace aidl::android::hardware::security::keymint::trusty
diff --git a/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.xml b/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.xml
index 3dc9c88..f74d212 100644
--- a/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.xml
+++ b/trusty/keymaster/keymint/android.hardware.security.keymint-service.trusty.xml
@@ -1,7 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.security.keymint</name>
- <version>3</version>
+ <version>4</version>
<fqname>IKeyMintDevice/default</fqname>
</hal>
<hal format="aidl">
diff --git a/trusty/secretkeeper/Android.bp b/trusty/secretkeeper/Android.bp
index 6523eda..d399bf8 100644
--- a/trusty/secretkeeper/Android.bp
+++ b/trusty/secretkeeper/Android.bp
@@ -27,18 +27,16 @@
"src/hal_main.rs",
],
rustlibs: [
+ "android.hardware.security.secretkeeper-V1-rust",
"libandroid_logger",
"libauthgraph_hal",
"libauthgraph_wire",
"libbinder_rs",
"liblibc",
"liblog_rust",
- "libsecretkeeper_hal",
+ "libsecretkeeper_hal_v1",
"libtrusty-rs",
],
- defaults: [
- "secretkeeper_use_latest_hal_aidl_rust",
- ],
prefer_rlib: true,
}
diff --git a/trusty/trusty-storage-cf.mk b/trusty/trusty-storage-cf.mk
index 3b46445..acefd3e 100644
--- a/trusty/trusty-storage-cf.mk
+++ b/trusty/trusty-storage-cf.mk
@@ -22,4 +22,5 @@
PRODUCT_PACKAGES += \
storageproxyd.system \
rpmb_dev.system \
+ rpmb_dev.test.system \
diff --git a/trusty/utils/rpmb_dev/Android.bp b/trusty/utils/rpmb_dev/Android.bp
index ef23cc5..2f362e8 100644
--- a/trusty/utils/rpmb_dev/Android.bp
+++ b/trusty/utils/rpmb_dev/Android.bp
@@ -58,3 +58,12 @@
"rpmb_dev.wv.system.rc",
],
}
+
+cc_binary {
+ name: "rpmb_dev.test.system",
+ defaults: ["rpmb_dev.cc_defaults"],
+ system_ext_specific: true,
+ init_rc: [
+ "rpmb_dev.test.system.rc",
+ ],
+}
diff --git a/trusty/utils/rpmb_dev/rpmb_dev.test.system.rc b/trusty/utils/rpmb_dev/rpmb_dev.test.system.rc
new file mode 100644
index 0000000..2127798
--- /dev/null
+++ b/trusty/utils/rpmb_dev/rpmb_dev.test.system.rc
@@ -0,0 +1,56 @@
+service trusty_test_vm /apex/com.android.virt/bin/vm run \
+ /data/local/tmp/TrustyTestVM_UnitTests/trusty-test_vm-config.json
+ disabled
+ user system
+ group system
+
+service storageproxyd_test_system /system_ext/bin/storageproxyd.system \
+ -d VSOCK:${trusty.test_vm.vm_cid}:1 \
+ -r /dev/socket/rpmb_mock_test_system \
+ -p /data/secure_storage_test_system \
+ -t sock
+ disabled
+ class hal
+ user system
+ group system
+
+service rpmb_mock_init_test_system /system_ext/bin/rpmb_dev.test.system \
+ --dev /mnt/secure_storage_rpmb_test_system/persist/RPMB_DATA --init --size 2048
+ disabled
+ user system
+ group system
+ oneshot
+
+service rpmb_mock_test_system /system_ext/bin/rpmb_dev.test.system \
+ --dev /mnt/secure_storage_rpmb_test_system/persist/RPMB_DATA \
+ --sock rpmb_mock_test_system
+ disabled
+ user system
+ group system
+ socket rpmb_mock_test_system stream 660 system system
+
+# RPMB Mock
+on post-fs-data
+ # Create a persistent location for the RPMB data
+ # (work around lack of RPMb block device on CF).
+ # file contexts secure_storage_rpmb_system_file
+ # (only used on Cuttlefish as this is non secure)
+ mkdir /metadata/secure_storage_rpmb_test_system 0770 system system
+ mkdir /mnt/secure_storage_rpmb_test_system 0770 system system
+ symlink /metadata/secure_storage_rpmb_test_system \
+ /mnt/secure_storage_rpmb_test_system/persist
+ # Create a system persist directory in /metadata
+ # (work around lack of dedicated system persist partition).
+ # file contexts secure_storage_persist_system_file
+ mkdir /metadata/secure_storage_persist_test_system 0770 system system
+ mkdir /mnt/secure_storage_persist_test_system 0770 system system
+ symlink /metadata/secure_storage_persist_test_system \
+ /mnt/secure_storage_persist_test_system/persist
+ # file contexts secure_storage_system_file
+ mkdir /data/secure_storage_test_system 0770 root system
+ symlink /mnt/secure_storage_persist_test_system/persist \
+ /data/secure_storage_test_system/persist
+ chown root system /data/secure_storage_test_system/persist
+ # setprop storageproxyd_test_system.trusty_ipc_dev VSOCK:${trusty.test_vm.vm_cid}:1
+ exec_start rpmb_mock_init_test_system
+ start rpmb_mock_test_system
diff --git a/trusty/utils/rpmb_dev/rpmb_dev.wv.system.rc b/trusty/utils/rpmb_dev/rpmb_dev.wv.system.rc
index 3e7f8b4..003b6fe 100644
--- a/trusty/utils/rpmb_dev/rpmb_dev.wv.system.rc
+++ b/trusty/utils/rpmb_dev/rpmb_dev.wv.system.rc
@@ -33,7 +33,7 @@
# RPMB Mock
on early-boot && \
- property:ro.hardware.security.trusty.widevine_vm.system=1 && \
+ property:trusty.widevine_vm.enabled=1 && \
property:trusty.widevine_vm.vm_cid=* && \
property:ro.boot.vendor.apex.com.android.services.widevine=\
com.android.services.widevine.cf_guest_trusty_nonsecure
diff --git a/watchdogd/Android.bp b/watchdogd/Android.bp
index 0388208..bc7ffb6 100644
--- a/watchdogd/Android.bp
+++ b/watchdogd/Android.bp
@@ -2,9 +2,8 @@
default_applicable_licenses: ["Android-Apache-2.0"],
}
-cc_binary {
- name: "watchdogd",
- recovery_available: true,
+cc_defaults {
+ name: "watchdogd_defaults",
srcs: ["watchdogd.cpp"],
cflags: [
"-Wall",
@@ -16,3 +15,19 @@
misc_undefined: ["signed-integer-overflow"],
},
}
+
+cc_binary {
+ name: "watchdogd",
+ defaults: [
+ "watchdogd_defaults",
+ ],
+}
+
+cc_binary {
+ name: "watchdogd.recovery",
+ defaults: [
+ "watchdogd_defaults",
+ ],
+ recovery: true,
+ stem: "watchdogd",
+}