Merge "Revert "Partial revert of "libcutils: fs_config.c mark vendor, odm and oem partitions in duplicate" Revert just the wifi hardware part."" into oc-dev
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 568879e..0b4bbfb 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -29,6 +29,7 @@
#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/macros.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
@@ -149,7 +150,7 @@
// Returns -1 if we fail to read a response from tombstoned, otherwise the received return code.
void FinishIntercept(int* result);
- void StartProcess(std::function<void()> function);
+ void StartProcess(std::function<void()> function, std::function<pid_t()> forker = fork);
void StartCrasher(const std::string& crash_type);
void FinishCrasher();
void AssertDeath(int signo);
@@ -195,14 +196,14 @@
}
}
-void CrasherTest::StartProcess(std::function<void()> function) {
+void CrasherTest::StartProcess(std::function<void()> function, std::function<pid_t()> forker) {
unique_fd read_pipe;
unique_fd crasher_read_pipe;
if (!Pipe(&crasher_read_pipe, &crasher_pipe)) {
FAIL() << "failed to create pipe: " << strerror(errno);
}
- crasher_pid = fork();
+ crasher_pid = forker();
if (crasher_pid == -1) {
FAIL() << "fork failed: " << strerror(errno);
} else if (crasher_pid == 0) {
@@ -527,6 +528,37 @@
ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(tgkill)");
}
+TEST_F(CrasherTest, fake_pid) {
+ int intercept_result;
+ unique_fd output_fd;
+
+ // Prime the getpid/gettid caches.
+ UNUSED(getpid());
+ UNUSED(gettid());
+
+ std::function<pid_t()> clone_fn = []() {
+ return syscall(__NR_clone, SIGCHLD, nullptr, nullptr, nullptr, nullptr);
+ };
+ StartProcess(
+ []() {
+ ASSERT_NE(getpid(), syscall(__NR_getpid));
+ ASSERT_NE(gettid(), syscall(__NR_gettid));
+ raise(SIGSEGV);
+ },
+ clone_fn);
+
+ StartIntercept(&output_fd);
+ FinishCrasher();
+ AssertDeath(SIGSEGV);
+ FinishIntercept(&intercept_result);
+
+ ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
+
+ std::string result;
+ ConsumeFd(std::move(output_fd), &result);
+ ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(tgkill)");
+}
+
TEST(crash_dump, zombie) {
pid_t forkpid = fork();
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index b70554f..d58c73d 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -62,6 +62,16 @@
#define CRASH_DUMP_PATH "/system/bin/" CRASH_DUMP_NAME
+// Wrappers that directly invoke the respective syscalls, in case the cached values are invalid.
+#pragma GCC poison getpid gettid
+static pid_t __getpid() {
+ return syscall(__NR_getpid);
+}
+
+static pid_t __gettid() {
+ return syscall(__NR_gettid);
+}
+
class ErrnoRestorer {
public:
ErrnoRestorer() : saved_errno_(errno) {
@@ -120,7 +130,7 @@
}
if (signum == DEBUGGER_SIGNAL) {
- __libc_format_log(ANDROID_LOG_INFO, "libc", "Requested dump for tid %d (%s)", gettid(),
+ __libc_format_log(ANDROID_LOG_INFO, "libc", "Requested dump for tid %d (%s)", __gettid(),
thread_name);
return;
}
@@ -173,7 +183,7 @@
}
__libc_format_log(ANDROID_LOG_FATAL, "libc", "Fatal signal %d (%s)%s%s in tid %d (%s)", signum,
- signal_name, code_desc, addr_desc, gettid(), thread_name);
+ signal_name, code_desc, addr_desc, __gettid(), thread_name);
}
/*
@@ -331,7 +341,7 @@
// rt_tgsigqueueinfo(2) to preserve SA_SIGINFO) will cause it to be delivered
// when our signal handler returns.
if (crash_dump_started || info->si_signo != DEBUGGER_SIGNAL) {
- int rc = syscall(SYS_rt_tgsigqueueinfo, getpid(), gettid(), info->si_signo, info);
+ int rc = syscall(SYS_rt_tgsigqueueinfo, __getpid(), __gettid(), info->si_signo, info);
if (rc != 0) {
fatal_errno("failed to resend signal during crash");
}
@@ -356,7 +366,7 @@
memset(&si, 0, sizeof(si));
si.si_signo = signal_number;
si.si_code = SI_USER;
- si.si_pid = getpid();
+ si.si_pid = __getpid();
si.si_uid = getuid();
info = &si;
} else if (info->si_code >= 0 || info->si_code == SI_TKILL) {
@@ -398,7 +408,7 @@
debugger_thread_info thread_info = {
.crash_dump_started = false,
.pseudothread_tid = -1,
- .crashing_tid = gettid(),
+ .crashing_tid = __gettid(),
.signal_number = signal_number,
.info = info
};
diff --git a/debuggerd/libdebuggerd/arm/machine.cpp b/debuggerd/libdebuggerd/arm/machine.cpp
index 78c2306..ac833ae 100644
--- a/debuggerd/libdebuggerd/arm/machine.cpp
+++ b/debuggerd/libdebuggerd/arm/machine.cpp
@@ -48,6 +48,21 @@
}
}
+#define DUMP_GP_REGISTERS(log, reg_prefix) \
+ _LOG(log, logtype::REGISTERS, " r0 %08x r1 %08x r2 %08x r3 %08x\n", \
+ static_cast<uint32_t>(reg_prefix##r0), static_cast<uint32_t>(reg_prefix##r1), \
+ static_cast<uint32_t>(reg_prefix##r2), static_cast<uint32_t>(reg_prefix##r3)); \
+ _LOG(log, logtype::REGISTERS, " r4 %08x r5 %08x r6 %08x r7 %08x\n", \
+ static_cast<uint32_t>(reg_prefix##r4), static_cast<uint32_t>(reg_prefix##r5), \
+ static_cast<uint32_t>(reg_prefix##r6), static_cast<uint32_t>(reg_prefix##r7)); \
+ _LOG(log, logtype::REGISTERS, " r8 %08x r9 %08x sl %08x fp %08x\n", \
+ static_cast<uint32_t>(reg_prefix##r8), static_cast<uint32_t>(reg_prefix##r9), \
+ static_cast<uint32_t>(reg_prefix##r10), static_cast<uint32_t>(reg_prefix##fp)); \
+ _LOG(log, logtype::REGISTERS, " ip %08x sp %08x lr %08x pc %08x cpsr %08x\n", \
+ static_cast<uint32_t>(reg_prefix##ip), static_cast<uint32_t>(reg_prefix##sp), \
+ static_cast<uint32_t>(reg_prefix##lr), static_cast<uint32_t>(reg_prefix##pc), \
+ static_cast<uint32_t>(reg_prefix##cpsr))
+
void dump_registers(log_t* log, pid_t tid) {
pt_regs r;
if (ptrace(PTRACE_GETREGS, tid, 0, &r)) {
@@ -55,19 +70,7 @@
return;
}
- _LOG(log, logtype::REGISTERS, " r0 %08x r1 %08x r2 %08x r3 %08x\n",
- static_cast<uint32_t>(r.ARM_r0), static_cast<uint32_t>(r.ARM_r1),
- static_cast<uint32_t>(r.ARM_r2), static_cast<uint32_t>(r.ARM_r3));
- _LOG(log, logtype::REGISTERS, " r4 %08x r5 %08x r6 %08x r7 %08x\n",
- static_cast<uint32_t>(r.ARM_r4), static_cast<uint32_t>(r.ARM_r5),
- static_cast<uint32_t>(r.ARM_r6), static_cast<uint32_t>(r.ARM_r7));
- _LOG(log, logtype::REGISTERS, " r8 %08x r9 %08x sl %08x fp %08x\n",
- static_cast<uint32_t>(r.ARM_r8), static_cast<uint32_t>(r.ARM_r9),
- static_cast<uint32_t>(r.ARM_r10), static_cast<uint32_t>(r.ARM_fp));
- _LOG(log, logtype::REGISTERS, " ip %08x sp %08x lr %08x pc %08x cpsr %08x\n",
- static_cast<uint32_t>(r.ARM_ip), static_cast<uint32_t>(r.ARM_sp),
- static_cast<uint32_t>(r.ARM_lr), static_cast<uint32_t>(r.ARM_pc),
- static_cast<uint32_t>(r.ARM_cpsr));
+ DUMP_GP_REGISTERS(log, r.ARM_);
user_vfp vfp_regs;
if (ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) {
@@ -81,3 +84,7 @@
}
_LOG(log, logtype::FP_REGISTERS, " scr %08lx\n", vfp_regs.fpscr);
}
+
+void dump_registers(log_t* log, const ucontext_t* uc) {
+ DUMP_GP_REGISTERS(log, uc->uc_mcontext.arm_);
+}
diff --git a/debuggerd/libdebuggerd/arm64/machine.cpp b/debuggerd/libdebuggerd/arm64/machine.cpp
index e7bf79a..fa73c99a 100644
--- a/debuggerd/libdebuggerd/arm64/machine.cpp
+++ b/debuggerd/libdebuggerd/arm64/machine.cpp
@@ -52,6 +52,17 @@
}
}
+#define DUMP_GP_REGISTERS(log) \
+ for (int i = 0; i < 28; i += 4) { \
+ const char* fmt = " x%-2d %016llx x%-2d %016llx x%-2d %016llx x%-2d %016llx\n"; \
+ _LOG(log, logtype::REGISTERS, fmt, i, r.regs[i], i + 1, r.regs[i + 1], i + 2, r.regs[i + 2], \
+ i + 3, r.regs[i + 3]); \
+ } \
+ _LOG(log, logtype::REGISTERS, " x28 %016llx x29 %016llx x30 %016llx\n", r.regs[28], \
+ r.regs[29], r.regs[30]); \
+ _LOG(log, logtype::REGISTERS, " sp %016llx pc %016llx pstate %016llx\n", r.sp, r.pc, \
+ r.pstate)
+
void dump_registers(log_t* log, pid_t tid) {
struct user_pt_regs r;
struct iovec io;
@@ -63,20 +74,7 @@
return;
}
- for (int i = 0; i < 28; i += 4) {
- _LOG(log, logtype::REGISTERS,
- " x%-2d %016llx x%-2d %016llx x%-2d %016llx x%-2d %016llx\n",
- i, r.regs[i],
- i+1, r.regs[i+1],
- i+2, r.regs[i+2],
- i+3, r.regs[i+3]);
- }
-
- _LOG(log, logtype::REGISTERS, " x28 %016llx x29 %016llx x30 %016llx\n",
- r.regs[28], r.regs[29], r.regs[30]);
-
- _LOG(log, logtype::REGISTERS, " sp %016llx pc %016llx pstate %016llx\n",
- r.sp, r.pc, r.pstate);
+ DUMP_GP_REGISTERS(log);
struct user_fpsimd_state f;
io.iov_base = &f;
@@ -99,3 +97,8 @@
}
_LOG(log, logtype::FP_REGISTERS, " fpsr %08x fpcr %08x\n", f.fpsr, f.fpcr);
}
+
+void dump_registers(log_t* log, const ucontext_t* ucontext) {
+ const mcontext_t& r = ucontext->uc_mcontext;
+ DUMP_GP_REGISTERS(log);
+}
diff --git a/debuggerd/libdebuggerd/include/machine.h b/debuggerd/libdebuggerd/include/machine.h
index e65b147..5e56682 100644
--- a/debuggerd/libdebuggerd/include/machine.h
+++ b/debuggerd/libdebuggerd/include/machine.h
@@ -25,5 +25,6 @@
void dump_memory_and_code(log_t* log, Backtrace* backtrace);
void dump_registers(log_t* log, pid_t tid);
+void dump_registers(log_t* log, const ucontext_t* uc);
#endif // _DEBUGGERD_MACHINE_H
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index 0c38449..edc7be5 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -470,6 +470,11 @@
}
}
+// Weak noop implementation, real implementations are in <arch>/machine.cpp.
+__attribute__((weak)) void dump_registers(log_t* log, const ucontext_t*) {
+ _LOG(log, logtype::REGISTERS, " register dumping unimplemented on this architecture");
+}
+
static void dump_thread(log_t* log, pid_t pid, pid_t tid, const std::string& process_name,
const std::string& thread_name, BacktraceMap* map,
uintptr_t abort_msg_address, bool primary_thread) {
@@ -749,11 +754,15 @@
read_with_default("/proc/self/comm", thread_name, sizeof(thread_name), "<unknown>");
read_with_default("/proc/self/cmdline", process_name, sizeof(process_name), "<unknown>");
+ _LOG(&log, logtype::HEADER, "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
+ dump_header_info(&log);
dump_thread_info(&log, pid, tid, thread_name, process_name);
dump_signal_info(&log, siginfo);
std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid));
dump_abort_message(backtrace.get(), &log, abort_msg_address);
+ dump_registers(&log, ucontext);
+
// TODO: Dump registers from the ucontext.
if (backtrace->Unwind(0, ucontext)) {
dump_backtrace_and_stack(backtrace.get(), &log);
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index e3d4f87..e224aec 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -744,23 +744,6 @@
}
}
-static std::string extract_by_name_prefix(struct fstab* fstab) {
- // We assume that there's an entry for the /misc mount point in the
- // fstab file and use that to get the device file by-name prefix.
- // The device needs not to have an actual /misc partition.
- // e.g.,
- // - /dev/block/platform/soc.0/7824900.sdhci/by-name/misc ->
- // - /dev/block/platform/soc.0/7824900.sdhci/by-name/
- struct fstab_rec* fstab_entry = fs_mgr_get_entry_for_mount_point(fstab, "/misc");
- if (fstab_entry == nullptr) {
- LERROR << "/misc mount point not found in fstab";
- return "";
- }
- std::string full_path(fstab_entry->blk_device);
- size_t end_slash = full_path.find_last_of("/");
- return full_path.substr(0, end_slash + 1);
-}
-
// TODO: add ueventd notifiers if they don't exist.
// This is just doing a wait_for_device for maximum of 1s
int fs_mgr_test_access(const char *device) {
@@ -850,7 +833,7 @@
if (fstab->recs[i].fs_mgr_flags & MF_AVB) {
if (!avb_handle) {
- avb_handle = FsManagerAvbHandle::Open(extract_by_name_prefix(fstab));
+ avb_handle = FsManagerAvbHandle::Open(*fstab);
if (!avb_handle) {
LERROR << "Failed to open FsManagerAvbHandle";
return -1;
@@ -1047,8 +1030,7 @@
}
int fs_stat = 0;
- int force_check = do_quota_with_shutdown_check(fstab->recs[i].blk_device,
- fstab->recs[i].fs_type,
+ int force_check = do_quota_with_shutdown_check(n_blk_device, fstab->recs[i].fs_type,
&fstab->recs[i], &fs_stat);
if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) {
@@ -1062,7 +1044,7 @@
if (fstab->recs[i].fs_mgr_flags & MF_AVB) {
if (!avb_handle) {
- avb_handle = FsManagerAvbHandle::Open(extract_by_name_prefix(fstab));
+ avb_handle = FsManagerAvbHandle::Open(*fstab);
if (!avb_handle) {
LERROR << "Failed to open FsManagerAvbHandle";
return -1;
@@ -1367,7 +1349,8 @@
std::string mount_point;
if (system_root && !strcmp(fstab->recs[i].mount_point, "/")) {
- mount_point = "system";
+ // In AVB, the dm device name is vroot instead of system.
+ mount_point = fs_mgr_is_avb(&fstab->recs[i]) ? "vroot" : "system";
} else {
mount_point = basename(fstab->recs[i].mount_point);
}
@@ -1386,6 +1369,10 @@
status = &buffer[io->data_start + sizeof(struct dm_target_spec)];
+ // To be consistent in vboot 1.0 and vboot 2.0 (AVB), change the mount_point
+ // back to 'system' for the callback. So it has property [partition.system.verified]
+ // instead of [partition.vroot.verified].
+ if (mount_point == "vroot") mount_point = "system";
if (*status == 'C' || *status == 'V') {
callback(&fstab->recs[i], mount_point.c_str(), mode, *status);
}
diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp
index 83bf8a7..36883e6 100644
--- a/fs_mgr/fs_mgr_avb.cpp
+++ b/fs_mgr/fs_mgr_avb.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "fs_mgr_avb.h"
+
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
@@ -38,9 +40,8 @@
#include <utils/Compat.h>
#include "fs_mgr.h"
-#include "fs_mgr_avb.h"
-#include "fs_mgr_avb_ops.h"
#include "fs_mgr_priv.h"
+#include "fs_mgr_priv_avb_ops.h"
#include "fs_mgr_priv_dm_ioctl.h"
#include "fs_mgr_priv_sha.h"
@@ -457,12 +458,21 @@
return true;
}
-FsManagerAvbUniquePtr FsManagerAvbHandle::Open(const std::string& device_file_by_name_prefix) {
- if (device_file_by_name_prefix.empty()) {
- LERROR << "Missing device file by-name prefix";
+FsManagerAvbUniquePtr FsManagerAvbHandle::Open(const fstab& fstab) {
+ FsManagerAvbOps avb_ops(fstab);
+ return DoOpen(&avb_ops);
+}
+
+FsManagerAvbUniquePtr FsManagerAvbHandle::Open(ByNameSymlinkMap&& by_name_symlink_map) {
+ if (by_name_symlink_map.empty()) {
+ LERROR << "Empty by_name_symlink_map when opening FsManagerAvbHandle";
return nullptr;
}
+ FsManagerAvbOps avb_ops(std::move(by_name_symlink_map));
+ return DoOpen(&avb_ops);
+}
+FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) {
// Gets the expected hash value of vbmeta images from kernel cmdline.
std::unique_ptr<FsManagerAvbVerifier> avb_verifier = FsManagerAvbVerifier::Create();
if (!avb_verifier) {
@@ -476,20 +486,40 @@
return nullptr;
}
- FsManagerAvbOps avb_ops(device_file_by_name_prefix);
- AvbSlotVerifyResult verify_result = avb_ops.AvbSlotVerify(
+ AvbSlotVerifyResult verify_result = avb_ops->AvbSlotVerify(
fs_mgr_get_slot_suffix(), avb_verifier->IsDeviceUnlocked(), &avb_handle->avb_slot_data_);
// Only allow two verify results:
// - AVB_SLOT_VERIFY_RESULT_OK.
// - AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION (for UNLOCKED state).
- if (verify_result == AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION) {
- if (!avb_verifier->IsDeviceUnlocked()) {
- LERROR << "ERROR_VERIFICATION isn't allowed";
+ // If the device is UNLOCKED, i.e., |allow_verification_error| is true for
+ // AvbSlotVerify(), then the following return values are all non-fatal:
+ // * AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION
+ // * AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED
+ // * AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX
+ // The latter two results were checked by bootloader prior to start fs_mgr so
+ // we just need to handle the first result here. See *dummy* operations in
+ // FsManagerAvbOps and the comments in external/avb/libavb/avb_slot_verify.h
+ // for more details.
+ switch (verify_result) {
+ case AVB_SLOT_VERIFY_RESULT_OK:
+ avb_handle->status_ = kFsManagerAvbHandleSuccess;
+ break;
+ case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
+ if (!avb_verifier->IsDeviceUnlocked()) {
+ LERROR << "ERROR_VERIFICATION isn't allowed when the device is LOCKED";
+ return nullptr;
+ }
+ avb_handle->status_ = kFsManagerAvbHandleErrorVerification;
+ break;
+ default:
+ LERROR << "avb_slot_verify failed, result: " << verify_result;
return nullptr;
- }
- } else if (verify_result != AVB_SLOT_VERIFY_RESULT_OK) {
- LERROR << "avb_slot_verify failed, result: " << verify_result;
+ }
+
+ // Verifies vbmeta images against the digest passed from bootloader.
+ if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) {
+ LERROR << "VerifyVbmetaImages failed";
return nullptr;
}
@@ -497,30 +527,20 @@
avb_handle->avb_version_ =
android::base::StringPrintf("%d.%d", AVB_VERSION_MAJOR, AVB_VERSION_MINOR);
- // Verifies vbmeta images against the digest passed from bootloader.
- if (!avb_verifier->VerifyVbmetaImages(*avb_handle->avb_slot_data_)) {
- LERROR << "VerifyVbmetaImages failed";
- return nullptr;
- } else {
- // Checks whether FLAGS_HASHTREE_DISABLED is set.
- AvbVBMetaImageHeader vbmeta_header;
- avb_vbmeta_image_header_to_host_byte_order(
- (AvbVBMetaImageHeader*)avb_handle->avb_slot_data_->vbmeta_images[0].vbmeta_data,
- &vbmeta_header);
+ // Checks whether FLAGS_HASHTREE_DISABLED is set.
+ AvbVBMetaImageHeader vbmeta_header;
+ avb_vbmeta_image_header_to_host_byte_order(
+ (AvbVBMetaImageHeader*)avb_handle->avb_slot_data_->vbmeta_images[0].vbmeta_data,
+ &vbmeta_header);
- bool hashtree_disabled =
- ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
- if (hashtree_disabled) {
- avb_handle->status_ = kFsManagerAvbHandleHashtreeDisabled;
- return avb_handle;
- }
+ bool hashtree_disabled =
+ ((AvbVBMetaImageFlags)vbmeta_header.flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED);
+ if (hashtree_disabled) {
+ avb_handle->status_ = kFsManagerAvbHandleHashtreeDisabled;
}
- if (verify_result == AVB_SLOT_VERIFY_RESULT_OK) {
- avb_handle->status_ = kFsManagerAvbHandleSuccess;
- return avb_handle;
- }
- return nullptr;
+ LINFO << "Returning avb_handle with status: " << avb_handle->status_;
+ return avb_handle;
}
bool FsManagerAvbHandle::SetUpAvb(struct fstab_rec* fstab_entry, bool wait_for_verity_dev) {
@@ -528,11 +548,12 @@
if (!avb_slot_data_ || avb_slot_data_->num_vbmeta_images < 1) {
return false;
}
+
+ if (status_ == kFsManagerAvbHandleUninitialized) return false;
if (status_ == kFsManagerAvbHandleHashtreeDisabled) {
LINFO << "AVB HASHTREE disabled on:" << fstab_entry->mount_point;
return true;
}
- if (status_ != kFsManagerAvbHandleSuccess) return false;
std::string partition_name(basename(fstab_entry->mount_point));
if (!avb_validate_utf8((const uint8_t*)partition_name.c_str(), partition_name.length())) {
diff --git a/fs_mgr/fs_mgr_avb_ops.cpp b/fs_mgr/fs_mgr_avb_ops.cpp
index 981e9fc..47df861 100644
--- a/fs_mgr/fs_mgr_avb_ops.cpp
+++ b/fs_mgr/fs_mgr_avb_ops.cpp
@@ -22,6 +22,8 @@
* SOFTWARE.
*/
+#include "fs_mgr_priv_avb_ops.h"
+
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
@@ -36,7 +38,6 @@
#include <utils/Compat.h>
#include "fs_mgr.h"
-#include "fs_mgr_avb_ops.h"
#include "fs_mgr_priv.h"
static AvbIOResult read_from_partition(AvbOps* ops, const char* partition, int64_t offset,
@@ -88,11 +89,7 @@
return AVB_IO_RESULT_OK;
}
-FsManagerAvbOps::FsManagerAvbOps(const std::string& device_file_by_name_prefix)
- : device_file_by_name_prefix_(device_file_by_name_prefix) {
- if (device_file_by_name_prefix_.back() != '/') {
- device_file_by_name_prefix_ += '/';
- }
+void FsManagerAvbOps::InitializeAvbOps() {
// We only need to provide the implementation of read_from_partition()
// operation since that's all what is being used by the avb_slot_verify().
// Other I/O operations are only required in bootloader but not in
@@ -107,13 +104,31 @@
avb_ops_.user_data = this;
}
+FsManagerAvbOps::FsManagerAvbOps(std::map<std::string, std::string>&& by_name_symlink_map)
+ : by_name_symlink_map_(std::move(by_name_symlink_map)) {
+ InitializeAvbOps();
+}
+
+FsManagerAvbOps::FsManagerAvbOps(const fstab& fstab) {
+ // Constructs the by-name symlink map for each fstab record.
+ // /dev/block/platform/soc.0/7824900.sdhci/by-name/system_a =>
+ // by_name_symlink_map_["system_a"] = "/dev/block/platform/soc.0/7824900.sdhci/by-name/system_a"
+ for (int i = 0; i < fstab.num_entries; i++) {
+ std::string partition_name = basename(fstab.recs[i].blk_device);
+ by_name_symlink_map_[partition_name] = fstab.recs[i].blk_device;
+ }
+ InitializeAvbOps();
+}
+
AvbIOResult FsManagerAvbOps::ReadFromPartition(const char* partition, int64_t offset,
size_t num_bytes, void* buffer,
size_t* out_num_read) {
- // Appends |partition| to the device_file_by_name_prefix_, e.g.,
- // - /dev/block/platform/soc.0/7824900.sdhci/by-name/ ->
- // - /dev/block/platform/soc.0/7824900.sdhci/by-name/system_a
- std::string path = device_file_by_name_prefix_ + partition;
+ const auto iter = by_name_symlink_map_.find(partition);
+ if (iter == by_name_symlink_map_.end()) {
+ LERROR << "by-name symlink not found for partition: '" << partition << "'";
+ return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
+ }
+ std::string path = iter->second;
// Ensures the device path (a symlink created by init) is ready to
// access. fs_mgr_test_access() will test a few iterations if the
@@ -124,7 +139,7 @@
android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(path.c_str(), O_RDONLY | O_CLOEXEC)));
if (fd < 0) {
- PERROR << "Failed to open " << path.c_str();
+ PERROR << "Failed to open " << path;
return AVB_IO_RESULT_ERROR_IO;
}
@@ -148,8 +163,7 @@
// for EOF).
ssize_t num_read = TEMP_FAILURE_RETRY(pread64(fd, buffer, num_bytes, offset));
if (num_read < 0 || (size_t)num_read != num_bytes) {
- PERROR << "Failed to read " << num_bytes << " bytes from " << path.c_str() << " offset "
- << offset;
+ PERROR << "Failed to read " << num_bytes << " bytes from " << path << " offset " << offset;
return AVB_IO_RESULT_ERROR_IO;
}
diff --git a/fs_mgr/fs_mgr_avb_ops.h b/fs_mgr/fs_mgr_priv_avb_ops.h
similarity index 87%
rename from fs_mgr/fs_mgr_avb_ops.h
rename to fs_mgr/fs_mgr_priv_avb_ops.h
index ec4a8c9..a6b52e4 100644
--- a/fs_mgr/fs_mgr_avb_ops.h
+++ b/fs_mgr/fs_mgr_priv_avb_ops.h
@@ -22,8 +22,11 @@
* SOFTWARE.
*/
-#ifndef __CORE_FS_MGR_AVB_OPS_H
-#define __CORE_FS_MGR_AVB_OPS_H
+#ifndef __CORE_FS_MGR_PRIV_AVB_OPS_H
+#define __CORE_FS_MGR_PRIV_AVB_OPS_H
+
+#include <map>
+#include <string>
#include <libavb/libavb.h>
@@ -43,7 +46,8 @@
//
class FsManagerAvbOps {
public:
- FsManagerAvbOps(const std::string& device_file_by_name_prefix);
+ FsManagerAvbOps(const fstab& fstab);
+ FsManagerAvbOps(std::map<std::string, std::string>&& by_name_symlink_map);
static FsManagerAvbOps* GetInstanceFromAvbOps(AvbOps* ops) {
return reinterpret_cast<FsManagerAvbOps*>(ops->user_data);
@@ -56,7 +60,9 @@
AvbSlotVerifyData** out_data);
private:
+ void InitializeAvbOps();
+
AvbOps avb_ops_;
- std::string device_file_by_name_prefix_;
+ std::map<std::string, std::string> by_name_symlink_map_;
};
-#endif /* __CORE_FS_MGR_AVB_OPS_H */
+#endif /* __CORE_FS_MGR_PRIV_AVB_OPS_H */
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 0bf173b..5fa10bc 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -663,7 +663,7 @@
/* use the kernel parameter if set */
std::string veritymode;
if (fs_mgr_get_boot_config("veritymode", &veritymode)) {
- if (veritymode.compare("enforcing")) {
+ if (veritymode == "enforcing") {
*mode = VERITY_MODE_DEFAULT;
}
return 0;
diff --git a/fs_mgr/include/fs_mgr_avb.h b/fs_mgr/include/fs_mgr_avb.h
index a66ff42..bbafe1a 100644
--- a/fs_mgr/include/fs_mgr_avb.h
+++ b/fs_mgr/include/fs_mgr_avb.h
@@ -17,6 +17,7 @@
#ifndef __CORE_FS_MGR_AVB_H
#define __CORE_FS_MGR_AVB_H
+#include <map>
#include <memory>
#include <string>
@@ -25,14 +26,19 @@
#include "fs_mgr.h"
enum FsManagerAvbHandleStatus {
+ kFsManagerAvbHandleUninitialized = -1,
kFsManagerAvbHandleSuccess = 0,
kFsManagerAvbHandleHashtreeDisabled = 1,
- kFsManagerAvbHandleFail = 2,
+ kFsManagerAvbHandleErrorVerification = 2,
};
+class FsManagerAvbOps;
+
class FsManagerAvbHandle;
using FsManagerAvbUniquePtr = std::unique_ptr<FsManagerAvbHandle>;
+using ByNameSymlinkMap = std::map<std::string, std::string>;
+
// Provides a factory method to return a unique_ptr pointing to itself and the
// SetUpAvb() function to extract dm-verity parameters from AVB metadata to
// load verity table into kernel through ioctl.
@@ -48,6 +54,13 @@
// A typical usage will be:
// - FsManagerAvbUniquePtr handle = FsManagerAvbHandle::Open();
//
+ // There are two overloaded Open() functions with a single parameter.
+ // The argument can be a ByNameSymlinkMap describing the mapping from partition
+ // name to by-name symlink, or a fstab file to which the ByNameSymlinkMap is
+ // constructed from. e.g.,
+ // - /dev/block/platform/soc.0/7824900.sdhci/by-name/system_a ->
+ // - ByNameSymlinkMap["system_a"] = "/dev/block/platform/soc.0/7824900.sdhci/by-name/system_a"
+ //
// Possible return values:
// - nullptr: any error when reading and verifying the metadata,
// e.g., I/O error, digest value mismatch, size mismatch, etc.
@@ -60,7 +73,8 @@
// - a valid unique_ptr with status kFsMgrAvbHandleSuccess: the metadata
// is verified and can be trusted.
//
- static FsManagerAvbUniquePtr Open(const std::string& device_file_by_name_prefix);
+ static FsManagerAvbUniquePtr Open(const fstab& fstab);
+ static FsManagerAvbUniquePtr Open(ByNameSymlinkMap&& by_name_symlink_map);
// Sets up dm-verity on the given fstab entry.
// The 'wait_for_verity_dev' parameter makes this function wait for the
@@ -87,10 +101,10 @@
}
};
- protected:
- FsManagerAvbHandle() : avb_slot_data_(nullptr), status_(kFsManagerAvbHandleFail) {}
-
private:
+ FsManagerAvbHandle() : avb_slot_data_(nullptr), status_(kFsManagerAvbHandleUninitialized) {}
+ static FsManagerAvbUniquePtr DoOpen(FsManagerAvbOps* avb_ops);
+
AvbSlotVerifyData* avb_slot_data_;
FsManagerAvbHandleStatus status_;
std::string avb_version_;
diff --git a/init/devices.cpp b/init/devices.cpp
index 405f92e..39571ac 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -526,8 +526,7 @@
return NULL;
}
-static char **get_block_device_symlinks(struct uevent *uevent)
-{
+char** get_block_device_symlinks(struct uevent* uevent) {
const char *device;
struct platform_node *pdev;
const char *slash;
diff --git a/init/devices.h b/init/devices.h
index 26a064b..3f2cde4 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -55,4 +55,6 @@
unsigned short wildcard);
int get_device_fd();
+char** get_block_device_symlinks(struct uevent* uevent);
+
#endif /* _INIT_DEVICES_H */
diff --git a/init/init.cpp b/init/init.cpp
index 84e4f84..bb6355a 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -19,6 +19,7 @@
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <keyutils.h>
#include <libgen.h>
#include <paths.h>
#include <signal.h>
@@ -1028,6 +1029,11 @@
InitKernelLogging(argv);
LOG(INFO) << "init second stage started!";
+ // Set up a session keyring that all processes will have access to. It
+ // will hold things like FBE encryption keys. No process should override
+ // its session keyring.
+ keyctl(KEYCTL_GET_KEYRING_ID, KEY_SPEC_SESSION_KEYRING, 1);
+
// Indicate that booting is in progress to background fw loaders, etc.
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index e6b2f24..bcc8d1b 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -47,18 +47,22 @@
bool InitDevices();
protected:
- void InitRequiredDevices(std::set<std::string>* devices_partition_names);
+ void InitRequiredDevices();
void InitVerityDevice(const std::string& verity_device);
bool MountPartitions();
- virtual bool GetRequiredDevices(std::set<std::string>* out_devices_partition_names,
- bool* out_need_dm_verity) = 0;
+ virtual coldboot_action_t ColdbootCallback(uevent* uevent);
+
+ // Pure virtual functions.
+ virtual bool GetRequiredDevices() = 0;
virtual bool SetUpDmVerity(fstab_rec* fstab_rec) = 0;
+ bool need_dm_verity_;
// Device tree fstab entries.
std::unique_ptr<fstab, decltype(&fs_mgr_free_fstab)> device_tree_fstab_;
// Eligible first stage mount candidates, only allow /system, /vendor and/or /odm.
std::vector<fstab_rec*> mount_fstab_recs_;
+ std::set<std::string> required_devices_partition_names_;
};
class FirstStageMountVBootV1 : public FirstStageMount {
@@ -67,27 +71,26 @@
~FirstStageMountVBootV1() override = default;
protected:
- bool GetRequiredDevices(std::set<std::string>* out_devices_partition_names,
- bool* out_need_dm_verity) override;
+ bool GetRequiredDevices() override;
bool SetUpDmVerity(fstab_rec* fstab_rec) override;
};
class FirstStageMountVBootV2 : public FirstStageMount {
public:
+ friend void SetInitAvbVersionInRecovery();
+
FirstStageMountVBootV2();
~FirstStageMountVBootV2() override = default;
- const std::string& by_name_prefix() const { return device_tree_by_name_prefix_; }
-
protected:
- bool GetRequiredDevices(std::set<std::string>* out_devices_partition_names,
- bool* out_need_dm_verity) override;
+ coldboot_action_t ColdbootCallback(uevent* uevent) override;
+ bool GetRequiredDevices() override;
bool SetUpDmVerity(fstab_rec* fstab_rec) override;
bool InitAvbHandle();
std::string device_tree_vbmeta_parts_;
- std::string device_tree_by_name_prefix_;
FsManagerAvbUniquePtr avb_handle_;
+ ByNameSymlinkMap by_name_symlink_map_;
};
// Static Functions
@@ -102,7 +105,8 @@
// Class Definitions
// -----------------
-FirstStageMount::FirstStageMount() : device_tree_fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab) {
+FirstStageMount::FirstStageMount()
+ : need_dm_verity_(false), device_tree_fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab) {
if (!device_tree_fstab_) {
LOG(ERROR) << "Failed to read fstab from device tree";
return;
@@ -136,69 +140,71 @@
}
bool FirstStageMount::InitDevices() {
- bool need_dm_verity;
- std::set<std::string> devices_partition_names;
+ if (!GetRequiredDevices()) return false;
- // The partition name in devices_partition_names MUST have A/B suffix when A/B is used.
- if (!GetRequiredDevices(&devices_partition_names, &need_dm_verity)) return false;
+ InitRequiredDevices();
- if (need_dm_verity) {
- device_init("/sys/devices/virtual/misc/device-mapper",
- [&](uevent* uevent) -> coldboot_action_t { return COLDBOOT_STOP; });
- }
-
- bool success = false;
- InitRequiredDevices(&devices_partition_names);
-
- // InitRequiredDevices() will remove found partitions from devices_partition_names.
+ // InitRequiredDevices() will remove found partitions from required_devices_partition_names_.
// So if it isn't empty here, it means some partitions are not found.
- if (!devices_partition_names.empty()) {
+ if (!required_devices_partition_names_.empty()) {
LOG(ERROR) << __FUNCTION__ << "(): partition(s) not found: "
- << android::base::Join(devices_partition_names, ", ");
+ << android::base::Join(required_devices_partition_names_, ", ");
+ return false;
} else {
- success = true;
+ return true;
}
-
- device_close();
- return success;
}
-// Creates devices with uevent->partition_name matching one in the in/out
-// devices_partition_names. Found partitions will then be removed from the
-// devices_partition_names for the caller to check which devices are NOT created.
-void FirstStageMount::InitRequiredDevices(std::set<std::string>* devices_partition_names) {
- if (devices_partition_names->empty()) {
+// Creates devices with uevent->partition_name matching one in the member variable
+// required_devices_partition_names_. Found partitions will then be removed from it
+// for the subsequent member function to check which devices are NOT created.
+void FirstStageMount::InitRequiredDevices() {
+ if (required_devices_partition_names_.empty()) {
return;
}
- device_init(nullptr, [=](uevent* uevent) -> coldboot_action_t {
- // We need platform devices to create symlinks.
- if (!strncmp(uevent->subsystem, "platform", 8)) {
- return COLDBOOT_CREATE;
- }
- // Ignores everything that is not a block device.
- if (strncmp(uevent->subsystem, "block", 5)) {
- return COLDBOOT_CONTINUE;
- }
+ if (need_dm_verity_) {
+ const std::string dm_path = "/devices/virtual/misc/device-mapper";
+ device_init(("/sys" + dm_path).c_str(), [&dm_path](uevent* uevent) -> coldboot_action_t {
+ if (uevent->path && uevent->path == dm_path) return COLDBOOT_STOP;
+ return COLDBOOT_CONTINUE; // dm_path not found, continue to find it.
+ });
+ }
- if (uevent->partition_name) {
- // Matches partition name to create device nodes.
- // Both devices_partition_names and uevent->partition_name have A/B
- // suffix when A/B is used.
- auto iter = devices_partition_names->find(uevent->partition_name);
- if (iter != devices_partition_names->end()) {
- LOG(VERBOSE) << __FUNCTION__ << "(): found partition: " << *iter;
- devices_partition_names->erase(iter);
- if (devices_partition_names->empty()) {
- return COLDBOOT_STOP; // Found all partitions, stop coldboot.
- } else {
- return COLDBOOT_CREATE; // Creates this device and continue to find others.
- }
+ device_init(nullptr,
+ [this](uevent* uevent) -> coldboot_action_t { return ColdbootCallback(uevent); });
+
+ device_close();
+}
+
+coldboot_action_t FirstStageMount::ColdbootCallback(uevent* uevent) {
+ // We need platform devices to create symlinks.
+ if (!strncmp(uevent->subsystem, "platform", 8)) {
+ return COLDBOOT_CREATE;
+ }
+
+ // Ignores everything that is not a block device.
+ if (strncmp(uevent->subsystem, "block", 5)) {
+ return COLDBOOT_CONTINUE;
+ }
+
+ if (uevent->partition_name) {
+ // Matches partition name to create device nodes.
+ // Both required_devices_partition_names_ and uevent->partition_name have A/B
+ // suffix when A/B is used.
+ auto iter = required_devices_partition_names_.find(uevent->partition_name);
+ if (iter != required_devices_partition_names_.end()) {
+ LOG(VERBOSE) << __FUNCTION__ << "(): found partition: " << *iter;
+ required_devices_partition_names_.erase(iter);
+ if (required_devices_partition_names_.empty()) {
+ return COLDBOOT_STOP; // Found all partitions, stop coldboot.
+ } else {
+ return COLDBOOT_CREATE; // Creates this device and continue to find others.
}
}
- // Not found a partition or find an unneeded partition, continue to find others.
- return COLDBOOT_CONTINUE;
- });
+ }
+ // Not found a partition or find an unneeded partition, continue to find others.
+ return COLDBOOT_CONTINUE;
}
// Creates "/dev/block/dm-XX" for dm-verity by running coldboot on /sys/block/dm-XX.
@@ -207,7 +213,7 @@
const std::string syspath = "/sys/block/" + device_name;
device_init(syspath.c_str(), [&](uevent* uevent) -> coldboot_action_t {
- if (uevent->device_name && device_name == uevent->device_name) {
+ if (uevent->device_name && uevent->device_name == device_name) {
LOG(VERBOSE) << "Creating dm-verity device : " << verity_device;
return COLDBOOT_STOP;
}
@@ -230,10 +236,9 @@
return true;
}
-bool FirstStageMountVBootV1::GetRequiredDevices(std::set<std::string>* out_devices_partition_names,
- bool* out_need_dm_verity) {
+bool FirstStageMountVBootV1::GetRequiredDevices() {
std::string verity_loc_device;
- *out_need_dm_verity = false;
+ need_dm_verity_ = false;
for (auto fstab_rec : mount_fstab_recs_) {
// Don't allow verifyatboot in the first stage.
@@ -243,7 +248,7 @@
}
// Checks for verified partitions.
if (fs_mgr_is_verified(fstab_rec)) {
- *out_need_dm_verity = true;
+ need_dm_verity_ = true;
}
// Checks if verity metadata is on a separate partition. Note that it is
// not partition specific, so there must be only one additional partition
@@ -262,11 +267,11 @@
// Includes the partition names of fstab records and verity_loc_device (if any).
// Notes that fstab_rec->blk_device has A/B suffix updated by fs_mgr when A/B is used.
for (auto fstab_rec : mount_fstab_recs_) {
- out_devices_partition_names->emplace(basename(fstab_rec->blk_device));
+ required_devices_partition_names_.emplace(basename(fstab_rec->blk_device));
}
if (!verity_loc_device.empty()) {
- out_devices_partition_names->emplace(basename(verity_loc_device.c_str()));
+ required_devices_partition_names_.emplace(basename(verity_loc_device.c_str()));
}
return true;
@@ -289,15 +294,13 @@
}
// FirstStageMountVBootV2 constructor.
-// Gets the vbmeta configurations from device tree.
-// Specifically, the 'parts' and 'by_name_prefix' below.
+// Gets the vbmeta partitions from device tree.
// /{
// firmware {
// android {
// vbmeta {
// compatible = "android,vbmeta";
// parts = "vbmeta,boot,system,vendor"
-// by_name_prefix = "/dev/block/platform/soc.0/f9824900.sdhci/by-name/"
// };
// };
// };
@@ -307,31 +310,24 @@
PLOG(ERROR) << "Failed to read vbmeta/parts from device tree";
return;
}
-
- // TODO: removes by_name_prefix to allow partitions on different block devices.
- if (!read_android_dt_file("vbmeta/by_name_prefix", &device_tree_by_name_prefix_)) {
- PLOG(ERROR) << "Failed to read vbmeta/by_name_prefix from dt";
- return;
- }
}
-bool FirstStageMountVBootV2::GetRequiredDevices(std::set<std::string>* out_devices_partition_names,
- bool* out_need_dm_verity) {
- *out_need_dm_verity = false;
+bool FirstStageMountVBootV2::GetRequiredDevices() {
+ need_dm_verity_ = false;
// fstab_rec->blk_device has A/B suffix.
for (auto fstab_rec : mount_fstab_recs_) {
if (fs_mgr_is_avb(fstab_rec)) {
- *out_need_dm_verity = true;
+ need_dm_verity_ = true;
}
- out_devices_partition_names->emplace(basename(fstab_rec->blk_device));
+ required_devices_partition_names_.emplace(basename(fstab_rec->blk_device));
}
// libavb verifies AVB metadata on all verified partitions at once.
// e.g., The device_tree_vbmeta_parts_ will be "vbmeta,boot,system,vendor"
// for libavb to verify metadata, even if there is only /vendor in the
// above mount_fstab_recs_.
- if (*out_need_dm_verity) {
+ if (need_dm_verity_) {
if (device_tree_vbmeta_parts_.empty()) {
LOG(ERROR) << "Missing vbmeta parts in device tree";
return false;
@@ -339,16 +335,45 @@
std::vector<std::string> partitions = android::base::Split(device_tree_vbmeta_parts_, ",");
std::string ab_suffix = fs_mgr_get_slot_suffix();
for (const auto& partition : partitions) {
- // out_devices_partition_names is of type std::set so it's not an issue to emplace
- // a partition twice. e.g., /vendor might be in both places:
+ // required_devices_partition_names_ is of type std::set so it's not an issue
+ // to emplace a partition twice. e.g., /vendor might be in both places:
// - device_tree_vbmeta_parts_ = "vbmeta,boot,system,vendor"
// - mount_fstab_recs_: /vendor_a
- out_devices_partition_names->emplace(partition + ab_suffix);
+ required_devices_partition_names_.emplace(partition + ab_suffix);
}
}
return true;
}
+coldboot_action_t FirstStageMountVBootV2::ColdbootCallback(uevent* uevent) {
+ // Invokes the parent function to see if any desired partition has been found.
+ // If yes, record the by-name symlink for creating FsManagerAvbHandle later.
+ coldboot_action_t parent_callback_ret = FirstStageMount::ColdbootCallback(uevent);
+
+ // Skips the uevent if the parent function returns COLDBOOT_CONTINUE (meaning
+ // that the uevent was skipped) or there is no uevent->partition_name to
+ // create the by-name symlink.
+ if (parent_callback_ret != COLDBOOT_CONTINUE && uevent->partition_name) {
+ // get_block_device_symlinks() will return three symlinks at most, depending on
+ // the content of uevent. by-name symlink will be at [0] if uevent->partition_name
+ // is not empty. e.g.,
+ // - /dev/block/platform/soc.0/f9824900.sdhci/by-name/modem
+ // - /dev/block/platform/soc.0/f9824900.sdhci/by-num/p1
+ // - /dev/block/platform/soc.0/f9824900.sdhci/mmcblk0p1
+ char** links = get_block_device_symlinks(uevent);
+ if (links && links[0]) {
+ auto[it, inserted] = by_name_symlink_map_.emplace(uevent->partition_name, links[0]);
+ if (!inserted) {
+ LOG(ERROR) << "Partition '" << uevent->partition_name
+ << "' already existed in the by-name symlink map with a value of '"
+ << it->second << "', new value '" << links[0] << "' will be ignored.";
+ }
+ }
+ }
+
+ return parent_callback_ret;
+}
+
bool FirstStageMountVBootV2::SetUpDmVerity(fstab_rec* fstab_rec) {
if (fs_mgr_is_avb(fstab_rec)) {
if (!InitAvbHandle()) return false;
@@ -368,7 +393,14 @@
bool FirstStageMountVBootV2::InitAvbHandle() {
if (avb_handle_) return true; // Returns true if the handle is already initialized.
- avb_handle_ = FsManagerAvbHandle::Open(device_tree_by_name_prefix_);
+ if (by_name_symlink_map_.empty()) {
+ LOG(ERROR) << "by_name_symlink_map_ is empty";
+ return false;
+ }
+
+ avb_handle_ = FsManagerAvbHandle::Open(std::move(by_name_symlink_map_));
+ by_name_symlink_map_.clear(); // Removes all elements after the above std::move().
+
if (!avb_handle_) {
PLOG(ERROR) << "Failed to open FsManagerAvbHandle";
return false;
@@ -424,7 +456,8 @@
return;
}
- FsManagerAvbUniquePtr avb_handle = FsManagerAvbHandle::Open(avb_first_mount.by_name_prefix());
+ FsManagerAvbUniquePtr avb_handle =
+ FsManagerAvbHandle::Open(std::move(avb_first_mount.by_name_symlink_map_));
if (!avb_handle) {
PLOG(ERROR) << "Failed to open FsManagerAvbHandle for INIT_AVB_VERSION";
return;
diff --git a/init/keyutils.h b/init/keyutils.h
new file mode 100644
index 0000000..de01beb
--- /dev/null
+++ b/init/keyutils.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+/* Miniature version of a header-only keyutils.h (no library required) */
+
+#ifndef _INIT_KEYUTILS_H_
+#define _INIT_KEYUTILS_H_
+
+#ifndef KEYUTILS_H /* walk away if the _real_ one exists */
+
+#include <linux/keyctl.h>
+#include <stdarg.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+static inline long keyctl(int cmd, ...) {
+ va_list va;
+ unsigned long arg2, arg3, arg4, arg5;
+
+ va_start(va, cmd);
+ arg2 = va_arg(va, unsigned long);
+ arg3 = va_arg(va, unsigned long);
+ arg4 = va_arg(va, unsigned long);
+ arg5 = va_arg(va, unsigned long);
+ va_end(va);
+ return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
+}
+
+#endif
+
+#endif
diff --git a/init/reboot.cpp b/init/reboot.cpp
index c997519..aac1b5c 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -331,7 +331,7 @@
// keep debugging tools until non critical ones are all gone.
const std::set<std::string> kill_after_apps{"tombstoned", "logd", "adbd"};
// watchdogd is a vendor specific component but should be alive to complete shutdown safely.
- const std::set<std::string> to_starts{"watchdogd", "vold"};
+ const std::set<std::string> to_starts{"watchdogd", "vold", "ueventd"};
ServiceManager::GetInstance().ForEachService([&kill_after_apps, &to_starts](Service* s) {
if (kill_after_apps.count(s->name())) {
s->SetShutdownCritical();
diff --git a/libappfuse/FuseBuffer.cc b/libappfuse/FuseBuffer.cc
index b42a049..653e96b 100644
--- a/libappfuse/FuseBuffer.cc
+++ b/libappfuse/FuseBuffer.cc
@@ -119,7 +119,12 @@
return ResultOrAgain::kFailure;
}
}
- CHECK(static_cast<uint32_t>(result) == header.len);
+
+ if (static_cast<unsigned int>(result) != header.len) {
+ LOG(ERROR) << "Written bytes " << result << " is different from length in header "
+ << header.len;
+ return ResultOrAgain::kFailure;
+ }
return ResultOrAgain::kSuccess;
}
}
@@ -141,8 +146,8 @@
}
constexpr int kMaxMessageSize = sizeof(FuseBuffer);
- if (setsockopt(fds[0], SOL_SOCKET, SO_SNDBUF, &kMaxMessageSize, sizeof(int)) != 0 ||
- setsockopt(fds[1], SOL_SOCKET, SO_SNDBUF, &kMaxMessageSize, sizeof(int)) != 0) {
+ if (setsockopt(fds[0], SOL_SOCKET, SO_SNDBUFFORCE, &kMaxMessageSize, sizeof(int)) != 0 ||
+ setsockopt(fds[1], SOL_SOCKET, SO_SNDBUFFORCE, &kMaxMessageSize, sizeof(int)) != 0) {
PLOG(ERROR) << "Failed to update buffer size for socket";
return false;
}
diff --git a/libcrypto_utils/Android.bp b/libcrypto_utils/Android.bp
index f2560e6..4a5f2a7 100644
--- a/libcrypto_utils/Android.bp
+++ b/libcrypto_utils/Android.bp
@@ -16,6 +16,7 @@
cc_library {
name: "libcrypto_utils",
+ vendor_available: true,
host_supported: true,
srcs: [
"android_pubkey.c",
diff --git a/libnativeloader/include/nativeloader/dlext_namespaces.h b/libnativeloader/include/nativeloader/dlext_namespaces.h
index ac64f71..9121277 100644
--- a/libnativeloader/include/nativeloader/dlext_namespaces.h
+++ b/libnativeloader/include/nativeloader/dlext_namespaces.h
@@ -55,6 +55,12 @@
* permitted_path from the caller's namespace.
*/
ANDROID_NAMESPACE_TYPE_SHARED = 2,
+
+ /* This flag instructs linker to enable grey-list workaround for the namespace.
+ * See http://b/26394120 for details.
+ */
+ ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED = 0x08000000,
+
ANDROID_NAMESPACE_TYPE_SHARED_ISOLATED = ANDROID_NAMESPACE_TYPE_SHARED |
ANDROID_NAMESPACE_TYPE_ISOLATED,
};
diff --git a/libnativeloader/native_loader.cpp b/libnativeloader/native_loader.cpp
index ebd6d4b..100c31d 100644
--- a/libnativeloader/native_loader.cpp
+++ b/libnativeloader/native_loader.cpp
@@ -99,6 +99,7 @@
LibraryNamespaces() : initialized_(false) { }
bool Create(JNIEnv* env,
+ uint32_t target_sdk_version,
jobject class_loader,
bool is_shared,
jstring java_library_path,
@@ -141,6 +142,10 @@
namespace_type |= ANDROID_NAMESPACE_TYPE_SHARED;
}
+ if (target_sdk_version < 24) {
+ namespace_type |= ANDROID_NAMESPACE_TYPE_GREYLIST_ENABLED;
+ }
+
NativeLoaderNamespace parent_ns;
bool found_parent_namespace = FindParentNamespaceByClassLoader(env, class_loader, &parent_ns);
@@ -397,12 +402,12 @@
jstring library_path,
jstring permitted_path) {
#if defined(__ANDROID__)
- UNUSED(target_sdk_version);
std::lock_guard<std::mutex> guard(g_namespaces_mutex);
std::string error_msg;
NativeLoaderNamespace ns;
bool success = g_namespaces->Create(env,
+ target_sdk_version,
class_loader,
is_shared,
library_path,
@@ -439,7 +444,14 @@
if (!g_namespaces->FindNamespaceByClassLoader(env, class_loader, &ns)) {
// This is the case where the classloader was not created by ApplicationLoaders
// In this case we create an isolated not-shared namespace for it.
- if (!g_namespaces->Create(env, class_loader, false, library_path, nullptr, &ns, error_msg)) {
+ if (!g_namespaces->Create(env,
+ target_sdk_version,
+ class_loader,
+ false,
+ library_path,
+ nullptr,
+ &ns,
+ error_msg)) {
return nullptr;
}
}
diff --git a/libutils/include/utils/Flattenable.h b/libutils/include/utils/Flattenable.h
index 22b811a..070c710 100644
--- a/libutils/include/utils/Flattenable.h
+++ b/libutils/include/utils/Flattenable.h
@@ -189,11 +189,11 @@
}
inline status_t flatten(void* buffer, size_t size) const {
if (size < sizeof(T)) return NO_MEMORY;
- *reinterpret_cast<T*>(buffer) = *static_cast<T const*>(this);
+ memcpy(buffer, static_cast<T const*>(this), sizeof(T));
return NO_ERROR;
}
inline status_t unflatten(void const* buffer, size_t) {
- *static_cast<T*>(this) = *reinterpret_cast<T const*>(buffer);
+ memcpy(static_cast<T*>(this), buffer, sizeof(T));
return NO_ERROR;
}
};
diff --git a/libvndksupport/Android.bp b/libvndksupport/Android.bp
new file mode 100644
index 0000000..ab9e26f
--- /dev/null
+++ b/libvndksupport/Android.bp
@@ -0,0 +1,15 @@
+subdirs = ["tests"]
+
+cc_library_shared {
+ name: "libvndksupport",
+ srcs: ["linker.c"],
+ local_include_dirs: ["include/vndksupport"],
+ export_include_dirs: ["include"],
+ shared_libs: ["liblog"],
+}
+
+llndk_library {
+ name: "libvndksupport",
+ symbol_file: "libvndksupport.map.txt",
+ export_include_dirs: ["include"],
+}
diff --git a/libvndksupport/include/vndksupport/linker.h b/libvndksupport/include/vndksupport/linker.h
new file mode 100644
index 0000000..f509564
--- /dev/null
+++ b/libvndksupport/include/vndksupport/linker.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+#ifndef VNDKSUPPORT_LINKER_H_
+#define VNDKSUPPORT_LINKER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void* android_load_sphal_library(const char* name, int flag);
+
+int android_unload_sphal_library(void* handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // VNDKSUPPORT_LINKER_H_
diff --git a/libvndksupport/libvndksupport.map.txt b/libvndksupport/libvndksupport.map.txt
new file mode 100644
index 0000000..16e38da
--- /dev/null
+++ b/libvndksupport/libvndksupport.map.txt
@@ -0,0 +1,7 @@
+LIBVNDKSUPPORT {
+ global:
+ android_load_sphal_library; # vndk
+ android_unload_sphal_library; # vndk
+ local:
+ *;
+};
diff --git a/libvndksupport/linker.c b/libvndksupport/linker.c
new file mode 100644
index 0000000..12aa3be
--- /dev/null
+++ b/libvndksupport/linker.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include "linker.h"
+
+#include <android/dlext.h>
+#include <dlfcn.h>
+
+#define LOG_TAG "vndksupport"
+#include <log/log.h>
+
+extern struct android_namespace_t* android_get_exported_namespace(const char*);
+
+void* android_load_sphal_library(const char* name, int flag) {
+ struct android_namespace_t* sphal_namespace = android_get_exported_namespace("sphal");
+ if (sphal_namespace != NULL) {
+ const android_dlextinfo dlextinfo = {
+ .flags = ANDROID_DLEXT_USE_NAMESPACE, .library_namespace = sphal_namespace,
+ };
+ void* handle = android_dlopen_ext(name, flag, &dlextinfo);
+ if (handle) {
+ return handle;
+ } else {
+ ALOGW(
+ "Could not load %s from sphal namespace: %s. "
+ "Falling back to loading it from the current namespace,",
+ name, dlerror());
+ }
+ } else {
+ ALOGI(
+ "sphal namespace is not configured for this process. "
+ "Loading %s from the current namespace instead.",
+ name);
+ }
+ return dlopen(name, flag);
+}
+
+int android_unload_sphal_library(void* handle) { return dlclose(handle); }
diff --git a/libvndksupport/tests/Android.bp b/libvndksupport/tests/Android.bp
new file mode 100644
index 0000000..3587cf8
--- /dev/null
+++ b/libvndksupport/tests/Android.bp
@@ -0,0 +1,26 @@
+// Copyright (C) 2017 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.
+
+cc_test {
+ name: "libvndksupport-tests",
+ srcs: [
+ "linker_test.cpp",
+ ],
+
+ host_supported: false,
+ shared_libs: [
+ "libvndksupport",
+ "libbase",
+ ]
+}
diff --git a/libvndksupport/tests/linker_test.cpp b/libvndksupport/tests/linker_test.cpp
new file mode 100644
index 0000000..7ce27d4
--- /dev/null
+++ b/libvndksupport/tests/linker_test.cpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <gtest/gtest.h>
+
+#include <android-base/strings.h>
+#include <dirent.h>
+#include <dlfcn.h>
+#include <vndksupport/linker.h>
+#include <string>
+
+// Since the test executable will be in /data and ld.config.txt does not
+// configure sphal namespace for executables in /data, the call to
+// android_load_sphal_library will always fallback to the plain dlopen from the
+// default namespace.
+
+// Let's use libEGL_<chipset>.so as a SP-HAL in test
+static std::string find_sphal_lib() {
+ const char* path =
+#if defined(__LP64__)
+ "/vendor/lib64/egl";
+#else
+ "/vendor/lib/egl";
+#endif
+ std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(path), closedir);
+
+ dirent* dp;
+ while ((dp = readdir(dir.get())) != nullptr) {
+ std::string name = dp->d_name;
+ if (android::base::StartsWith(name, "libEGL_")) {
+ return std::string(path) + "/" + name;
+ }
+ }
+ return "";
+}
+
+TEST(linker, load_existing_lib) {
+ std::string name = find_sphal_lib();
+ ASSERT_NE("", name);
+ void* handle = android_load_sphal_library(name.c_str(), RTLD_NOW | RTLD_LOCAL);
+ ASSERT_NE(nullptr, handle);
+ android_unload_sphal_library(handle);
+}
+
+TEST(linker, load_nonexisting_lib) {
+ void* handle = android_load_sphal_library("libNeverUseThisName.so", RTLD_NOW | RTLD_LOCAL);
+ ASSERT_EQ(nullptr, handle);
+}
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 21179fb..5961411 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -60,11 +60,7 @@
namespace.sphal.links = default,vndk,rs
# WARNING: only NDK libs can be listed here.
-# However, this is commented out because some SP-HALs (gralloc.msm8996.so, etc)
-# are currently using some non-stable libs such as libbacktrace.so. We will get back
-# to this list once the dependencies are fixed.
-#namespace.sphal.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libsync.so
-namespace.sphal.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libbacktrace.so:libGLESv1_CM.so:libGLESv2.so
+namespace.sphal.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libvndksupport.so
# WARNING: only VNDK-SP libs can be listed here. DO NOT EDIT this line.
namespace.sphal.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.base@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidltransport.so:libutils.so:libc++.so
@@ -81,11 +77,14 @@
# to load the compiled *.so file and libmediandk.so can be used here.
###############################################################################
namespace.rs.isolated = true
-namespace.rs.search.paths = /system/${LIB}/vndk-sp:/vendor/${LIB}
+namespace.rs.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/vendor/${LIB}
namespace.rs.permitted.paths = /vendor/${LIB}:/data
+namespace.rs.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/vendor/${LIB}:/vendor/${LIB}
+namespace.rs.asan.permitted.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data
+
namespace.rs.links = default,vndk
-namespace.rs.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libbacktrace.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libui.so
+namespace.rs.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libGLESv1_CM.so:libGLESv2.so:libmediandk.so:libui.so:libvndksupport.so
namespace.rs.link.vndk.shared_libs = android.hardware.renderscript@1.0.so:android.hardware.graphics.allocator@2.0.so:android.hardware.graphics.mapper@2.0.so:android.hardware.graphics.common@1.0.so:android.hidl.base@1.0.so:libhwbinder.so:libbase.so:libcutils.so:libhardware.so:libhidlbase.so:libhidltransport.so:libutils.so:libc++.so
###############################################################################
@@ -94,27 +93,21 @@
# This namespace is exclusively for vndk-sp libs.
###############################################################################
namespace.vndk.isolated = true
-namespace.vndk.search.paths = /system/${LIB}/vndk-sp:/vendor/${LIB}
+namespace.vndk.search.paths = /vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/vendor/${LIB}
namespace.vndk.permitted.paths = /vendor/${LIB}/hw:/vendor/${LIB}/egl
-namespace.vndk.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/vendor/${LIB}:/vendor/${LIB}
+namespace.vndk.asan.search.paths = /data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/vendor/${LIB}:/vendor/${LIB}
namespace.vndk.asan.permitted.paths = /data/asan/vendor/${LIB}/hw:/vendor/${LIB}/hw:/data/asan/vendor/${LIB}/egl:/vendor/${LIB}/egl
# When these NDK libs are required inside this namespace, then it is redirected
# to the default namespace. This is possible since their ABI is stable across
# Android releases.
namespace.vndk.links = default
-
-# WARNING: only NDK libs can be listed here.
-# However, this is commented out because some SP-HALs (gralloc.msm8996.so, etc)
-# are currently using some non-stable libs such as libbacktrace.so. We will get back
-# to this list once the dependencies are fixed.
-#namespace.vndk.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libsync.so
-namespace.vndk.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libbacktrace.so
+namespace.vndk.link.default.shared_libs = libc.so:libz.so:libm.so:libdl.so:libstdc++.so:liblog.so:libnativewindow.so:libEGL.so:libsync.so:libvndksupport.so
[vendor]
namespace.default.isolated = false
-namespace.default.search.paths = /vendor/${LIB}:/vendor/${LIB}/vndk-sp:/system/${LIB}
+namespace.default.search.paths = /vendor/${LIB}:/vendor/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/system/${LIB}
-namespace.default.asan.search.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}:/system/${LIB}
+namespace.default.asan.search.paths = /data/asan/vendor/${LIB}:/vendor/${LIB}:/data/asan/vendor/${LIB}/vndk-sp:/vendor/${LIB}/vndk-sp:/data/asan/system/${LIB}/vndk-sp:/system/${LIB}/vndk-sp:/data/asan/system/${LIB}:/system/${LIB}
diff --git a/rootdir/init.rc b/rootdir/init.rc
index def686b..944aae7 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -657,12 +657,6 @@
on property:sys.boot_completed=1
bootchart stop
-on property:sys.boot_completed=1 && property:ro.build.type=user
- write /proc/sys/kernel/modules_disabled 1
-
-on property:sys.boot_completed=1 && property:ro.build.type=userdebug
- write /proc/sys/kernel/modules_disabled 1
-
# system server cannot write to /proc/sys files,
# and chown/chmod does not work for /proc/sys/ entries.
# So proxy writes through init.