Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 396b4e5b authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 4557233 from 72fc33fc to pi-release

Change-Id: I2b7176c514ec8602d0972a7ef60fd6aa48c5e558
parents e683f317 72fc33fc
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -1944,7 +1944,8 @@ static int install_multiple_app(int argc, const char** argv) {
    for (int i = argc - 1; i >= 0; i--) {
        const char* file = argv[i];

        if (android::base::EndsWithIgnoreCase(file, ".apk")) {
        if (android::base::EndsWithIgnoreCase(file, ".apk") ||
            android::base::EndsWithIgnoreCase(file, ".dm")) {
            struct stat sb;
            if (stat(file, &sb) != -1) total_size += sb.st_size;
            first_apk = i;
@@ -2005,9 +2006,8 @@ static int install_multiple_app(int argc, const char** argv) {
        }

        std::string cmd = android::base::StringPrintf(
                "%s install-write -S %" PRIu64 " %d %d_%s -",
                install_cmd.c_str(), static_cast<uint64_t>(sb.st_size), session_id, i,
                android::base::Basename(file).c_str());
            "%s install-write -S %" PRIu64 " %d %s -", install_cmd.c_str(),
            static_cast<uint64_t>(sb.st_size), session_id, android::base::Basename(file).c_str());

        int localFd = adb_open(file, O_RDONLY);
        if (localFd < 0) {
+1 −0
Original line number Diff line number Diff line
@@ -195,6 +195,7 @@ cc_test {
        "libcutils",
        "libdebuggerd_client",
        "liblog",
        "libminijail",
        "libnativehelper"
    ],

debuggerd/Android.mk

0 → 100644
+23 −0
Original line number Diff line number Diff line
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := crash_dump.policy
LOCAL_MODULE_CLASS := ETC
LOCAL_MULTILIB := both

ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), arm arm64))
LOCAL_MODULE_STEM_32 := crash_dump.arm.policy
LOCAL_MODULE_STEM_64 := crash_dump.arm64.policy
endif

ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), x86 x86_64))
LOCAL_MODULE_STEM_32 := crash_dump.x86.policy
LOCAL_MODULE_STEM_64 := crash_dump.x86_64.policy
endif

LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
LOCAL_SRC_FILES_arm := seccomp_policy/crash_dump.arm.policy
LOCAL_SRC_FILES_arm64 := seccomp_policy/crash_dump.arm64.policy
LOCAL_SRC_FILES_x86 := seccomp_policy/crash_dump.x86.policy
LOCAL_SRC_FILES_x86_64 := seccomp_policy/crash_dump.x86_64.policy
include $(BUILD_PREBUILT)
+140 −3
Original line number Diff line number Diff line
@@ -41,6 +41,9 @@
#include <cutils/sockets.h>
#include <gtest/gtest.h>

#include <libminijail.h>
#include <scoped_minijail.h>

#include "debuggerd/handler.h"
#include "protocol.h"
#include "tombstoned/tombstoned.h"
@@ -77,8 +80,7 @@ constexpr char kWaitForGdbKey[] = "debug.debuggerd.wait_for_gdb";
  }()

#define ASSERT_BACKTRACE_FRAME(result, frame_name) \
  ASSERT_MATCH(result, R"(#\d\d pc [0-9a-f]+\s+ /system/lib)" ARCH_SUFFIX \
                       R"(/libc.so \()" frame_name R"(\+)")
  ASSERT_MATCH(result, R"(#\d\d pc [0-9a-f]+\s+ \S+ \()" frame_name R"(\+)");

static void tombstoned_intercept(pid_t target_pid, unique_fd* intercept_fd, unique_fd* output_fd,
                                 InterceptStatus* status, DebuggerdDumpType intercept_type) {
@@ -565,6 +567,141 @@ TEST_F(CrasherTest, fake_pid) {
  ASSERT_BACKTRACE_FRAME(result, "tgkill");
}

static const char* const kDebuggerdSeccompPolicy =
    "/system/etc/seccomp_policy/crash_dump." ABI_STRING ".policy";

pid_t seccomp_fork() {
  unique_fd policy_fd(open(kDebuggerdSeccompPolicy, O_RDONLY | O_CLOEXEC));
  if (policy_fd == -1) {
    LOG(FATAL) << "failed to open policy " << kDebuggerdSeccompPolicy;
  }

  ScopedMinijail jail{minijail_new()};
  if (!jail) {
    LOG(FATAL) << "failed to create minijail";
  }

  minijail_no_new_privs(jail.get());
  minijail_log_seccomp_filter_failures(jail.get());
  minijail_use_seccomp_filter(jail.get());
  minijail_parse_seccomp_filters_from_fd(jail.get(), policy_fd.release());

  pid_t result = fork();
  if (result == -1) {
    return result;
  } else if (result != 0) {
    return result;
  }

  // Spawn and detach a thread that spins forever.
  std::atomic<bool> thread_ready(false);
  std::thread thread([&jail, &thread_ready]() {
    minijail_enter(jail.get());
    thread_ready = true;
    for (;;)
      ;
  });
  thread.detach();

  while (!thread_ready) {
    continue;
  }

  minijail_enter(jail.get());
  return result;
}

TEST_F(CrasherTest, seccomp_crash) {
  int intercept_result;
  unique_fd output_fd;

  StartProcess([]() { abort(); }, &seccomp_fork);

  StartIntercept(&output_fd);
  FinishCrasher();
  AssertDeath(SIGABRT);
  FinishIntercept(&intercept_result);
  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);
  ASSERT_BACKTRACE_FRAME(result, "abort");
}

__attribute__((noinline)) extern "C" bool raise_debugger_signal(DebuggerdDumpType dump_type) {
  siginfo_t siginfo;
  siginfo.si_code = SI_QUEUE;
  siginfo.si_pid = getpid();
  siginfo.si_uid = getuid();

  if (dump_type != kDebuggerdNativeBacktrace && dump_type != kDebuggerdTombstone) {
    PLOG(FATAL) << "invalid dump type";
  }

  siginfo.si_value.sival_int = dump_type == kDebuggerdNativeBacktrace;

  if (syscall(__NR_rt_tgsigqueueinfo, getpid(), gettid(), DEBUGGER_SIGNAL, &siginfo) != 0) {
    PLOG(ERROR) << "libdebuggerd_client: failed to send signal to self";
    return false;
  }

  return true;
}

TEST_F(CrasherTest, seccomp_tombstone) {
  int intercept_result;
  unique_fd output_fd;

  static const auto dump_type = kDebuggerdTombstone;
  StartProcess(
      []() {
        raise_debugger_signal(dump_type);
        _exit(0);
      },
      &seccomp_fork);

  StartIntercept(&output_fd, dump_type);
  FinishCrasher();
  AssertDeath(0);
  FinishIntercept(&intercept_result);
  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);
  ASSERT_BACKTRACE_FRAME(result, "raise_debugger_signal");
}

TEST_F(CrasherTest, seccomp_backtrace) {
  int intercept_result;
  unique_fd output_fd;

  static const auto dump_type = kDebuggerdNativeBacktrace;
  StartProcess(
      []() {
        raise_debugger_signal(dump_type);
        _exit(0);
      },
      &seccomp_fork);

  StartIntercept(&output_fd, dump_type);
  FinishCrasher();
  AssertDeath(0);
  FinishIntercept(&intercept_result);
  ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";

  std::string result;
  ConsumeFd(std::move(output_fd), &result);
  ASSERT_BACKTRACE_FRAME(result, "raise_debugger_signal");
}

TEST_F(CrasherTest, seccomp_crash_logcat) {
  StartProcess([]() { abort(); }, &seccomp_fork);
  FinishCrasher();

  // Make sure we don't get SIGSYS when trying to dump a crash to logcat.
  AssertDeath(SIGABRT);
}

TEST_F(CrasherTest, competing_tracer) {
  int intercept_result;
  unique_fd output_fd;
+3 −3
Original line number Diff line number Diff line
@@ -40,16 +40,16 @@ int open_tombstone(std::string* path);
/* Creates a tombstone file and writes the crash dump to it. */
void engrave_tombstone(int tombstone_fd, BacktraceMap* map, const OpenFilesList* open_files,
                       pid_t pid, pid_t tid, const std::string& process_name,
                       const std::map<pid_t, std::string>& threads, uintptr_t abort_msg_address,
                       const std::map<pid_t, std::string>& threads, uint64_t abort_msg_address,
                       std::string* amfd_data);

void engrave_tombstone_ucontext(int tombstone_fd, uintptr_t abort_msg_address, siginfo_t* siginfo,
void engrave_tombstone_ucontext(int tombstone_fd, uint64_t abort_msg_address, siginfo_t* siginfo,
                                ucontext_t* ucontext);

void engrave_tombstone(android::base::unique_fd output_fd, BacktraceMap* map,
                       unwindstack::Memory* process_memory,
                       const std::map<pid_t, ThreadInfo>& thread_info, pid_t target_thread,
                       uintptr_t abort_msg_address, OpenFilesList* open_files,
                       uint64_t abort_msg_address, OpenFilesList* open_files,
                       std::string* amfd_data);

#endif  // _DEBUGGERD_TOMBSTONE_H
Loading