summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--adb/Android.mk2
-rw-r--r--adb/adb.cpp33
-rw-r--r--adb/adb_utils.cpp37
-rw-r--r--adb/adb_utils.h2
-rw-r--r--adb/client/main.cpp28
-rw-r--r--adb/daemon/main.cpp24
-rw-r--r--adb/transport_local.cpp27
-rw-r--r--base/chrono_utils.cpp5
-rw-r--r--base/chrono_utils_test.cpp36
-rw-r--r--base/include/android-base/chrono_utils.h17
-rwxr-xr-xbase/include/android-base/utf8.h19
-rw-r--r--base/utf8.cpp52
-rw-r--r--base/utf8_test.cpp76
-rw-r--r--bootstat/bootstat.cpp13
-rw-r--r--debuggerd/Android.bp2
-rw-r--r--debuggerd/client/debuggerd_client_test.cpp15
-rw-r--r--debuggerd/crash_dump.cpp86
-rw-r--r--debuggerd/crasher/crasher.cpp12
-rw-r--r--debuggerd/debuggerd.cpp20
-rw-r--r--debuggerd/debuggerd_test.cpp98
-rw-r--r--debuggerd/libdebuggerd/test/tombstone_test.cpp140
-rw-r--r--debuggerd/libdebuggerd/tombstone.cpp24
-rw-r--r--debuggerd/tombstoned/tombstoned.cpp13
-rw-r--r--debuggerd/tombstoned/tombstoned.rc1
-rw-r--r--demangle/Android.bp4
-rw-r--r--fastboot/Android.mk3
-rw-r--r--fastboot/fs.cpp86
-rw-r--r--fs_mgr/Android.bp49
-rw-r--r--fs_mgr/fs_mgr.cpp476
-rw-r--r--fs_mgr/fs_mgr_avb.cpp14
-rw-r--r--fs_mgr/fs_mgr_avb_ops.cpp6
-rw-r--r--fs_mgr/fs_mgr_boot_config.cpp8
-rw-r--r--fs_mgr/fs_mgr_format.cpp8
-rw-r--r--fs_mgr/fs_mgr_fstab.cpp18
-rw-r--r--fs_mgr/fs_mgr_priv.h14
-rw-r--r--fs_mgr/fs_mgr_verity.cpp74
-rw-r--r--fs_mgr/include/fs_mgr.h73
-rw-r--r--fs_mgr/include_fstab/fstab/fstab.h101
-rw-r--r--gatekeeperd/Android.mk3
-rw-r--r--gatekeeperd/IUserManager.cpp57
-rw-r--r--gatekeeperd/IUserManager.h46
-rw-r--r--gatekeeperd/SoftGateKeeper.h2
-rw-r--r--gatekeeperd/SoftGateKeeperDevice.h2
-rw-r--r--gatekeeperd/gatekeeperd.cpp19
-rw-r--r--gatekeeperd/tests/gatekeeper_test.cpp2
-rw-r--r--healthd/Android.bp7
-rw-r--r--healthd/BatteryMonitor.cpp4
-rw-r--r--healthd/healthd_mode_charger.cpp22
-rw-r--r--init/Android.bp2
-rw-r--r--init/Android.mk6
-rw-r--r--init/README.md12
-rw-r--r--init/action.cpp22
-rw-r--r--init/action.h6
-rw-r--r--init/bootchart.cpp6
-rw-r--r--init/bootchart.h6
-rw-r--r--init/builtins.cpp22
-rw-r--r--init/builtins.h6
-rw-r--r--init/capabilities.cpp22
-rw-r--r--init/capabilities.h14
-rw-r--r--init/descriptors.cpp11
-rw-r--r--init/descriptors.h6
-rw-r--r--init/devices.cpp133
-rw-r--r--init/devices.h14
-rw-r--r--init/devices_test.cpp121
-rw-r--r--init/firmware_handler.cpp44
-rw-r--r--init/firmware_handler.h6
-rw-r--r--init/import_parser.cpp6
-rw-r--r--init/import_parser.h6
-rw-r--r--init/init.cpp38
-rw-r--r--init/init.h8
-rw-r--r--init/init_first_stage.cpp9
-rw-r--r--init/init_first_stage.h6
-rw-r--r--init/init_parser.cpp9
-rw-r--r--init/init_parser.h6
-rw-r--r--init/init_parser_test.cpp15
-rw-r--r--init/init_test.cpp6
-rw-r--r--init/keychords.cpp9
-rw-r--r--init/keychords.h10
-rw-r--r--init/keyword_map.h6
-rw-r--r--init/log.cpp6
-rw-r--r--init/log.h6
-rw-r--r--init/parser.cpp6
-rw-r--r--init/parser.h6
-rw-r--r--init/property_service.cpp102
-rw-r--r--init/property_service.h7
-rw-r--r--init/property_service_test.cpp6
-rw-r--r--init/reboot.cpp71
-rw-r--r--init/reboot.h6
-rw-r--r--init/service.cpp151
-rw-r--r--init/service.h19
-rw-r--r--init/service_test.cpp6
-rw-r--r--init/signal_handler.cpp7
-rw-r--r--init/signal_handler.h6
-rw-r--r--init/uevent.h6
-rw-r--r--init/uevent_listener.cpp8
-rw-r--r--init/uevent_listener.h8
-rw-r--r--init/ueventd.cpp23
-rw-r--r--init/ueventd.h6
-rw-r--r--init/ueventd_parser.cpp6
-rw-r--r--init/ueventd_parser.h6
-rw-r--r--init/ueventd_test.cpp122
-rw-r--r--init/util.cpp11
-rw-r--r--init/util.h26
-rw-r--r--init/util_test.cpp6
-rw-r--r--init/watchdogd.cpp6
-rw-r--r--init/watchdogd.h6
-rw-r--r--libappfuse/FuseBridgeLoop.cc6
-rw-r--r--libappfuse/tests/FuseBridgeLoopTest.cc1
-rw-r--r--libbacktrace/Android.bp1
-rw-r--r--libbacktrace/Backtrace.cpp5
-rw-r--r--libbacktrace/UnwindCurrent.cpp5
-rw-r--r--libbacktrace/UnwindMap.cpp4
-rw-r--r--libbacktrace/UnwindPtrace.cpp5
-rw-r--r--libbacktrace/backtrace_offline_test.cpp16
-rw-r--r--libbacktrace/backtrace_test.cpp20
-rw-r--r--libbacktrace/include/backtrace/Backtrace.h1
-rw-r--r--libbacktrace/include/backtrace/BacktraceMap.h10
-rw-r--r--libcutils/fs_config.cpp39
-rw-r--r--libcutils/include/cutils/sched_policy.h2
-rw-r--r--libcutils/sched_policy.cpp24
-rw-r--r--libcutils/tests/fs_config.cpp47
-rw-r--r--liblog/Android.bp23
-rw-r--r--liblog/include/log/log.h4
-rw-r--r--liblog/include/log/log_main.h9
-rw-r--r--liblog/include_vndk/log/log.h1
l---------liblog/include_vndk/log/log_system.h1
-rw-r--r--liblog/tests/Android.mk2
-rw-r--r--libmemunreachable/Allocator.cpp138
-rw-r--r--libmemunreachable/Allocator.h132
-rw-r--r--libmemunreachable/Android.bp16
-rw-r--r--libmemunreachable/Binder.cpp80
-rw-r--r--libmemunreachable/Binder.h28
-rw-r--r--libmemunreachable/HeapWalker.cpp15
-rw-r--r--libmemunreachable/HeapWalker.h42
-rw-r--r--libmemunreachable/Leak.h13
-rw-r--r--libmemunreachable/LeakFolding.cpp68
-rw-r--r--libmemunreachable/LeakFolding.h31
-rw-r--r--libmemunreachable/LeakPipe.cpp12
-rw-r--r--libmemunreachable/LeakPipe.h37
-rw-r--r--libmemunreachable/LineBuffer.cpp8
-rw-r--r--libmemunreachable/LineBuffer.h6
-rw-r--r--libmemunreachable/LinkedList.h69
-rw-r--r--libmemunreachable/MemUnreachable.cpp106
-rw-r--r--libmemunreachable/ProcessMappings.cpp10
-rw-r--r--libmemunreachable/ProcessMappings.h6
-rw-r--r--libmemunreachable/PtracerThread.cpp27
-rw-r--r--libmemunreachable/PtracerThread.h7
-rw-r--r--libmemunreachable/ScopedAlarm.h16
-rw-r--r--libmemunreachable/ScopedDisableMalloc.h38
-rw-r--r--libmemunreachable/ScopedPipe.h19
-rw-r--r--libmemunreachable/ScopedSignalHandler.h13
-rw-r--r--libmemunreachable/Semaphore.h8
-rw-r--r--libmemunreachable/Tarjan.h42
-rw-r--r--libmemunreachable/ThreadCapture.cpp34
-rw-r--r--libmemunreachable/ThreadCapture.h8
-rw-r--r--libmemunreachable/anon_vma_naming.h6
-rw-r--r--libmemunreachable/bionic.h6
-rw-r--r--libmemunreachable/include/memunreachable/memunreachable.h9
-rw-r--r--libmemunreachable/log.h19
-rw-r--r--libmemunreachable/tests/Allocator_test.cpp24
-rw-r--r--libmemunreachable/tests/AndroidTest.xml26
-rw-r--r--libmemunreachable/tests/Binder_test.cpp156
-rw-r--r--libmemunreachable/tests/DisableMalloc_test.cpp132
-rw-r--r--libmemunreachable/tests/HeapWalker_test.cpp12
-rw-r--r--libmemunreachable/tests/HostMallocStub.cpp6
-rw-r--r--libmemunreachable/tests/LeakFolding_test.cpp42
-rw-r--r--libmemunreachable/tests/MemUnreachable_test.cpp30
-rw-r--r--libmemunreachable/tests/ThreadCapture_test.cpp186
-rw-r--r--libmetricslogger/Android.bp1
-rw-r--r--libnativebridge/Android.bp11
-rw-r--r--libnativebridge/include/nativebridge/native_bridge.h (renamed from include/nativebridge/native_bridge.h)0
-rw-r--r--libnativebridge/tests/Android.bp1
-rw-r--r--libnativeloader/native_loader.cpp2
-rw-r--r--libpixelflinger/codeflinger/mips64_disassem.c1
-rw-r--r--libpixelflinger/codeflinger/mips_disassem.c1
-rw-r--r--libprocessgroup/include/processgroup/processgroup.h4
-rw-r--r--libprocessgroup/processgroup.cpp54
-rw-r--r--libprocinfo/include/procinfo/process.h10
-rw-r--r--libprocinfo/process.cpp23
-rw-r--r--libprocinfo/process_test.cpp34
-rw-r--r--libsync/libsync.map.txt4
-rw-r--r--libsysutils/src/FrameworkListener.cpp3
-rw-r--r--libsysutils/src/NetlinkListener.cpp2
-rw-r--r--libunwindstack/Android.bp128
-rw-r--r--libunwindstack/ArmExidx.cpp31
-rw-r--r--libunwindstack/ArmExidx.h4
-rw-r--r--libunwindstack/AsmGetRegsX86.S62
-rw-r--r--libunwindstack/AsmGetRegsX86_64.S62
-rw-r--r--libunwindstack/Check.h34
-rw-r--r--libunwindstack/DwarfCfa.cpp11
-rw-r--r--libunwindstack/DwarfCfa.h11
-rw-r--r--libunwindstack/DwarfDebugFrame.cpp316
-rw-r--r--libunwindstack/DwarfDebugFrame.h80
-rw-r--r--libunwindstack/DwarfEhFrame.cpp217
-rw-r--r--libunwindstack/DwarfEhFrame.h93
-rw-r--r--libunwindstack/DwarfEncoding.h4
-rw-r--r--libunwindstack/DwarfError.h4
-rw-r--r--libunwindstack/DwarfMemory.cpp15
-rw-r--r--libunwindstack/DwarfOp.cpp13
-rw-r--r--libunwindstack/DwarfOp.h5
-rw-r--r--libunwindstack/DwarfSection.cpp26
-rw-r--r--libunwindstack/Elf.cpp75
-rw-r--r--libunwindstack/ElfInterface.cpp203
-rw-r--r--libunwindstack/ElfInterfaceArm.cpp10
-rw-r--r--libunwindstack/ElfInterfaceArm.h8
-rw-r--r--libunwindstack/Log.cpp6
-rw-r--r--libunwindstack/Machine.h70
-rw-r--r--libunwindstack/MapInfo.cpp18
-rw-r--r--libunwindstack/Maps.cpp28
-rw-r--r--libunwindstack/Memory.cpp13
-rw-r--r--libunwindstack/Regs.cpp363
-rw-r--r--libunwindstack/Symbols.cpp11
-rw-r--r--libunwindstack/Symbols.h4
-rw-r--r--libunwindstack/Ucontext.h184
-rw-r--r--libunwindstack/User.h4
-rw-r--r--libunwindstack/include/unwindstack/DwarfLocation.h (renamed from libunwindstack/DwarfLocation.h)4
-rw-r--r--libunwindstack/include/unwindstack/DwarfMemory.h (renamed from libunwindstack/DwarfMemory.h)4
-rw-r--r--libunwindstack/include/unwindstack/DwarfSection.h (renamed from libunwindstack/DwarfSection.h)16
-rw-r--r--libunwindstack/include/unwindstack/DwarfStructs.h (renamed from libunwindstack/DwarfStructs.h)8
-rw-r--r--libunwindstack/include/unwindstack/Elf.h (renamed from libunwindstack/Elf.h)30
-rw-r--r--libunwindstack/include/unwindstack/ElfInterface.h (renamed from libunwindstack/ElfInterface.h)39
-rw-r--r--libunwindstack/include/unwindstack/Log.h (renamed from libunwindstack/Log.h)4
-rw-r--r--libunwindstack/include/unwindstack/MapInfo.h (renamed from libunwindstack/MapInfo.h)4
-rw-r--r--libunwindstack/include/unwindstack/Maps.h (renamed from libunwindstack/Maps.h)7
-rw-r--r--libunwindstack/include/unwindstack/Memory.h (renamed from libunwindstack/Memory.h)18
-rw-r--r--libunwindstack/include/unwindstack/Regs.h (renamed from libunwindstack/Regs.h)38
-rw-r--r--libunwindstack/include/unwindstack/RegsGetLocal.h104
-rw-r--r--libunwindstack/tests/ArmExidxDecodeTest.cpp9
-rw-r--r--libunwindstack/tests/ArmExidxExtractTest.cpp7
-rw-r--r--libunwindstack/tests/DwarfCfaLogTest.cpp13
-rw-r--r--libunwindstack/tests/DwarfCfaTest.cpp14
-rw-r--r--libunwindstack/tests/DwarfDebugFrameTest.cpp461
-rw-r--r--libunwindstack/tests/DwarfEhFrameTest.cpp414
-rw-r--r--libunwindstack/tests/DwarfMemoryTest.cpp54
-rw-r--r--libunwindstack/tests/DwarfOpLogTest.cpp11
-rw-r--r--libunwindstack/tests/DwarfOpTest.cpp9
-rw-r--r--libunwindstack/tests/DwarfSectionImplTest.cpp9
-rw-r--r--libunwindstack/tests/DwarfSectionTest.cpp6
-rw-r--r--libunwindstack/tests/ElfInterfaceArmTest.cpp7
-rw-r--r--libunwindstack/tests/ElfInterfaceTest.cpp358
-rw-r--r--libunwindstack/tests/ElfTest.cpp177
-rw-r--r--libunwindstack/tests/ElfTestUtils.cpp142
-rw-r--r--libunwindstack/tests/ElfTestUtils.h35
-rw-r--r--libunwindstack/tests/GenGnuDebugdata.cpp112
-rw-r--r--libunwindstack/tests/LogFake.cpp5
-rw-r--r--libunwindstack/tests/LogFake.h4
-rw-r--r--libunwindstack/tests/MapInfoCreateMemoryTest.cpp (renamed from libunwindstack/tests/MapInfoTest.cpp)45
-rw-r--r--libunwindstack/tests/MapInfoGetElfTest.cpp146
-rw-r--r--libunwindstack/tests/MapsTest.cpp6
-rw-r--r--libunwindstack/tests/MemoryBufferTest.cpp (renamed from libunwindstack/tests/MemoryBuffer.cpp)6
-rw-r--r--libunwindstack/tests/MemoryFake.cpp4
-rw-r--r--libunwindstack/tests/MemoryFake.h6
-rw-r--r--libunwindstack/tests/MemoryFileTest.cpp6
-rw-r--r--libunwindstack/tests/MemoryLocalTest.cpp6
-rw-r--r--libunwindstack/tests/MemoryRangeTest.cpp29
-rw-r--r--libunwindstack/tests/MemoryRemoteTest.cpp9
-rw-r--r--libunwindstack/tests/MemoryTest.cpp6
-rw-r--r--libunwindstack/tests/RegsFake.h10
-rw-r--r--libunwindstack/tests/RegsStepIfSignalHandlerTest.cpp201
-rw-r--r--libunwindstack/tests/RegsTest.cpp95
-rw-r--r--libunwindstack/tests/SymbolsTest.cpp7
-rw-r--r--libunwindstack/tests/UnwindTest.cpp316
-rw-r--r--libunwindstack/tests/files/elf32.xzbin0 -> 140 bytes
-rw-r--r--libunwindstack/tests/files/elf64.xzbin0 -> 144 bytes
-rw-r--r--libunwindstack/tools/unwind.cpp162
-rw-r--r--libunwindstack/tools/unwind_info.cpp (renamed from libunwindstack/unwind_info.cpp)115
-rw-r--r--libunwindstack/tools/unwind_symbols.cpp98
-rw-r--r--libutils/Android.bp8
-rw-r--r--libutils/Log.cpp37
-rw-r--r--libutils/Printer.cpp2
-rw-r--r--libutils/include/utils/Log.h73
-rw-r--r--libziparchive/Android.bp35
-rw-r--r--libziparchive/entry_name_utils-inl.h1
-rw-r--r--libziparchive/entry_name_utils_test.cc19
-rw-r--r--libziparchive/include/ziparchive/zip_archive.h (renamed from include/ziparchive/zip_archive.h)40
-rw-r--r--libziparchive/include/ziparchive/zip_archive_stream_entry.h (renamed from include/ziparchive/zip_archive_stream_entry.h)0
-rw-r--r--libziparchive/include/ziparchive/zip_writer.h (renamed from include/ziparchive/zip_writer.h)13
-rw-r--r--libziparchive/unzip.cpp345
-rw-r--r--libziparchive/zip_archive.cc360
-rw-r--r--libziparchive/zip_archive_common.h8
-rw-r--r--libziparchive/zip_archive_private.h136
-rw-r--r--libziparchive/zip_archive_stream_entry.cc21
-rw-r--r--libziparchive/zip_archive_test.cc225
-rw-r--r--libziparchive/zip_writer.cc61
-rw-r--r--libziparchive/zip_writer_test.cc28
-rw-r--r--lmkd/lmkd.c120
-rw-r--r--logcat/logcat.cpp2
-rw-r--r--logd/Android.bp78
-rw-r--r--logd/Android.mk67
-rw-r--r--logd/tests/Android.mk2
-rw-r--r--logd/tests/logd_test.cpp8
-rw-r--r--rootdir/Android.mk2
-rw-r--r--rootdir/etc/ld.config.txt4
-rw-r--r--rootdir/init.rc9
-rw-r--r--shell_and_utilities/Android.bp1
-rw-r--r--storaged/include/storaged.h3
-rw-r--r--storaged/include/storaged_info.h37
-rw-r--r--storaged/main.cpp2
-rw-r--r--storaged/storaged.cpp7
-rw-r--r--storaged/storaged_info.cpp56
-rw-r--r--toolbox/upstream-netbsd/include/sys/mtio.h1
-rw-r--r--trusty/keymaster/trusty_keymaster_device_test.cpp2
-rw-r--r--tzdatacheck/Android.bp14
-rw-r--r--tzdatacheck/tzdatacheck.cpp601
304 files changed, 9534 insertions, 3581 deletions
diff --git a/adb/Android.mk b/adb/Android.mk
index 6ed01fac4..5913d940a 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -350,11 +350,11 @@ LOCAL_CFLAGS := \
350 -D_GNU_SOURCE \ 350 -D_GNU_SOURCE \
351 -Wno-deprecated-declarations \ 351 -Wno-deprecated-declarations \
352 352
353LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=$(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),1,0)
353LOCAL_CFLAGS += -DALLOW_ADBD_NO_AUTH=$(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),1,0) 354LOCAL_CFLAGS += -DALLOW_ADBD_NO_AUTH=$(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),1,0)
354 355
355ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT))) 356ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
356LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1 357LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
357LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
358endif 358endif
359 359
360LOCAL_MODULE := adbd 360LOCAL_MODULE := adbd
diff --git a/adb/adb.cpp b/adb/adb.cpp
index bfb1144d4..ff7b71f81 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -49,6 +49,7 @@
49#include "adb_auth.h" 49#include "adb_auth.h"
50#include "adb_io.h" 50#include "adb_io.h"
51#include "adb_listeners.h" 51#include "adb_listeners.h"
52#include "adb_unique_fd.h"
52#include "adb_utils.h" 53#include "adb_utils.h"
53#include "sysdeps/chrono.h" 54#include "sysdeps/chrono.h"
54#include "transport.h" 55#include "transport.h"
@@ -656,6 +657,26 @@ static unsigned __stdcall _redirect_stderr_thread(HANDLE h) {
656 657
657#endif 658#endif
658 659
660static void ReportServerStartupFailure(pid_t pid) {
661 fprintf(stderr, "ADB server didn't ACK\n");
662 fprintf(stderr, "Full server startup log: %s\n", GetLogFilePath().c_str());
663 fprintf(stderr, "Server had pid: %d\n", pid);
664
665 unique_fd fd(adb_open(GetLogFilePath().c_str(), O_RDONLY));
666 if (fd == -1) return;
667
668 // Let's not show more than 128KiB of log...
669 adb_lseek(fd, -128 * 1024, SEEK_END);
670 std::string content;
671 if (!android::base::ReadFdToString(fd, &content)) return;
672
673 std::string header = android::base::StringPrintf("--- adb starting (pid %d) ---", pid);
674 std::vector<std::string> lines = android::base::Split(content, "\n");
675 int i = lines.size() - 1;
676 while (i >= 0 && lines[i] != header) --i;
677 while (static_cast<size_t>(i) < lines.size()) fprintf(stderr, "%s\n", lines[i++].c_str());
678}
679
659int launch_server(const std::string& socket_spec) { 680int launch_server(const std::string& socket_spec) {
660#if defined(_WIN32) 681#if defined(_WIN32)
661 /* we need to start the server in the background */ 682 /* we need to start the server in the background */
@@ -835,7 +856,8 @@ int launch_server(const std::string& socket_spec) {
835 memcmp(temp, expected, expected_length) == 0) { 856 memcmp(temp, expected, expected_length) == 0) {
836 got_ack = true; 857 got_ack = true;
837 } else { 858 } else {
838 fprintf(stderr, "ADB server didn't ACK\n"); 859 ReportServerStartupFailure(GetProcessId(process_handle.get()));
860 return -1;
839 } 861 }
840 } else { 862 } else {
841 const DWORD err = GetLastError(); 863 const DWORD err = GetLastError();
@@ -909,12 +931,9 @@ int launch_server(const std::string& socket_spec) {
909 "--reply-fd", reply_fd, NULL); 931 "--reply-fd", reply_fd, NULL);
910 // this should not return 932 // this should not return
911 fprintf(stderr, "adb: execl returned %d: %s\n", result, strerror(errno)); 933 fprintf(stderr, "adb: execl returned %d: %s\n", result, strerror(errno));
912 } else { 934 } else {
913 // parent side of the fork 935 // parent side of the fork
914 936 char temp[3] = {};
915 char temp[3];
916
917 temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C';
918 // wait for the "OK\n" message 937 // wait for the "OK\n" message
919 adb_close(fd[1]); 938 adb_close(fd[1]);
920 int ret = adb_read(fd[0], temp, 3); 939 int ret = adb_read(fd[0], temp, 3);
@@ -925,7 +944,7 @@ int launch_server(const std::string& socket_spec) {
925 return -1; 944 return -1;
926 } 945 }
927 if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { 946 if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') {
928 fprintf(stderr, "ADB server didn't ACK\n" ); 947 ReportServerStartupFailure(pid);
929 return -1; 948 return -1;
930 } 949 }
931 } 950 }
diff --git a/adb/adb_utils.cpp b/adb/adb_utils.cpp
index 6f2403d03..b236fb39f 100644
--- a/adb/adb_utils.cpp
+++ b/adb/adb_utils.cpp
@@ -157,7 +157,12 @@ bool mkdirs(const std::string& path) {
157} 157}
158 158
159std::string dump_hex(const void* data, size_t byte_count) { 159std::string dump_hex(const void* data, size_t byte_count) {
160 byte_count = std::min(byte_count, size_t(16)); 160 size_t truncate_len = 16;
161 bool truncated = false;
162 if (byte_count > truncate_len) {
163 byte_count = truncate_len;
164 truncated = true;
165 }
161 166
162 const uint8_t* p = reinterpret_cast<const uint8_t*>(data); 167 const uint8_t* p = reinterpret_cast<const uint8_t*>(data);
163 168
@@ -172,6 +177,10 @@ std::string dump_hex(const void* data, size_t byte_count) {
172 line.push_back(isprint(ch) ? ch : '.'); 177 line.push_back(isprint(ch) ? ch : '.');
173 } 178 }
174 179
180 if (truncated) {
181 line += " [truncated]";
182 }
183
175 return line; 184 return line;
176} 185}
177 186
@@ -278,3 +287,29 @@ int syntax_error(const char* fmt, ...) {
278 fprintf(stderr, "\n"); 287 fprintf(stderr, "\n");
279 return 1; 288 return 1;
280} 289}
290
291std::string GetLogFilePath() {
292#if defined(_WIN32)
293 const char log_name[] = "adb.log";
294 WCHAR temp_path[MAX_PATH];
295
296 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
297 DWORD nchars = GetTempPathW(arraysize(temp_path), temp_path);
298 if (nchars >= arraysize(temp_path) || nchars == 0) {
299 // If string truncation or some other error.
300 fatal("cannot retrieve temporary file path: %s\n",
301 android::base::SystemErrorCodeToString(GetLastError()).c_str());
302 }
303
304 std::string temp_path_utf8;
305 if (!android::base::WideToUTF8(temp_path, &temp_path_utf8)) {
306 fatal_errno("cannot convert temporary file path from UTF-16 to UTF-8");
307 }
308
309 return temp_path_utf8 + log_name;
310#else
311 const char* tmp_dir = getenv("TMPDIR");
312 if (tmp_dir == nullptr) tmp_dir = "/tmp";
313 return android::base::StringPrintf("%s/adb.%u.log", tmp_dir, getuid());
314#endif
315}
diff --git a/adb/adb_utils.h b/adb/adb_utils.h
index 11c0ec9cc..f764a0eea 100644
--- a/adb/adb_utils.h
+++ b/adb/adb_utils.h
@@ -89,4 +89,6 @@ class BlockingQueue {
89 } 89 }
90}; 90};
91 91
92std::string GetLogFilePath();
93
92#endif 94#endif
diff --git a/adb/client/main.cpp b/adb/client/main.cpp
index 62798cde7..f0d0ce799 100644
--- a/adb/client/main.cpp
+++ b/adb/client/main.cpp
@@ -39,33 +39,7 @@
39#include "sysdeps/chrono.h" 39#include "sysdeps/chrono.h"
40#include "transport.h" 40#include "transport.h"
41 41
42static std::string GetLogFilePath() { 42static void setup_daemon_logging() {
43#if defined(_WIN32)
44 const char log_name[] = "adb.log";
45 WCHAR temp_path[MAX_PATH];
46
47 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364992%28v=vs.85%29.aspx
48 DWORD nchars = GetTempPathW(arraysize(temp_path), temp_path);
49 if (nchars >= arraysize(temp_path) || nchars == 0) {
50 // If string truncation or some other error.
51 fatal("cannot retrieve temporary file path: %s\n",
52 android::base::SystemErrorCodeToString(GetLastError()).c_str());
53 }
54
55 std::string temp_path_utf8;
56 if (!android::base::WideToUTF8(temp_path, &temp_path_utf8)) {
57 fatal_errno("cannot convert temporary file path from UTF-16 to UTF-8");
58 }
59
60 return temp_path_utf8 + log_name;
61#else
62 const char* tmp_dir = getenv("TMPDIR");
63 if (tmp_dir == nullptr) tmp_dir = "/tmp";
64 return android::base::StringPrintf("%s/adb.%u.log", tmp_dir, getuid());
65#endif
66}
67
68static void setup_daemon_logging(void) {
69 const std::string log_file_path(GetLogFilePath()); 43 const std::string log_file_path(GetLogFilePath());
70 int fd = unix_open(log_file_path.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0640); 44 int fd = unix_open(log_file_path.c_str(), O_WRONLY | O_CREAT | O_APPEND, 0640);
71 if (fd == -1) { 45 if (fd == -1) {
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index 1c94298da..e0629abdd 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -49,17 +49,23 @@
49 49
50static const char* root_seclabel = nullptr; 50static const char* root_seclabel = nullptr;
51 51
52static inline bool is_device_unlocked() {
53 return "orange" == android::base::GetProperty("ro.boot.verifiedbootstate", "");
54}
55
52static void drop_capabilities_bounding_set_if_needed(struct minijail *j) { 56static void drop_capabilities_bounding_set_if_needed(struct minijail *j) {
53#if defined(ALLOW_ADBD_ROOT) 57 if (ALLOW_ADBD_ROOT || is_device_unlocked()) {
54 if (__android_log_is_debuggable()) { 58 if (__android_log_is_debuggable()) {
55 return; 59 return;
60 }
56 } 61 }
57#endif
58 minijail_capbset_drop(j, CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID)); 62 minijail_capbset_drop(j, CAP_TO_MASK(CAP_SETUID) | CAP_TO_MASK(CAP_SETGID));
59} 63}
60 64
61static bool should_drop_privileges() { 65static bool should_drop_privileges() {
62#if defined(ALLOW_ADBD_ROOT) 66 // "adb root" not allowed, always drop privileges.
67 if (!ALLOW_ADBD_ROOT && !is_device_unlocked()) return true;
68
63 // The properties that affect `adb root` and `adb unroot` are ro.secure and 69 // The properties that affect `adb root` and `adb unroot` are ro.secure and
64 // ro.debuggable. In this context the names don't make the expected behavior 70 // ro.debuggable. In this context the names don't make the expected behavior
65 // particularly obvious. 71 // particularly obvious.
@@ -89,9 +95,6 @@ static bool should_drop_privileges() {
89 } 95 }
90 96
91 return drop; 97 return drop;
92#else
93 return true; // "adb root" not allowed, always drop privileges.
94#endif // ALLOW_ADBD_ROOT
95} 98}
96 99
97static void drop_privileges(int server_port) { 100static void drop_privileges(int server_port) {
@@ -158,7 +161,10 @@ int adbd_main(int server_port) {
158 // descriptor will always be open. 161 // descriptor will always be open.
159 adbd_cloexec_auth_socket(); 162 adbd_cloexec_auth_socket();
160 163
161 if (ALLOW_ADBD_NO_AUTH && !android::base::GetBoolProperty("ro.adb.secure", false)) { 164 // Respect ro.adb.secure in userdebug/eng builds (ALLOW_ADBD_NO_AUTH), or when the
165 // device is unlocked.
166 if ((ALLOW_ADBD_NO_AUTH || is_device_unlocked()) &&
167 !android::base::GetBoolProperty("ro.adb.secure", false)) {
162 auth_required = false; 168 auth_required = false;
163 } 169 }
164 170
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index 809ed89c5..9cd378cad 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -388,6 +388,25 @@ static void qemu_socket_thread(int port) {
388 D("transport: qemu_socket_thread() exiting"); 388 D("transport: qemu_socket_thread() exiting");
389 return; 389 return;
390} 390}
391
392// If adbd is running inside the emulator, it will normally use QEMUD pipe (aka
393// goldfish) as the transport. This can either be explicitly set by the
394// service.adb.transport property, or be inferred from ro.kernel.qemu that is
395// set to "1" for ranchu/goldfish.
396static bool use_qemu_goldfish() {
397 // Legacy way to detect if adbd should use the goldfish pipe is to check for
398 // ro.kernel.qemu, keep that behaviour for backward compatibility.
399 if (android::base::GetBoolProperty("ro.kernel.qemu", false)) {
400 return true;
401 }
402 // If service.adb.transport is present and is set to "goldfish", use the
403 // QEMUD pipe.
404 if (android::base::GetProperty("service.adb.transport", "") == "goldfish") {
405 return true;
406 }
407 return false;
408}
409
391#endif // !ADB_HOST 410#endif // !ADB_HOST
392 411
393void local_init(int port) 412void local_init(int port)
@@ -401,13 +420,7 @@ void local_init(int port)
401#else 420#else
402 // For the adbd daemon in the system image we need to distinguish 421 // For the adbd daemon in the system image we need to distinguish
403 // between the device, and the emulator. 422 // between the device, and the emulator.
404 if (android::base::GetBoolProperty("ro.kernel.qemu", false)) { 423 func = use_qemu_goldfish() ? qemu_socket_thread : server_socket_thread;
405 // Running inside the emulator: use QEMUD pipe as the transport.
406 func = qemu_socket_thread;
407 } else {
408 // Running inside the device: use TCP socket as the transport.
409 func = server_socket_thread;
410 }
411 debug_name = "server"; 424 debug_name = "server";
412#endif // !ADB_HOST 425#endif // !ADB_HOST
413 426
diff --git a/base/chrono_utils.cpp b/base/chrono_utils.cpp
index 5eedf3bce..b6bf701ea 100644
--- a/base/chrono_utils.cpp
+++ b/base/chrono_utils.cpp
@@ -33,5 +33,10 @@ boot_clock::time_point boot_clock::now() {
33#endif // __ANDROID__ 33#endif // __ANDROID__
34} 34}
35 35
36std::ostream& operator<<(std::ostream& os, const Timer& t) {
37 os << t.duration().count() << "ms";
38 return os;
39}
40
36} // namespace base 41} // namespace base
37} // namespace android 42} // namespace android
diff --git a/base/chrono_utils_test.cpp b/base/chrono_utils_test.cpp
index 057132d9f..da442f455 100644
--- a/base/chrono_utils_test.cpp
+++ b/base/chrono_utils_test.cpp
@@ -19,6 +19,9 @@
19#include <time.h> 19#include <time.h>
20 20
21#include <chrono> 21#include <chrono>
22#include <sstream>
23#include <string>
24#include <thread>
22 25
23#include <gtest/gtest.h> 26#include <gtest/gtest.h>
24 27
@@ -42,5 +45,36 @@ TEST(ChronoUtilsTest, BootClockNowSeconds) {
42 EXPECT_EQ(now, boot_seconds); 45 EXPECT_EQ(now, boot_seconds);
43} 46}
44 47
48template <typename T>
49void ExpectAboutEqual(T expected, T actual) {
50 auto expected_upper_bound = expected * 1.05f;
51 auto expected_lower_bound = expected * .95;
52 EXPECT_GT(expected_upper_bound, actual);
53 EXPECT_LT(expected_lower_bound, actual);
54}
55
56TEST(ChronoUtilsTest, TimerDurationIsSane) {
57 auto start = boot_clock::now();
58 Timer t;
59 std::this_thread::sleep_for(50ms);
60 auto stop = boot_clock::now();
61 auto stop_timer = t.duration();
62
63 auto expected = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
64 ExpectAboutEqual(expected, stop_timer);
65}
66
67TEST(ChronoUtilsTest, TimerOstream) {
68 Timer t;
69 std::this_thread::sleep_for(50ms);
70 auto stop_timer = t.duration().count();
71 std::stringstream os;
72 os << t;
73 decltype(stop_timer) stop_timer_from_stream;
74 os >> stop_timer_from_stream;
75 EXPECT_NE(0, stop_timer);
76 ExpectAboutEqual(stop_timer, stop_timer_from_stream);
77}
78
45} // namespace base 79} // namespace base
46} // namespace android \ No newline at end of file 80} // namespace android
diff --git a/base/include/android-base/chrono_utils.h b/base/include/android-base/chrono_utils.h
index 0086425e5..7679d4c94 100644
--- a/base/include/android-base/chrono_utils.h
+++ b/base/include/android-base/chrono_utils.h
@@ -18,6 +18,9 @@
18#define ANDROID_BASE_CHRONO_UTILS_H 18#define ANDROID_BASE_CHRONO_UTILS_H
19 19
20#include <chrono> 20#include <chrono>
21#include <sstream>
22
23using namespace std::chrono_literals;
21 24
22namespace android { 25namespace android {
23namespace base { 26namespace base {
@@ -31,6 +34,20 @@ class boot_clock {
31 static time_point now(); 34 static time_point now();
32}; 35};
33 36
37class Timer {
38 public:
39 Timer() : start_(boot_clock::now()) {}
40
41 std::chrono::milliseconds duration() const {
42 return std::chrono::duration_cast<std::chrono::milliseconds>(boot_clock::now() - start_);
43 }
44
45 private:
46 boot_clock::time_point start_;
47};
48
49std::ostream& operator<<(std::ostream& os, const Timer& t);
50
34} // namespace base 51} // namespace base
35} // namespace android 52} // namespace android
36 53
diff --git a/base/include/android-base/utf8.h b/base/include/android-base/utf8.h
index 2d5a6f6d7..c9cc1ab0c 100755
--- a/base/include/android-base/utf8.h
+++ b/base/include/android-base/utf8.h
@@ -22,6 +22,8 @@
22#else 22#else
23// Bring in prototypes for standard APIs so that we can import them into the utf8 namespace. 23// Bring in prototypes for standard APIs so that we can import them into the utf8 namespace.
24#include <fcntl.h> // open 24#include <fcntl.h> // open
25#include <stdio.h> // fopen
26#include <sys/stat.h> // mkdir
25#include <unistd.h> // unlink 27#include <unistd.h> // unlink
26#endif 28#endif
27 29
@@ -53,6 +55,19 @@ bool UTF8ToWide(const char* utf8, std::wstring* utf16);
53// Convert a UTF-8 std::string (including any embedded NULL characters) to 55// Convert a UTF-8 std::string (including any embedded NULL characters) to
54// UTF-16. Returns whether the conversion was done successfully. 56// UTF-16. Returns whether the conversion was done successfully.
55bool UTF8ToWide(const std::string& utf8, std::wstring* utf16); 57bool UTF8ToWide(const std::string& utf8, std::wstring* utf16);
58
59// Convert a file system path, represented as a NULL-terminated string of
60// UTF-8 characters, to a UTF-16 string representing the same file system
61// path using the Windows extended-lengh path representation.
62//
63// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx#MAXPATH:
64// ```The Windows API has many functions that also have Unicode versions to
65// permit an extended-length path for a maximum total path length of 32,767
66// characters. To specify an extended-length path, use the "\\?\" prefix.
67// For example, "\\?\D:\very long path".```
68//
69// Returns whether the conversion was done successfully.
70bool UTF8PathToWindowsLongPath(const char* utf8, std::wstring* utf16);
56#endif 71#endif
57 72
58// The functions in the utf8 namespace take UTF-8 strings. For Windows, these 73// The functions in the utf8 namespace take UTF-8 strings. For Windows, these
@@ -73,9 +88,13 @@ bool UTF8ToWide(const std::string& utf8, std::wstring* utf16);
73namespace utf8 { 88namespace utf8 {
74 89
75#ifdef _WIN32 90#ifdef _WIN32
91FILE* fopen(const char* name, const char* mode);
92int mkdir(const char* name, mode_t mode);
76int open(const char* name, int flags, ...); 93int open(const char* name, int flags, ...);
77int unlink(const char* name); 94int unlink(const char* name);
78#else 95#else
96using ::fopen;
97using ::mkdir;
79using ::open; 98using ::open;
80using ::unlink; 99using ::unlink;
81#endif 100#endif
diff --git a/base/utf8.cpp b/base/utf8.cpp
index 3cca70026..5984fb06c 100644
--- a/base/utf8.cpp
+++ b/base/utf8.cpp
@@ -19,7 +19,9 @@
19#include "android-base/utf8.h" 19#include "android-base/utf8.h"
20 20
21#include <fcntl.h> 21#include <fcntl.h>
22#include <stdio.h>
22 23
24#include <algorithm>
23#include <string> 25#include <string>
24 26
25#include "android-base/logging.h" 27#include "android-base/logging.h"
@@ -153,12 +155,58 @@ bool UTF8ToWide(const std::string& utf8, std::wstring* utf16) {
153 return UTF8ToWide(utf8.c_str(), utf8.length(), utf16); 155 return UTF8ToWide(utf8.c_str(), utf8.length(), utf16);
154} 156}
155 157
158static bool isDriveLetter(wchar_t c) {
159 return (c >= L'a' && c <= L'z') || (c >= L'A' && c <= L'Z');
160}
161
162bool UTF8PathToWindowsLongPath(const char* utf8, std::wstring* utf16) {
163 if (!UTF8ToWide(utf8, utf16)) {
164 return false;
165 }
166 // Note: Although most Win32 File I/O API are limited to MAX_PATH (260
167 // characters), the CreateDirectory API is limited to 248 characters.
168 if (utf16->length() >= 248) {
169 // If path is of the form "x:\" or "x:/"
170 if (isDriveLetter((*utf16)[0]) && (*utf16)[1] == L':' &&
171 ((*utf16)[2] == L'\\' || (*utf16)[2] == L'/')) {
172 // Append long path prefix, and make sure there are no unix-style
173 // separators to ensure a fully compliant Win32 long path string.
174 utf16->insert(0, LR"(\\?\)");
175 std::replace(utf16->begin(), utf16->end(), L'/', L'\\');
176 }
177 }
178 return true;
179}
180
156// Versions of standard library APIs that support UTF-8 strings. 181// Versions of standard library APIs that support UTF-8 strings.
157namespace utf8 { 182namespace utf8 {
158 183
184FILE* fopen(const char* name, const char* mode) {
185 std::wstring name_utf16;
186 if (!UTF8PathToWindowsLongPath(name, &name_utf16)) {
187 return nullptr;
188 }
189
190 std::wstring mode_utf16;
191 if (!UTF8ToWide(mode, &mode_utf16)) {
192 return nullptr;
193 }
194
195 return _wfopen(name_utf16.c_str(), mode_utf16.c_str());
196}
197
198int mkdir(const char* name, mode_t mode) {
199 std::wstring name_utf16;
200 if (!UTF8PathToWindowsLongPath(name, &name_utf16)) {
201 return -1;
202 }
203
204 return _wmkdir(name_utf16.c_str());
205}
206
159int open(const char* name, int flags, ...) { 207int open(const char* name, int flags, ...) {
160 std::wstring name_utf16; 208 std::wstring name_utf16;
161 if (!UTF8ToWide(name, &name_utf16)) { 209 if (!UTF8PathToWindowsLongPath(name, &name_utf16)) {
162 return -1; 210 return -1;
163 } 211 }
164 212
@@ -175,7 +223,7 @@ int open(const char* name, int flags, ...) {
175 223
176int unlink(const char* name) { 224int unlink(const char* name) {
177 std::wstring name_utf16; 225 std::wstring name_utf16;
178 if (!UTF8ToWide(name, &name_utf16)) { 226 if (!UTF8PathToWindowsLongPath(name, &name_utf16)) {
179 return -1; 227 return -1;
180 } 228 }
181 229
diff --git a/base/utf8_test.cpp b/base/utf8_test.cpp
index ae8fc8c79..fcb25c350 100644
--- a/base/utf8_test.cpp
+++ b/base/utf8_test.cpp
@@ -18,7 +18,12 @@
18 18
19#include <gtest/gtest.h> 19#include <gtest/gtest.h>
20 20
21#include <fcntl.h>
22#include <stdlib.h>
23
21#include "android-base/macros.h" 24#include "android-base/macros.h"
25#include "android-base/test_utils.h"
26#include "android-base/unique_fd.h"
22 27
23namespace android { 28namespace android {
24namespace base { 29namespace base {
@@ -408,5 +413,76 @@ TEST(SysStrings, SysUTF8ToWide) {
408 EXPECT_EQ(expected_null, SysUTF8ToWide(utf8_null)); 413 EXPECT_EQ(expected_null, SysUTF8ToWide(utf8_null));
409} 414}
410 415
416TEST(UTF8PathToWindowsLongPathTest, DontAddPrefixIfShorterThanMaxPath) {
417 std::string utf8 = "c:\\mypath\\myfile.txt";
418
419 std::wstring wide;
420 EXPECT_TRUE(UTF8PathToWindowsLongPath(utf8.c_str(), &wide));
421
422 EXPECT_EQ(std::string::npos, wide.find(LR"(\\?\)"));
423}
424
425TEST(UTF8PathToWindowsLongPathTest, AddPrefixIfLongerThanMaxPath) {
426 std::string utf8 = "c:\\mypath";
427 while (utf8.length() < 300 /* MAX_PATH is 260 */) {
428 utf8 += "\\mypathsegment";
429 }
430
431 std::wstring wide;
432 EXPECT_TRUE(UTF8PathToWindowsLongPath(utf8.c_str(), &wide));
433
434 EXPECT_EQ(0U, wide.find(LR"(\\?\)"));
435 EXPECT_EQ(std::string::npos, wide.find(L"/"));
436}
437
438TEST(UTF8PathToWindowsLongPathTest, AddPrefixAndFixSeparatorsIfLongerThanMaxPath) {
439 std::string utf8 = "c:/mypath";
440 while (utf8.length() < 300 /* MAX_PATH is 260 */) {
441 utf8 += "/mypathsegment";
442 }
443
444 std::wstring wide;
445 EXPECT_TRUE(UTF8PathToWindowsLongPath(utf8.c_str(), &wide));
446
447 EXPECT_EQ(0U, wide.find(LR"(\\?\)"));
448 EXPECT_EQ(std::string::npos, wide.find(L"/"));
449}
450
451namespace utf8 {
452
453TEST(Utf8FilesTest, CanCreateOpenAndDeleteFileWithLongPath) {
454 TemporaryDir td;
455
456 // Create long directory path
457 std::string utf8 = td.path;
458 while (utf8.length() < 300 /* MAX_PATH is 260 */) {
459 utf8 += "\\mypathsegment";
460 EXPECT_EQ(0, mkdir(utf8.c_str(), 0));
461 }
462
463 // Create file
464 utf8 += "\\test-file.bin";
465 int flags = O_WRONLY | O_CREAT | O_TRUNC | O_BINARY;
466 int mode = 0666;
467 android::base::unique_fd fd(open(utf8.c_str(), flags, mode));
468 EXPECT_NE(-1, fd.get());
469
470 // Close file
471 fd.reset();
472 EXPECT_EQ(-1, fd.get());
473
474 // Open file with fopen
475 FILE* file = fopen(utf8.c_str(), "rb");
476 EXPECT_NE(nullptr, file);
477
478 if (file) {
479 fclose(file);
480 }
481
482 // Delete file
483 EXPECT_EQ(0, unlink(utf8.c_str()));
484}
485
486} // namespace utf8
411} // namespace base 487} // namespace base
412} // namespace android 488} // namespace android
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index a4c216033..344fa9aae 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -85,12 +85,13 @@ void ShowHelp(const char *cmd) {
85 fprintf(stderr, "Usage: %s [options]\n", cmd); 85 fprintf(stderr, "Usage: %s [options]\n", cmd);
86 fprintf(stderr, 86 fprintf(stderr,
87 "options include:\n" 87 "options include:\n"
88 " -h, --help Show this help\n" 88 " -h, --help Show this help\n"
89 " -l, --log Log all metrics to logstorage\n" 89 " -l, --log Log all metrics to logstorage\n"
90 " -p, --print Dump the boot event records to the console\n" 90 " -p, --print Dump the boot event records to the console\n"
91 " -r, --record Record the timestamp of a named boot event\n" 91 " -r, --record Record the timestamp of a named boot event\n"
92 " --value Optional value to associate with the boot event\n" 92 " --value Optional value to associate with the boot event\n"
93 " --record_boot_reason Record the reason why the device booted\n" 93 " --record_boot_complete Record metrics related to the time for the device boot\n"
94 " --record_boot_reason Record the reason why the device booted\n"
94 " --record_time_since_factory_reset Record the time since the device was reset\n"); 95 " --record_time_since_factory_reset Record the time since the device was reset\n");
95} 96}
96 97
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index 5565cfdd7..f86aaa014 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -274,7 +274,7 @@ cc_binary {
274 "libbase", 274 "libbase",
275 "libdebuggerd_client", 275 "libdebuggerd_client",
276 "liblog", 276 "liblog",
277 "libselinux", 277 "libprocinfo",
278 ], 278 ],
279 279
280 local_include_dirs: ["include"], 280 local_include_dirs: ["include"],
diff --git a/debuggerd/client/debuggerd_client_test.cpp b/debuggerd/client/debuggerd_client_test.cpp
index 8420f038f..9c2f0d632 100644
--- a/debuggerd/client/debuggerd_client_test.cpp
+++ b/debuggerd/client/debuggerd_client_test.cpp
@@ -27,6 +27,7 @@
27#include <gtest/gtest.h> 27#include <gtest/gtest.h>
28 28
29#include <android-base/file.h> 29#include <android-base/file.h>
30#include <android-base/properties.h>
30#include <android-base/stringprintf.h> 31#include <android-base/stringprintf.h>
31#include <android-base/strings.h> 32#include <android-base/strings.h>
32#include <android-base/unique_fd.h> 33#include <android-base/unique_fd.h>
@@ -36,8 +37,20 @@
36using namespace std::chrono_literals; 37using namespace std::chrono_literals;
37using android::base::unique_fd; 38using android::base::unique_fd;
38 39
40static int getThreadCount() {
41 int threadCount = 1024;
42 std::vector<std::string> characteristics =
43 android::base::Split(android::base::GetProperty("ro.build.characteristics", ""), ",");
44 if (std::find(characteristics.begin(), characteristics.end(), "embedded")
45 != characteristics.end()) {
46 // 128 is the realistic number for iot devices.
47 threadCount = 128;
48 }
49 return threadCount;
50}
51
39TEST(debuggerd_client, race) { 52TEST(debuggerd_client, race) {
40 static constexpr int THREAD_COUNT = 1024; 53 static int THREAD_COUNT = getThreadCount();
41 pid_t forkpid = fork(); 54 pid_t forkpid = fork();
42 55
43 ASSERT_NE(-1, forkpid); 56 ASSERT_NE(-1, forkpid);
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index 5db0e5fed..4b1e51dde 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -44,6 +44,9 @@
44#include <private/android_filesystem_config.h> 44#include <private/android_filesystem_config.h>
45#include <procinfo/process.h> 45#include <procinfo/process.h>
46 46
47#define ATRACE_TAG ATRACE_TAG_BIONIC
48#include <utils/Trace.h>
49
47#include "backtrace.h" 50#include "backtrace.h"
48#include "tombstone.h" 51#include "tombstone.h"
49#include "utility.h" 52#include "utility.h"
@@ -101,6 +104,7 @@ static bool ptrace_seize_thread(int pid_proc_fd, pid_t tid, std::string* error)
101} 104}
102 105
103static bool activity_manager_notify(pid_t pid, int signal, const std::string& amfd_data) { 106static bool activity_manager_notify(pid_t pid, int signal, const std::string& amfd_data) {
107 ATRACE_CALL();
104 android::base::unique_fd amfd(socket_local_client( 108 android::base::unique_fd amfd(socket_local_client(
105 "/data/system/ndebugsocket", ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM)); 109 "/data/system/ndebugsocket", ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM));
106 if (amfd.get() == -1) { 110 if (amfd.get() == -1) {
@@ -176,6 +180,7 @@ static void abort_handler(pid_t target, const bool tombstoned_connected,
176} 180}
177 181
178static void drop_capabilities() { 182static void drop_capabilities() {
183 ATRACE_CALL();
179 __user_cap_header_struct capheader; 184 __user_cap_header_struct capheader;
180 memset(&capheader, 0, sizeof(capheader)); 185 memset(&capheader, 0, sizeof(capheader));
181 capheader.version = _LINUX_CAPABILITY_VERSION_3; 186 capheader.version = _LINUX_CAPABILITY_VERSION_3;
@@ -194,6 +199,8 @@ static void drop_capabilities() {
194} 199}
195 200
196int main(int argc, char** argv) { 201int main(int argc, char** argv) {
202 atrace_begin(ATRACE_TAG, "before reparent");
203
197 pid_t target = getppid(); 204 pid_t target = getppid();
198 bool tombstoned_connected = false; 205 bool tombstoned_connected = false;
199 unique_fd tombstoned_socket; 206 unique_fd tombstoned_socket;
@@ -261,6 +268,8 @@ int main(int argc, char** argv) {
261 PLOG(FATAL) << "parent died"; 268 PLOG(FATAL) << "parent died";
262 } 269 }
263 270
271 atrace_end(ATRACE_TAG);
272
264 // Reparent ourselves to init, so that the signal handler can waitpid on the 273 // Reparent ourselves to init, so that the signal handler can waitpid on the
265 // original process to avoid leaving a zombie for non-fatal dumps. 274 // original process to avoid leaving a zombie for non-fatal dumps.
266 pid_t forkpid = fork(); 275 pid_t forkpid = fork();
@@ -270,6 +279,8 @@ int main(int argc, char** argv) {
270 exit(0); 279 exit(0);
271 } 280 }
272 281
282 ATRACE_NAME("after reparent");
283
273 // Die if we take too long. 284 // Die if we take too long.
274 // 285 //
275 // Note: processes with many threads and minidebug-info can take a bit to 286 // Note: processes with many threads and minidebug-info can take a bit to
@@ -278,42 +289,53 @@ int main(int argc, char** argv) {
278 289
279 std::string attach_error; 290 std::string attach_error;
280 291
281 // Seize the main thread.
282 if (!ptrace_seize_thread(target_proc_fd, main_tid, &attach_error)) {
283 LOG(FATAL) << attach_error;
284 }
285
286 // Seize the siblings.
287 std::map<pid_t, std::string> threads; 292 std::map<pid_t, std::string> threads;
293
288 { 294 {
289 std::set<pid_t> siblings; 295 ATRACE_NAME("ptrace");
290 if (!android::procinfo::GetProcessTids(target, &siblings)) { 296 // Seize the main thread.
291 PLOG(FATAL) << "failed to get process siblings"; 297 if (!ptrace_seize_thread(target_proc_fd, main_tid, &attach_error)) {
298 LOG(FATAL) << attach_error;
292 } 299 }
293 300
294 // but not the already attached main thread. 301 // Seize the siblings.
295 siblings.erase(main_tid); 302 {
296 // or the handler pseudothread. 303 std::set<pid_t> siblings;
297 siblings.erase(pseudothread_tid); 304 if (!android::procinfo::GetProcessTids(target, &siblings)) {
305 PLOG(FATAL) << "failed to get process siblings";
306 }
298 307
299 for (pid_t sibling_tid : siblings) { 308 // but not the already attached main thread.
300 if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) { 309 siblings.erase(main_tid);
301 LOG(WARNING) << attach_error; 310 // or the handler pseudothread.
302 } else { 311 siblings.erase(pseudothread_tid);
303 threads.emplace(sibling_tid, get_thread_name(sibling_tid)); 312
313 for (pid_t sibling_tid : siblings) {
314 if (!ptrace_seize_thread(target_proc_fd, sibling_tid, &attach_error)) {
315 LOG(WARNING) << attach_error;
316 } else {
317 threads.emplace(sibling_tid, get_thread_name(sibling_tid));
318 }
304 } 319 }
305 } 320 }
306 } 321 }
307 322
308 // Collect the backtrace map, open files, and process/thread names, while we still have caps. 323 // Collect the backtrace map, open files, and process/thread names, while we still have caps.
309 std::unique_ptr<BacktraceMap> backtrace_map(BacktraceMap::Create(main_tid)); 324 std::unique_ptr<BacktraceMap> backtrace_map;
310 if (!backtrace_map) { 325 {
311 LOG(FATAL) << "failed to create backtrace map"; 326 ATRACE_NAME("backtrace map");
327 backtrace_map.reset(BacktraceMap::Create(main_tid));
328 if (!backtrace_map) {
329 LOG(FATAL) << "failed to create backtrace map";
330 }
312 } 331 }
313 332
314 // Collect the list of open files. 333 // Collect the list of open files.
315 OpenFilesList open_files; 334 OpenFilesList open_files;
316 populate_open_files_list(target, &open_files); 335 {
336 ATRACE_NAME("open files");
337 populate_open_files_list(target, &open_files);
338 }
317 339
318 std::string process_name = get_process_name(main_tid); 340 std::string process_name = get_process_name(main_tid);
319 threads.emplace(main_tid, get_thread_name(main_tid)); 341 threads.emplace(main_tid, get_thread_name(main_tid));
@@ -321,9 +343,12 @@ int main(int argc, char** argv) {
321 // Drop our capabilities now that we've attached to the threads we care about. 343 // Drop our capabilities now that we've attached to the threads we care about.
322 drop_capabilities(); 344 drop_capabilities();
323 345
324 const DebuggerdDumpType dump_type_enum = static_cast<DebuggerdDumpType>(dump_type); 346 {
325 LOG(INFO) << "obtaining output fd from tombstoned, type: " << dump_type_enum; 347 ATRACE_NAME("tombstoned_connect");
326 tombstoned_connected = tombstoned_connect(target, &tombstoned_socket, &output_fd, dump_type_enum); 348 const DebuggerdDumpType dump_type_enum = static_cast<DebuggerdDumpType>(dump_type);
349 LOG(INFO) << "obtaining output fd from tombstoned, type: " << dump_type_enum;
350 tombstoned_connected = tombstoned_connect(target, &tombstoned_socket, &output_fd, dump_type_enum);
351 }
327 352
328 // Write a '\1' to stdout to tell the crashing process to resume. 353 // Write a '\1' to stdout to tell the crashing process to resume.
329 // It also restores the value of PR_SET_DUMPABLE at this point. 354 // It also restores the value of PR_SET_DUMPABLE at this point.
@@ -352,9 +377,12 @@ int main(int argc, char** argv) {
352 } 377 }
353 378
354 siginfo_t siginfo = {}; 379 siginfo_t siginfo = {};
355 if (!wait_for_signal(main_tid, &siginfo)) { 380 {
356 printf("failed to wait for signal in tid %d: %s\n", main_tid, strerror(errno)); 381 ATRACE_NAME("wait_for_signal");
357 exit(1); 382 if (!wait_for_signal(main_tid, &siginfo)) {
383 printf("failed to wait for signal in tid %d: %s\n", main_tid, strerror(errno));
384 exit(1);
385 }
358 } 386 }
359 387
360 int signo = siginfo.si_signo; 388 int signo = siginfo.si_signo;
@@ -376,8 +404,10 @@ int main(int argc, char** argv) {
376 404
377 std::string amfd_data; 405 std::string amfd_data;
378 if (backtrace) { 406 if (backtrace) {
407 ATRACE_NAME("dump_backtrace");
379 dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, process_name, threads, 0); 408 dump_backtrace(output_fd.get(), backtrace_map.get(), target, main_tid, process_name, threads, 0);
380 } else { 409 } else {
410 ATRACE_NAME("engrave_tombstone");
381 engrave_tombstone(output_fd.get(), backtrace_map.get(), &open_files, target, main_tid, 411 engrave_tombstone(output_fd.get(), backtrace_map.get(), &open_files, target, main_tid,
382 process_name, threads, abort_address, fatal_signal ? &amfd_data : nullptr); 412 process_name, threads, abort_address, fatal_signal ? &amfd_data : nullptr);
383 } 413 }
diff --git a/debuggerd/crasher/crasher.cpp b/debuggerd/crasher/crasher.cpp
index 697020171..f57349b16 100644
--- a/debuggerd/crasher/crasher.cpp
+++ b/debuggerd/crasher/crasher.cpp
@@ -134,6 +134,14 @@ noinline void abuse_heap() {
134 free(buf); // GCC is smart enough to warn about this, but we're doing it deliberately. 134 free(buf); // GCC is smart enough to warn about this, but we're doing it deliberately.
135} 135}
136 136
137noinline void leak() {
138 while (true) {
139 void* mapping =
140 mmap(nullptr, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
141 static_cast<volatile char*>(mapping)[0] = 'a';
142 }
143}
144
137noinline void sigsegv_non_null() { 145noinline void sigsegv_non_null() {
138 int* a = (int *)(&do_action); 146 int* a = (int *)(&do_action);
139 *a = 42; 147 *a = 42;
@@ -160,8 +168,8 @@ static int usage() {
160 fprintf(stderr, " stack-overflow recurse until the stack overflows\n"); 168 fprintf(stderr, " stack-overflow recurse until the stack overflows\n");
161 fprintf(stderr, " nostack crash with a NULL stack pointer\n"); 169 fprintf(stderr, " nostack crash with a NULL stack pointer\n");
162 fprintf(stderr, "\n"); 170 fprintf(stderr, "\n");
163 fprintf(stderr, " heap-corruption cause a libc abort by corrupting the heap\n");
164 fprintf(stderr, " heap-usage cause a libc abort by abusing a heap function\n"); 171 fprintf(stderr, " heap-usage cause a libc abort by abusing a heap function\n");
172 fprintf(stderr, " leak leak memory until we get OOM-killed\n");
165 fprintf(stderr, "\n"); 173 fprintf(stderr, "\n");
166 fprintf(stderr, " abort call abort()\n"); 174 fprintf(stderr, " abort call abort()\n");
167 fprintf(stderr, " assert call assert() without a function\n"); 175 fprintf(stderr, " assert call assert() without a function\n");
@@ -265,6 +273,8 @@ noinline int do_action(const char* arg) {
265 return pthread_join(0, nullptr); 273 return pthread_join(0, nullptr);
266 } else if (!strcasecmp(arg, "heap-usage")) { 274 } else if (!strcasecmp(arg, "heap-usage")) {
267 abuse_heap(); 275 abuse_heap();
276 } else if (!strcasecmp(arg, "leak")) {
277 leak();
268 } else if (!strcasecmp(arg, "SIGSEGV-unmapped")) { 278 } else if (!strcasecmp(arg, "SIGSEGV-unmapped")) {
269 char* map = reinterpret_cast<char*>(mmap(nullptr, sizeof(int), PROT_READ | PROT_WRITE, 279 char* map = reinterpret_cast<char*>(mmap(nullptr, sizeof(int), PROT_READ | PROT_WRITE,
270 MAP_SHARED | MAP_ANONYMOUS, -1, 0)); 280 MAP_SHARED | MAP_ANONYMOUS, -1, 0));
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 6298ace9d..b016e23ee 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -27,7 +27,7 @@
27#include <android-base/parseint.h> 27#include <android-base/parseint.h>
28#include <android-base/unique_fd.h> 28#include <android-base/unique_fd.h>
29#include <debuggerd/client.h> 29#include <debuggerd/client.h>
30#include <selinux/selinux.h> 30#include <procinfo/process.h>
31#include "util.h" 31#include "util.h"
32 32
33using android::base::unique_fd; 33using android::base::unique_fd;
@@ -66,6 +66,24 @@ int main(int argc, char* argv[]) {
66 usage(1); 66 usage(1);
67 } 67 }
68 68
69 if (getuid() != 0) {
70 errx(1, "root is required");
71 }
72
73 // Check to see if the process exists and that we can actually send a signal to it.
74 android::procinfo::ProcessInfo proc_info;
75 if (!android::procinfo::GetProcessInfo(pid, &proc_info)) {
76 err(1, "failed to fetch info for process %d", pid);
77 }
78
79 if (proc_info.state == android::procinfo::kProcessStateZombie) {
80 errx(1, "process %d is a zombie", pid);
81 }
82
83 if (kill(pid, 0) != 0) {
84 err(1, "cannot send signal to process %d", pid);
85 }
86
69 unique_fd piperead, pipewrite; 87 unique_fd piperead, pipewrite;
70 if (!Pipe(&piperead, &pipewrite)) { 88 if (!Pipe(&piperead, &pipewrite)) {
71 err(1, "failed to create pipe"); 89 err(1, "failed to create pipe");
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 201515761..b51fc665e 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -88,8 +88,12 @@ constexpr char kWaitForGdbKey[] = "debug.debuggerd.wait_for_gdb";
88 } \ 88 } \
89 } while (0) 89 } while (0)
90 90
91#define ASSERT_BACKTRACE_FRAME(result, frame_name) \
92 ASSERT_MATCH(result, R"(#\d\d pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX \
93 R"(/libc.so \()" frame_name R"(\+)")
94
91static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, unique_fd* output_fd, 95static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, unique_fd* output_fd,
92 DebuggerdDumpType intercept_type) { 96 InterceptStatus* status, DebuggerdDumpType intercept_type) {
93 intercept_fd->reset(socket_local_client(kTombstonedInterceptSocketName, 97 intercept_fd->reset(socket_local_client(kTombstonedInterceptSocketName,
94 ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET)); 98 ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_SEQPACKET));
95 if (intercept_fd->get() == -1) { 99 if (intercept_fd->get() == -1) {
@@ -136,7 +140,7 @@ static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, uniq
136 << ", received " << rc; 140 << ", received " << rc;
137 } 141 }
138 142
139 ASSERT_EQ(InterceptStatus::kRegistered, response.status); 143 *status = response.status;
140} 144}
141 145
142class CrasherTest : public ::testing::Test { 146class CrasherTest : public ::testing::Test {
@@ -180,7 +184,9 @@ void CrasherTest::StartIntercept(unique_fd* output_fd, DebuggerdDumpType interce
180 FAIL() << "crasher hasn't been started"; 184 FAIL() << "crasher hasn't been started";
181 } 185 }
182 186
183 tombstoned_intercept(crasher_pid, &this->intercept_fd, output_fd, intercept_type); 187 InterceptStatus status;
188 tombstoned_intercept(crasher_pid, &this->intercept_fd, output_fd, &status, intercept_type);
189 ASSERT_EQ(InterceptStatus::kRegistered, status);
184} 190}
185 191
186void CrasherTest::FinishIntercept(int* result) { 192void CrasherTest::FinishIntercept(int* result) {
@@ -305,7 +311,7 @@ TEST_F(CrasherTest, abort) {
305 311
306 std::string result; 312 std::string result;
307 ConsumeFd(std::move(output_fd), &result); 313 ConsumeFd(std::move(output_fd), &result);
308 ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(abort)"); 314 ASSERT_BACKTRACE_FRAME(result, "abort");
309} 315}
310 316
311TEST_F(CrasherTest, signal) { 317TEST_F(CrasherTest, signal) {
@@ -441,7 +447,7 @@ TEST_F(CrasherTest, backtrace) {
441 FinishIntercept(&intercept_result); 447 FinishIntercept(&intercept_result);
442 ASSERT_EQ(1, intercept_result) << "tombstoned reported failure"; 448 ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
443 ConsumeFd(std::move(output_fd), &result); 449 ConsumeFd(std::move(output_fd), &result);
444 ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(read\+)"); 450 ASSERT_BACKTRACE_FRAME(result, "read");
445 451
446 int status; 452 int status;
447 ASSERT_EQ(0, waitpid(crasher_pid, &status, WNOHANG | WUNTRACED)); 453 ASSERT_EQ(0, waitpid(crasher_pid, &status, WNOHANG | WUNTRACED));
@@ -452,7 +458,7 @@ TEST_F(CrasherTest, backtrace) {
452 FinishIntercept(&intercept_result); 458 FinishIntercept(&intercept_result);
453 ASSERT_EQ(1, intercept_result) << "tombstoned reported failure"; 459 ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
454 ConsumeFd(std::move(output_fd), &result); 460 ConsumeFd(std::move(output_fd), &result);
455 ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(abort)"); 461 ASSERT_BACKTRACE_FRAME(result, "abort");
456} 462}
457 463
458TEST_F(CrasherTest, PR_SET_DUMPABLE_0_crash) { 464TEST_F(CrasherTest, PR_SET_DUMPABLE_0_crash) {
@@ -472,7 +478,7 @@ TEST_F(CrasherTest, PR_SET_DUMPABLE_0_crash) {
472 478
473 std::string result; 479 std::string result;
474 ConsumeFd(std::move(output_fd), &result); 480 ConsumeFd(std::move(output_fd), &result);
475 ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(abort)"); 481 ASSERT_BACKTRACE_FRAME(result, "abort");
476} 482}
477 483
478TEST_F(CrasherTest, capabilities) { 484TEST_F(CrasherTest, capabilities) {
@@ -529,7 +535,7 @@ TEST_F(CrasherTest, capabilities) {
529 ASSERT_EQ(1, intercept_result) << "tombstoned reported failure"; 535 ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
530 ConsumeFd(std::move(output_fd), &result); 536 ConsumeFd(std::move(output_fd), &result);
531 ASSERT_MATCH(result, R"(name: thread_name\s+>>> .+debuggerd_test(32|64) <<<)"); 537 ASSERT_MATCH(result, R"(name: thread_name\s+>>> .+debuggerd_test(32|64) <<<)");
532 ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(tgkill)"); 538 ASSERT_BACKTRACE_FRAME(result, "tgkill");
533} 539}
534 540
535TEST_F(CrasherTest, fake_pid) { 541TEST_F(CrasherTest, fake_pid) {
@@ -560,7 +566,7 @@ TEST_F(CrasherTest, fake_pid) {
560 566
561 std::string result; 567 std::string result;
562 ConsumeFd(std::move(output_fd), &result); 568 ConsumeFd(std::move(output_fd), &result);
563 ASSERT_MATCH(result, R"(#00 pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX R"(/libc.so \(tgkill)"); 569 ASSERT_BACKTRACE_FRAME(result, "tgkill");
564} 570}
565 571
566TEST(crash_dump, zombie) { 572TEST(crash_dump, zombie) {
@@ -598,7 +604,9 @@ TEST(tombstoned, no_notify) {
598 pid_t pid = 123'456'789 + i; 604 pid_t pid = 123'456'789 + i;
599 605
600 unique_fd intercept_fd, output_fd; 606 unique_fd intercept_fd, output_fd;
601 tombstoned_intercept(pid, &intercept_fd, &output_fd, kDebuggerdTombstone); 607 InterceptStatus status;
608 tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone);
609 ASSERT_EQ(InterceptStatus::kRegistered, status);
602 610
603 { 611 {
604 unique_fd tombstoned_socket, input_fd; 612 unique_fd tombstoned_socket, input_fd;
@@ -630,7 +638,9 @@ TEST(tombstoned, stress) {
630 pid_t pid = pid_base + dump; 638 pid_t pid = pid_base + dump;
631 639
632 unique_fd intercept_fd, output_fd; 640 unique_fd intercept_fd, output_fd;
633 tombstoned_intercept(pid, &intercept_fd, &output_fd, kDebuggerdTombstone); 641 InterceptStatus status;
642 tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone);
643 ASSERT_EQ(InterceptStatus::kRegistered, status);
634 644
635 // Pretend to crash, and then immediately close the socket. 645 // Pretend to crash, and then immediately close the socket.
636 unique_fd sockfd(socket_local_client(kTombstonedCrashSocketName, 646 unique_fd sockfd(socket_local_client(kTombstonedCrashSocketName,
@@ -661,7 +671,9 @@ TEST(tombstoned, stress) {
661 pid_t pid = pid_base + dump; 671 pid_t pid = pid_base + dump;
662 672
663 unique_fd intercept_fd, output_fd; 673 unique_fd intercept_fd, output_fd;
664 tombstoned_intercept(pid, &intercept_fd, &output_fd, kDebuggerdTombstone); 674 InterceptStatus status;
675 tombstoned_intercept(pid, &intercept_fd, &output_fd, &status, kDebuggerdTombstone);
676 ASSERT_EQ(InterceptStatus::kRegistered, status);
665 677
666 { 678 {
667 unique_fd tombstoned_socket, input_fd; 679 unique_fd tombstoned_socket, input_fd;
@@ -685,3 +697,65 @@ TEST(tombstoned, stress) {
685 thread.join(); 697 thread.join();
686 } 698 }
687} 699}
700
701TEST(tombstoned, java_trace_intercept_smoke) {
702 // Using a "real" PID is a little dangerous here - if the test fails
703 // or crashes, we might end up getting a bogus / unreliable stack
704 // trace.
705 const pid_t self = getpid();
706
707 unique_fd intercept_fd, output_fd;
708 InterceptStatus status;
709 tombstoned_intercept(self, &intercept_fd, &output_fd, &status, kDebuggerdJavaBacktrace);
710 ASSERT_EQ(InterceptStatus::kRegistered, status);
711
712 // First connect to tombstoned requesting a native backtrace. This
713 // should result in a "regular" FD and not the installed intercept.
714 const char native[] = "native";
715 unique_fd tombstoned_socket, input_fd;
716 ASSERT_TRUE(tombstoned_connect(self, &tombstoned_socket, &input_fd, kDebuggerdNativeBacktrace));
717 ASSERT_TRUE(android::base::WriteFully(input_fd.get(), native, sizeof(native)));
718 tombstoned_notify_completion(tombstoned_socket.get());
719
720 // Then, connect to tombstoned asking for a java backtrace. This *should*
721 // trigger the intercept.
722 const char java[] = "java";
723 ASSERT_TRUE(tombstoned_connect(self, &tombstoned_socket, &input_fd, kDebuggerdJavaBacktrace));
724 ASSERT_TRUE(android::base::WriteFully(input_fd.get(), java, sizeof(java)));
725 tombstoned_notify_completion(tombstoned_socket.get());
726
727 char outbuf[sizeof(java)];
728 ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf)));
729 ASSERT_STREQ("java", outbuf);
730}
731
732TEST(tombstoned, multiple_intercepts) {
733 const pid_t fake_pid = 1'234'567;
734 unique_fd intercept_fd, output_fd;
735 InterceptStatus status;
736 tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &status, kDebuggerdJavaBacktrace);
737 ASSERT_EQ(InterceptStatus::kRegistered, status);
738
739 unique_fd intercept_fd_2, output_fd_2;
740 tombstoned_intercept(fake_pid, &intercept_fd_2, &output_fd_2, &status, kDebuggerdNativeBacktrace);
741 ASSERT_EQ(InterceptStatus::kFailedAlreadyRegistered, status);
742}
743
744TEST(tombstoned, intercept_any) {
745 const pid_t fake_pid = 1'234'567;
746
747 unique_fd intercept_fd, output_fd;
748 InterceptStatus status;
749 tombstoned_intercept(fake_pid, &intercept_fd, &output_fd, &status, kDebuggerdNativeBacktrace);
750 ASSERT_EQ(InterceptStatus::kRegistered, status);
751
752 const char any[] = "any";
753 unique_fd tombstoned_socket, input_fd;
754 ASSERT_TRUE(tombstoned_connect(fake_pid, &tombstoned_socket, &input_fd, kDebuggerdAnyIntercept));
755 ASSERT_TRUE(android::base::WriteFully(input_fd.get(), any, sizeof(any)));
756 tombstoned_notify_completion(tombstoned_socket.get());
757
758 char outbuf[sizeof(any)];
759 ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf)));
760 ASSERT_STREQ("any", outbuf);
761}
diff --git a/debuggerd/libdebuggerd/test/tombstone_test.cpp b/debuggerd/libdebuggerd/test/tombstone_test.cpp
index 325210d94..6be59e7ac 100644
--- a/debuggerd/libdebuggerd/test/tombstone_test.cpp
+++ b/debuggerd/libdebuggerd/test/tombstone_test.cpp
@@ -220,21 +220,21 @@ TEST_F(TombstoneTest, multiple_maps) {
220 map.start = 0xa434000; 220 map.start = 0xa434000;
221 map.end = 0xa435000; 221 map.end = 0xa435000;
222 map.offset = 0x1000; 222 map.offset = 0x1000;
223 map.load_base = 0xd000; 223 map.load_bias = 0xd000;
224 map.flags = PROT_WRITE; 224 map.flags = PROT_WRITE;
225 map_mock_->AddMap(map); 225 map_mock_->AddMap(map);
226 226
227 map.start = 0xa534000; 227 map.start = 0xa534000;
228 map.end = 0xa535000; 228 map.end = 0xa535000;
229 map.offset = 0x3000; 229 map.offset = 0x3000;
230 map.load_base = 0x2000; 230 map.load_bias = 0x2000;
231 map.flags = PROT_EXEC; 231 map.flags = PROT_EXEC;
232 map_mock_->AddMap(map); 232 map_mock_->AddMap(map);
233 233
234 map.start = 0xa634000; 234 map.start = 0xa634000;
235 map.end = 0xa635000; 235 map.end = 0xa635000;
236 map.offset = 0; 236 map.offset = 0;
237 map.load_base = 0; 237 map.load_bias = 0;
238 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC; 238 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
239 map.name = "/system/lib/fake.so"; 239 map.name = "/system/lib/fake.so";
240 map_mock_->AddMap(map); 240 map_mock_->AddMap(map);
@@ -244,20 +244,20 @@ TEST_F(TombstoneTest, multiple_maps) {
244 std::string tombstone_contents; 244 std::string tombstone_contents;
245 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 245 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
246 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); 246 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
247 const char* expected_dump = \ 247 const char* expected_dump =
248"\nmemory map:\n" 248 "\nmemory map:\n"
249#if defined(__LP64__) 249#if defined(__LP64__)
250" 00000000'0a234000-00000000'0a234fff --- 0 1000\n" 250 " 00000000'0a234000-00000000'0a234fff --- 0 1000\n"
251" 00000000'0a334000-00000000'0a334fff r-- f000 1000\n" 251 " 00000000'0a334000-00000000'0a334fff r-- f000 1000\n"
252" 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n" 252 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load bias 0xd000)\n"
253" 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n" 253 " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load bias 0x2000)\n"
254" 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n"; 254 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
255#else 255#else
256" 0a234000-0a234fff --- 0 1000\n" 256 " 0a234000-0a234fff --- 0 1000\n"
257" 0a334000-0a334fff r-- f000 1000\n" 257 " 0a334000-0a334fff r-- f000 1000\n"
258" 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n" 258 " 0a434000-0a434fff -w- 1000 1000 (load bias 0xd000)\n"
259" 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n" 259 " 0a534000-0a534fff --x 3000 1000 (load bias 0x2000)\n"
260" 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n"; 260 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
261#endif 261#endif
262 ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); 262 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
263 263
@@ -274,21 +274,21 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_before) {
274 map.start = 0xa434000; 274 map.start = 0xa434000;
275 map.end = 0xa435000; 275 map.end = 0xa435000;
276 map.offset = 0x1000; 276 map.offset = 0x1000;
277 map.load_base = 0xd000; 277 map.load_bias = 0xd000;
278 map.flags = PROT_WRITE; 278 map.flags = PROT_WRITE;
279 map_mock_->AddMap(map); 279 map_mock_->AddMap(map);
280 280
281 map.start = 0xa534000; 281 map.start = 0xa534000;
282 map.end = 0xa535000; 282 map.end = 0xa535000;
283 map.offset = 0x3000; 283 map.offset = 0x3000;
284 map.load_base = 0x2000; 284 map.load_bias = 0x2000;
285 map.flags = PROT_EXEC; 285 map.flags = PROT_EXEC;
286 map_mock_->AddMap(map); 286 map_mock_->AddMap(map);
287 287
288 map.start = 0xa634000; 288 map.start = 0xa634000;
289 map.end = 0xa635000; 289 map.end = 0xa635000;
290 map.offset = 0; 290 map.offset = 0;
291 map.load_base = 0; 291 map.load_bias = 0;
292 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC; 292 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
293 map.name = "/system/lib/fake.so"; 293 map.name = "/system/lib/fake.so";
294 map_mock_->AddMap(map); 294 map_mock_->AddMap(map);
@@ -304,18 +304,18 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_before) {
304 std::string tombstone_contents; 304 std::string tombstone_contents;
305 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 305 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
306 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); 306 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
307 const char* expected_dump = \ 307 const char* expected_dump =
308"\nmemory map: (fault address prefixed with --->)\n" 308 "\nmemory map: (fault address prefixed with --->)\n"
309#if defined(__LP64__) 309#if defined(__LP64__)
310"--->Fault address falls at 00000000'00001000 before any mapped regions\n" 310 "--->Fault address falls at 00000000'00001000 before any mapped regions\n"
311" 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n" 311 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load bias 0xd000)\n"
312" 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n" 312 " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load bias 0x2000)\n"
313" 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n"; 313 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
314#else 314#else
315"--->Fault address falls at 00001000 before any mapped regions\n" 315 "--->Fault address falls at 00001000 before any mapped regions\n"
316" 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n" 316 " 0a434000-0a434fff -w- 1000 1000 (load bias 0xd000)\n"
317" 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n" 317 " 0a534000-0a534fff --x 3000 1000 (load bias 0x2000)\n"
318" 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n"; 318 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
319#endif 319#endif
320 ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); 320 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
321 321
@@ -332,21 +332,21 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_between) {
332 map.start = 0xa434000; 332 map.start = 0xa434000;
333 map.end = 0xa435000; 333 map.end = 0xa435000;
334 map.offset = 0x1000; 334 map.offset = 0x1000;
335 map.load_base = 0xd000; 335 map.load_bias = 0xd000;
336 map.flags = PROT_WRITE; 336 map.flags = PROT_WRITE;
337 map_mock_->AddMap(map); 337 map_mock_->AddMap(map);
338 338
339 map.start = 0xa534000; 339 map.start = 0xa534000;
340 map.end = 0xa535000; 340 map.end = 0xa535000;
341 map.offset = 0x3000; 341 map.offset = 0x3000;
342 map.load_base = 0x2000; 342 map.load_bias = 0x2000;
343 map.flags = PROT_EXEC; 343 map.flags = PROT_EXEC;
344 map_mock_->AddMap(map); 344 map_mock_->AddMap(map);
345 345
346 map.start = 0xa634000; 346 map.start = 0xa634000;
347 map.end = 0xa635000; 347 map.end = 0xa635000;
348 map.offset = 0; 348 map.offset = 0;
349 map.load_base = 0; 349 map.load_bias = 0;
350 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC; 350 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
351 map.name = "/system/lib/fake.so"; 351 map.name = "/system/lib/fake.so";
352 map_mock_->AddMap(map); 352 map_mock_->AddMap(map);
@@ -362,18 +362,18 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_between) {
362 std::string tombstone_contents; 362 std::string tombstone_contents;
363 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 363 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
364 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); 364 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
365 const char* expected_dump = \ 365 const char* expected_dump =
366"\nmemory map: (fault address prefixed with --->)\n" 366 "\nmemory map: (fault address prefixed with --->)\n"
367#if defined(__LP64__) 367#if defined(__LP64__)
368" 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n" 368 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load bias 0xd000)\n"
369"--->Fault address falls at 00000000'0a533000 between mapped regions\n" 369 "--->Fault address falls at 00000000'0a533000 between mapped regions\n"
370" 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n" 370 " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load bias 0x2000)\n"
371" 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n"; 371 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
372#else 372#else
373" 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n" 373 " 0a434000-0a434fff -w- 1000 1000 (load bias 0xd000)\n"
374"--->Fault address falls at 0a533000 between mapped regions\n" 374 "--->Fault address falls at 0a533000 between mapped regions\n"
375" 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n" 375 " 0a534000-0a534fff --x 3000 1000 (load bias 0x2000)\n"
376" 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n"; 376 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
377#endif 377#endif
378 ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); 378 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
379 379
@@ -390,21 +390,21 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_in_map) {
390 map.start = 0xa434000; 390 map.start = 0xa434000;
391 map.end = 0xa435000; 391 map.end = 0xa435000;
392 map.offset = 0x1000; 392 map.offset = 0x1000;
393 map.load_base = 0xd000; 393 map.load_bias = 0xd000;
394 map.flags = PROT_WRITE; 394 map.flags = PROT_WRITE;
395 map_mock_->AddMap(map); 395 map_mock_->AddMap(map);
396 396
397 map.start = 0xa534000; 397 map.start = 0xa534000;
398 map.end = 0xa535000; 398 map.end = 0xa535000;
399 map.offset = 0x3000; 399 map.offset = 0x3000;
400 map.load_base = 0x2000; 400 map.load_bias = 0x2000;
401 map.flags = PROT_EXEC; 401 map.flags = PROT_EXEC;
402 map_mock_->AddMap(map); 402 map_mock_->AddMap(map);
403 403
404 map.start = 0xa634000; 404 map.start = 0xa634000;
405 map.end = 0xa635000; 405 map.end = 0xa635000;
406 map.offset = 0; 406 map.offset = 0;
407 map.load_base = 0; 407 map.load_bias = 0;
408 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC; 408 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
409 map.name = "/system/lib/fake.so"; 409 map.name = "/system/lib/fake.so";
410 map_mock_->AddMap(map); 410 map_mock_->AddMap(map);
@@ -420,16 +420,16 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_in_map) {
420 std::string tombstone_contents; 420 std::string tombstone_contents;
421 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 421 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
422 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); 422 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
423 const char* expected_dump = \ 423 const char* expected_dump =
424"\nmemory map: (fault address prefixed with --->)\n" 424 "\nmemory map: (fault address prefixed with --->)\n"
425#if defined(__LP64__) 425#if defined(__LP64__)
426" 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n" 426 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load bias 0xd000)\n"
427"--->00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n" 427 "--->00000000'0a534000-00000000'0a534fff --x 3000 1000 (load bias 0x2000)\n"
428" 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n"; 428 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n";
429#else 429#else
430" 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n" 430 " 0a434000-0a434fff -w- 1000 1000 (load bias 0xd000)\n"
431"--->0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n" 431 "--->0a534000-0a534fff --x 3000 1000 (load bias 0x2000)\n"
432" 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n"; 432 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n";
433#endif 433#endif
434 ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); 434 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
435 435
@@ -446,21 +446,21 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_after) {
446 map.start = 0xa434000; 446 map.start = 0xa434000;
447 map.end = 0xa435000; 447 map.end = 0xa435000;
448 map.offset = 0x1000; 448 map.offset = 0x1000;
449 map.load_base = 0xd000; 449 map.load_bias = 0xd000;
450 map.flags = PROT_WRITE; 450 map.flags = PROT_WRITE;
451 map_mock_->AddMap(map); 451 map_mock_->AddMap(map);
452 452
453 map.start = 0xa534000; 453 map.start = 0xa534000;
454 map.end = 0xa535000; 454 map.end = 0xa535000;
455 map.offset = 0x3000; 455 map.offset = 0x3000;
456 map.load_base = 0x2000; 456 map.load_bias = 0x2000;
457 map.flags = PROT_EXEC; 457 map.flags = PROT_EXEC;
458 map_mock_->AddMap(map); 458 map_mock_->AddMap(map);
459 459
460 map.start = 0xa634000; 460 map.start = 0xa634000;
461 map.end = 0xa635000; 461 map.end = 0xa635000;
462 map.offset = 0; 462 map.offset = 0;
463 map.load_base = 0; 463 map.load_bias = 0;
464 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC; 464 map.flags = PROT_READ | PROT_WRITE | PROT_EXEC;
465 map.name = "/system/lib/fake.so"; 465 map.name = "/system/lib/fake.so";
466 map_mock_->AddMap(map); 466 map_mock_->AddMap(map);
@@ -480,18 +480,18 @@ TEST_F(TombstoneTest, multiple_maps_fault_address_after) {
480 std::string tombstone_contents; 480 std::string tombstone_contents;
481 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 481 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
482 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); 482 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
483 const char* expected_dump = \ 483 const char* expected_dump =
484"\nmemory map: (fault address prefixed with --->)\n" 484 "\nmemory map: (fault address prefixed with --->)\n"
485#if defined(__LP64__) 485#if defined(__LP64__)
486" 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n" 486 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load bias 0xd000)\n"
487" 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load base 0x2000)\n" 487 " 00000000'0a534000-00000000'0a534fff --x 3000 1000 (load bias 0x2000)\n"
488" 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n" 488 " 00000000'0a634000-00000000'0a634fff rwx 0 1000 /system/lib/fake.so\n"
489"--->Fault address falls at 00001234'5a534040 after any mapped regions\n"; 489 "--->Fault address falls at 00001234'5a534040 after any mapped regions\n";
490#else 490#else
491" 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n" 491 " 0a434000-0a434fff -w- 1000 1000 (load bias 0xd000)\n"
492" 0a534000-0a534fff --x 3000 1000 (load base 0x2000)\n" 492 " 0a534000-0a534fff --x 3000 1000 (load bias 0x2000)\n"
493" 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n" 493 " 0a634000-0a634fff rwx 0 1000 /system/lib/fake.so\n"
494"--->Fault address falls at 0f534040 after any mapped regions\n"; 494 "--->Fault address falls at 0f534040 after any mapped regions\n";
495#endif 495#endif
496 ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); 496 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
497 497
@@ -508,7 +508,7 @@ TEST_F(TombstoneTest, multiple_maps_getsiginfo_fail) {
508 map.start = 0xa434000; 508 map.start = 0xa434000;
509 map.end = 0xa435000; 509 map.end = 0xa435000;
510 map.offset = 0x1000; 510 map.offset = 0x1000;
511 map.load_base = 0xd000; 511 map.load_bias = 0xd000;
512 map.flags = PROT_WRITE; 512 map.flags = PROT_WRITE;
513 map_mock_->AddMap(map); 513 map_mock_->AddMap(map);
514 514
@@ -520,12 +520,12 @@ TEST_F(TombstoneTest, multiple_maps_getsiginfo_fail) {
520 std::string tombstone_contents; 520 std::string tombstone_contents;
521 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0); 521 ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
522 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents)); 522 ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
523 const char* expected_dump = \ 523 const char* expected_dump =
524"\nmemory map:\n" 524 "\nmemory map:\n"
525#if defined(__LP64__) 525#if defined(__LP64__)
526" 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n"; 526 " 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load bias 0xd000)\n";
527#else 527#else
528" 0a434000-0a434fff -w- 1000 1000 (load base 0xd000)\n"; 528 " 0a434000-0a434fff -w- 1000 1000 (load bias 0xd000)\n";
529#endif 529#endif
530 ASSERT_STREQ(expected_dump, tombstone_contents.c_str()); 530 ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
531 531
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index edc7be5e2..011313149 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -168,6 +168,26 @@ static const char* get_sigcode(int signo, int code) {
168 case TRAP_BRANCH: return "TRAP_BRANCH"; 168 case TRAP_BRANCH: return "TRAP_BRANCH";
169 case TRAP_HWBKPT: return "TRAP_HWBKPT"; 169 case TRAP_HWBKPT: return "TRAP_HWBKPT";
170 } 170 }
171 if ((code & 0xff) == SIGTRAP) {
172 switch ((code >> 8) & 0xff) {
173 case PTRACE_EVENT_FORK:
174 return "PTRACE_EVENT_FORK";
175 case PTRACE_EVENT_VFORK:
176 return "PTRACE_EVENT_VFORK";
177 case PTRACE_EVENT_CLONE:
178 return "PTRACE_EVENT_CLONE";
179 case PTRACE_EVENT_EXEC:
180 return "PTRACE_EVENT_EXEC";
181 case PTRACE_EVENT_VFORK_DONE:
182 return "PTRACE_EVENT_VFORK_DONE";
183 case PTRACE_EVENT_EXIT:
184 return "PTRACE_EVENT_EXIT";
185 case PTRACE_EVENT_SECCOMP:
186 return "PTRACE_EVENT_SECCOMP";
187 case PTRACE_EVENT_STOP:
188 return "PTRACE_EVENT_STOP";
189 }
190 }
171 static_assert(NSIGTRAP == TRAP_HWBKPT, "missing TRAP_* si_code"); 191 static_assert(NSIGTRAP == TRAP_HWBKPT, "missing TRAP_* si_code");
172 break; 192 break;
173 } 193 }
@@ -446,11 +466,11 @@ static void dump_all_maps(Backtrace* backtrace, BacktraceMap* map, log_t* log, p
446 line += " (BuildId: " + build_id + ")"; 466 line += " (BuildId: " + build_id + ")";
447 } 467 }
448 } 468 }
449 if (it->load_base != 0) { 469 if (it->load_bias != 0) {
450 if (space_needed) { 470 if (space_needed) {
451 line += ' '; 471 line += ' ';
452 } 472 }
453 line += StringPrintf(" (load base 0x%" PRIxPTR ")", it->load_base); 473 line += StringPrintf(" (load bias 0x%" PRIxPTR ")", it->load_bias);
454 } 474 }
455 _LOG(log, logtype::MAPS, "%s\n", line.c_str()); 475 _LOG(log, logtype::MAPS, "%s\n", line.c_str());
456 } 476 }
diff --git a/debuggerd/tombstoned/tombstoned.cpp b/debuggerd/tombstoned/tombstoned.cpp
index 09cff4559..93c7fb5b8 100644
--- a/debuggerd/tombstoned/tombstoned.cpp
+++ b/debuggerd/tombstoned/tombstoned.cpp
@@ -103,7 +103,7 @@ class CrashQueue {
103 } 103 }
104 104
105 static CrashQueue* for_anrs() { 105 static CrashQueue* for_anrs() {
106 static CrashQueue queue("/data/anr", "anr_" /* file_name_prefix */, 106 static CrashQueue queue("/data/anr", "trace_" /* file_name_prefix */,
107 GetIntProperty("tombstoned.max_anr_count", 64), 107 GetIntProperty("tombstoned.max_anr_count", 64),
108 4 /* max_concurrent_dumps */); 108 4 /* max_concurrent_dumps */);
109 return &queue; 109 return &queue;
@@ -194,7 +194,7 @@ class CrashQueue {
194}; 194};
195 195
196// Whether java trace dumps are produced via tombstoned. 196// Whether java trace dumps are produced via tombstoned.
197static constexpr bool kJavaTraceDumpsEnabled = false; 197static constexpr bool kJavaTraceDumpsEnabled = true;
198 198
199// Forward declare the callbacks so they can be placed in a sensible order. 199// Forward declare the callbacks so they can be placed in a sensible order.
200static void crash_accept_cb(evconnlistener* listener, evutil_socket_t sockfd, sockaddr*, int, void*); 200static void crash_accept_cb(evconnlistener* listener, evutil_socket_t sockfd, sockaddr*, int, void*);
@@ -343,7 +343,14 @@ static void crash_completed_cb(evutil_socket_t sockfd, short ev, void* arg) {
343 } 343 }
344 344
345 if (!crash->crash_path.empty()) { 345 if (!crash->crash_path.empty()) {
346 LOG(ERROR) << "Tombstone written to: " << crash->crash_path; 346 if (crash->crash_type == kDebuggerdJavaBacktrace) {
347 LOG(ERROR) << "Traces for pid " << crash->crash_pid << " written to: " << crash->crash_path;
348 } else {
349 // NOTE: Several tools parse this log message to figure out where the
350 // tombstone associated with a given native crash was written. Any changes
351 // to this message must be carefully considered.
352 LOG(ERROR) << "Tombstone written to: " << crash->crash_path;
353 }
347 } 354 }
348 355
349fail: 356fail:
diff --git a/debuggerd/tombstoned/tombstoned.rc b/debuggerd/tombstoned/tombstoned.rc
index b8345cacf..53ef01c5f 100644
--- a/debuggerd/tombstoned/tombstoned.rc
+++ b/debuggerd/tombstoned/tombstoned.rc
@@ -7,4 +7,5 @@ service tombstoned /system/bin/tombstoned
7 7
8 socket tombstoned_crash seqpacket 0666 system system 8 socket tombstoned_crash seqpacket 0666 system system
9 socket tombstoned_intercept seqpacket 0666 system system 9 socket tombstoned_intercept seqpacket 0666 system system
10 socket tombstoned_java_trace seqpacket 0666 system system
10 writepid /dev/cpuset/system-background/tasks 11 writepid /dev/cpuset/system-background/tasks
diff --git a/demangle/Android.bp b/demangle/Android.bp
index ce617a794..e55c8869f 100644
--- a/demangle/Android.bp
+++ b/demangle/Android.bp
@@ -28,10 +28,8 @@ cc_defaults {
28 28
29cc_library { 29cc_library {
30 name: "libdemangle", 30 name: "libdemangle",
31
32 vendor_available: true,
33
34 defaults: ["libdemangle_defaults"], 31 defaults: ["libdemangle_defaults"],
32 vendor_available: true,
35 33
36 srcs: [ 34 srcs: [
37 "Demangler.cpp", 35 "Demangler.cpp",
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 80def732c..dd8bad9aa 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -40,6 +40,7 @@ LOCAL_MODULE := fastboot
40LOCAL_MODULE_TAGS := debug 40LOCAL_MODULE_TAGS := debug
41LOCAL_MODULE_HOST_OS := darwin linux windows 41LOCAL_MODULE_HOST_OS := darwin linux windows
42LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code 42LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code
43LOCAL_REQUIRED_MODULES := mke2fs e2fsdroid
43 44
44LOCAL_SRC_FILES_linux := usb_linux.cpp 45LOCAL_SRC_FILES_linux := usb_linux.cpp
45LOCAL_STATIC_LIBRARIES_linux := libselinux 46LOCAL_STATIC_LIBRARIES_linux := libselinux
@@ -85,6 +86,8 @@ LOCAL_SHARED_LIBRARIES :=
85include $(BUILD_HOST_EXECUTABLE) 86include $(BUILD_HOST_EXECUTABLE)
86 87
87my_dist_files := $(LOCAL_BUILT_MODULE) 88my_dist_files := $(LOCAL_BUILT_MODULE)
89my_dist_files += $(HOST_OUT_EXECUTABLES)/mke2fs$(HOST_EXECUTABLE_SUFFIX)
90my_dist_files += $(HOST_OUT_EXECUTABLES)/e2fsdroid$(HOST_EXECUTABLE_SUFFIX)
88ifeq ($(HOST_OS),linux) 91ifeq ($(HOST_OS),linux)
89my_dist_files += $(HOST_LIBRARY_PATH)/libf2fs_fmt_host_dyn$(HOST_SHLIB_SUFFIX) 92my_dist_files += $(HOST_LIBRARY_PATH)/libf2fs_fmt_host_dyn$(HOST_SHLIB_SUFFIX)
90endif 93endif
diff --git a/fastboot/fs.cpp b/fastboot/fs.cpp
index 99ca7dd81..f3c000eb7 100644
--- a/fastboot/fs.cpp
+++ b/fastboot/fs.cpp
@@ -10,14 +10,22 @@
10#include <string.h> 10#include <string.h>
11#include <sys/stat.h> 11#include <sys/stat.h>
12#include <sys/types.h> 12#include <sys/types.h>
13#ifndef WIN32
14#include <sys/wait.h>
15#endif
13#include <unistd.h> 16#include <unistd.h>
17#include <vector>
14 18
19#include <android-base/file.h>
20#include <android-base/stringprintf.h>
15#include <android-base/unique_fd.h> 21#include <android-base/unique_fd.h>
16#include <ext4_utils/make_ext4fs.h> 22#include <ext4_utils/make_ext4fs.h>
17#include <sparse/sparse.h> 23#include <sparse/sparse.h>
18 24
25using android::base::StringPrintf;
19using android::base::unique_fd; 26using android::base::unique_fd;
20 27
28#ifdef WIN32
21static int generate_ext4_image(const char* fileName, long long partSize, const std::string& initial_dir, 29static int generate_ext4_image(const char* fileName, long long partSize, const std::string& initial_dir,
22 unsigned eraseBlkSize, unsigned logicalBlkSize) 30 unsigned eraseBlkSize, unsigned logicalBlkSize)
23{ 31{
@@ -34,6 +42,84 @@ static int generate_ext4_image(const char* fileName, long long partSize, const s
34 } 42 }
35 return 0; 43 return 0;
36} 44}
45#else
46static int exec_e2fs_cmd(const char* path, char* const argv[]) {
47 int status;
48 pid_t child;
49 if ((child = fork()) == 0) {
50 setenv("MKE2FS_CONFIG", "", 1);
51 execvp(path, argv);
52 _exit(EXIT_FAILURE);
53 }
54 if (child < 0) {
55 fprintf(stderr, "%s failed with fork %s\n", path, strerror(errno));
56 return -1;
57 }
58 if (TEMP_FAILURE_RETRY(waitpid(child, &status, 0)) == -1) {
59 fprintf(stderr, "%s failed with waitpid %s\n", path, strerror(errno));
60 return -1;
61 }
62 int ret = -1;
63 if (WIFEXITED(status)) {
64 ret = WEXITSTATUS(status);
65 if (ret != 0) {
66 fprintf(stderr, "%s failed with status %d\n", path, ret);
67 }
68 }
69 return ret;
70}
71
72static int generate_ext4_image(const char* fileName, long long partSize,
73 const std::string& initial_dir, unsigned eraseBlkSize,
74 unsigned logicalBlkSize) {
75 static constexpr int block_size = 4096;
76 const std::string exec_dir = android::base::GetExecutableDirectory();
77
78 const std::string mke2fs_path = exec_dir + "/mke2fs";
79 std::vector<const char*> mke2fs_args = {mke2fs_path.c_str(), "-t", "ext4", "-b"};
80
81 std::string block_size_str = std::to_string(block_size);
82 mke2fs_args.push_back(block_size_str.c_str());
83
84 std::string ext_attr = "android_sparse";
85 if (eraseBlkSize != 0 && logicalBlkSize != 0) {
86 int raid_stride = logicalBlkSize / block_size;
87 int raid_stripe_width = eraseBlkSize / block_size;
88 // stride should be the max of 8kb and logical block size
89 if (logicalBlkSize != 0 && logicalBlkSize < 8192) raid_stride = 8192 / block_size;
90 ext_attr += StringPrintf(",stride=%d,stripe-width=%d", raid_stride, raid_stripe_width);
91 }
92 mke2fs_args.push_back("-E");
93 mke2fs_args.push_back(ext_attr.c_str());
94 mke2fs_args.push_back(fileName);
95
96 std::string size_str = std::to_string(partSize / block_size);
97 mke2fs_args.push_back(size_str.c_str());
98 mke2fs_args.push_back(nullptr);
99
100 int ret = exec_e2fs_cmd(mke2fs_args[0], const_cast<char**>(mke2fs_args.data()));
101 if (ret != 0) {
102 fprintf(stderr, "mke2fs failed: %d\n", ret);
103 return -1;
104 }
105
106 if (initial_dir.empty()) {
107 return 0;
108 }
109
110 const std::string e2fsdroid_path = exec_dir + "/e2fsdroid";
111 std::vector<const char*> e2fsdroid_args = {e2fsdroid_path.c_str(), "-f", initial_dir.c_str(),
112 fileName, nullptr};
113
114 ret = exec_e2fs_cmd(e2fsdroid_args[0], const_cast<char**>(e2fsdroid_args.data()));
115 if (ret != 0) {
116 fprintf(stderr, "e2fsdroid failed: %d\n", ret);
117 return -1;
118 }
119
120 return 0;
121}
122#endif
37 123
38#ifdef USE_F2FS 124#ifdef USE_F2FS
39static int generate_f2fs_image(const char* fileName, long long partSize, const std::string& initial_dir, 125static int generate_f2fs_image(const char* fileName, long long partSize, const std::string& initial_dir,
diff --git a/fs_mgr/Android.bp b/fs_mgr/Android.bp
index 4441ad0c1..7fd67c293 100644
--- a/fs_mgr/Android.bp
+++ b/fs_mgr/Android.bp
@@ -21,20 +21,6 @@ cc_defaults {
21 }, 21 },
22 local_include_dirs: ["include/"], 22 local_include_dirs: ["include/"],
23 cppflags: ["-Werror"], 23 cppflags: ["-Werror"],
24 static_libs: [
25 "libfec",
26 "libfec_rs",
27 "libbase",
28 "libcrypto_utils",
29 "libcrypto",
30 "libext4_utils",
31 "libsquashfs_utils",
32 "libselinux",
33 "libavb",
34 ],
35 whole_static_libs: [
36 "liblogwrap",
37 ],
38} 24}
39 25
40cc_library_static { 26cc_library_static {
@@ -46,12 +32,28 @@ cc_library_static {
46 "fs_mgr.cpp", 32 "fs_mgr.cpp",
47 "fs_mgr_dm_ioctl.cpp", 33 "fs_mgr_dm_ioctl.cpp",
48 "fs_mgr_format.cpp", 34 "fs_mgr_format.cpp",
49 "fs_mgr_fstab.cpp",
50 "fs_mgr_slotselect.cpp",
51 "fs_mgr_verity.cpp", 35 "fs_mgr_verity.cpp",
52 "fs_mgr_avb.cpp", 36 "fs_mgr_avb.cpp",
53 "fs_mgr_avb_ops.cpp", 37 "fs_mgr_avb_ops.cpp",
54 "fs_mgr_boot_config.cpp", 38 ],
39 static_libs: [
40 "libfec",
41 "libfec_rs",
42 "libbase",
43 "libcrypto_utils",
44 "libcrypto",
45 "libext4_utils",
46 "libsquashfs_utils",
47 "libselinux",
48 "libavb",
49 "libfstab",
50 ],
51 export_static_lib_headers: [
52 "libfstab",
53 ],
54 whole_static_libs: [
55 "liblogwrap",
56 "libfstab",
55 ], 57 ],
56 product_variables: { 58 product_variables: {
57 debuggable: { 59 debuggable: {
@@ -62,3 +64,16 @@ cc_library_static {
62 }, 64 },
63 }, 65 },
64} 66}
67
68cc_library_static {
69 name: "libfstab",
70 vendor_available: true,
71 defaults: ["fs_mgr_defaults"],
72 srcs: [
73 "fs_mgr_fstab.cpp",
74 "fs_mgr_boot_config.cpp",
75 "fs_mgr_slotselect.cpp",
76 ],
77 export_include_dirs: ["include_fstab"],
78 header_libs: ["libbase_headers"],
79}
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index e0093834b..91ed49663 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -32,6 +32,7 @@
32#include <unistd.h> 32#include <unistd.h>
33 33
34#include <memory> 34#include <memory>
35#include <thread>
35 36
36#include <android-base/file.h> 37#include <android-base/file.h>
37#include <android-base/properties.h> 38#include <android-base/properties.h>
@@ -78,43 +79,33 @@ enum FsStatFlags {
78 FS_STAT_E2FSCK_F_ALWAYS = 0x0004, 79 FS_STAT_E2FSCK_F_ALWAYS = 0x0004,
79 FS_STAT_UNCLEAN_SHUTDOWN = 0x0008, 80 FS_STAT_UNCLEAN_SHUTDOWN = 0x0008,
80 FS_STAT_QUOTA_ENABLED = 0x0010, 81 FS_STAT_QUOTA_ENABLED = 0x0010,
81 FS_STAT_TUNE2FS_FAILED = 0x0020,
82 FS_STAT_RO_MOUNT_FAILED = 0x0040, 82 FS_STAT_RO_MOUNT_FAILED = 0x0040,
83 FS_STAT_RO_UNMOUNT_FAILED = 0x0080, 83 FS_STAT_RO_UNMOUNT_FAILED = 0x0080,
84 FS_STAT_FULL_MOUNT_FAILED = 0x0100, 84 FS_STAT_FULL_MOUNT_FAILED = 0x0100,
85 FS_STAT_E2FSCK_FAILED = 0x0200, 85 FS_STAT_E2FSCK_FAILED = 0x0200,
86 FS_STAT_E2FSCK_FS_FIXED = 0x0400, 86 FS_STAT_E2FSCK_FS_FIXED = 0x0400,
87 FS_STAT_EXT4_INVALID_MAGIC = 0x0800, 87 FS_STAT_EXT4_INVALID_MAGIC = 0x0800,
88 FS_STAT_TOGGLE_QUOTAS_FAILED = 0x10000,
89 FS_STAT_SET_RESERVED_BLOCKS_FAILED = 0x20000,
90 FS_STAT_ENABLE_ENCRYPTION_FAILED = 0x40000,
88}; 91};
89 92
90/* 93// TODO: switch to inotify()
91 * gettime() - returns the time in seconds of the system's monotonic clock or 94bool fs_mgr_wait_for_file(const std::string& filename,
92 * zero on error. 95 const std::chrono::milliseconds relative_timeout) {
93 */ 96 auto start_time = std::chrono::steady_clock::now();
94static time_t gettime(void)
95{
96 struct timespec ts;
97 int ret;
98
99 ret = clock_gettime(CLOCK_MONOTONIC, &ts);
100 if (ret < 0) {
101 PERROR << "clock_gettime(CLOCK_MONOTONIC) failed";
102 return 0;
103 }
104 97
105 return ts.tv_sec; 98 while (true) {
106} 99 if (!access(filename.c_str(), F_OK) || errno != ENOENT) {
107 100 return true;
108static int wait_for_file(const char *filename, int timeout) 101 }
109{
110 struct stat info;
111 time_t timeout_time = gettime() + timeout;
112 int ret = -1;
113 102
114 while (gettime() < timeout_time && ((ret = stat(filename, &info)) < 0)) 103 std::this_thread::sleep_for(50ms);
115 usleep(10000);
116 104
117 return ret; 105 auto now = std::chrono::steady_clock::now();
106 auto time_elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time);
107 if (time_elapsed > relative_timeout) return false;
108 }
118} 109}
119 110
120static void log_fs_stat(const char* blk_device, int fs_stat) 111static void log_fs_stat(const char* blk_device, int fs_stat)
@@ -128,10 +119,16 @@ static void log_fs_stat(const char* blk_device, int fs_stat)
128 } 119 }
129} 120}
130 121
122static bool is_extfs(const std::string& fs_type) {
123 return fs_type == "ext4" || fs_type == "ext3" || fs_type == "ext2";
124}
125
131static bool should_force_check(int fs_stat) { 126static bool should_force_check(int fs_stat) {
132 return fs_stat & (FS_STAT_E2FSCK_F_ALWAYS | FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED | 127 return fs_stat &
133 FS_STAT_TUNE2FS_FAILED | FS_STAT_RO_MOUNT_FAILED | FS_STAT_RO_UNMOUNT_FAILED | 128 (FS_STAT_E2FSCK_F_ALWAYS | FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED |
134 FS_STAT_FULL_MOUNT_FAILED | FS_STAT_E2FSCK_FAILED); 129 FS_STAT_RO_MOUNT_FAILED | FS_STAT_RO_UNMOUNT_FAILED | FS_STAT_FULL_MOUNT_FAILED |
130 FS_STAT_E2FSCK_FAILED | FS_STAT_TOGGLE_QUOTAS_FAILED |
131 FS_STAT_SET_RESERVED_BLOCKS_FAILED | FS_STAT_ENABLE_ENCRYPTION_FAILED);
135} 132}
136 133
137static void check_fs(const char *blk_device, char *fs_type, char *target, int *fs_stat) 134static void check_fs(const char *blk_device, char *fs_type, char *target, int *fs_stat)
@@ -144,7 +141,7 @@ static void check_fs(const char *blk_device, char *fs_type, char *target, int *f
144 const char* e2fsck_forced_argv[] = {E2FSCK_BIN, "-f", "-y", blk_device}; 141 const char* e2fsck_forced_argv[] = {E2FSCK_BIN, "-f", "-y", blk_device};
145 142
146 /* Check for the types of filesystems we know how to check */ 143 /* Check for the types of filesystems we know how to check */
147 if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) { 144 if (is_extfs(fs_type)) {
148 if (*fs_stat & FS_STAT_EXT4_INVALID_MAGIC) { // will fail, so do not try 145 if (*fs_stat & FS_STAT_EXT4_INVALID_MAGIC) { // will fail, so do not try
149 return; 146 return;
150 } 147 }
@@ -242,186 +239,208 @@ static void check_fs(const char *blk_device, char *fs_type, char *target, int *f
242 return; 239 return;
243} 240}
244 241
245/* Function to read the primary superblock */ 242static ext4_fsblk_t ext4_blocks_count(const struct ext4_super_block* es) {
246static int read_super_block(int fd, struct ext4_super_block *sb) 243 return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) |
247{ 244 le32_to_cpu(es->s_blocks_count_lo);
248 off64_t ret; 245}
249 246
250 ret = lseek64(fd, 1024, SEEK_SET); 247static ext4_fsblk_t ext4_r_blocks_count(const struct ext4_super_block* es) {
251 if (ret < 0) 248 return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) |
252 return ret; 249 le32_to_cpu(es->s_r_blocks_count_lo);
250}
253 251
254 ret = read(fd, sb, sizeof(*sb)); 252// Read the primary superblock from an ext4 filesystem. On failure return
255 if (ret < 0) 253// false. If it's not an ext4 filesystem, also set FS_STAT_EXT4_INVALID_MAGIC.
256 return ret; 254static bool read_ext4_superblock(const char* blk_device, struct ext4_super_block* sb, int* fs_stat) {
257 if (ret != sizeof(*sb)) 255 android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)));
258 return ret;
259 256
260 return 0; 257 if (fd < 0) {
258 PERROR << "Failed to open '" << blk_device << "'";
259 return false;
260 }
261
262 if (pread(fd, sb, sizeof(*sb), 1024) != sizeof(*sb)) {
263 PERROR << "Can't read '" << blk_device << "' superblock";
264 return false;
265 }
266
267 if (sb->s_magic != EXT4_SUPER_MAGIC) {
268 LINFO << "Invalid ext4 magic:0x" << std::hex << sb->s_magic << " "
269 << "on '" << blk_device << "'";
270 // not a valid fs, tune2fs, fsck, and mount will all fail.
271 *fs_stat |= FS_STAT_EXT4_INVALID_MAGIC;
272 return false;
273 }
274 *fs_stat |= FS_STAT_IS_EXT4;
275 LINFO << "superblock s_max_mnt_count:" << sb->s_max_mnt_count << "," << blk_device;
276 if (sb->s_max_mnt_count == 0xffff) { // -1 (int16) in ext2, but uint16 in ext4
277 *fs_stat |= FS_STAT_NEW_IMAGE_VERSION;
278 }
279 return true;
261} 280}
262 281
263static ext4_fsblk_t ext4_blocks_count(struct ext4_super_block *es) 282// Some system images do not have tune2fs for licensing reasons.
264{ 283// Detect these and skip running it.
265 return ((ext4_fsblk_t)le32_to_cpu(es->s_blocks_count_hi) << 32) | 284static bool tune2fs_available(void) {
266 le32_to_cpu(es->s_blocks_count_lo); 285 return access(TUNE2FS_BIN, X_OK) == 0;
267} 286}
268 287
269static ext4_fsblk_t ext4_r_blocks_count(struct ext4_super_block *es) 288static bool run_tune2fs(const char* argv[], int argc) {
270{ 289 int ret;
271 return ((ext4_fsblk_t)le32_to_cpu(es->s_r_blocks_count_hi) << 32) | 290
272 le32_to_cpu(es->s_r_blocks_count_lo); 291 ret = android_fork_execvp_ext(argc, const_cast<char**>(argv), nullptr, true,
292 LOG_KLOG | LOG_FILE, true, nullptr, nullptr, 0);
293 return ret == 0;
273} 294}
274 295
275static int do_quota_with_shutdown_check(char *blk_device, char *fs_type, 296// Enable/disable quota support on the filesystem if needed.
276 struct fstab_rec *rec, int *fs_stat) 297static void tune_quota(const char* blk_device, const struct fstab_rec* rec,
277{ 298 const struct ext4_super_block* sb, int* fs_stat) {
278 int force_check = 0; 299 bool has_quota = (sb->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0;
279 if (!strcmp(fs_type, "ext4")) { 300 bool want_quota = fs_mgr_is_quota(rec) != 0;
280 /*
281 * Some system images do not have tune2fs for licensing reasons
282 * Detect these and skip reserve blocks.
283 */
284 if (access(TUNE2FS_BIN, X_OK)) {
285 LERROR << "Not running " << TUNE2FS_BIN << " on "
286 << blk_device << " (executable not in system image)";
287 } else {
288 const char* arg1 = nullptr;
289 const char* arg2 = nullptr;
290 int status = 0;
291 int ret = 0;
292 android::base::unique_fd fd(
293 TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)));
294 if (fd >= 0) {
295 struct ext4_super_block sb;
296 ret = read_super_block(fd, &sb);
297 if (ret < 0) {
298 PERROR << "Can't read '" << blk_device << "' super block";
299 return force_check;
300 }
301 if (sb.s_magic != EXT4_SUPER_MAGIC) {
302 LINFO << "Invalid ext4 magic:0x" << std::hex << sb.s_magic << "," << blk_device;
303 *fs_stat |= FS_STAT_EXT4_INVALID_MAGIC;
304 return 0; // not a valid fs, tune2fs, fsck, and mount will all fail.
305 }
306 *fs_stat |= FS_STAT_IS_EXT4;
307 LINFO << "superblock s_max_mnt_count:" << sb.s_max_mnt_count << "," << blk_device;
308 if (sb.s_max_mnt_count == 0xffff) { // -1 (int16) in ext2, but uint16 in ext4
309 *fs_stat |= FS_STAT_NEW_IMAGE_VERSION;
310 }
311 if ((sb.s_feature_incompat & EXT4_FEATURE_INCOMPAT_RECOVER) != 0 ||
312 (sb.s_state & EXT4_VALID_FS) == 0) {
313 LINFO << __FUNCTION__ << "(): was not clealy shutdown, state flag:"
314 << std::hex << sb.s_state
315 << "incompat flag:" << std::hex << sb.s_feature_incompat;
316 force_check = 1;
317 *fs_stat |= FS_STAT_UNCLEAN_SHUTDOWN;
318 }
319 int has_quota = (sb.s_feature_ro_compat
320 & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_QUOTA)) != 0;
321 int want_quota = fs_mgr_is_quota(rec) != 0;
322
323 if (has_quota == want_quota) {
324 LINFO << "Requested quota status is match on " << blk_device;
325 return force_check;
326 } else if (want_quota) {
327 LINFO << "Enabling quota on " << blk_device;
328 arg1 = "-Oquota";
329 arg2 = "-Qusrquota,grpquota";
330 force_check = 1;
331 *fs_stat |= FS_STAT_QUOTA_ENABLED;
332 } else {
333 LINFO << "Disabling quota on " << blk_device;
334 arg1 = "-Q^usrquota,^grpquota";
335 arg2 = "-O^quota";
336 }
337 } else {
338 PERROR << "Failed to open '" << blk_device << "'";
339 return force_check;
340 }
341 301
342 const char *tune2fs_argv[] = { 302 if (has_quota == want_quota) {
343 TUNE2FS_BIN, 303 return;
344 arg1, 304 }
345 arg2, 305
346 blk_device, 306 if (!tune2fs_available()) {
347 }; 307 LERROR << "Unable to " << (want_quota ? "enable" : "disable") << " quotas on " << blk_device
348 ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv), 308 << " because " TUNE2FS_BIN " is missing";
349 const_cast<char **>(tune2fs_argv), 309 return;
350 &status, true, LOG_KLOG | LOG_FILE, 310 }
351 true, NULL, NULL, 0); 311
352 if (ret < 0) { 312 const char* argv[] = {TUNE2FS_BIN, nullptr, nullptr, blk_device};
353 /* No need to check for error in fork, we can't really handle it now */ 313
354 LERROR << "Failed trying to run " << TUNE2FS_BIN; 314 if (want_quota) {
355 *fs_stat |= FS_STAT_TUNE2FS_FAILED; 315 LINFO << "Enabling quotas on " << blk_device;
356 } 316 argv[1] = "-Oquota";
357 } 317 argv[2] = "-Qusrquota,grpquota";
318 *fs_stat |= FS_STAT_QUOTA_ENABLED;
319 } else {
320 LINFO << "Disabling quotas on " << blk_device;
321 argv[1] = "-O^quota";
322 argv[2] = "-Q^usrquota,^grpquota";
323 }
324
325 if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
326 LERROR << "Failed to run " TUNE2FS_BIN " to " << (want_quota ? "enable" : "disable")
327 << " quotas on " << blk_device;
328 *fs_stat |= FS_STAT_TOGGLE_QUOTAS_FAILED;
358 } 329 }
359 return force_check;
360} 330}
361 331
362static void do_reserved_size(char *blk_device, char *fs_type, struct fstab_rec *rec, int *fs_stat) 332// Set the number of reserved filesystem blocks if needed.
363{ 333static void tune_reserved_size(const char* blk_device, const struct fstab_rec* rec,
364 /* Check for the types of filesystems we know how to check */ 334 const struct ext4_super_block* sb, int* fs_stat) {
365 if (!strcmp(fs_type, "ext2") || !strcmp(fs_type, "ext3") || !strcmp(fs_type, "ext4")) { 335 if (!(rec->fs_mgr_flags & MF_RESERVEDSIZE)) {
366 /* 336 return;
367 * Some system images do not have tune2fs for licensing reasons 337 }
368 * Detect these and skip reserve blocks.
369 */
370 if (access(TUNE2FS_BIN, X_OK)) {
371 LERROR << "Not running " << TUNE2FS_BIN << " on "
372 << blk_device << " (executable not in system image)";
373 } else {
374 LINFO << "Running " << TUNE2FS_BIN << " on " << blk_device;
375
376 int status = 0;
377 int ret = 0;
378 unsigned long reserved_blocks = 0;
379 android::base::unique_fd fd(
380 TEMP_FAILURE_RETRY(open(blk_device, O_RDONLY | O_CLOEXEC)));
381 if (fd >= 0) {
382 struct ext4_super_block sb;
383 ret = read_super_block(fd, &sb);
384 if (ret < 0) {
385 PERROR << "Can't read '" << blk_device << "' super block";
386 return;
387 }
388 reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(&sb);
389 unsigned long reserved_threshold = ext4_blocks_count(&sb) * 0.02;
390 if (reserved_threshold < reserved_blocks) {
391 LWARNING << "Reserved blocks " << reserved_blocks
392 << " is too large";
393 reserved_blocks = reserved_threshold;
394 }
395 338
396 if (ext4_r_blocks_count(&sb) == reserved_blocks) { 339 // The size to reserve is given in the fstab, but we won't reserve more
397 LINFO << "Have reserved same blocks"; 340 // than 2% of the filesystem.
398 return; 341 const uint64_t max_reserved_blocks = ext4_blocks_count(sb) * 0.02;
399 } 342 uint64_t reserved_blocks = rec->reserved_size / EXT4_BLOCK_SIZE(sb);
400 } else {
401 PERROR << "Failed to open '" << blk_device << "'";
402 return;
403 }
404 343
405 char buf[16] = {0}; 344 if (reserved_blocks > max_reserved_blocks) {
406 snprintf(buf, sizeof (buf), "-r %lu", reserved_blocks); 345 LWARNING << "Reserved blocks " << reserved_blocks << " is too large; "
407 const char *tune2fs_argv[] = { 346 << "capping to " << max_reserved_blocks;
408 TUNE2FS_BIN, 347 reserved_blocks = max_reserved_blocks;
409 buf, 348 }
410 blk_device,
411 };
412 349
413 ret = android_fork_execvp_ext(ARRAY_SIZE(tune2fs_argv), 350 if (ext4_r_blocks_count(sb) == reserved_blocks) {
414 const_cast<char **>(tune2fs_argv), 351 return;
415 &status, true, LOG_KLOG | LOG_FILE, 352 }
416 true, NULL, NULL, 0);
417 353
418 if (ret < 0) { 354 if (!tune2fs_available()) {
419 /* No need to check for error in fork, we can't really handle it now */ 355 LERROR << "Unable to set the number of reserved blocks on " << blk_device
420 LERROR << "Failed trying to run " << TUNE2FS_BIN; 356 << " because " TUNE2FS_BIN " is missing";
421 *fs_stat |= FS_STAT_TUNE2FS_FAILED; 357 return;
358 }
359
360 char buf[32];
361 const char* argv[] = {TUNE2FS_BIN, "-r", buf, blk_device};
362
363 snprintf(buf, sizeof(buf), "%" PRIu64, reserved_blocks);
364 LINFO << "Setting reserved block count on " << blk_device << " to " << reserved_blocks;
365 if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
366 LERROR << "Failed to run " TUNE2FS_BIN " to set the number of reserved blocks on "
367 << blk_device;
368 *fs_stat |= FS_STAT_SET_RESERVED_BLOCKS_FAILED;
369 }
370}
371
372// Enable file-based encryption if needed.
373static void tune_encrypt(const char* blk_device, const struct fstab_rec* rec,
374 const struct ext4_super_block* sb, int* fs_stat) {
375 bool has_encrypt = (sb->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_ENCRYPT)) != 0;
376 bool want_encrypt = fs_mgr_is_file_encrypted(rec) != 0;
377
378 if (has_encrypt || !want_encrypt) {
379 return;
380 }
381
382 if (!tune2fs_available()) {
383 LERROR << "Unable to enable ext4 encryption on " << blk_device
384 << " because " TUNE2FS_BIN " is missing";
385 return;
386 }
387
388 const char* argv[] = {TUNE2FS_BIN, "-Oencrypt", blk_device};
389
390 LINFO << "Enabling ext4 encryption on " << blk_device;
391 if (!run_tune2fs(argv, ARRAY_SIZE(argv))) {
392 LERROR << "Failed to run " TUNE2FS_BIN " to enable "
393 << "ext4 encryption on " << blk_device;
394 *fs_stat |= FS_STAT_ENABLE_ENCRYPTION_FAILED;
395 }
396}
397
398//
399// Prepare the filesystem on the given block device to be mounted.
400//
401// If the "check" option was given in the fstab record, or it seems that the
402// filesystem was uncleanly shut down, we'll run fsck on the filesystem.
403//
404// If needed, we'll also enable (or disable) filesystem features as specified by
405// the fstab record.
406//
407static int prepare_fs_for_mount(const char* blk_device, const struct fstab_rec* rec) {
408 int fs_stat = 0;
409
410 if (is_extfs(rec->fs_type)) {
411 struct ext4_super_block sb;
412
413 if (read_ext4_superblock(blk_device, &sb, &fs_stat)) {
414 if ((sb.s_feature_incompat & EXT4_FEATURE_INCOMPAT_RECOVER) != 0 ||
415 (sb.s_state & EXT4_VALID_FS) == 0) {
416 LINFO << "Filesystem on " << blk_device << " was not cleanly shutdown; "
417 << "state flags: 0x" << std::hex << sb.s_state << ", "
418 << "incompat feature flags: 0x" << std::hex << sb.s_feature_incompat;
419 fs_stat |= FS_STAT_UNCLEAN_SHUTDOWN;
422 } 420 }
421
422 // Note: quotas should be enabled before running fsck.
423 tune_quota(blk_device, rec, &sb, &fs_stat);
424 } else {
425 return fs_stat;
426 }
427 }
428
429 if ((rec->fs_mgr_flags & MF_CHECK) ||
430 (fs_stat & (FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED))) {
431 check_fs(blk_device, rec->fs_type, rec->mount_point, &fs_stat);
432 }
433
434 if (is_extfs(rec->fs_type) && (rec->fs_mgr_flags & (MF_RESERVEDSIZE | MF_FILEENCRYPTION))) {
435 struct ext4_super_block sb;
436
437 if (read_ext4_superblock(blk_device, &sb, &fs_stat)) {
438 tune_reserved_size(blk_device, rec, &sb, &fs_stat);
439 tune_encrypt(blk_device, rec, &sb, &fs_stat);
423 } 440 }
424 } 441 }
442
443 return fs_stat;
425} 444}
426 445
427static void remove_trailing_slashes(char *n) 446static void remove_trailing_slashes(char *n)
@@ -457,6 +476,16 @@ int fs_mgr_set_blk_ro(const char *blockdev)
457 return rc; 476 return rc;
458} 477}
459 478
479// Orange state means the device is unlocked, see the following link for details.
480// https://source.android.com/security/verifiedboot/verified-boot#device_state
481bool fs_mgr_is_device_unlocked() {
482 std::string verified_boot_state;
483 if (fs_mgr_get_boot_config("verifiedbootstate", &verified_boot_state)) {
484 return verified_boot_state == "orange";
485 }
486 return false;
487}
488
460/* 489/*
461 * __mount(): wrapper around the mount() system call which also 490 * __mount(): wrapper around the mount() system call which also
462 * sets the underlying block device to read-only if the mount is read-only. 491 * sets the underlying block device to read-only if the mount is read-only.
@@ -476,10 +505,11 @@ static int __mount(const char *source, const char *target, const struct fstab_re
476 if ((info.st_mode & S_IFMT) == S_IFLNK) 505 if ((info.st_mode & S_IFMT) == S_IFLNK)
477 unlink(target); 506 unlink(target);
478 mkdir(target, 0755); 507 mkdir(target, 0755);
508 errno = 0;
479 ret = mount(source, target, rec->fs_type, mountflags, rec->fs_options); 509 ret = mount(source, target, rec->fs_type, mountflags, rec->fs_options);
480 save_errno = errno; 510 save_errno = errno;
481 LINFO << __FUNCTION__ << "(source=" << source << ",target=" 511 PINFO << __FUNCTION__ << "(source=" << source << ",target=" << target
482 << target << ",type=" << rec->fs_type << ")=" << ret; 512 << ",type=" << rec->fs_type << ")=" << ret;
483 if ((ret == 0) && (mountflags & MS_RDONLY) != 0) { 513 if ((ret == 0) && (mountflags & MS_RDONLY) != 0) {
484 fs_mgr_set_blk_ro(source); 514 fs_mgr_set_blk_ro(source);
485 } 515 }
@@ -559,10 +589,7 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_
559 continue; 589 continue;
560 } 590 }
561 591
562 int fs_stat = 0; 592 int fs_stat = prepare_fs_for_mount(fstab->recs[i].blk_device, &fstab->recs[i]);
563 int force_check = do_quota_with_shutdown_check(fstab->recs[i].blk_device,
564 fstab->recs[i].fs_type,
565 &fstab->recs[i], &fs_stat);
566 if (fs_stat & FS_STAT_EXT4_INVALID_MAGIC) { 593 if (fs_stat & FS_STAT_EXT4_INVALID_MAGIC) {
567 LERROR << __FUNCTION__ << "(): skipping mount, invalid ext4, mountpoint=" 594 LERROR << __FUNCTION__ << "(): skipping mount, invalid ext4, mountpoint="
568 << fstab->recs[i].mount_point << " rec[" << i 595 << fstab->recs[i].mount_point << " rec[" << i
@@ -570,15 +597,6 @@ static int mount_with_alternatives(struct fstab *fstab, int start_idx, int *end_
570 mount_errno = EINVAL; // continue bootup for FDE 597 mount_errno = EINVAL; // continue bootup for FDE
571 continue; 598 continue;
572 } 599 }
573 if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) {
574 check_fs(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
575 fstab->recs[i].mount_point, &fs_stat);
576 }
577
578 if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
579 do_reserved_size(fstab->recs[i].blk_device, fstab->recs[i].fs_type,
580 &fstab->recs[i], &fs_stat);
581 }
582 600
583 int retry_count = 2; 601 int retry_count = 2;
584 while (retry_count-- > 0) { 602 while (retry_count-- > 0) {
@@ -756,19 +774,6 @@ static int handle_encryptable(const struct fstab_rec* rec)
756 } 774 }
757} 775}
758 776
759// TODO: add ueventd notifiers if they don't exist.
760// This is just doing a wait_for_device for maximum of 1s
761int fs_mgr_test_access(const char *device) {
762 int tries = 25;
763 while (tries--) {
764 if (!access(device, F_OK) || errno != ENOENT) {
765 return 0;
766 }
767 usleep(40 * 1000);
768 }
769 return -1;
770}
771
772bool is_device_secure() { 777bool is_device_secure() {
773 int ret = -1; 778 int ret = -1;
774 char value[PROP_VALUE_MAX]; 779 char value[PROP_VALUE_MAX];
@@ -829,9 +834,7 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
829 } 834 }
830 835
831 /* Translate LABEL= file system labels into block devices */ 836 /* Translate LABEL= file system labels into block devices */
832 if (!strcmp(fstab->recs[i].fs_type, "ext2") || 837 if (is_extfs(fstab->recs[i].fs_type)) {
833 !strcmp(fstab->recs[i].fs_type, "ext3") ||
834 !strcmp(fstab->recs[i].fs_type, "ext4")) {
835 int tret = translate_ext_labels(&fstab->recs[i]); 838 int tret = translate_ext_labels(&fstab->recs[i]);
836 if (tret < 0) { 839 if (tret < 0) {
837 LERROR << "Could not translate label to block device"; 840 LERROR << "Could not translate label to block device";
@@ -839,8 +842,10 @@ int fs_mgr_mount_all(struct fstab *fstab, int mount_mode)
839 } 842 }
840 } 843 }
841 844
842 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { 845 if (fstab->recs[i].fs_mgr_flags & MF_WAIT &&
843 wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT); 846 !fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) {
847 LERROR << "Skipping '" << fstab->recs[i].blk_device << "' during mount_all";
848 continue;
844 } 849 }
845 850
846 if (fstab->recs[i].fs_mgr_flags & MF_AVB) { 851 if (fstab->recs[i].fs_mgr_flags & MF_AVB) {
@@ -1047,22 +1052,12 @@ int fs_mgr_do_mount(struct fstab *fstab, const char *n_name, char *n_blk_device,
1047 } 1052 }
1048 1053
1049 /* First check the filesystem if requested */ 1054 /* First check the filesystem if requested */
1050 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { 1055 if (fstab->recs[i].fs_mgr_flags & MF_WAIT && !fs_mgr_wait_for_file(n_blk_device, 20s)) {
1051 wait_for_file(n_blk_device, WAIT_TIMEOUT); 1056 LERROR << "Skipping mounting '" << n_blk_device << "'";
1057 continue;
1052 } 1058 }
1053 1059
1054 int fs_stat = 0; 1060 int fs_stat = prepare_fs_for_mount(n_blk_device, &fstab->recs[i]);
1055 int force_check = do_quota_with_shutdown_check(n_blk_device, fstab->recs[i].fs_type,
1056 &fstab->recs[i], &fs_stat);
1057
1058 if ((fstab->recs[i].fs_mgr_flags & MF_CHECK) || force_check) {
1059 check_fs(n_blk_device, fstab->recs[i].fs_type,
1060 fstab->recs[i].mount_point, &fs_stat);
1061 }
1062
1063 if (fstab->recs[i].fs_mgr_flags & MF_RESERVEDSIZE) {
1064 do_reserved_size(n_blk_device, fstab->recs[i].fs_type, &fstab->recs[i], &fs_stat);
1065 }
1066 1061
1067 if (fstab->recs[i].fs_mgr_flags & MF_AVB) { 1062 if (fstab->recs[i].fs_mgr_flags & MF_AVB) {
1068 if (!avb_handle) { 1063 if (!avb_handle) {
@@ -1221,8 +1216,11 @@ int fs_mgr_swapon_all(struct fstab *fstab)
1221 fclose(zram_fp); 1216 fclose(zram_fp);
1222 } 1217 }
1223 1218
1224 if (fstab->recs[i].fs_mgr_flags & MF_WAIT) { 1219 if (fstab->recs[i].fs_mgr_flags & MF_WAIT &&
1225 wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT); 1220 !fs_mgr_wait_for_file(fstab->recs[i].blk_device, 20s)) {
1221 LERROR << "Skipping mkswap for '" << fstab->recs[i].blk_device << "'";
1222 ret = -1;
1223 continue;
1226 } 1224 }
1227 1225
1228 /* Initialize the swap area */ 1226 /* Initialize the swap area */
diff --git a/fs_mgr/fs_mgr_avb.cpp b/fs_mgr/fs_mgr_avb.cpp
index 2c99aa7c5..7824cfa70 100644
--- a/fs_mgr/fs_mgr_avb.cpp
+++ b/fs_mgr/fs_mgr_avb.cpp
@@ -397,7 +397,7 @@ static bool hashtree_dm_verity_setup(struct fstab_rec* fstab_entry,
397 fstab_entry->blk_device = strdup(verity_blk_name.c_str()); 397 fstab_entry->blk_device = strdup(verity_blk_name.c_str());
398 398
399 // Makes sure we've set everything up properly. 399 // Makes sure we've set everything up properly.
400 if (wait_for_verity_dev && fs_mgr_test_access(verity_blk_name.c_str()) < 0) { 400 if (wait_for_verity_dev && !fs_mgr_wait_for_file(verity_blk_name, 1s)) {
401 return false; 401 return false;
402 } 402 }
403 403
@@ -473,16 +473,6 @@ static bool get_hashtree_descriptor(const std::string& partition_name,
473 return true; 473 return true;
474} 474}
475 475
476// Orange state means the device is unlocked, see the following link for details.
477// https://source.android.com/security/verifiedboot/verified-boot#device_state
478static inline bool IsDeviceUnlocked() {
479 std::string verified_boot_state;
480 if (fs_mgr_get_boot_config("verifiedbootstate", &verified_boot_state)) {
481 return verified_boot_state == "orange";
482 }
483 return false;
484}
485
486FsManagerAvbUniquePtr FsManagerAvbHandle::Open(const fstab& fstab) { 476FsManagerAvbUniquePtr FsManagerAvbHandle::Open(const fstab& fstab) {
487 FsManagerAvbOps avb_ops(fstab); 477 FsManagerAvbOps avb_ops(fstab);
488 return DoOpen(&avb_ops); 478 return DoOpen(&avb_ops);
@@ -498,7 +488,7 @@ FsManagerAvbUniquePtr FsManagerAvbHandle::Open(ByNameSymlinkMap&& by_name_symlin
498} 488}
499 489
500FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) { 490FsManagerAvbUniquePtr FsManagerAvbHandle::DoOpen(FsManagerAvbOps* avb_ops) {
501 bool is_device_unlocked = IsDeviceUnlocked(); 491 bool is_device_unlocked = fs_mgr_is_device_unlocked();
502 492
503 FsManagerAvbUniquePtr avb_handle(new FsManagerAvbHandle()); 493 FsManagerAvbUniquePtr avb_handle(new FsManagerAvbHandle());
504 if (!avb_handle) { 494 if (!avb_handle) {
diff --git a/fs_mgr/fs_mgr_avb_ops.cpp b/fs_mgr/fs_mgr_avb_ops.cpp
index ba1262fde..43879fe56 100644
--- a/fs_mgr/fs_mgr_avb_ops.cpp
+++ b/fs_mgr/fs_mgr_avb_ops.cpp
@@ -142,10 +142,8 @@ AvbIOResult FsManagerAvbOps::ReadFromPartition(const char* partition, int64_t of
142 } 142 }
143 std::string path = iter->second; 143 std::string path = iter->second;
144 144
145 // Ensures the device path (a symlink created by init) is ready to 145 // Ensures the device path (a symlink created by init) is ready to access.
146 // access. fs_mgr_test_access() will test a few iterations if the 146 if (!fs_mgr_wait_for_file(path, 1s)) {
147 // path doesn't exist yet.
148 if (fs_mgr_test_access(path.c_str()) < 0) {
149 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION; 147 return AVB_IO_RESULT_ERROR_NO_SUCH_PARTITION;
150 } 148 }
151 149
diff --git a/fs_mgr/fs_mgr_boot_config.cpp b/fs_mgr/fs_mgr_boot_config.cpp
index ab5beed81..911766752 100644
--- a/fs_mgr/fs_mgr_boot_config.cpp
+++ b/fs_mgr/fs_mgr_boot_config.cpp
@@ -14,6 +14,8 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <string>
18
17#include <android-base/file.h> 19#include <android-base/file.h>
18#include <android-base/stringprintf.h> 20#include <android-base/stringprintf.h>
19#include <android-base/strings.h> 21#include <android-base/strings.h>
@@ -51,9 +53,11 @@ bool fs_mgr_get_boot_config(const std::string& key, std::string* out_val) {
51 // lastly, check the device tree 53 // lastly, check the device tree
52 if (is_dt_compatible()) { 54 if (is_dt_compatible()) {
53 std::string file_name = kAndroidDtDir + "/" + key; 55 std::string file_name = kAndroidDtDir + "/" + key;
54 // DT entries terminate with '\0' but so do the properties
55 if (android::base::ReadFileToString(file_name, out_val)) { 56 if (android::base::ReadFileToString(file_name, out_val)) {
56 return true; 57 if (!out_val->empty()) {
58 out_val->pop_back(); // Trims the trailing '\0' out.
59 return true;
60 }
57 } 61 }
58 } 62 }
59 63
diff --git a/fs_mgr/fs_mgr_format.cpp b/fs_mgr/fs_mgr_format.cpp
index 75feee798..fc88217ce 100644
--- a/fs_mgr/fs_mgr_format.cpp
+++ b/fs_mgr/fs_mgr_format.cpp
@@ -38,7 +38,6 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
38{ 38{
39 uint64_t dev_sz; 39 uint64_t dev_sz;
40 int fd, rc = 0; 40 int fd, rc = 0;
41 int status;
42 41
43 if ((fd = open(fs_blkdev, O_WRONLY)) < 0) { 42 if ((fd = open(fs_blkdev, O_WRONLY)) < 0) {
44 PERROR << "Cannot open block device"; 43 PERROR << "Cannot open block device";
@@ -62,7 +61,7 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
62 const char* const mke2fs_args[] = { 61 const char* const mke2fs_args[] = {
63 "/system/bin/mke2fs", "-t", "ext4", "-b", "4096", fs_blkdev, size_str.c_str(), nullptr}; 62 "/system/bin/mke2fs", "-t", "ext4", "-b", "4096", fs_blkdev, size_str.c_str(), nullptr};
64 63
65 rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast<char**>(mke2fs_args), &status, 64 rc = android_fork_execvp_ext(arraysize(mke2fs_args), const_cast<char**>(mke2fs_args), NULL,
66 true, LOG_KLOG, true, nullptr, nullptr, 0); 65 true, LOG_KLOG, true, nullptr, nullptr, 0);
67 if (rc) { 66 if (rc) {
68 LERROR << "mke2fs returned " << rc; 67 LERROR << "mke2fs returned " << rc;
@@ -78,7 +77,7 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
78 nullptr}; 77 nullptr};
79 78
80 rc = android_fork_execvp_ext(arraysize(e2fsdroid_args), const_cast<char**>(e2fsdroid_args), 79 rc = android_fork_execvp_ext(arraysize(e2fsdroid_args), const_cast<char**>(e2fsdroid_args),
81 &status, true, LOG_KLOG, true, nullptr, nullptr, 0); 80 NULL, true, LOG_KLOG, true, nullptr, nullptr, 0);
82 if (rc) { 81 if (rc) {
83 LERROR << "e2fsdroid returned " << rc; 82 LERROR << "e2fsdroid returned " << rc;
84 } 83 }
@@ -88,10 +87,9 @@ static int format_ext4(char *fs_blkdev, char *fs_mnt_point, bool crypt_footer)
88 87
89static int format_f2fs(char *fs_blkdev) 88static int format_f2fs(char *fs_blkdev)
90{ 89{
91 int status;
92 const char* const args[] = {"/system/bin/make_f2fs", "-f", "-O encrypt", fs_blkdev, nullptr}; 90 const char* const args[] = {"/system/bin/make_f2fs", "-f", "-O encrypt", fs_blkdev, nullptr};
93 91
94 return android_fork_execvp_ext(arraysize(args), const_cast<char**>(args), &status, true, 92 return android_fork_execvp_ext(arraysize(args), const_cast<char**>(args), NULL, true,
95 LOG_KLOG, true, nullptr, nullptr, 0); 93 LOG_KLOG, true, nullptr, nullptr, 0);
96} 94}
97 95
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index 6c527c573..6dcbded49 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -864,32 +864,26 @@ int fs_mgr_is_noemulatedsd(const struct fstab_rec *fstab)
864 return fstab->fs_mgr_flags & MF_NOEMULATEDSD; 864 return fstab->fs_mgr_flags & MF_NOEMULATEDSD;
865} 865}
866 866
867int fs_mgr_is_notrim(struct fstab_rec *fstab) 867int fs_mgr_is_notrim(const struct fstab_rec* fstab) {
868{
869 return fstab->fs_mgr_flags & MF_NOTRIM; 868 return fstab->fs_mgr_flags & MF_NOTRIM;
870} 869}
871 870
872int fs_mgr_is_formattable(struct fstab_rec *fstab) 871int fs_mgr_is_formattable(const struct fstab_rec* fstab) {
873{
874 return fstab->fs_mgr_flags & (MF_FORMATTABLE); 872 return fstab->fs_mgr_flags & (MF_FORMATTABLE);
875} 873}
876 874
877int fs_mgr_is_slotselect(struct fstab_rec *fstab) 875int fs_mgr_is_slotselect(const struct fstab_rec* fstab) {
878{
879 return fstab->fs_mgr_flags & MF_SLOTSELECT; 876 return fstab->fs_mgr_flags & MF_SLOTSELECT;
880} 877}
881 878
882int fs_mgr_is_nofail(struct fstab_rec *fstab) 879int fs_mgr_is_nofail(const struct fstab_rec* fstab) {
883{
884 return fstab->fs_mgr_flags & MF_NOFAIL; 880 return fstab->fs_mgr_flags & MF_NOFAIL;
885} 881}
886 882
887int fs_mgr_is_latemount(struct fstab_rec *fstab) 883int fs_mgr_is_latemount(const struct fstab_rec* fstab) {
888{
889 return fstab->fs_mgr_flags & MF_LATEMOUNT; 884 return fstab->fs_mgr_flags & MF_LATEMOUNT;
890} 885}
891 886
892int fs_mgr_is_quota(struct fstab_rec *fstab) 887int fs_mgr_is_quota(const struct fstab_rec* fstab) {
893{
894 return fstab->fs_mgr_flags & MF_QUOTA; 888 return fstab->fs_mgr_flags & MF_QUOTA;
895} 889}
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 3ca507b8b..a5d172b03 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -17,8 +17,12 @@
17#ifndef __CORE_FS_MGR_PRIV_H 17#ifndef __CORE_FS_MGR_PRIV_H
18#define __CORE_FS_MGR_PRIV_H 18#define __CORE_FS_MGR_PRIV_H
19 19
20#include <chrono>
21#include <string>
22
20#include <android-base/logging.h> 23#include <android-base/logging.h>
21#include <fs_mgr.h> 24
25#include "fs_mgr.h"
22#include "fs_mgr_priv_boot_config.h" 26#include "fs_mgr_priv_boot_config.h"
23 27
24/* The CHECK() in logging.h will use program invocation name as the tag. 28/* The CHECK() in logging.h will use program invocation name as the tag.
@@ -43,8 +47,6 @@
43 47
44#define CRYPTO_TMPFS_OPTIONS "size=256m,mode=0771,uid=1000,gid=1000" 48#define CRYPTO_TMPFS_OPTIONS "size=256m,mode=0771,uid=1000,gid=1000"
45 49
46#define WAIT_TIMEOUT 20
47
48/* fstab has the following format: 50/* fstab has the following format:
49 * 51 *
50 * Any line starting with a # is a comment and ignored 52 * Any line starting with a # is a comment and ignored
@@ -111,9 +113,13 @@
111 113
112#define DM_BUF_SIZE 4096 114#define DM_BUF_SIZE 4096
113 115
116using namespace std::chrono_literals;
117
114int fs_mgr_set_blk_ro(const char *blockdev); 118int fs_mgr_set_blk_ro(const char *blockdev);
115int fs_mgr_test_access(const char *device); 119bool fs_mgr_wait_for_file(const std::string& filename,
120 const std::chrono::milliseconds relative_timeout);
116bool fs_mgr_update_for_slotselect(struct fstab *fstab); 121bool fs_mgr_update_for_slotselect(struct fstab *fstab);
122bool fs_mgr_is_device_unlocked();
117bool is_dt_compatible(); 123bool is_dt_compatible();
118bool is_device_secure(); 124bool is_device_secure();
119int load_verity_state(struct fstab_rec* fstab, int* mode); 125int load_verity_state(struct fstab_rec* fstab, int* mode);
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 8904995aa..7f8e1e213 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -348,10 +348,13 @@ out:
348 348
349static int was_verity_restart() 349static int was_verity_restart()
350{ 350{
351 static const char *files[] = { 351 static const char* files[] = {
352 // clang-format off
353 "/sys/fs/pstore/console-ramoops-0",
352 "/sys/fs/pstore/console-ramoops", 354 "/sys/fs/pstore/console-ramoops",
353 "/proc/last_kmsg", 355 "/proc/last_kmsg",
354 NULL 356 NULL
357 // clang-format on
355 }; 358 };
356 int i; 359 int i;
357 360
@@ -689,27 +692,55 @@ int load_verity_state(struct fstab_rec* fstab, int* mode) {
689 return read_verity_state(fstab->verity_loc, offset, mode); 692 return read_verity_state(fstab->verity_loc, offset, mode);
690} 693}
691 694
692static void update_verity_table_blk_device(char *blk_device, char **table) 695// Update the verity table using the actual block device path.
693{ 696// Two cases:
694 std::string result, word; 697// Case-1: verity table is shared for devices with different by-name prefix.
698// Example:
699// verity table token: /dev/block/bootdevice/by-name/vendor
700// blk_device-1 (non-A/B): /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor
701// blk_device-2 (A/B): /dev/block/platform/soc.0/f9824900.sdhci/by-name/vendor_a
702//
703// Case-2: append A/B suffix in the verity table.
704// Example:
705// verity table token: /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor
706// blk_device: /dev/block/platform/soc.0/7824900.sdhci/by-name/vendor_a
707static void update_verity_table_blk_device(const std::string& blk_device, char** table,
708 bool slot_select) {
709 bool updated = false;
710 std::string result, ab_suffix;
695 auto tokens = android::base::Split(*table, " "); 711 auto tokens = android::base::Split(*table, " ");
696 712
713 // If slot_select is set, it means blk_device is already updated with ab_suffix.
714 if (slot_select) ab_suffix = fs_mgr_get_slot_suffix();
715
697 for (const auto& token : tokens) { 716 for (const auto& token : tokens) {
698 if (android::base::StartsWith(token, "/dev/block/") && 717 std::string new_token;
699 android::base::StartsWith(blk_device, token.c_str())) { 718 if (android::base::StartsWith(token, "/dev/block/")) {
700 word = blk_device; 719 if (token == blk_device) return; // no need to update if they're already the same.
720 std::size_t found1 = blk_device.find("by-name");
721 std::size_t found2 = token.find("by-name");
722 if (found1 != std::string::npos && found2 != std::string::npos &&
723 blk_device.substr(found1) == token.substr(found2) + ab_suffix) {
724 new_token = blk_device;
725 }
726 }
727
728 if (!new_token.empty()) {
729 updated = true;
730 LINFO << "Verity table: updated block device from '" << token << "' to '" << new_token
731 << "'";
701 } else { 732 } else {
702 word = token; 733 new_token = token;
703 } 734 }
704 735
705 if (result.empty()) { 736 if (result.empty()) {
706 result = word; 737 result = new_token;
707 } else { 738 } else {
708 result += " " + word; 739 result += " " + new_token;
709 } 740 }
710 } 741 }
711 742
712 if (result.empty()) { 743 if (!updated) {
713 return; 744 return;
714 } 745 }
715 746
@@ -751,8 +782,8 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev)
751 if (fec_verity_get_metadata(f, &verity) < 0) { 782 if (fec_verity_get_metadata(f, &verity) < 0) {
752 PERROR << "Failed to get verity metadata '" << fstab->blk_device << "'"; 783 PERROR << "Failed to get verity metadata '" << fstab->blk_device << "'";
753 // Allow verity disabled when the device is unlocked without metadata 784 // Allow verity disabled when the device is unlocked without metadata
754 if ("0" == android::base::GetProperty("ro.boot.flash.locked", "")) { 785 if (fs_mgr_is_device_unlocked()) {
755 retval = FS_MGR_SETUP_VERITY_DISABLED; 786 retval = FS_MGR_SETUP_VERITY_SKIPPED;
756 LWARNING << "Allow invalid metadata when the device is unlocked"; 787 LWARNING << "Allow invalid metadata when the device is unlocked";
757 } 788 }
758 goto out; 789 goto out;
@@ -810,9 +841,15 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev)
810 841
811 // verify the signature on the table 842 // verify the signature on the table
812 if (verify_verity_signature(verity) < 0) { 843 if (verify_verity_signature(verity) < 0) {
844 // Allow signature verification error when the device is unlocked
845 if (fs_mgr_is_device_unlocked()) {
846 retval = FS_MGR_SETUP_VERITY_SKIPPED;
847 LWARNING << "Allow signature verification error when the device is unlocked";
848 goto out;
849 }
813 if (params.mode == VERITY_MODE_LOGGING) { 850 if (params.mode == VERITY_MODE_LOGGING) {
814 // the user has been warned, allow mounting without dm-verity 851 // the user has been warned, allow mounting without dm-verity
815 retval = FS_MGR_SETUP_VERITY_SUCCESS; 852 retval = FS_MGR_SETUP_VERITY_SKIPPED;
816 goto out; 853 goto out;
817 } 854 }
818 855
@@ -825,10 +862,9 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev)
825 LINFO << "Enabling dm-verity for " << mount_point.c_str() 862 LINFO << "Enabling dm-verity for " << mount_point.c_str()
826 << " (mode " << params.mode << ")"; 863 << " (mode " << params.mode << ")";
827 864
828 if (fstab->fs_mgr_flags & MF_SLOTSELECT) { 865 // Update the verity params using the actual block device path
829 // Update the verity params using the actual block device path 866 update_verity_table_blk_device(fstab->blk_device, &params.table,
830 update_verity_table_blk_device(fstab->blk_device, &params.table); 867 fstab->fs_mgr_flags & MF_SLOTSELECT);
831 }
832 868
833 // load the verity mapping table 869 // load the verity mapping table
834 if (load_verity_table(io, mount_point, verity.data_size, fd, &params, 870 if (load_verity_table(io, mount_point, verity.data_size, fd, &params,
@@ -899,7 +935,7 @@ loaded:
899 } 935 }
900 936
901 // make sure we've set everything up properly 937 // make sure we've set everything up properly
902 if (wait_for_verity_dev && fs_mgr_test_access(fstab->blk_device) < 0) { 938 if (wait_for_verity_dev && !fs_mgr_wait_for_file(fstab->blk_device, 1s)) {
903 goto out; 939 goto out;
904 } 940 }
905 941
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index e033d4749..c74f6c85c 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -22,11 +22,7 @@
22#include <stdbool.h> 22#include <stdbool.h>
23#include <linux/dm-ioctl.h> 23#include <linux/dm-ioctl.h>
24 24
25// C++ only headers 25#include <fstab/fstab.h>
26// TODO: move this into separate header files under include/fs_mgr/*.h
27#ifdef __cplusplus
28#include <string>
29#endif
30 26
31// Magic number at start of verity metadata 27// Magic number at start of verity metadata
32#define VERITY_METADATA_MAGIC_NUMBER 0xb001b001 28#define VERITY_METADATA_MAGIC_NUMBER 0xb001b001
@@ -53,49 +49,10 @@ enum mount_mode {
53 MOUNT_MODE_LATE = 2 49 MOUNT_MODE_LATE = 2
54}; 50};
55 51
56/*
57 * The entries must be kept in the same order as they were seen in the fstab.
58 * Unless explicitly requested, a lookup on mount point should always
59 * return the 1st one.
60 */
61struct fstab {
62 int num_entries;
63 struct fstab_rec *recs;
64 char *fstab_filename;
65};
66
67struct fstab_rec {
68 char *blk_device;
69 char *mount_point;
70 char *fs_type;
71 unsigned long flags;
72 char *fs_options;
73 int fs_mgr_flags;
74 char *key_loc;
75 char* key_dir;
76 char *verity_loc;
77 long long length;
78 char *label;
79 int partnum;
80 int swap_prio;
81 int max_comp_streams;
82 unsigned int zram_size;
83 uint64_t reserved_size;
84 unsigned int file_contents_mode;
85 unsigned int file_names_mode;
86 unsigned int erase_blk_size;
87 unsigned int logical_blk_size;
88};
89
90// Callback function for verity status 52// Callback function for verity status
91typedef void (*fs_mgr_verity_state_callback)(struct fstab_rec *fstab, 53typedef void (*fs_mgr_verity_state_callback)(struct fstab_rec *fstab,
92 const char *mount_point, int mode, int status); 54 const char *mount_point, int mode, int status);
93 55
94struct fstab *fs_mgr_read_fstab_default();
95struct fstab *fs_mgr_read_fstab_dt();
96struct fstab *fs_mgr_read_fstab(const char *fstab_path);
97void fs_mgr_free_fstab(struct fstab *fstab);
98
99#define FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED 7 56#define FS_MGR_MNTALL_DEV_IS_METADATA_ENCRYPTED 7
100#define FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION 6 57#define FS_MGR_MNTALL_DEV_NEEDS_METADATA_ENCRYPTION 6
101#define FS_MGR_MNTALL_DEV_FILE_ENCRYPTED 5 58#define FS_MGR_MNTALL_DEV_FILE_ENCRYPTED 5
@@ -120,28 +77,6 @@ struct fstab_rec const* fs_mgr_get_crypt_entry(struct fstab const* fstab);
120void fs_mgr_get_crypt_info(struct fstab* fstab, char* key_loc, char* real_blk_device, size_t size); 77void fs_mgr_get_crypt_info(struct fstab* fstab, char* key_loc, char* real_blk_device, size_t size);
121bool fs_mgr_load_verity_state(int* mode); 78bool fs_mgr_load_verity_state(int* mode);
122bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback); 79bool fs_mgr_update_verity_state(fs_mgr_verity_state_callback callback);
123int fs_mgr_add_entry(struct fstab *fstab,
124 const char *mount_point, const char *fs_type,
125 const char *blk_device);
126struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const char *path);
127int fs_mgr_is_voldmanaged(const struct fstab_rec *fstab);
128int fs_mgr_is_nonremovable(const struct fstab_rec *fstab);
129int fs_mgr_is_verified(const struct fstab_rec *fstab);
130int fs_mgr_is_verifyatboot(const struct fstab_rec *fstab);
131int fs_mgr_is_avb(const struct fstab_rec *fstab);
132int fs_mgr_is_encryptable(const struct fstab_rec *fstab);
133int fs_mgr_is_file_encrypted(const struct fstab_rec *fstab);
134void fs_mgr_get_file_encryption_modes(const struct fstab_rec *fstab,
135 const char **contents_mode_ret,
136 const char **filenames_mode_ret);
137int fs_mgr_is_convertible_to_fbe(const struct fstab_rec *fstab);
138int fs_mgr_is_noemulatedsd(const struct fstab_rec *fstab);
139int fs_mgr_is_notrim(struct fstab_rec *fstab);
140int fs_mgr_is_formattable(struct fstab_rec *fstab);
141int fs_mgr_is_slotselect(struct fstab_rec *fstab);
142int fs_mgr_is_nofail(struct fstab_rec *fstab);
143int fs_mgr_is_latemount(struct fstab_rec *fstab);
144int fs_mgr_is_quota(struct fstab_rec *fstab);
145int fs_mgr_swapon_all(struct fstab *fstab); 80int fs_mgr_swapon_all(struct fstab *fstab);
146 81
147int fs_mgr_do_format(struct fstab_rec *fstab, bool reserve_footer); 82int fs_mgr_do_format(struct fstab_rec *fstab, bool reserve_footer);
@@ -154,10 +89,4 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab, bool wait_for_verity_dev);
154 89
155__END_DECLS 90__END_DECLS
156 91
157// C++ only functions
158// TODO: move this into separate header files under include/fs_mgr/*.h
159#ifdef __cplusplus
160std::string fs_mgr_get_slot_suffix();
161#endif
162
163#endif /* __CORE_FS_MGR_H */ 92#endif /* __CORE_FS_MGR_H */
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
new file mode 100644
index 000000000..15c8cafe6
--- /dev/null
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -0,0 +1,101 @@
1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef __CORE_FS_TAB_H
18#define __CORE_FS_TAB_H
19
20#include <linux/dm-ioctl.h>
21#include <stdbool.h>
22#include <stdint.h>
23#include <stdio.h>
24
25// C++ only headers
26// TODO: move this into separate header files under include/fs_mgr/*.h
27#ifdef __cplusplus
28#include <string>
29#endif
30
31__BEGIN_DECLS
32
33/*
34 * The entries must be kept in the same order as they were seen in the fstab.
35 * Unless explicitly requested, a lookup on mount point should always
36 * return the 1st one.
37 */
38struct fstab {
39 int num_entries;
40 struct fstab_rec* recs;
41 char* fstab_filename;
42};
43
44struct fstab_rec {
45 char* blk_device;
46 char* mount_point;
47 char* fs_type;
48 unsigned long flags;
49 char* fs_options;
50 int fs_mgr_flags;
51 char* key_loc;
52 char* key_dir;
53 char* verity_loc;
54 long long length;
55 char* label;
56 int partnum;
57 int swap_prio;
58 int max_comp_streams;
59 unsigned int zram_size;
60 uint64_t reserved_size;
61 unsigned int file_contents_mode;
62 unsigned int file_names_mode;
63 unsigned int erase_blk_size;
64 unsigned int logical_blk_size;
65};
66
67struct fstab* fs_mgr_read_fstab_default();
68struct fstab* fs_mgr_read_fstab_dt();
69struct fstab* fs_mgr_read_fstab(const char* fstab_path);
70void fs_mgr_free_fstab(struct fstab* fstab);
71
72int fs_mgr_add_entry(struct fstab* fstab, const char* mount_point, const char* fs_type,
73 const char* blk_device);
74struct fstab_rec* fs_mgr_get_entry_for_mount_point(struct fstab* fstab, const char* path);
75int fs_mgr_is_voldmanaged(const struct fstab_rec* fstab);
76int fs_mgr_is_nonremovable(const struct fstab_rec* fstab);
77int fs_mgr_is_verified(const struct fstab_rec* fstab);
78int fs_mgr_is_verifyatboot(const struct fstab_rec* fstab);
79int fs_mgr_is_avb(const struct fstab_rec* fstab);
80int fs_mgr_is_encryptable(const struct fstab_rec* fstab);
81int fs_mgr_is_file_encrypted(const struct fstab_rec* fstab);
82void fs_mgr_get_file_encryption_modes(const struct fstab_rec* fstab, const char** contents_mode_ret,
83 const char** filenames_mode_ret);
84int fs_mgr_is_convertible_to_fbe(const struct fstab_rec* fstab);
85int fs_mgr_is_noemulatedsd(const struct fstab_rec* fstab);
86int fs_mgr_is_notrim(const struct fstab_rec* fstab);
87int fs_mgr_is_formattable(const struct fstab_rec* fstab);
88int fs_mgr_is_slotselect(const struct fstab_rec* fstab);
89int fs_mgr_is_nofail(const struct fstab_rec* fstab);
90int fs_mgr_is_latemount(const struct fstab_rec* fstab);
91int fs_mgr_is_quota(const struct fstab_rec* fstab);
92
93__END_DECLS
94
95// C++ only functions
96// TODO: move this into separate header files under include/fs_mgr/*.h
97#ifdef __cplusplus
98std::string fs_mgr_get_slot_suffix();
99#endif
100
101#endif /* __CORE_FS_TAB_H */
diff --git a/gatekeeperd/Android.mk b/gatekeeperd/Android.mk
index 0dfd9d8a9..28f0b07ab 100644
--- a/gatekeeperd/Android.mk
+++ b/gatekeeperd/Android.mk
@@ -21,8 +21,7 @@ LOCAL_CFLAGS := -Wall -Wextra -Werror -Wunused
21LOCAL_SRC_FILES := \ 21LOCAL_SRC_FILES := \
22 SoftGateKeeperDevice.cpp \ 22 SoftGateKeeperDevice.cpp \
23 IGateKeeperService.cpp \ 23 IGateKeeperService.cpp \
24 gatekeeperd.cpp \ 24 gatekeeperd.cpp
25 IUserManager.cpp
26 25
27LOCAL_MODULE := gatekeeperd 26LOCAL_MODULE := gatekeeperd
28LOCAL_SHARED_LIBRARIES := \ 27LOCAL_SHARED_LIBRARIES := \
diff --git a/gatekeeperd/IUserManager.cpp b/gatekeeperd/IUserM