Merge "lpdump: Fix slot handling on retrofit devices."
diff --git a/bootctl/Android.bp b/bootctl/Android.bp
index a58723c..e580415 100644
--- a/bootctl/Android.bp
+++ b/bootctl/Android.bp
@@ -9,8 +9,6 @@
     ],
     shared_libs: [
         "libhidlbase",
-        "libhidltransport",
-        "libhwbinder",
         "libutils",
         "android.hardware.boot@1.0",
     ],
diff --git a/boottime_tools/bootio/bootio_collector.cpp b/boottime_tools/bootio/bootio_collector.cpp
index 495a9aa..dc13525 100644
--- a/boottime_tools/bootio/bootio_collector.cpp
+++ b/boottime_tools/bootio/bootio_collector.cpp
@@ -275,10 +275,8 @@
             stats.rbytes += (newerSample->readbytes() - olderSample->readbytes());
             stats.wbytes += (newerSample->writebytes() - olderSample->writebytes());
 
-            // Note that all of these are explicitly `long long`s, not int64_t,
-            // so we can't use PRId64 here.
-#define NUMBER "%-13lld"
-            printf("%5lld - %-5lld  " NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER "%-9.2f\n",
+#define NUMBER "%-13" PRId64
+            printf("%5" PRId64 " - %-5" PRId64 "  " NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER "%-9.2f\n",
 #undef NUMBER
                    olderSample->uptime(),
                    newerSample->uptime(),
@@ -292,7 +290,7 @@
             isFirstSample = false;
         }
         printf("-----------------------------------------------------------------------------\n");
-#define NUMBER "%-13lld"
+#define NUMBER "%-13" PRId64
         printf("%-15s" NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER "\n",
 #undef NUMBER
                "Total",
diff --git a/libfscrypt/fscrypt.cpp b/libfscrypt/fscrypt.cpp
index adeb66a..5182afc 100644
--- a/libfscrypt/fscrypt.cpp
+++ b/libfscrypt/fscrypt.cpp
@@ -16,41 +16,29 @@
 
 #include "fscrypt/fscrypt.h"
 
-#include <array>
-
+#include <android-base/file.h>
+#include <android-base/logging.h>
+#include <android-base/unique_fd.h>
 #include <asm/ioctl.h>
-#include <dirent.h>
+#include <cutils/properties.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <linux/fs.h>
+#include <logwrap/logwrap.h>
 #include <string.h>
 #include <sys/stat.h>
-#include <sys/syscall.h>
 #include <sys/types.h>
 #include <unistd.h>
-
-#include <android-base/file.h>
-#include <android-base/logging.h>
-#include <cutils/properties.h>
-#include <logwrap/logwrap.h>
 #include <utils/misc.h>
 
+#include <array>
+
 #define FS_KEY_DESCRIPTOR_SIZE_HEX (2 * FS_KEY_DESCRIPTOR_SIZE + 1)
 
 /* modes not supported by upstream kernel, so not in <linux/fs.h> */
 #define FS_ENCRYPTION_MODE_AES_256_HEH      126
 #define FS_ENCRYPTION_MODE_PRIVATE          127
 
-/* new definition, not yet in Bionic's <linux/fs.h> */
-#ifndef FS_ENCRYPTION_MODE_ADIANTUM
-#define FS_ENCRYPTION_MODE_ADIANTUM         9
-#endif
-
-/* new definition, not yet in Bionic's <linux/fs.h> */
-#ifndef FS_POLICY_FLAG_DIRECT_KEY
-#define FS_POLICY_FLAG_DIRECT_KEY           0x4
-#endif
-
 #define HEX_LOOKUP "0123456789abcdef"
 
 bool fscrypt_is_native() {
@@ -88,36 +76,6 @@
     hex[FS_KEY_DESCRIPTOR_SIZE_HEX - 1] = '\0';
 }
 
-static bool is_dir_empty(const char *dirname, bool *is_empty)
-{
-    int n = 0;
-    auto dirp = std::unique_ptr<DIR, int (*)(DIR*)>(opendir(dirname), closedir);
-    if (!dirp) {
-        PLOG(ERROR) << "Unable to read directory: " << dirname;
-        return false;
-    }
-    for (;;) {
-        errno = 0;
-        auto entry = readdir(dirp.get());
-        if (!entry) {
-            if (errno) {
-                PLOG(ERROR) << "Unable to read directory: " << dirname;
-                return false;
-            }
-            break;
-        }
-        if (strcmp(entry->d_name, "lost+found") != 0) { // Skip lost+found
-            ++n;
-            if (n > 2) {
-                *is_empty = false;
-                return true;
-            }
-        }
-    }
-    *is_empty = true;
-    return true;
-}
-
 static uint8_t fscrypt_get_policy_flags(int filenames_encryption_mode) {
     if (filenames_encryption_mode == FS_ENCRYPTION_MODE_AES_256_CTS) {
         // Use legacy padding with our original filenames encryption mode.
@@ -135,107 +93,9 @@
     return FS_POLICY_FLAGS_PAD_16;
 }
 
-static bool fscrypt_policy_set(const char *directory, const char *policy,
-                               size_t policy_length,
-                               int contents_encryption_mode,
-                               int filenames_encryption_mode) {
-    if (policy_length != FS_KEY_DESCRIPTOR_SIZE) {
-        LOG(ERROR) << "Policy wrong length: " << policy_length;
-        return false;
-    }
-    char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-    policy_to_hex(policy, policy_hex);
-
-    int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to open directory " << directory;
-        return false;
-    }
-
+static bool fscrypt_is_encrypted(int fd) {
     fscrypt_policy fp;
-    fp.version = 0;
-    fp.contents_encryption_mode = contents_encryption_mode;
-    fp.filenames_encryption_mode = filenames_encryption_mode;
-    fp.flags = fscrypt_get_policy_flags(filenames_encryption_mode);
-    memcpy(fp.master_key_descriptor, policy, FS_KEY_DESCRIPTOR_SIZE);
-    if (ioctl(fd, FS_IOC_SET_ENCRYPTION_POLICY, &fp)) {
-        PLOG(ERROR) << "Failed to set encryption policy for " << directory  << " to " << policy_hex
-            << " modes " << contents_encryption_mode << "/" << filenames_encryption_mode;
-        close(fd);
-        return false;
-    }
-    close(fd);
-
-    LOG(INFO) << "Policy for " << directory << " set to " << policy_hex
-        << " modes " << contents_encryption_mode << "/" << filenames_encryption_mode;
-    return true;
-}
-
-static bool fscrypt_policy_get(const char *directory, char *policy,
-                               size_t policy_length,
-                               int contents_encryption_mode,
-                               int filenames_encryption_mode) {
-    if (policy_length != FS_KEY_DESCRIPTOR_SIZE) {
-        LOG(ERROR) << "Policy wrong length: " << policy_length;
-        return false;
-    }
-
-    int fd = open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
-    if (fd == -1) {
-        PLOG(ERROR) << "Failed to open directory " << directory;
-        return false;
-    }
-
-    fscrypt_policy fp;
-    memset(&fp, 0, sizeof(fscrypt_policy));
-    if (ioctl(fd, FS_IOC_GET_ENCRYPTION_POLICY, &fp) != 0) {
-        PLOG(ERROR) << "Failed to get encryption policy for " << directory;
-        close(fd);
-        log_ls(directory);
-        return false;
-    }
-    close(fd);
-
-    if ((fp.version != 0)
-            || (fp.contents_encryption_mode != contents_encryption_mode)
-            || (fp.filenames_encryption_mode != filenames_encryption_mode)
-            || (fp.flags !=
-                fscrypt_get_policy_flags(filenames_encryption_mode))) {
-        LOG(ERROR) << "Failed to find matching encryption policy for " << directory;
-        return false;
-    }
-    memcpy(policy, fp.master_key_descriptor, FS_KEY_DESCRIPTOR_SIZE);
-
-    return true;
-}
-
-static bool fscrypt_policy_check(const char *directory, const char *policy,
-                                 size_t policy_length,
-                                 int contents_encryption_mode,
-                                 int filenames_encryption_mode) {
-    if (policy_length != FS_KEY_DESCRIPTOR_SIZE) {
-        LOG(ERROR) << "Policy wrong length: " << policy_length;
-        return false;
-    }
-    char existing_policy[FS_KEY_DESCRIPTOR_SIZE];
-    if (!fscrypt_policy_get(directory, existing_policy, FS_KEY_DESCRIPTOR_SIZE,
-                            contents_encryption_mode,
-                            filenames_encryption_mode)) return false;
-    char existing_policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-
-    policy_to_hex(existing_policy, existing_policy_hex);
-
-    if (memcmp(policy, existing_policy, FS_KEY_DESCRIPTOR_SIZE) != 0) {
-        char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
-        policy_to_hex(policy, policy_hex);
-        LOG(ERROR) << "Found policy " << existing_policy_hex << " at " << directory
-                   << " which doesn't match expected value " << policy_hex;
-        log_ls(directory);
-        return false;
-    }
-    LOG(INFO) << "Found policy " << existing_policy_hex << " at " << directory
-              << " which matches expected value";
-    return true;
+    return ioctl(fd, FS_IOC_GET_ENCRYPTION_POLICY, &fp) == 0;
 }
 
 int fscrypt_policy_ensure(const char *directory, const char *policy,
@@ -270,14 +130,55 @@
         return -1;
     }
 
-    bool is_empty;
-    if (!is_dir_empty(directory, &is_empty)) return -1;
-    if (is_empty) {
-        if (!fscrypt_policy_set(directory, policy, policy_length,
-                                contents_mode, filenames_mode)) return -1;
+    if (policy_length != FS_KEY_DESCRIPTOR_SIZE) {
+        LOG(ERROR) << "Policy wrong length: " << policy_length;
+        return -1;
+    }
+    char policy_hex[FS_KEY_DESCRIPTOR_SIZE_HEX];
+    policy_to_hex(policy, policy_hex);
+
+    fscrypt_policy fp;
+    fp.version = 0;
+    fp.contents_encryption_mode = contents_mode;
+    fp.filenames_encryption_mode = filenames_mode;
+    fp.flags = fscrypt_get_policy_flags(filenames_mode);
+    memcpy(fp.master_key_descriptor, policy, FS_KEY_DESCRIPTOR_SIZE);
+
+    android::base::unique_fd fd(open(directory, O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC));
+    if (fd == -1) {
+        PLOG(ERROR) << "Failed to open directory " << directory;
+        return -1;
+    }
+
+    bool already_encrypted = fscrypt_is_encrypted(fd);
+
+    // FS_IOC_SET_ENCRYPTION_POLICY will set the policy if the directory is
+    // unencrypted; otherwise it will verify that the existing policy matches.
+    // Setting the policy will fail if the directory is already nonempty.
+    if (ioctl(fd, FS_IOC_SET_ENCRYPTION_POLICY, &fp) != 0) {
+        std::string reason;
+        switch (errno) {
+            case EEXIST:
+                reason = "The directory already has a different encryption policy.";
+                break;
+            default:
+                reason = strerror(errno);
+                break;
+        }
+        LOG(ERROR) << "Failed to set encryption policy of " << directory << " to " << policy_hex
+                   << " modes " << contents_mode << "/" << filenames_mode << ": " << reason;
+        if (errno == ENOTEMPTY) {
+            log_ls(directory);
+        }
+        return -1;
+    }
+
+    if (already_encrypted) {
+        LOG(INFO) << "Verified that " << directory << " has the encryption policy " << policy_hex
+                  << " modes " << contents_mode << "/" << filenames_mode;
     } else {
-        if (!fscrypt_policy_check(directory, policy, policy_length,
-                                  contents_mode, filenames_mode)) return -1;
+        LOG(INFO) << "Encryption policy of " << directory << " set to " << policy_hex << " modes "
+                  << contents_mode << "/" << filenames_mode;
     }
     return 0;
 }
diff --git a/libjsonpb/parse/jsonpb.cpp b/libjsonpb/parse/jsonpb.cpp
index bd95dbd..d7feb67 100644
--- a/libjsonpb/parse/jsonpb.cpp
+++ b/libjsonpb/parse/jsonpb.cpp
@@ -27,7 +27,6 @@
 
 using google::protobuf::DescriptorPool;
 using google::protobuf::Message;
-using google::protobuf::scoped_ptr;
 using google::protobuf::util::NewTypeResolverForDescriptorPool;
 using google::protobuf::util::TypeResolver;
 
@@ -38,7 +37,7 @@
 }
 
 ErrorOr<std::string> MessageToJsonString(const Message& message) {
-    scoped_ptr<TypeResolver> resolver(
+    std::unique_ptr<TypeResolver> resolver(
             NewTypeResolverForDescriptorPool(kTypeUrlPrefix, DescriptorPool::generated_pool()));
 
     google::protobuf::util::JsonOptions options;
@@ -56,7 +55,7 @@
 
 namespace internal {
 ErrorOr<std::monostate> JsonStringToMessage(const std::string& content, Message* message) {
-    scoped_ptr<TypeResolver> resolver(
+    std::unique_ptr<TypeResolver> resolver(
             NewTypeResolverForDescriptorPool(kTypeUrlPrefix, DescriptorPool::generated_pool()));
 
     std::string binary;
diff --git a/libjsonpb/verify/test.cpp b/libjsonpb/verify/test.cpp
index 2ffc923..31a734a 100644
--- a/libjsonpb/verify/test.cpp
+++ b/libjsonpb/verify/test.cpp
@@ -122,9 +122,9 @@
   EXPECT_TRUE(AllFieldsAreKnown(*object, json, &error)) << error;
 }
 
-// JSON field name is lowerCamelCase of Proto field name;
-// AllFieldsAreKnown should return false. Although the lowerCamelCase name is a
-// valid key accepted by Protobuf's JSON parser, we explicitly disallow the
+// JSON field name is lower/UpperCamelCase of Proto field name;
+// AllFieldsAreKnown should return false. Although the lower/UpperCamelCase name
+// is a valid key accepted by Protobuf's JSON parser, we explicitly disallow the
 // behavior.
 TEST_F(JsonKeyTest, NoJsonNameFooBar) {
   EXPECT_EQ("fooBar", GetFieldJsonName<NoJsonName>("foo_bar"));
@@ -137,13 +137,13 @@
 }
 
 TEST_F(JsonKeyTest, NoJsonNameBazQux) {
-  EXPECT_EQ("bazQux", GetFieldJsonName<NoJsonName>("BazQux"));
-  TestParseOkWithUnknownKey<NoJsonName>("BazQux", "bazQux");
+  EXPECT_EQ("BazQux", GetFieldJsonName<NoJsonName>("BazQux"));
+  // No test for BazQux because its JSON name is the same as field_name
 }
 
 TEST_F(JsonKeyTest, NoJsonNameQuxQuux) {
-  EXPECT_EQ("qUXQUUX", GetFieldJsonName<NoJsonName>("QUX_QUUX"));
-  TestParseOkWithUnknownKey<NoJsonName>("QUX_QUUX", "qUXQUUX");
+  EXPECT_EQ("QUXQUUX", GetFieldJsonName<NoJsonName>("QUX_QUUX"));
+  TestParseOkWithUnknownKey<NoJsonName>("QUX_QUUX", "QUXQUUX");
 }
 
 class EmbeddedJsonKeyTest : public LibJsonpbVerifyTest {
@@ -198,16 +198,16 @@
   EXPECT_EQ("test", object->repeated_with_json_name().begin()->barbaz());
 }
 
-TEST_F(EmbeddedJsonKeyTest, BazQux) {
-  auto object =
-      TestEmbeddedError("{\"no_json_name\": {\"bazQux\": \"test\"}}", "bazQux");
+TEST_F(EmbeddedJsonKeyTest, NoJsonName) {
+  auto object = TestEmbeddedError(
+      "{\"no_json_name\": {\"QUXQUUX\": \"test\"}}", "QUXQUUX");
   ASSERT_TRUE(object.ok()) << object.error();
-  EXPECT_EQ("test", object->no_json_name().bazqux());
+  EXPECT_EQ("test", object->no_json_name().qux_quux());
 }
 
 TEST_F(EmbeddedJsonKeyTest, QuxQuux) {
   auto object = TestEmbeddedError(
-      "{\"repeated_no_json_name\": [{\"qUXQUUX\": \"test\"}]}", "qUXQUUX");
+      "{\"repeated_no_json_name\": [{\"QUXQUUX\": \"test\"}]}", "QUXQUUX");
   ASSERT_TRUE(object.ok()) << object.error();
   ASSERT_EQ(1u, object->repeated_no_json_name().size());
   EXPECT_EQ("test", object->repeated_no_json_name().begin()->qux_quux());
diff --git a/toolchain-extras/profile-globals.c b/toolchain-extras/profile-globals.c
index 95bd46d..309f060 100644
--- a/toolchain-extras/profile-globals.c
+++ b/toolchain-extras/profile-globals.c
@@ -17,6 +17,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
+#include <sys/stat.h>
 #include <sys/types.h>
 
 // This file provides a wrapper for getenv that appends the userid (geteuid())
@@ -38,5 +39,6 @@
   }
 
   sprintf(modified_gcov_prefix, "%s/%u", __real_getenv(name), geteuid());
+  mkdir(modified_gcov_prefix, 0777);
   return modified_gcov_prefix;
 }
diff --git a/verity/hash_tree_builder.cpp b/verity/hash_tree_builder.cpp
index 197c38e..d061ca5 100644
--- a/verity/hash_tree_builder.cpp
+++ b/verity/hash_tree_builder.cpp
@@ -197,7 +197,9 @@
       return false;
     }
     leftover_.clear();
-    data += append_len;
+    if (data != nullptr) {
+      data += append_len;
+    }
     len -= append_len;
   }
   if (len % block_size_ != 0) {