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

Commit 7405a92e authored by Alex Buynytskyy's avatar Alex Buynytskyy
Browse files

Signature checks.

- signature size validation,
- no-signature files support (e.g. .dm).

Bug: 157077910 150803885
Fixes: 157077910
Test: atest adb_test adbd_test

Change-Id: I03a4f32a87568bd6f447f66c8aab666fb0b27199
parent a8b8d108
Loading
Loading
Loading
Loading
+27 −11
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ static std::pair<unique_fd, std::vector<char>> read_signature(Size file_size,
    struct stat st;
    if (stat(signature_file.c_str(), &st)) {
        if (!silent) {
            fprintf(stderr, "Failed to stat signature file %s. Abort.\n", signature_file.c_str());
            fprintf(stderr, "Failed to stat signature file %s.\n", signature_file.c_str());
        }
        return {};
    }
@@ -50,11 +50,21 @@ static std::pair<unique_fd, std::vector<char>> read_signature(Size file_size,
    unique_fd fd(adb_open(signature_file.c_str(), O_RDONLY));
    if (fd < 0) {
        if (!silent) {
            fprintf(stderr, "Failed to open signature file: %s. Abort.\n", signature_file.c_str());
            fprintf(stderr, "Failed to open signature file: %s.\n", signature_file.c_str());
        }
        return {};
    }

    std::vector<char> invalid_signature;

    if (st.st_size > kMaxSignatureSize) {
        if (!silent) {
            fprintf(stderr, "Signature is too long. Max allowed is %d. Abort.\n",
                    kMaxSignatureSize);
        }
        return {std::move(fd), std::move(invalid_signature)};
    }

    auto [signature, tree_size] = read_id_sig_headers(fd);
    if (auto expected = verity_tree_size_for_file(file_size); tree_size != expected) {
        if (!silent) {
@@ -62,7 +72,7 @@ static std::pair<unique_fd, std::vector<char>> read_signature(Size file_size,
                    "Verity tree size mismatch in signature file: %s [was %lld, expected %lld].\n",
                    signature_file.c_str(), (long long)tree_size, (long long)expected);
        }
        return {};
        return {std::move(fd), std::move(invalid_signature)};
    }

    return {std::move(fd), std::move(signature)};
@@ -72,9 +82,11 @@ static std::pair<unique_fd, std::vector<char>> read_signature(Size file_size,
static std::pair<unique_fd, std::string> read_and_encode_signature(Size file_size,
                                                                   std::string signature_file,
                                                                   bool silent) {
    std::string encoded_signature;

    auto [fd, signature] = read_signature(file_size, std::move(signature_file), silent);
    if (!fd.ok()) {
        return {};
    if (!fd.ok() || signature.empty()) {
        return {std::move(fd), std::move(encoded_signature)};
    }

    size_t base64_len = 0;
@@ -82,9 +94,10 @@ static std::pair<unique_fd, std::string> read_and_encode_signature(Size file_siz
        if (!silent) {
            fprintf(stderr, "Fail to estimate base64 encoded length. Abort.\n");
        }
        return {};
        return {std::move(fd), std::move(encoded_signature)};
    }
    std::string encoded_signature(base64_len, '\0');

    encoded_signature.resize(base64_len, '\0');
    encoded_signature.resize(EVP_EncodeBlock((uint8_t*)encoded_signature.data(),
                                             (const uint8_t*)signature.data(), signature.size()));

@@ -109,7 +122,7 @@ static unique_fd start_install(const Files& files, const Args& passthrough_args,
        }

        auto [signature_fd, signature] = read_and_encode_signature(st.st_size, file, silent);
        if (!signature_fd.ok()) {
        if (signature_fd.ok() && signature.empty()) {
            return {};
        }

@@ -138,11 +151,14 @@ bool can_install(const Files& files) {
            return false;
        }

        auto [fd, _] = read_signature(st.st_size, file, true);
        if (android::base::EndsWithIgnoreCase(file, ".apk")) {
            // Signature has to be present for APKs.
            auto [fd, _] = read_signature(st.st_size, file, /*silent=*/true);
            if (!fd.ok()) {
                return false;
            }
        }
    }
    return true;
}

+7 −1
Original line number Diff line number Diff line
@@ -171,6 +171,8 @@ class File {

    const std::vector<BlockIdx>& PriorityBlocks() const { return priority_blocks_; }

    bool hasTree() const { return tree_fd_.ok(); }

    std::vector<bool> sentBlocks;
    NumBlocks sentBlocksCount = 0;

@@ -349,6 +351,9 @@ std::optional<RequestCommand> IncrementalServer::ReadRequest(bool blocking) {

bool IncrementalServer::SendTreeBlocksForDataBlock(const FileId fileId, const BlockIdx blockIdx) {
    auto& file = files_[fileId];
    if (!file.hasTree()) {
        return true;
    }
    const int32_t data_block_count = numBytesToNumBlocks(file.size);

    const int32_t total_nodes_count(file.sentTreeBlocks.size());
@@ -670,7 +675,8 @@ static std::pair<unique_fd, int64_t> open_signature(int64_t file_size, const cha

    unique_fd fd(adb_open(signature_file.c_str(), O_RDONLY));
    if (fd < 0) {
        error_exit("inc-server: failed to open file '%s'.", signature_file.c_str());
        D("No signature file found for '%s'('%s')", filepath, signature_file.c_str());
        return {};
    }

    auto [tree_offset, tree_size] = skip_id_sig_headers(fd);
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ using Size = int64_t;
constexpr int kBlockSize = 4096;
constexpr int kSha256DigestSize = 32;
constexpr int kDigestSize = kSha256DigestSize;
constexpr int kMaxSignatureSize = 8096;  // incrementalfs.h

constexpr std::string_view IDSIG = ".idsig";