void CrasherTest::FinishCrasher() {
  if (crasher_pipe == -1) {
    FAIL() << "crasher pipe uninitialized";
  }

  ssize_t rc = write(crasher_pipe.get(), "\n", 1);
  if (rc == -1) {
    FAIL() << "failed to write to crasher pipe: " << strerror(errno);
  } else if (rc == 0) {
    FAIL() << "crasher pipe was closed";
  }
}
예제 #2
0
static void abort_handler(pid_t target, const bool tombstoned_connected,
                          unique_fd& tombstoned_socket, unique_fd& output_fd,
                          const char* abort_msg) {
  // If we abort before we get an output fd, contact tombstoned to let any
  // potential listeners know that we failed.
  if (!tombstoned_connected) {
    if (!tombstoned_connect(target, &tombstoned_socket, &output_fd, kDebuggerdAnyIntercept)) {
      // We failed to connect, not much we can do.
      LOG(ERROR) << "failed to connected to tombstoned to report failure";
      _exit(1);
    }
  }

  dprintf(output_fd.get(), "crash_dump failed to dump process");
  if (target != 1) {
    dprintf(output_fd.get(), " %d: %s\n", target, abort_msg);
  } else {
    dprintf(output_fd.get(), ": %s\n", abort_msg);
  }

  _exit(1);
}
void CrasherTest::FinishIntercept(int* result) {
  InterceptResponse response;

  // Timeout for tombstoned intercept is 10 seconds.
  ssize_t rc = TIMEOUT(20, read(intercept_fd.get(), &response, sizeof(response)));
  if (rc == -1) {
    FAIL() << "failed to read response from tombstoned: " << strerror(errno);
  } else if (rc == 0) {
    *result = -1;
  } else if (rc != sizeof(response)) {
    FAIL() << "received packet of unexpected length from tombstoned: expected " << sizeof(response)
           << ", received " << rc;
  } else {
    *result = response.status == InterceptStatus::kStarted ? 1 : 0;
  }
}
static void ConsumeFd(unique_fd fd, std::string* output) {
  constexpr size_t read_length = PAGE_SIZE;
  std::string result;

  while (true) {
    size_t offset = result.size();
    result.resize(result.size() + PAGE_SIZE);
    ssize_t rc = TEMP_FAILURE_RETRY(read(fd.get(), &result[offset], read_length));
    if (rc == -1) {
      FAIL() << "read failed: " << strerror(errno);
    } else if (rc == 0) {
      result.resize(result.size() - PAGE_SIZE);
      break;
    }

    result.resize(result.size() - PAGE_SIZE + rc);
  }

  *output = std::move(result);
}
예제 #5
0
void remount_service(unique_fd fd, const std::string& cmd) {
    bool user_requested_reboot = cmd == "-R";

    if (getuid() != 0) {
        WriteFdExactly(fd.get(), "Not running as root. Try \"adb root\" first.\n");
        return;
    }

    bool system_verified = !(android::base::GetProperty("partition.system.verified", "").empty());
    bool vendor_verified = !(android::base::GetProperty("partition.vendor.verified", "").empty());

    std::vector<std::string> partitions{"/",        "/odm",   "/oem", "/product_services",
                                        "/product", "/vendor"};

    bool verity_enabled = (system_verified || vendor_verified);

    // If we can use overlayfs, lets get it in place first
    // before we struggle with determining deduplication operations.
    if (!verity_enabled && fs_mgr_overlayfs_setup()) {
        Fstab fstab;
        if (ReadDefaultFstab(&fstab) && fs_mgr_overlayfs_mount_all(&fstab)) {
            WriteFdExactly(fd.get(), "overlayfs mounted\n");
        }
    }

    // Find partitions that are deduplicated, and can be un-deduplicated.
    std::set<std::string> dedup;
    for (const auto& part : partitions) {
        auto partition = part;
        if ((part == "/") && !find_mount("/system", false).empty()) partition = "/system";
        std::string dev = find_mount(partition.c_str(), partition == "/");
        if (dev.empty() || !fs_mgr_has_shared_blocks(partition, dev)) {
            continue;
        }
        if (can_unshare_blocks(fd.get(), dev.c_str())) {
            dedup.emplace(partition);
        }
    }

    // Reboot now if the user requested it (and an operation needs a reboot).
    if (user_requested_reboot) {
        if (!dedup.empty() || verity_enabled) {
            if (verity_enabled) {
                set_verity_enabled_state_service(unique_fd(dup(fd.get())), false);
            }
            reboot_for_remount(fd.get(), !dedup.empty());
            return;
        }
        WriteFdExactly(fd.get(), "No reboot needed, skipping -R.\n");
    }

    // If we need to disable-verity, but we also need to perform a recovery
    // fsck for deduplicated partitions, hold off on warning about verity. We
    // can handle both verity and the recovery fsck in the same reboot cycle.
    if (verity_enabled && dedup.empty()) {
        // Allow remount but warn of likely bad effects
        bool both = system_verified && vendor_verified;
        WriteFdFmt(fd.get(), "dm_verity is enabled on the %s%s%s partition%s.\n",
                   system_verified ? "system" : "", both ? " and " : "",
                   vendor_verified ? "vendor" : "", both ? "s" : "");
        WriteFdExactly(fd.get(),
                       "Use \"adb disable-verity\" to disable verity.\n"
                       "If you do not, remount may succeed, however, you will still "
                       "not be able to write to these volumes.\n");
        WriteFdExactly(fd.get(),
                       "Alternately, use \"adb remount -R\" to disable verity "
                       "and automatically reboot.\n");
    }

    bool success = true;
    for (const auto& partition : partitions) {
        // Don't try to remount partitions that need an fsck in recovery.
        if (dedup.count(partition)) {
            continue;
        }
        success &= remount_partition(fd.get(), partition.c_str());
    }

    if (!dedup.empty()) {
        WriteFdExactly(fd.get(),
                       "The following partitions are deduplicated and cannot "
                       "yet be remounted:\n");
        for (const std::string& name : dedup) {
            WriteFdFmt(fd.get(), "  %s\n", name.c_str());
        }

        WriteFdExactly(fd.get(),
                       "To reboot and un-deduplicate the listed partitions, "
                       "please retry with adb remount -R.\n");
        if (system_verified || vendor_verified) {
            WriteFdExactly(fd.get(), "Note: verity will be automatically disabled after reboot.\n");
        }
        return;
    }

    if (!success) {
        WriteFdExactly(fd.get(), "remount failed\n");
    } else {
        WriteFdExactly(fd.get(), "remount succeeded\n");
    }
}
void framebuffer_service(unique_fd fd) {
    struct fbinfo fbinfo;
    unsigned int i, bsize;
    char buf[640];
    int fd_screencap;
    int w, h, f, c;
    int fds[2];
    pid_t pid;

    if (pipe2(fds, O_CLOEXEC) < 0) return;

    pid = fork();
    if (pid < 0) goto done;

    if (pid == 0) {
        dup2(fds[1], STDOUT_FILENO);
        adb_close(fds[0]);
        adb_close(fds[1]);
        const char* command = "screencap";
        const char *args[2] = {command, nullptr};
        execvp(command, (char**)args);
        perror_exit("exec screencap failed");
    }

    adb_close(fds[1]);
    fd_screencap = fds[0];

    /* read w, h, format & color space */
    if(!ReadFdExactly(fd_screencap, &w, 4)) goto done;
    if(!ReadFdExactly(fd_screencap, &h, 4)) goto done;
    if(!ReadFdExactly(fd_screencap, &f, 4)) goto done;
    if(!ReadFdExactly(fd_screencap, &c, 4)) goto done;

    fbinfo.version = DDMS_RAWIMAGE_VERSION;
    fbinfo.colorSpace = c;
    /* see hardware/hardware.h */
    switch (f) {
        case 1: /* RGBA_8888 */
            fbinfo.bpp = 32;
            fbinfo.size = w * h * 4;
            fbinfo.width = w;
            fbinfo.height = h;
            fbinfo.red_offset = 0;
            fbinfo.red_length = 8;
            fbinfo.green_offset = 8;
            fbinfo.green_length = 8;
            fbinfo.blue_offset = 16;
            fbinfo.blue_length = 8;
            fbinfo.alpha_offset = 24;
            fbinfo.alpha_length = 8;
            break;
        case 2: /* RGBX_8888 */
            fbinfo.bpp = 32;
            fbinfo.size = w * h * 4;
            fbinfo.width = w;
            fbinfo.height = h;
            fbinfo.red_offset = 0;
            fbinfo.red_length = 8;
            fbinfo.green_offset = 8;
            fbinfo.green_length = 8;
            fbinfo.blue_offset = 16;
            fbinfo.blue_length = 8;
            fbinfo.alpha_offset = 24;
            fbinfo.alpha_length = 0;
            break;
        case 3: /* RGB_888 */
            fbinfo.bpp = 24;
            fbinfo.size = w * h * 3;
            fbinfo.width = w;
            fbinfo.height = h;
            fbinfo.red_offset = 0;
            fbinfo.red_length = 8;
            fbinfo.green_offset = 8;
            fbinfo.green_length = 8;
            fbinfo.blue_offset = 16;
            fbinfo.blue_length = 8;
            fbinfo.alpha_offset = 24;
            fbinfo.alpha_length = 0;
            break;
        case 4: /* RGB_565 */
            fbinfo.bpp = 16;
            fbinfo.size = w * h * 2;
            fbinfo.width = w;
            fbinfo.height = h;
            fbinfo.red_offset = 11;
            fbinfo.red_length = 5;
            fbinfo.green_offset = 5;
            fbinfo.green_length = 6;
            fbinfo.blue_offset = 0;
            fbinfo.blue_length = 5;
            fbinfo.alpha_offset = 0;
            fbinfo.alpha_length = 0;
            break;
        case 5: /* BGRA_8888 */
            fbinfo.bpp = 32;
            fbinfo.size = w * h * 4;
            fbinfo.width = w;
            fbinfo.height = h;
            fbinfo.red_offset = 16;
            fbinfo.red_length = 8;
            fbinfo.green_offset = 8;
            fbinfo.green_length = 8;
            fbinfo.blue_offset = 0;
            fbinfo.blue_length = 8;
            fbinfo.alpha_offset = 24;
            fbinfo.alpha_length = 8;
           break;
        default:
            goto done;
    }

    /* write header */
    if (!WriteFdExactly(fd.get(), &fbinfo, sizeof(fbinfo))) goto done;

    /* write data */
    for(i = 0; i < fbinfo.size; i += bsize) {
      bsize = sizeof(buf);
      if (i + bsize > fbinfo.size)
        bsize = fbinfo.size - i;
      if(!ReadFdExactly(fd_screencap, buf, bsize)) goto done;
      if (!WriteFdExactly(fd.get(), buf, bsize)) goto done;
    }

done:
    adb_close(fds[0]);

    TEMP_FAILURE_RETRY(waitpid(pid, nullptr, 0));
}