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
diff --git a/adb/client/incremental.cpp b/adb/client/incremental.cpp
index a8b0ab3..1e985ed 100644
--- a/adb/client/incremental.cpp
+++ b/adb/client/incremental.cpp
@@ -42,7 +42,7 @@
     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 @@
     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 @@
                     "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::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 @@
         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 @@
         }
 
         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,9 +151,12 @@
             return false;
         }
 
-        auto [fd, _] = read_signature(st.st_size, file, true);
-        if (!fd.ok()) {
-            return false;
+        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;
diff --git a/adb/client/incremental_server.cpp b/adb/client/incremental_server.cpp
index bfe18c0..0654a11 100644
--- a/adb/client/incremental_server.cpp
+++ b/adb/client/incremental_server.cpp
@@ -171,6 +171,8 @@
 
     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 @@
 
 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 @@
 
     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);
diff --git a/adb/client/incremental_utils.h b/adb/client/incremental_utils.h
index fe2914d..4ad60dd 100644
--- a/adb/client/incremental_utils.h
+++ b/adb/client/incremental_utils.h
@@ -33,6 +33,7 @@
 constexpr int kBlockSize = 4096;
 constexpr int kSha256DigestSize = 32;
 constexpr int kDigestSize = kSha256DigestSize;
+constexpr int kMaxSignatureSize = 8096;  // incrementalfs.h
 
 constexpr std::string_view IDSIG = ".idsig";