aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--error_code.h22
-rw-r--r--install.cpp2
-rw-r--r--uncrypt/uncrypt.cpp105
3 files changed, 88 insertions, 41 deletions
diff --git a/error_code.h b/error_code.h
index 259319ab..09ea8201 100644
--- a/error_code.h
+++ b/error_code.h
@@ -43,4 +43,26 @@ enum CauseCode {
43 kVendorFailure = 200 43 kVendorFailure = 200
44}; 44};
45 45
46enum UncryptErrorCode {
47 kUncryptNoError = -1,
48 kUncryptErrorHolder = 50,
49 kUncryptTimeoutError = 100,
50 kUncryptFileRemoveError,
51 kUncryptFileOpenError,
52 kUncryptSocketOpenError,
53 kUncryptSocketWriteError,
54 kUncryptSocketListenError,
55 kUncryptSocketAcceptError,
56 kUncryptFstabReadError,
57 kUncryptFileStatError,
58 kUncryptBlockOpenError,
59 kUncryptIoctlError,
60 kUncryptReadError,
61 kUncryptWriteError,
62 kUncryptFileSyncError,
63 kUncryptFileCloseError,
64 kUncryptFileRenameError,
65 kUncryptPackageMissingError,
66};
67
46#endif 68#endif
diff --git a/install.cpp b/install.cpp
index 01b839ff..427bea1a 100644
--- a/install.cpp
+++ b/install.cpp
@@ -377,7 +377,7 @@ install_package(const char* path, bool* wipe_cache, const char* install_file,
377 std::string uncrypt_status; 377 std::string uncrypt_status;
378 if (!android::base::ReadFileToString(UNCRYPT_STATUS, &uncrypt_status)) { 378 if (!android::base::ReadFileToString(UNCRYPT_STATUS, &uncrypt_status)) {
379 PLOG(WARNING) << "failed to read uncrypt status"; 379 PLOG(WARNING) << "failed to read uncrypt status";
380 } else if (!android::base::StartsWith(uncrypt_status, "uncrypt_time:")) { 380 } else if (!android::base::StartsWith(uncrypt_status, "uncrypt_:")) {
381 PLOG(WARNING) << "corrupted uncrypt_status: " << uncrypt_status; 381 PLOG(WARNING) << "corrupted uncrypt_status: " << uncrypt_status;
382 } else { 382 } else {
383 log_buffer.push_back(android::base::Trim(uncrypt_status)); 383 log_buffer.push_back(android::base::Trim(uncrypt_status));
diff --git a/uncrypt/uncrypt.cpp b/uncrypt/uncrypt.cpp
index dea8445e..c77e987b 100644
--- a/uncrypt/uncrypt.cpp
+++ b/uncrypt/uncrypt.cpp
@@ -116,6 +116,8 @@
116#include <cutils/sockets.h> 116#include <cutils/sockets.h>
117#include <fs_mgr.h> 117#include <fs_mgr.h>
118 118
119#include "error_code.h"
120
119#define WINDOW_SIZE 5 121#define WINDOW_SIZE 5
120 122
121// uncrypt provides three services: SETUP_BCB, CLEAR_BCB and UNCRYPT. 123// 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*
231 std::string err; 233 std::string err;
232 if (!android::base::RemoveFileIfExists(map_file, &err)) { 234 if (!android::base::RemoveFileIfExists(map_file, &err)) {
233 LOG(ERROR) << "failed to remove the existing map file " << map_file << ": " << err; 235 LOG(ERROR) << "failed to remove the existing map file " << map_file << ": " << err;
234 return -1; 236 return kUncryptFileRemoveError;
235 } 237 }
236 std::string tmp_map_file = std::string(map_file) + ".tmp"; 238 std::string tmp_map_file = std::string(map_file) + ".tmp";
237 android::base::unique_fd mapfd(open(tmp_map_file.c_str(), 239 android::base::unique_fd mapfd(open(tmp_map_file.c_str(),
238 O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR)); 240 O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR));
239 if (mapfd == -1) { 241 if (mapfd == -1) {
240 PLOG(ERROR) << "failed to open " << tmp_map_file; 242 PLOG(ERROR) << "failed to open " << tmp_map_file;
241 return -1; 243 return kUncryptFileOpenError;
242 } 244 }
243 245
244 // Make sure we can write to the socket. 246 // Make sure we can write to the socket.
245 if (!write_status_to_socket(0, socket)) { 247 if (!write_status_to_socket(0, socket)) {
246 LOG(ERROR) << "failed to write to socket " << socket; 248 LOG(ERROR) << "failed to write to socket " << socket;
247 return -1; 249 return kUncryptSocketWriteError;
248 } 250 }
249 251
250 struct stat sb; 252 struct stat sb;
251 if (stat(path, &sb) != 0) { 253 if (stat(path, &sb) != 0) {
252 LOG(ERROR) << "failed to stat " << path; 254 LOG(ERROR) << "failed to stat " << path;
253 return -1; 255 return kUncryptFileStatError;
254 } 256 }
255 257
256 LOG(INFO) << " block size: " << sb.st_blksize << " bytes"; 258 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*
265 static_cast<int64_t>(sb.st_blksize)); 267 static_cast<int64_t>(sb.st_blksize));
266 if (!android::base::WriteStringToFd(s, mapfd)) { 268 if (!android::base::WriteStringToFd(s, mapfd)) {
267 PLOG(ERROR) << "failed to write " << tmp_map_file; 269 PLOG(ERROR) << "failed to write " << tmp_map_file;
268 return -1; 270 return kUncryptWriteError;
269 } 271 }
270 272
271 std::vector<std::vector<unsigned char>> buffers; 273 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*
278 android::base::unique_fd fd(open(path, O_RDONLY)); 280 android::base::unique_fd fd(open(path, O_RDONLY));
279 if (fd == -1) { 281 if (fd == -1) {
280 PLOG(ERROR) << "failed to open " << path << " for reading"; 282 PLOG(ERROR) << "failed to open " << path << " for reading";
281 return -1; 283 return kUncryptFileOpenError;
282 } 284 }
283 285
284 android::base::unique_fd wfd; 286 android::base::unique_fd wfd;
@@ -286,7 +288,7 @@ static int produce_block_map(const char* path, const char* map_file, const char*
286 wfd.reset(open(blk_dev, O_WRONLY)); 288 wfd.reset(open(blk_dev, O_WRONLY));
287 if (wfd == -1) { 289 if (wfd == -1) {
288 PLOG(ERROR) << "failed to open " << blk_dev << " for writing"; 290 PLOG(ERROR) << "failed to open " << blk_dev << " for writing";
289 return -1; 291 return kUncryptBlockOpenError;
290 } 292 }
291 } 293 }
292 294
@@ -304,14 +306,14 @@ static int produce_block_map(const char* path, const char* map_file, const char*
304 // write out head buffer 306 // write out head buffer
305 int block = head_block; 307 int block = head_block;
306 if (ioctl(fd, FIBMAP, &block) != 0) { 308 if (ioctl(fd, FIBMAP, &block) != 0) {
307 LOG(ERROR) << "failed to find block " << head_block; 309 PLOG(ERROR) << "failed to find block " << head_block;
308 return -1; 310 return kUncryptIoctlError;
309 } 311 }
310 add_block_to_ranges(ranges, block); 312 add_block_to_ranges(ranges, block);
311 if (encrypted) { 313 if (encrypted) {
312 if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd, 314 if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,
313 static_cast<off64_t>(sb.st_blksize) * block) != 0) { 315 static_cast<off64_t>(sb.st_blksize) * block) != 0) {
314 return -1; 316 return kUncryptWriteError;
315 } 317 }
316 } 318 }
317 head = (head + 1) % WINDOW_SIZE; 319 head = (head + 1) % WINDOW_SIZE;
@@ -324,7 +326,7 @@ static int produce_block_map(const char* path, const char* map_file, const char*
324 std::min(static_cast<off64_t>(sb.st_blksize), sb.st_size - pos)); 326 std::min(static_cast<off64_t>(sb.st_blksize), sb.st_size - pos));
325 if (!android::base::ReadFully(fd, buffers[tail].data(), to_read)) { 327 if (!android::base::ReadFully(fd, buffers[tail].data(), to_read)) {
326 PLOG(ERROR) << "failed to read " << path; 328 PLOG(ERROR) << "failed to read " << path;
327 return -1; 329 return kUncryptReadError;
328 } 330 }
329 pos += to_read; 331 pos += to_read;
330 } else { 332 } else {
@@ -340,14 +342,14 @@ static int produce_block_map(const char* path, const char* map_file, const char*
340 // write out head buffer 342 // write out head buffer
341 int block = head_block; 343 int block = head_block;
342 if (ioctl(fd, FIBMAP, &block) != 0) { 344 if (ioctl(fd, FIBMAP, &block) != 0) {
343 LOG(ERROR) << "failed to find block " << head_block; 345 PLOG(ERROR) << "failed to find block " << head_block;
344 return -1; 346 return kUncryptIoctlError;
345 } 347 }
346 add_block_to_ranges(ranges, block); 348 add_block_to_ranges(ranges, block);
347 if (encrypted) { 349 if (encrypted) {
348 if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd, 350 if (write_at_offset(buffers[head].data(), sb.st_blksize, wfd,
349 static_cast<off64_t>(sb.st_blksize) * block) != 0) { 351 static_cast<off64_t>(sb.st_blksize) * block) != 0) {
350 return -1; 352 return kUncryptWriteError;
351 } 353 }
352 } 354 }
353 head = (head + 1) % WINDOW_SIZE; 355 head = (head + 1) % WINDOW_SIZE;
@@ -357,39 +359,39 @@ static int produce_block_map(const char* path, const char* map_file, const char*
357 if (!android::base::WriteStringToFd( 359 if (!android::base::WriteStringToFd(
358 android::base::StringPrintf("%zu\n", ranges.size() / 2), mapfd)) { 360 android::base::StringPrintf("%zu\n", ranges.size() / 2), mapfd)) {
359 PLOG(ERROR) << "failed to write " << tmp_map_file; 361 PLOG(ERROR) << "failed to write " << tmp_map_file;
360 return -1; 362 return kUncryptWriteError;
361 } 363 }
362 for (size_t i = 0; i < ranges.size(); i += 2) { 364 for (size_t i = 0; i < ranges.size(); i += 2) {
363 if (!android::base::WriteStringToFd( 365 if (!android::base::WriteStringToFd(
364 android::base::StringPrintf("%d %d\n", ranges[i], ranges[i+1]), mapfd)) { 366 android::base::StringPrintf("%d %d\n", ranges[i], ranges[i+1]), mapfd)) {
365 PLOG(ERROR) << "failed to write " << tmp_map_file; 367 PLOG(ERROR) << "failed to write " << tmp_map_file;
366 return -1; 368 return kUncryptWriteError;
367 } 369 }
368 } 370 }
369 371
370 if (fsync(mapfd) == -1) { 372 if (fsync(mapfd) == -1) {
371 PLOG(ERROR) << "failed to fsync \"" << tmp_map_file << "\""; 373 PLOG(ERROR) << "failed to fsync \"" << tmp_map_file << "\"";
372 return -1; 374 return kUncryptFileSyncError;
373 } 375 }
374 if (close(mapfd.release()) == -1) { 376 if (close(mapfd.release()) == -1) {
375 PLOG(ERROR) << "failed to close " << tmp_map_file; 377 PLOG(ERROR) << "failed to close " << tmp_map_file;
376 return -1; 378 return kUncryptFileCloseError;
377 } 379 }
378 380
379 if (encrypted) { 381 if (encrypted) {
380 if (fsync(wfd) == -1) { 382 if (fsync(wfd) == -1) {
381 PLOG(ERROR) << "failed to fsync \"" << blk_dev << "\""; 383 PLOG(ERROR) << "failed to fsync \"" << blk_dev << "\"";
382 return -1; 384 return kUncryptFileSyncError;
383 } 385 }
384 if (close(wfd.release()) == -1) { 386 if (close(wfd.release()) == -1) {
385 PLOG(ERROR) << "failed to close " << blk_dev; 387 PLOG(ERROR) << "failed to close " << blk_dev;
386 return -1; 388 return kUncryptFileCloseError;
387 } 389 }
388 } 390 }
389 391
390 if (rename(tmp_map_file.c_str(), map_file) == -1) { 392 if (rename(tmp_map_file.c_str(), map_file) == -1) {
391 PLOG(ERROR) << "failed to rename " << tmp_map_file << " to " << map_file; 393 PLOG(ERROR) << "failed to rename " << tmp_map_file << " to " << map_file;
392 return -1; 394 return kUncryptFileRenameError;
393 } 395 }
394 // Sync dir to make rename() result written to disk. 396 // Sync dir to make rename() result written to disk.
395 std::string file_name = map_file; 397 std::string file_name = map_file;
@@ -397,15 +399,15 @@ static int produce_block_map(const char* path, const char* map_file, const char*
397 android::base::unique_fd dfd(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY)); 399 android::base::unique_fd dfd(open(dir_name.c_str(), O_RDONLY | O_DIRECTORY));
398 if (dfd == -1) { 400 if (dfd == -1) {
399 PLOG(ERROR) << "failed to open dir " << dir_name; 401 PLOG(ERROR) << "failed to open dir " << dir_name;
400 return -1; 402 return kUncryptFileOpenError;
401 } 403 }
402 if (fsync(dfd) == -1) { 404 if (fsync(dfd) == -1) {
403 PLOG(ERROR) << "failed to fsync " << dir_name; 405 PLOG(ERROR) << "failed to fsync " << dir_name;
404 return -1; 406 return kUncryptFileSyncError;
405 } 407 }
406 if (close(dfd.release()) == -1) { 408 if (close(dfd.release()) == -1) {
407 PLOG(ERROR) << "failed to close " << dir_name; 409 PLOG(ERROR) << "failed to close " << dir_name;
408 return -1; 410 return kUncryptFileCloseError;
409 } 411 }
410 return 0; 412 return 0;
411} 413}
@@ -444,45 +446,52 @@ static int uncrypt(const char* input_path, const char* map_file, const int socke
444 // and /sdcard we leave the file alone. 446 // and /sdcard we leave the file alone.
445 if (strncmp(path, "/data/", 6) == 0) { 447 if (strncmp(path, "/data/", 6) == 0) {
446 LOG(INFO) << "writing block map " << map_file; 448 LOG(INFO) << "writing block map " << map_file;
447 if (produce_block_map(path, map_file, blk_dev, encrypted, socket) != 0) { 449 return produce_block_map(path, map_file, blk_dev, encrypted, socket);
448 return 1;
449 }
450 } 450 }
451 451
452 return 0; 452 return 0;
453} 453}
454 454
455static bool uncrypt_wrapper(const char* input_path, const char* map_file, const int socket) { 455static bool uncrypt_wrapper(const char* input_path, const char* map_file, const int socket) {
456 // Initialize the uncrypt error to kUncryptErrorHolder.
457 if (!android::base::WriteStringToFile(android::base::StringPrintf(
458 "uncrypt_error: %d\n", kUncryptErrorHolder), UNCRYPT_STATUS)) {
459 PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
460 }
461
456 std::string package; 462 std::string package;
457 if (input_path == nullptr) { 463 if (input_path == nullptr) {
458 if (!find_uncrypt_package(UNCRYPT_PATH_FILE, &package)) { 464 if (!find_uncrypt_package(UNCRYPT_PATH_FILE, &package)) {
459 write_status_to_socket(-1, socket); 465 write_status_to_socket(-1, socket);
466 // Overwrite the error message.
467 if (!android::base::WriteStringToFile(android::base::StringPrintf(
468 "uncrypt_error: %d\n", kUncryptPackageMissingError), UNCRYPT_STATUS)) {
469 PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
470 }
460 return false; 471 return false;
461 } 472 }
462 input_path = package.c_str(); 473 input_path = package.c_str();
463 } 474 }
464 CHECK(map_file != nullptr); 475 CHECK(map_file != nullptr);
465 476
466#define UNCRYPT_TIME_HOLDER 0x7FFFFFFF
467 // Intialize the uncrypt time cost to a huge number so that we can tell from
468 // the statistics if an uncrypt fails to finish.
469 if (!android::base::WriteStringToFile(android::base::StringPrintf(
470 "uncrypt_time: %d\n", UNCRYPT_TIME_HOLDER), UNCRYPT_STATUS)) {
471 PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
472 }
473
474 auto start = std::chrono::system_clock::now(); 477 auto start = std::chrono::system_clock::now();
475 int status = uncrypt(input_path, map_file, socket); 478 int status = uncrypt(input_path, map_file, socket);
479 std::chrono::duration<double> duration = std::chrono::system_clock::now() - start;
480 int count = static_cast<int>(duration.count());
481
482 std::string uncrypt_message = android::base::StringPrintf("uncrypt_time: %d\n", count);
476 if (status != 0) { 483 if (status != 0) {
484 // Log the time cost and error code if uncrypt fails.
485 uncrypt_message += android::base::StringPrintf("uncrypt_error: %d\n", status);
486 if (!android::base::WriteStringToFile(uncrypt_message, UNCRYPT_STATUS)) {
487 PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
488 }
489
477 write_status_to_socket(-1, socket); 490 write_status_to_socket(-1, socket);
478 return false; 491 return false;
479 } 492 }
480 493
481 std::chrono::duration<double> duration = std::chrono::system_clock::now() - start; 494 if (!android::base::WriteStringToFile(uncrypt_message, UNCRYPT_STATUS)) {
482 int count = static_cast<int>(duration.count());
483 // Overwrite the uncrypt_time if uncrypt finishes successfully.
484 if (!android::base::WriteStringToFile(
485 android::base::StringPrintf("uncrypt_time: %d\n", count), UNCRYPT_STATUS)) {
486 PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS; 495 PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
487 } 496 }
488 497
@@ -560,6 +569,10 @@ int main(int argc, char** argv) {
560 } 569 }
561 570
562 if ((fstab = read_fstab()) == nullptr) { 571 if ((fstab = read_fstab()) == nullptr) {
572 if (!android::base::WriteStringToFile(android::base::StringPrintf(
573 "uncrypt_error: %d\n", kUncryptFstabReadError), UNCRYPT_STATUS)) {
574 PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
575 }
563 return 1; 576 return 1;
564 } 577 }
565 578
@@ -568,18 +581,30 @@ int main(int argc, char** argv) {
568 android::base::unique_fd service_socket(android_get_control_socket(UNCRYPT_SOCKET.c_str())); 581 android::base::unique_fd service_socket(android_get_control_socket(UNCRYPT_SOCKET.c_str()));
569 if (service_socket == -1) { 582 if (service_socket == -1) {
570 PLOG(ERROR) << "failed to open socket \"" << UNCRYPT_SOCKET << "\""; 583 PLOG(ERROR) << "failed to open socket \"" << UNCRYPT_SOCKET << "\"";
584 if (!android::base::WriteStringToFile(android::base::StringPrintf(
585 "uncrypt_error: %d\n", kUncryptSocketOpenError), UNCRYPT_STATUS)) {
586 PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
587 }
571 return 1; 588 return 1;
572 } 589 }
573 fcntl(service_socket, F_SETFD, FD_CLOEXEC); 590 fcntl(service_socket, F_SETFD, FD_CLOEXEC);
574 591
575 if (listen(service_socket, 1) == -1) { 592 if (listen(service_socket, 1) == -1) {
576 PLOG(ERROR) << "failed to listen on socket " << service_socket.get(); 593 PLOG(ERROR) << "failed to listen on socket " << service_socket.get();
594 if (!android::base::WriteStringToFile(android::base::StringPrintf(
595 "uncrypt_error: %d\n", kUncryptSocketListenError), UNCRYPT_STATUS)) {
596 PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
597 }
577 return 1; 598 return 1;
578 } 599 }
579 600
580 android::base::unique_fd socket_fd(accept4(service_socket, nullptr, nullptr, SOCK_CLOEXEC)); 601 android::base::unique_fd socket_fd(accept4(service_socket, nullptr, nullptr, SOCK_CLOEXEC));
581 if (socket_fd == -1) { 602 if (socket_fd == -1) {
582 PLOG(ERROR) << "failed to accept on socket " << service_socket.get(); 603 PLOG(ERROR) << "failed to accept on socket " << service_socket.get();
604 if (!android::base::WriteStringToFile(android::base::StringPrintf(
605 "uncrypt_error: %d\n", kUncryptSocketAcceptError), UNCRYPT_STATUS)) {
606 PLOG(WARNING) << "failed to write to " << UNCRYPT_STATUS;
607 }
583 return 1; 608 return 1;
584 } 609 }
585 610