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

Commit 70d85f40 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 4693621 from b62346a3 to pi-release

Change-Id: Id0ab6c017f13c15033780bb750121e22f74eb084
parents 188fc97e b62346a3
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -82,6 +82,28 @@ on post-fs
    chmod 0666 /sys/kernel/debug/tracing/events/lowmemorykiller/enable
    chmod 0666 /sys/kernel/tracing/events/lowmemorykiller/enable

    # disk
    chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_sync_file_enter/enable
    chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_sync_file_enter/enable
    chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_sync_file_exit/enable
    chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_sync_file_exit/enable
    chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_write_begin/enable
    chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_write_begin/enable
    chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_write_end/enable
    chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_write_end/enable
    chmod 0666 /sys/kernel/tracing/events/ext4/ext4_da_write_begin/enable
    chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_da_write_begin/enable
    chmod 0666 /sys/kernel/tracing/events/ext4/ext4_da_write_end/enable
    chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_da_write_end/enable
    chmod 0666 /sys/kernel/tracing/events/ext4/ext4_sync_file_enter/enable
    chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable
    chmod 0666 /sys/kernel/tracing/events/ext4/ext4_sync_file_exit/enable
    chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_sync_file_exit/enable
    chmod 0666 /sys/kernel/tracing/events/block/block_rq_issue/enable
    chmod 0666 /sys/kernel/debug/tracing/events/block/block_rq_issue/enable
    chmod 0666 /sys/kernel/tracing/events/block/block_rq_complete/enable
    chmod 0666 /sys/kernel/debug/tracing/events/block/block_rq_complete/enable

# Tracing disabled by default
    write /sys/kernel/debug/tracing/tracing_on 0
    write /sys/kernel/tracing/tracing_on 0
+0 −22
Original line number Diff line number Diff line
@@ -19,25 +19,3 @@ on post-fs
    chmod 0666 /sys/kernel/debug/tracing/events/irq/enable
    chmod 0666 /sys/kernel/tracing/events/ipi/enable
    chmod 0666 /sys/kernel/debug/tracing/events/ipi/enable

    # disk
    chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_sync_file_enter/enable
    chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_sync_file_enter/enable
    chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_sync_file_exit/enable
    chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_sync_file_exit/enable
    chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_write_begin/enable
    chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_write_begin/enable
    chmod 0666 /sys/kernel/tracing/events/f2fs/f2fs_write_end/enable
    chmod 0666 /sys/kernel/debug/tracing/events/f2fs/f2fs_write_end/enable
    chmod 0666 /sys/kernel/tracing/events/ext4/ext4_da_write_begin/enable
    chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_da_write_begin/enable
    chmod 0666 /sys/kernel/tracing/events/ext4/ext4_da_write_end/enable
    chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_da_write_end/enable
    chmod 0666 /sys/kernel/tracing/events/ext4/ext4_sync_file_enter/enable
    chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable
    chmod 0666 /sys/kernel/tracing/events/ext4/ext4_sync_file_exit/enable
    chmod 0666 /sys/kernel/debug/tracing/events/ext4/ext4_sync_file_exit/enable
    chmod 0666 /sys/kernel/tracing/events/block/block_rq_issue/enable
    chmod 0666 /sys/kernel/debug/tracing/events/block/block_rq_issue/enable
    chmod 0666 /sys/kernel/tracing/events/block/block_rq_complete/enable
    chmod 0666 /sys/kernel/debug/tracing/events/block/block_rq_complete/enable
+85 −54
Original line number Diff line number Diff line
@@ -32,14 +32,20 @@
#include <sys/time.h>
#include <sys/wait.h>
#include <unistd.h>

#include <chrono>
#include <functional>
#include <future>
#include <memory>
#include <regex>
#include <set>
#include <string>
#include <utility>
#include <vector>

#include <android-base/file.h>
#include <android-base/properties.h>
#include <android-base/scopeguard.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
@@ -53,6 +59,7 @@
#include <private/android_filesystem_config.h>
#include <private/android_logger.h>
#include <serviceutils/PriorityDumper.h>
#include <utils/StrongPointer.h>
#include "DumpstateInternal.h"
#include "DumpstateSectionReporter.h"
#include "DumpstateService.h"
@@ -1533,77 +1540,101 @@ void Dumpstate::DumpstateBoard() {
    printf("== Board\n");
    printf("========================================================\n");

    ::android::sp<IDumpstateDevice> dumpstate_device(IDumpstateDevice::getService());
    if (dumpstate_device == nullptr) {
        MYLOGE("No IDumpstateDevice implementation\n");
        return;
    }

    if (!IsZipping()) {
        MYLOGD("Not dumping board info because it's not a zipped bugreport\n");
        return;
    }

    std::string path[NUM_OF_DUMPS];
    android::base::unique_fd fd[NUM_OF_DUMPS];
    int numFds = 0;

    std::vector<std::string> paths;
    std::vector<android::base::ScopeGuard<std::function<void()>>> remover;
    for (int i = 0; i < NUM_OF_DUMPS; i++) {
        path[i] = kDumpstateBoardPath + kDumpstateBoardFiles[i];
        MYLOGI("Calling IDumpstateDevice implementation using path %s\n", path[i].c_str());

        fd[i] = android::base::unique_fd(
            TEMP_FAILURE_RETRY(open(path[i].c_str(),
            O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
            S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
        if (fd[i] < 0) {
            MYLOGE("Could not open file %s: %s\n", path[i].c_str(), strerror(errno));
            return;
        } else {
            numFds++;
        paths.emplace_back(kDumpstateBoardPath + kDumpstateBoardFiles[i]);
        remover.emplace_back(android::base::make_scope_guard(std::bind(
            [](std::string path) {
                if (remove(path.c_str()) != 0 && errno != ENOENT) {
                    MYLOGE("Could not remove(%s): %s\n", path.c_str(), strerror(errno));
                }
            },
            paths[i])));
    }

    native_handle_t *handle = native_handle_create(numFds, 0);
    // Given that bugreport is required to diagnose failures, it's better to
    // drop the result of IDumpstateDevice than to block the rest of bugreport
    // for an arbitrary amount of time.
    std::packaged_task<std::unique_ptr<ssize_t[]>()>
        dumpstate_task([paths]() -> std::unique_ptr<ssize_t[]> {
            ::android::sp<IDumpstateDevice> dumpstate_device(IDumpstateDevice::getService());
            if (dumpstate_device == nullptr) {
                MYLOGE("No IDumpstateDevice implementation\n");
                return nullptr;
            }

            using ScopedNativeHandle =
                std::unique_ptr<native_handle_t, std::function<void(native_handle_t*)>>;
            ScopedNativeHandle handle(native_handle_create(static_cast<int>(paths.size()), 0),
                                      [](native_handle_t* handle) {
                                          native_handle_close(handle);
                                          native_handle_delete(handle);
                                      });
            if (handle == nullptr) {
                MYLOGE("Could not create native_handle\n");
        return;
                return nullptr;
            }

    for (int i = 0; i < numFds; i++) {
        handle->data[i] = fd[i].release();
            for (size_t i = 0; i < paths.size(); i++) {
                MYLOGI("Calling IDumpstateDevice implementation using path %s\n", paths[i].c_str());

                android::base::unique_fd fd(TEMP_FAILURE_RETRY(
                    open(paths[i].c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_CLOEXEC | O_NOFOLLOW,
                         S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)));
                if (fd < 0) {
                    MYLOGE("Could not open file %s: %s\n", paths[i].c_str(), strerror(errno));
                    return nullptr;
                }
                handle.get()->data[i] = fd.release();
            }

    // TODO: need a timeout mechanism so dumpstate does not hang on device implementation call.
    android::hardware::Return<void> status = dumpstate_device->dumpstateBoard(handle);
            android::hardware::Return<void> status = dumpstate_device->dumpstateBoard(handle.get());
            if (!status.isOk()) {
                MYLOGE("dumpstateBoard failed: %s\n", status.description().c_str());
        native_handle_close(handle);
        native_handle_delete(handle);
                return nullptr;
            }
            auto file_sizes = std::make_unique<ssize_t[]>(paths.size());
            for (size_t i = 0; i < paths.size(); i++) {
                struct stat s;
                if (fstat(handle.get()->data[i], &s) == -1) {
                    MYLOGE("Failed to fstat %s: %s\n", kDumpstateBoardFiles[i].c_str(),
                           strerror(errno));
                    file_sizes[i] = -1;
                    continue;
                }
                file_sizes[i] = s.st_size;
            }
            return file_sizes;
        });
    auto result = dumpstate_task.get_future();
    std::thread(std::move(dumpstate_task)).detach();
    if (result.wait_for(10s) != std::future_status::ready) {
        MYLOGE("dumpstateBoard timed out after 10s\n");
        return;
    }
    std::unique_ptr<ssize_t[]> file_sizes = result.get();
    if (file_sizes == nullptr) {
        return;
    }

    for (int i = 0; i < numFds; i++) {
        struct stat s;
        if (fstat(handle->data[i], &s) == -1) {
            MYLOGE("Failed to fstat %s: %d\n", kDumpstateBoardFiles[i].c_str(), errno);
        } else if (s.st_size > 0) {
            AddZipEntry(kDumpstateBoardFiles[i], path[i]);
        } else {
    for (size_t i = 0; i < paths.size(); i++) {
        if (file_sizes[i] == -1) {
            continue;
        }
        if (file_sizes[i] == 0) {
            MYLOGE("Ignoring empty %s\n", kDumpstateBoardFiles[i].c_str());
            continue;
        }
        AddZipEntry(kDumpstateBoardFiles[i], paths[i]);
    }

    printf("*** See dumpstate-board.txt entry ***\n");

    native_handle_close(handle);
    native_handle_delete(handle);

    for (int i = 0; i < numFds; i++) {
        if (remove(path[i].c_str()) != 0) {
            MYLOGE("Could not remove(%s): %s\n", path[i].c_str(), strerror(errno));
        }
    }
}

static void ShowUsageAndExit(int exitCode = 1) {
+57 −44
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <errno.h>
#include <fstream>
#include <fts.h>
#include <functional>
#include <inttypes.h>
#include <regex>
#include <stdlib.h>
@@ -2412,27 +2413,25 @@ binder::Status InstalldNativeService::deleteOdex(const std::string& apkPath,

// This kernel feature is experimental.
// TODO: remove local definition once upstreamed
#ifndef FS_IOC_SET_FSVERITY
struct fsverity_set {
    __u64 offset;
    __u64 flags;
};
#ifndef FS_IOC_ENABLE_VERITY

struct fsverity_root_hash {
    short root_hash_algorithm;
    short flags;
    __u8 reserved[4];
    __u8 root_hash[64];
};
#define FS_IOC_ENABLE_VERITY           _IO('f', 133)
#define FS_IOC_SET_VERITY_MEASUREMENT  _IOW('f', 134, struct fsverity_measurement)

#define FS_IOC_MEASURE_FSVERITY        _IOW('f', 133, struct fsverity_root_hash)
#define FS_IOC_SET_FSVERITY            _IOW('f', 134, struct fsverity_set)
#define FS_VERITY_ALG_SHA256           1

struct fsverity_measurement {
    __u16 digest_algorithm;
    __u16 digest_size;
    __u32 reserved1;
    __u64 reserved2[3];
    __u8 digest[];
};

#define FSVERITY_FLAG_ENABLED          0x0001
#endif

binder::Status InstalldNativeService::installApkVerity(const std::string& filePath,
        const ::android::base::unique_fd& verityInputAshmem) {
        const ::android::base::unique_fd& verityInputAshmem, int32_t contentSize) {
    ENFORCE_UID(AID_SYSTEM);
    CHECK_ARGUMENT_PATH(filePath);
    std::lock_guard<std::recursive_mutex> lock(mLock);
@@ -2440,7 +2439,7 @@ binder::Status InstalldNativeService::installApkVerity(const std::string& filePa
    if (!android::base::GetBoolProperty(kPropApkVerityMode, false)) {
        return ok();
    }
#if DEBUG
#ifndef NDEBUG
    ASSERT_PAGE_SIZE_4K();
#endif
    // TODO: also check fsverity support in the current file system if compiled with DEBUG.
@@ -2449,15 +2448,14 @@ binder::Status InstalldNativeService::installApkVerity(const std::string& filePa
        return error("FD is not an ashmem");
    }

    // TODO(71871109): Validate filePath.
    // 1. Seek to the next page boundary beyond the end of the file.
    ::android::base::unique_fd wfd(open(filePath.c_str(), O_WRONLY));
    if (wfd.get() < 0) {
        return error("Failed to open " + filePath + ": " + strerror(errno));
        return error("Failed to open " + filePath);
    }
    struct stat st;
    if (fstat(wfd.get(), &st) < 0) {
        return error("Failed to stat " + filePath + ": " + strerror(errno));
        return error("Failed to stat " + filePath);
    }
    // fsverity starts from the block boundary.
    off_t padding = kVerityPageSize - st.st_size % kVerityPageSize;
@@ -2465,38 +2463,51 @@ binder::Status InstalldNativeService::installApkVerity(const std::string& filePa
        padding = 0;
    }
    if (lseek(wfd.get(), st.st_size + padding, SEEK_SET) < 0) {
        return error("Failed to lseek " + filePath + ": " + strerror(errno));
        return error("Failed to lseek " + filePath);
    }

    // 2. Write everything in the ashmem to the file.
    int size = ashmem_get_size_region(verityInputAshmem.get());
    if (size < 0) {
        return error("Failed to get ashmem size: " + std::to_string(size));
    // 2. Write everything in the ashmem to the file.  Note that allocated
    //    ashmem size is multiple of page size, which is different from the
    //    actual content size.
    int shmSize = ashmem_get_size_region(verityInputAshmem.get());
    if (shmSize < 0) {
        return error("Failed to get ashmem size: " + std::to_string(shmSize));
    }
    void* data = mmap(NULL, size, PROT_READ, MAP_SHARED, verityInputAshmem.get(), 0);
    if (data == MAP_FAILED) {
        return error("Failed to mmap the ashmem: " + std::string(strerror(errno)));
    if (contentSize < 0) {
        return error("Invalid content size: " + std::to_string(contentSize));
    }
    char* cursor = reinterpret_cast<char*>(data);
    int remaining = size;
    if (contentSize > shmSize) {
        return error("Content size overflow: " + std::to_string(contentSize) + " > " +
                     std::to_string(shmSize));
    }
    auto data = std::unique_ptr<void, std::function<void (void *)>>(
        mmap(NULL, contentSize, PROT_READ, MAP_SHARED, verityInputAshmem.get(), 0),
        [contentSize] (void* ptr) {
          if (ptr != MAP_FAILED) {
            munmap(ptr, contentSize);
          }
        });

    if (data.get() == MAP_FAILED) {
        return error("Failed to mmap the ashmem");
    }
    char* cursor = reinterpret_cast<char*>(data.get());
    int remaining = contentSize;
    while (remaining > 0) {
        int ret = TEMP_FAILURE_RETRY(write(wfd.get(), cursor, remaining));
        if (ret < 0) {
            munmap(data, size);
            return error("Failed to write to " + filePath + " (" + std::to_string(remaining) +
                         + "/" + std::to_string(size) + "): " + strerror(errno));
                         + "/" + std::to_string(contentSize) + ")");
        }
        cursor += ret;
        remaining -= ret;
    }
    munmap(data, size);
    wfd.reset();

    // 3. Enable fsverity. Once it's done, the file becomes immutable.
    struct fsverity_set config;
    config.offset = st.st_size;
    config.flags = FSVERITY_FLAG_ENABLED;
    if (ioctl(wfd.get(), FS_IOC_SET_FSVERITY, &config) < 0) {
        return error("Failed to enable fsverity on " + filePath + ": " + strerror(errno));
    // 3. Enable fsverity (needs readonly fd. Once it's done, the file becomes immutable.
    ::android::base::unique_fd rfd(open(filePath.c_str(), O_RDONLY));
    if (ioctl(rfd.get(), FS_IOC_ENABLE_VERITY, nullptr) < 0) {
        return error("Failed to enable fsverity on " + filePath);
    }
    return ok();
}
@@ -2516,17 +2527,19 @@ binder::Status InstalldNativeService::assertFsverityRootHashMatches(const std::s
                     std::to_string(expectedHash.size()));
    }

    // TODO(71871109): Validate filePath.
    ::android::base::unique_fd fd(open(filePath.c_str(), O_RDONLY));
    if (fd.get() < 0) {
        return error("Failed to open " + filePath + ": " + strerror(errno));
    }

    struct fsverity_root_hash config;
    memset(&config, 0, sizeof(config));
    config.root_hash_algorithm = 0;  // SHA256
    memcpy(config.root_hash, expectedHash.data(), std::min(sizeof(config.root_hash), kSha256Size));
    if (ioctl(fd.get(), FS_IOC_MEASURE_FSVERITY, &config) < 0) {
    unsigned int buffer_size = sizeof(fsverity_measurement) + kSha256Size;
    std::vector<char> buffer(buffer_size, 0);

    fsverity_measurement* config = reinterpret_cast<fsverity_measurement*>(buffer.data());
    config->digest_algorithm = FS_VERITY_ALG_SHA256;
    config->digest_size = kSha256Size;
    memcpy(config->digest, expectedHash.data(), kSha256Size);
    if (ioctl(fd.get(), FS_IOC_SET_VERITY_MEASUREMENT, config) < 0) {
        // This includes an expected failure case with no FSVerity setup. It normally happens when
        // the apk does not contains the Merkle tree root hash.
        return error("Failed to measure fsverity on " + filePath + ": " + strerror(errno));
+1 −1
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ public:
    binder::Status deleteOdex(const std::string& apkPath, const std::string& instructionSet,
            const std::unique_ptr<std::string>& outputPath);
    binder::Status installApkVerity(const std::string& filePath,
            const ::android::base::unique_fd& verityInput);
            const ::android::base::unique_fd& verityInput, int32_t contentSize);
    binder::Status assertFsverityRootHashMatches(const std::string& filePath,
            const std::vector<uint8_t>& expectedHash);
    binder::Status reconcileSecondaryDexFile(const std::string& dexPath,
Loading