Skip to content

Commit

Permalink
DO NOT MERGE Report uncrypt errors in details
Browse files Browse the repository at this point in the history
Add the error codes for uncrypt and report the failure details in
uncrypt_status.

Test: uncrypt_error logs correctly in last_install
Bug: 31603820
Change-Id: I8e0de845ce1707b6f8f5ae84564c5e93fd5f5ef5
(cherry picked from commit da44cf1)
  • Loading branch information
Tianjie Xu committed Sep 29, 2016
1 parent a8c0d0b commit 37d7d67
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 40 deletions.
22 changes: 22 additions & 0 deletions error_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,26 @@ enum CauseCode {
kVendorFailure = 200
};

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

#endif
2 changes: 1 addition & 1 deletion install.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,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)) {
LOGW("failed to read uncrypt status: %s\n", strerror(errno));
} else if (!android::base::StartsWith(uncrypt_status, "uncrypt_time:")) {
} else if (!android::base::StartsWith(uncrypt_status, "uncrypt_")) {
LOGW("corrupted uncrypt_status: %s: %s\n", uncrypt_status.c_str(), strerror(errno));
} else {
log_buffer.push_back(android::base::Trim(uncrypt_status));
Expand Down
91 changes: 52 additions & 39 deletions uncrypt/uncrypt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
#define LOG_TAG "uncrypt"
#include <log/log.h>

#include "error_code.h"
#include "unique_fd.h"

#define WINDOW_SIZE 5
Expand Down Expand Up @@ -235,25 +236,25 @@ static int produce_block_map(const char* path, const char* map_file, const char*
std::string err;
if (!android::base::RemoveFileIfExists(map_file, &err)) {
ALOGE("failed to remove the existing map file %s: %s", map_file, err.c_str());
return -1;
return kUncryptFileRemoveError;
}
std::string tmp_map_file = std::string(map_file) + ".tmp";
unique_fd mapfd(open(tmp_map_file.c_str(), O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR));
if (!mapfd) {
ALOGE("failed to open %s: %s\n", tmp_map_file.c_str(), strerror(errno));
return -1;
return kUncryptFileOpenError;
}

// Make sure we can write to the socket.
if (!write_status_to_socket(0, socket)) {
ALOGE("failed to write to socket %d\n", socket);
return -1;
return kUncryptSocketWriteError;
}

struct stat sb;
if (stat(path, &sb) != 0) {
ALOGE("failed to stat %s", path);
return -1;
return kUncryptFileStatError;
}

ALOGI(" block size: %ld bytes", static_cast<long>(sb.st_blksize));
Expand All @@ -267,7 +268,7 @@ static int produce_block_map(const char* path, const char* map_file, const char*
blk_dev, sb.st_size, static_cast<long>(sb.st_blksize));
if (!android::base::WriteStringToFd(s, mapfd.get())) {
ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
return -1;
return kUncryptWriteError;
}

std::vector<std::vector<unsigned char>> buffers;
Expand All @@ -280,15 +281,15 @@ static int produce_block_map(const char* path, const char* map_file, const char*
unique_fd fd(open(path, O_RDONLY));
if (!fd) {
ALOGE("failed to open %s for reading: %s", path, strerror(errno));
return -1;
return kUncryptFileOpenError;
}

unique_fd wfd(-1);
if (encrypted) {
wfd = open(blk_dev, O_WRONLY);
if (!wfd) {
ALOGE("failed to open fd for writing: %s", strerror(errno));
return -1;
return kUncryptBlockOpenError;
}
}

Expand All @@ -307,13 +308,13 @@ static int produce_block_map(const char* path, const char* map_file, const char*
int block = head_block;
if (ioctl(fd.get(), FIBMAP, &block) != 0) {
ALOGE("failed to find block %d", head_block);
return -1;
return kUncryptIoctlError;
}
add_block_to_ranges(ranges, block);
if (encrypted) {
if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd.get(),
static_cast<off64_t>(sb.st_blksize) * block) != 0) {
return -1;
return kUncryptWriteError;
}
}
head = (head + 1) % WINDOW_SIZE;
Expand All @@ -326,7 +327,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.get(), buffers[tail].data(), to_read)) {
ALOGE("failed to read: %s", strerror(errno));
return -1;
return kUncryptReadError;
}
pos += to_read;
} else {
Expand All @@ -343,13 +344,13 @@ static int produce_block_map(const char* path, const char* map_file, const char*
int block = head_block;
if (ioctl(fd.get(), FIBMAP, &block) != 0) {
ALOGE("failed to find block %d", head_block);
return -1;
return kUncryptIoctlError;
}
add_block_to_ranges(ranges, block);
if (encrypted) {
if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd.get(),
static_cast<off64_t>(sb.st_blksize) * block) != 0) {
return -1;
return kUncryptWriteError;
}
}
head = (head + 1) % WINDOW_SIZE;
Expand All @@ -359,57 +360,57 @@ 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.get())) {
ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
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.get())) {
ALOGE("failed to write %s: %s", tmp_map_file.c_str(), strerror(errno));
return -1;
return kUncryptWriteError;
}
}

if (fsync(mapfd.get()) == -1) {
ALOGE("failed to fsync \"%s\": %s", tmp_map_file.c_str(), strerror(errno));
return -1;
return kUncryptFileSyncError;
}
if (close(mapfd.get()) == -1) {
ALOGE("failed to close %s: %s", tmp_map_file.c_str(), strerror(errno));
return -1;
return kUncryptFileCloseError;
}
mapfd = -1;

if (encrypted) {
if (fsync(wfd.get()) == -1) {
ALOGE("failed to fsync \"%s\": %s", blk_dev, strerror(errno));
return -1;
return kUncryptFileSyncError;
}
if (close(wfd.get()) == -1) {
ALOGE("failed to close %s: %s", blk_dev, strerror(errno));
return -1;
return kUncryptFileCloseError;
}
wfd = -1;
}

if (rename(tmp_map_file.c_str(), map_file) == -1) {
ALOGE("failed to rename %s to %s: %s", tmp_map_file.c_str(), map_file, strerror(errno));
return -1;
return kUncryptFileRenameError;
}
// Sync dir to make rename() result written to disk.
std::string file_name = map_file;
std::string dir_name = dirname(&file_name[0]);
unique_fd dfd(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY));
if (!dfd) {
ALOGE("failed to open dir %s: %s", dir_name.c_str(), strerror(errno));
return -1;
return kUncryptFileOpenError;
}
if (fsync(dfd.get()) == -1) {
ALOGE("failed to fsync %s: %s", dir_name.c_str(), strerror(errno));
return -1;
return kUncryptFileSyncError;
}
if (close(dfd.get()) == -1) {
ALOGE("failed to close %s: %s", dir_name.c_str(), strerror(errno));
return -1;
return kUncryptFileCloseError;
}
dfd = -1;
return 0;
Expand Down Expand Up @@ -449,46 +450,54 @@ 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) {
ALOGI("writing block map %s", 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 void log_uncrypt_error_code(UncryptErrorCode error_code) {
if (!android::base::WriteStringToFile(android::base::StringPrintf(
"uncrypt_error: %d\n", error_code), UNCRYPT_STATUS)) {
ALOGW("failed to write to %s: %s", UNCRYPT_STATUS.c_str(), strerror(errno));
}
}

static bool uncrypt_wrapper(const char* input_path, const char* map_file, const int socket) {
// Initialize the uncrypt error to kUncryptErrorPlaceholder.
log_uncrypt_error_code(kUncryptErrorPlaceholder);

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.
log_uncrypt_error_code(kUncryptPackageMissingError);
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)) {
ALOGW("failed to write to %s: %s", UNCRYPT_STATUS.c_str(), strerror(errno));
}

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)) {
PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
if (!android::base::WriteStringToFile(uncrypt_message, UNCRYPT_STATUS)) {
ALOGW("failed to write to %s: %s", UNCRYPT_STATUS.c_str(), strerror(errno));
}

write_status_to_socket(100, socket);
Expand Down Expand Up @@ -582,6 +591,7 @@ int main(int argc, char** argv) {
}

if ((fstab = read_fstab()) == nullptr) {
log_uncrypt_error_code(kUncryptFstabReadError);
return 1;
}

Expand All @@ -590,18 +600,21 @@ int main(int argc, char** argv) {
unique_fd service_socket(android_get_control_socket(UNCRYPT_SOCKET.c_str()));
if (!service_socket) {
ALOGE("failed to open socket \"%s\": %s", UNCRYPT_SOCKET.c_str(), strerror(errno));
log_uncrypt_error_code(kUncryptSocketOpenError);
return 1;
}
fcntl(service_socket.get(), F_SETFD, FD_CLOEXEC);

if (listen(service_socket.get(), 1) == -1) {
ALOGE("failed to listen on socket %d: %s", service_socket.get(), strerror(errno));
log_uncrypt_error_code(kUncryptSocketListenError);
return 1;
}

unique_fd socket_fd(accept4(service_socket.get(), nullptr, nullptr, SOCK_CLOEXEC));
if (!socket_fd) {
ALOGE("failed to accept on socket %d: %s", service_socket.get(), strerror(errno));
log_uncrypt_error_code(kUncryptSocketAcceptError);
return 1;
}

Expand Down

0 comments on commit 37d7d67

Please sign in to comment.