Merge "Report uncrypt errors in details" am: af8b9363c6
am: 7582609d61
am: fc887a8fba
Change-Id: I5e83be10f4443c8b107821975b3506381fcbdf0c
This commit is contained in:
commit
b0d0ee3c7d
3 changed files with 88 additions and 41 deletions
22
error_code.h
22
error_code.h
|
@ -44,4 +44,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
|
||||
|
|
|
@ -536,7 +536,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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -577,6 +586,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;
|
||||
}
|
||||
|
||||
|
@ -585,18 +598,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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue