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

Commit af8b9363 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Report uncrypt errors in details"

parents 95afc912 da44cf18
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -43,4 +43,26 @@ enum CauseCode {
    kVendorFailure = 200
};

enum UncryptErrorCode {
    kUncryptNoError = -1,
    kUncryptErrorHolder = 50,
    kUncryptTimeoutError = 100,
    kUncryptFileRemoveError,
    kUncryptFileOpenError,
    kUncryptSocketOpenError,
    kUncryptSocketWriteError,
    kUncryptSocketListenError,
    kUncryptSocketAcceptError,
    kUncryptFstabReadError,
    kUncryptFileStatError,
    kUncryptBlockOpenError,
    kUncryptIoctlError,
    kUncryptReadError,
    kUncryptWriteError,
    kUncryptFileSyncError,
    kUncryptFileCloseError,
    kUncryptFileRenameError,
    kUncryptPackageMissingError,
};

#endif
+1 −1
Original line number Diff line number Diff line
@@ -377,7 +377,7 @@ install_package(const char* path, bool* wipe_cache, const char* install_file,
        std::string uncrypt_status;
        if (!android::base::ReadFileToString(UNCRYPT_STATUS, &uncrypt_status)) {
            PLOG(WARNING) << "failed to read uncrypt status";
        } else if (!android::base::StartsWith(uncrypt_status, "uncrypt_time:")) {
        } else if (!android::base::StartsWith(uncrypt_status, "uncrypt_:")) {
            PLOG(WARNING) << "corrupted uncrypt_status: " << uncrypt_status;
        } else {
            log_buffer.push_back(android::base::Trim(uncrypt_status));
+65 −40
Original line number Diff line number Diff line
@@ -116,6 +116,8 @@
#include <cutils/sockets.h>
#include <fs_mgr.h>

#include "error_code.h"

#define WINDOW_SIZE 5

// uncrypt provides three services: SETUP_BCB, CLEAR_BCB and UNCRYPT.
@@ -231,26 +233,26 @@ static int produce_block_map(const char* path, const char* map_file, const char*
    std::string err;
    if (!android::base::RemoveFileIfExists(map_file, &err)) {
        LOG(ERROR) << "failed to remove the existing map file " << map_file << ": " << err;
        return -1;
        return kUncryptFileRemoveError;
    }
    std::string tmp_map_file = std::string(map_file) + ".tmp";
    android::base::unique_fd mapfd(open(tmp_map_file.c_str(),
                                        O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR));
    if (mapfd == -1) {
        PLOG(ERROR) << "failed to open " << tmp_map_file;
        return -1;
        return kUncryptFileOpenError;
    }

    // Make sure we can write to the socket.
    if (!write_status_to_socket(0, socket)) {
        LOG(ERROR) << "failed to write to socket " << socket;
        return -1;
        return kUncryptSocketWriteError;
    }

    struct stat sb;
    if (stat(path, &sb) != 0) {
        LOG(ERROR) << "failed to stat " << path;
        return -1;
        return kUncryptFileStatError;
    }

    LOG(INFO) << " block size: " << sb.st_blksize << " bytes";
@@ -265,7 +267,7 @@ static int produce_block_map(const char* path, const char* map_file, const char*
                       static_cast<int64_t>(sb.st_blksize));
    if (!android::base::WriteStringToFd(s, mapfd)) {
        PLOG(ERROR) << "failed to write " << tmp_map_file;
        return -1;
        return kUncryptWriteError;
    }

    std::vector<std::vector<unsigned char>> buffers;
@@ -278,7 +280,7 @@ static int produce_block_map(const char* path, const char* map_file, const char*
    android::base::unique_fd fd(open(path, O_RDONLY));
    if (fd == -1) {
        PLOG(ERROR) << "failed to open " << path << " for reading";
        return -1;
        return kUncryptFileOpenError;
    }

    android::base::unique_fd wfd;
@@ -286,7 +288,7 @@ static int produce_block_map(const char* path, const char* map_file, const char*
        wfd.reset(open(blk_dev, O_WRONLY));
        if (wfd == -1) {
            PLOG(ERROR) << "failed to open " << blk_dev << " for writing";
            return -1;
            return kUncryptBlockOpenError;
        }
    }

@@ -304,14 +306,14 @@ static int produce_block_map(const char* path, const char* map_file, const char*
            // write out head buffer
            int block = head_block;
            if (ioctl(fd, FIBMAP, &block) != 0) {
                LOG(ERROR) << "failed to find block " << head_block;
                return -1;
                PLOG(ERROR) << "failed to find block " << head_block;
                return kUncryptIoctlError;
            }
            add_block_to_ranges(ranges, block);
            if (encrypted) {
                if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,
                                    static_cast<off64_t>(sb.st_blksize) * block) != 0) {
                    return -1;
                    return kUncryptWriteError;
                }
            }
            head = (head + 1) % WINDOW_SIZE;
@@ -324,7 +326,7 @@ static int produce_block_map(const char* path, const char* map_file, const char*
                    std::min(static_cast<off64_t>(sb.st_blksize), sb.st_size - pos));
            if (!android::base::ReadFully(fd, buffers[tail].data(), to_read)) {
                PLOG(ERROR) << "failed to read " << path;
                return -1;
                return kUncryptReadError;
            }
            pos += to_read;
        } else {
@@ -340,14 +342,14 @@ static int produce_block_map(const char* path, const char* map_file, const char*
        // write out head buffer
        int block = head_block;
        if (ioctl(fd, FIBMAP, &block) != 0) {
            LOG(ERROR) << "failed to find block " << head_block;
            return -1;
            PLOG(ERROR) << "failed to find block " << head_block;
            return kUncryptIoctlError;
        }
        add_block_to_ranges(ranges, block);
        if (encrypted) {
            if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,
                                static_cast<off64_t>(sb.st_blksize) * block) != 0) {
                return -1;
                return kUncryptWriteError;
            }
        }
        head = (head + 1) % WINDOW_SIZE;
@@ -357,39 +359,39 @@ static int produce_block_map(const char* path, const char* map_file, const char*
    if (!android::base::WriteStringToFd(
            android::base::StringPrintf("%zu\n", ranges.size() / 2), mapfd)) {
        PLOG(ERROR) << "failed to write " << tmp_map_file;
        return -1;
        return kUncryptWriteError;
    }
    for (size_t i = 0; i < ranges.size(); i += 2) {
        if (!android::base::WriteStringToFd(
                android::base::StringPrintf("%d %d\n", ranges[i], ranges[i+1]), mapfd)) {
            PLOG(ERROR) << "failed to write " << tmp_map_file;
            return -1;
            return kUncryptWriteError;
        }
    }

    if (fsync(mapfd) == -1) {
        PLOG(ERROR) << "failed to fsync \"" << tmp_map_file << "\"";
        return -1;
        return kUncryptFileSyncError;
    }
    if (close(mapfd.release()) == -1) {
        PLOG(ERROR) << "failed to close " << tmp_map_file;
        return -1;
        return kUncryptFileCloseError;
    }

    if (encrypted) {
        if (fsync(wfd) == -1) {
            PLOG(ERROR) << "failed to fsync \"" << blk_dev << "\"";
            return -1;
            return kUncryptFileSyncError;
        }
        if (close(wfd.release()) == -1) {
            PLOG(ERROR) << "failed to close " << blk_dev;
            return -1;
            return kUncryptFileCloseError;
        }
    }

    if (rename(tmp_map_file.c_str(), map_file) == -1) {
        PLOG(ERROR) << "failed to rename " << tmp_map_file << " to " << map_file;
        return -1;
        return kUncryptFileRenameError;
    }
    // Sync dir to make rename() result written to disk.
    std::string file_name = map_file;
@@ -397,15 +399,15 @@ static int produce_block_map(const char* path, const char* map_file, const char*
    android::base::unique_fd dfd(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY));
    if (dfd == -1) {
        PLOG(ERROR) << "failed to open dir " << dir_name;
        return -1;
        return kUncryptFileOpenError;
    }
    if (fsync(dfd) == -1) {
        PLOG(ERROR) << "failed to fsync " << dir_name;
        return -1;
        return kUncryptFileSyncError;
    }
    if (close(dfd.release()) == -1) {
        PLOG(ERROR) << "failed to close " << dir_name;
        return -1;
        return kUncryptFileCloseError;
    }
    return 0;
}
@@ -444,45 +446,52 @@ static int uncrypt(const char* input_path, const char* map_file, const int socke
    // and /sdcard we leave the file alone.
    if (strncmp(path, "/data/", 6) == 0) {
        LOG(INFO) << "writing block map " << map_file;
        if (produce_block_map(path, map_file, blk_dev, encrypted, socket) != 0) {
            return 1;
        }
        return produce_block_map(path, map_file, blk_dev, encrypted, socket);
    }

    return 0;
}

static bool uncrypt_wrapper(const char* input_path, const char* map_file, const int socket) {
    // Initialize the uncrypt error to kUncryptErrorHolder.
    if (!android::base::WriteStringToFile(android::base::StringPrintf(
            "uncrypt_error: %d\n", kUncryptErrorHolder), UNCRYPT_STATUS)) {
        PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
    }

    std::string package;
    if (input_path == nullptr) {
        if (!find_uncrypt_package(UNCRYPT_PATH_FILE, &package)) {
            write_status_to_socket(-1, socket);
            // Overwrite the error message.
            if (!android::base::WriteStringToFile(android::base::StringPrintf(
                    "uncrypt_error: %d\n", kUncryptPackageMissingError), UNCRYPT_STATUS)) {
                PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
            }
            return false;
        }
        input_path = package.c_str();
    }
    CHECK(map_file != nullptr);

#define UNCRYPT_TIME_HOLDER 0x7FFFFFFF
    // Intialize the uncrypt time cost to a huge number so that we can tell from
    // the statistics if an uncrypt fails to finish.
    if (!android::base::WriteStringToFile(android::base::StringPrintf(
            "uncrypt_time: %d\n", UNCRYPT_TIME_HOLDER), UNCRYPT_STATUS)) {
        PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
    }

    auto start = std::chrono::system_clock::now();
    int status = uncrypt(input_path, map_file, socket);
    std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
    int count = static_cast<int>(duration.count());

    std::string uncrypt_message = android::base::StringPrintf("uncrypt_time: %d\n", count);
    if (status != 0) {
        // Log the time cost and error code if uncrypt fails.
        uncrypt_message += android::base::StringPrintf("uncrypt_error: %d\n", status);
        if (!android::base::WriteStringToFile(uncrypt_message, UNCRYPT_STATUS)) {
            PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
        }

        write_status_to_socket(-1, socket);
        return false;
    }

    std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
    int count = static_cast<int>(duration.count());
    // Overwrite the uncrypt_time if uncrypt finishes successfully.
    if (!android::base::WriteStringToFile(
            android::base::StringPrintf("uncrypt_time: %d\n", count), UNCRYPT_STATUS)) {
    if (!android::base::WriteStringToFile(uncrypt_message, UNCRYPT_STATUS)) {
        PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
    }

@@ -560,6 +569,10 @@ int main(int argc, char** argv) {
    }

    if ((fstab = read_fstab()) == nullptr) {
        if (!android::base::WriteStringToFile(android::base::StringPrintf(
                "uncrypt_error: %d\n", kUncryptFstabReadError), UNCRYPT_STATUS)) {
            PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
        }
        return 1;
    }

@@ -568,18 +581,30 @@ int main(int argc, char** argv) {
    android::base::unique_fd service_socket(android_get_control_socket(UNCRYPT_SOCKET.c_str()));
    if (service_socket == -1) {
        PLOG(ERROR) << "failed to open socket \"" << UNCRYPT_SOCKET << "\"";
        if (!android::base::WriteStringToFile(android::base::StringPrintf(
                "uncrypt_error: %d\n", kUncryptSocketOpenError), UNCRYPT_STATUS)) {
            PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
        }
        return 1;
    }
    fcntl(service_socket, F_SETFD, FD_CLOEXEC);

    if (listen(service_socket, 1) == -1) {
        PLOG(ERROR) << "failed to listen on socket " << service_socket.get();
        if (!android::base::WriteStringToFile(android::base::StringPrintf(
                "uncrypt_error: %d\n", kUncryptSocketListenError), UNCRYPT_STATUS)) {
            PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
        }
        return 1;
    }

    android::base::unique_fd socket_fd(accept4(service_socket, nullptr, nullptr, SOCK_CLOEXEC));
    if (socket_fd == -1) {
        PLOG(ERROR) << "failed to accept on socket " << service_socket.get();
        if (!android::base::WriteStringToFile(android::base::StringPrintf(
                "uncrypt_error: %d\n", kUncryptSocketAcceptError), UNCRYPT_STATUS)) {
            PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
        }
        return 1;
    }