Merge "init: fix first stage mount failure due to /dev/device-mapper not found"
diff --git a/adb/Android.mk b/adb/Android.mk
index d17b063..112bc80 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -363,6 +363,7 @@
 LOCAL_STRIP_MODULE := keep_symbols
 LOCAL_STATIC_LIBRARIES := \
     libadbd \
+    libavb_user \
     libbase \
     libbootloader_message \
     libfs_mgr \
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index b8f790d..a9b1540 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -761,55 +761,46 @@
     return RemoteShell(use_shell_protocol, shell_type_arg, escape_char, command);
 }
 
-static int adb_download_buffer(const char* service, const char* filename) {
-    std::string content;
-    if (!android::base::ReadFileToString(filename, &content)) {
-        fprintf(stderr, "error: couldn't read %s: %s\n", filename, strerror(errno));
-        return -1;
-    }
-
-    const uint8_t* data = reinterpret_cast<const uint8_t*>(content.data());
-    unsigned sz = content.size();
-
+static int adb_sideload_legacy(const char* filename, int in_fd, int size) {
     std::string error;
-    int fd = adb_connect(android::base::StringPrintf("%s:%d", service, sz), &error);
-    if (fd < 0) {
-        fprintf(stderr,"error: %s\n", error.c_str());
+    int out_fd = adb_connect(android::base::StringPrintf("sideload:%d", size), &error);
+    if (out_fd < 0) {
+        fprintf(stderr, "adb: pre-KitKat sideload connection failed: %s\n", error.c_str());
         return -1;
     }
 
     int opt = CHUNK_SIZE;
-    opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
+    opt = adb_setsockopt(out_fd, SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt));
 
-    unsigned total = sz;
-    const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
-
-    const char* x = strrchr(service, ':');
-    if (x) service = x + 1;
-
-    while (sz > 0) {
-        unsigned xfer = (sz > CHUNK_SIZE) ? CHUNK_SIZE : sz;
-        if (!WriteFdExactly(fd, ptr, xfer)) {
-            std::string error;
-            adb_status(fd, &error);
-            fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
-            adb_close(fd);
+    char buf[CHUNK_SIZE];
+    int total = size;
+    while (size > 0) {
+        unsigned xfer = (size > CHUNK_SIZE) ? CHUNK_SIZE : size;
+        if (!ReadFdExactly(in_fd, buf, xfer)) {
+            fprintf(stderr, "adb: failed to read data from %s: %s\n", filename, strerror(errno));
+            adb_close(out_fd);
             return -1;
         }
-        sz -= xfer;
-        ptr += xfer;
-        printf("sending: '%s' %4d%%    \r", filename, (int)(100LL - ((100LL * sz) / (total))));
+        if (!WriteFdExactly(out_fd, buf, xfer)) {
+            std::string error;
+            adb_status(out_fd, &error);
+            fprintf(stderr, "adb: failed to write data: %s\n", error.c_str());
+            adb_close(out_fd);
+            return -1;
+        }
+        size -= xfer;
+        printf("sending: '%s' %4d%%    \r", filename, (int)(100LL - ((100LL * size) / (total))));
         fflush(stdout);
     }
     printf("\n");
 
-    if (!adb_status(fd, &error)) {
-        fprintf(stderr,"* error response '%s' *\n", error.c_str());
-        adb_close(fd);
+    if (!adb_status(out_fd, &error)) {
+        fprintf(stderr, "adb: error response: %s\n", error.c_str());
+        adb_close(out_fd);
         return -1;
     }
 
-    adb_close(fd);
+    adb_close(out_fd);
     return 0;
 }
 
@@ -836,22 +827,17 @@
  */
 static int adb_sideload_host(const char* filename) {
     // TODO: use a LinePrinter instead...
-    fprintf(stdout, "opening '%s'...\n", filename);
-    fflush(stdout);
-
     struct stat sb;
     if (stat(filename, &sb) == -1) {
-        fprintf(stderr, "failed to stat file %s: %s\n", filename, strerror(errno));
+        fprintf(stderr, "adb: failed to stat file %s: %s\n", filename, strerror(errno));
         return -1;
     }
     unique_fd package_fd(adb_open(filename, O_RDONLY));
     if (package_fd == -1) {
-        fprintf(stderr, "failed to open file %s: %s\n", filename, strerror(errno));
+        fprintf(stderr, "adb: failed to open file %s: %s\n", filename, strerror(errno));
         return -1;
     }
 
-    fprintf(stdout, "connecting...\n");
-    fflush(stdout);
     std::string service = android::base::StringPrintf(
         "sideload-host:%d:%d", static_cast<int>(sb.st_size), SIDELOAD_HOST_BLOCK_SIZE);
     std::string error;
@@ -859,8 +845,9 @@
     if (device_fd < 0) {
         // Try falling back to the older (<= K) sideload method. Maybe this
         // is an older device that doesn't support sideload-host.
-        fprintf(stderr, "falling back to older sideload method...\n");
-        return adb_download_buffer("sideload", filename);
+        fprintf(stderr, "adb: sideload connection failed: %s\n", error.c_str());
+        fprintf(stderr, "adb: trying pre-KitKat sideload method...\n");
+        return adb_sideload_legacy(filename, package_fd, static_cast<int>(sb.st_size));
     }
 
     int opt = SIDELOAD_HOST_BLOCK_SIZE;
@@ -872,7 +859,7 @@
     int last_percent = -1;
     while (true) {
         if (!ReadFdExactly(device_fd, buf, 8)) {
-            fprintf(stderr, "* failed to read command: %s\n", strerror(errno));
+            fprintf(stderr, "adb: failed to read command: %s\n", strerror(errno));
             return -1;
         }
         buf[8] = '\0';
@@ -888,7 +875,7 @@
 
         size_t offset = block * SIDELOAD_HOST_BLOCK_SIZE;
         if (offset >= static_cast<size_t>(sb.st_size)) {
-            fprintf(stderr, "* attempt to read block %d past end\n", block);
+            fprintf(stderr, "adb: failed to read block %d past end\n", block);
             return -1;
         }
 
@@ -898,17 +885,17 @@
         }
 
         if (adb_lseek(package_fd, offset, SEEK_SET) != static_cast<int>(offset)) {
-            fprintf(stderr, "* failed to seek to package block: %s\n", strerror(errno));
+            fprintf(stderr, "adb: failed to seek to package block: %s\n", strerror(errno));
             return -1;
         }
         if (!ReadFdExactly(package_fd, buf, to_write)) {
-            fprintf(stderr, "* failed to read package block: %s\n", strerror(errno));
+            fprintf(stderr, "adb: failed to read package block: %s\n", strerror(errno));
             return -1;
         }
 
         if (!WriteFdExactly(device_fd, buf, to_write)) {
             adb_status(device_fd, &error);
-            fprintf(stderr,"* failed to write data '%s' *\n", error.c_str());
+            fprintf(stderr, "adb: failed to write data '%s' *\n", error.c_str());
             return -1;
         }
         xfer += to_write;
diff --git a/adb/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp
index d4dd256..b2b1c18 100644
--- a/adb/set_verity_enable_state_service.cpp
+++ b/adb/set_verity_enable_state_service.cpp
@@ -20,6 +20,7 @@
 
 #include <fcntl.h>
 #include <inttypes.h>
+#include <libavb_user/libavb_user.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <sys/stat.h>
@@ -45,13 +46,12 @@
 #endif
 
 /* Turn verity on/off */
-static int set_verity_enabled_state(int fd, const char *block_device,
-                                    const char* mount_point, bool enable)
-{
+static bool set_verity_enabled_state(int fd, const char* block_device, const char* mount_point,
+                                     bool enable) {
     if (!make_block_device_writable(block_device)) {
         WriteFdFmt(fd, "Could not make block device %s writable (%s).\n",
                    block_device, strerror(errno));
-        return -1;
+        return false;
     }
 
     fec::io fh(block_device, O_RDWR);
@@ -59,39 +59,84 @@
     if (!fh) {
         WriteFdFmt(fd, "Could not open block device %s (%s).\n", block_device, strerror(errno));
         WriteFdFmt(fd, "Maybe run adb root?\n");
-        return -1;
+        return false;
     }
 
     fec_verity_metadata metadata;
 
     if (!fh.get_verity_metadata(metadata)) {
         WriteFdFmt(fd, "Couldn't find verity metadata!\n");
-        return -1;
+        return false;
     }
 
     if (!enable && metadata.disabled) {
         WriteFdFmt(fd, "Verity already disabled on %s\n", mount_point);
-        return -1;
+        return false;
     }
 
     if (enable && !metadata.disabled) {
         WriteFdFmt(fd, "Verity already enabled on %s\n", mount_point);
-        return -1;
+        return false;
     }
 
     if (!fh.set_verity_status(enable)) {
         WriteFdFmt(fd, "Could not set verity %s flag on device %s with error %s\n",
                    enable ? "enabled" : "disabled",
                    block_device, strerror(errno));
-        return -1;
+        return false;
     }
 
     WriteFdFmt(fd, "Verity %s on %s\n", enable ? "enabled" : "disabled", mount_point);
-    return 0;
+    return true;
+}
+
+/* Helper function to get A/B suffix, if any. If the device isn't
+ * using A/B the empty string is returned. Otherwise either "_a",
+ * "_b", ... is returned.
+ *
+ * Note that since sometime in O androidboot.slot_suffix is deprecated
+ * and androidboot.slot should be used instead. Since bootloaders may
+ * be out of sync with the OS, we check both and for extra safety
+ * prepend a leading underscore if there isn't one already.
+ */
+static std::string get_ab_suffix() {
+    std::string ab_suffix = android::base::GetProperty("ro.boot.slot_suffix", "");
+    if (ab_suffix == "") {
+        ab_suffix = android::base::GetProperty("ro.boot.slot", "");
+    }
+    if (ab_suffix.size() > 0 && ab_suffix[0] != '_') {
+        ab_suffix = std::string("_") + ab_suffix;
+    }
+    return ab_suffix;
+}
+
+/* Use AVB to turn verity on/off */
+static bool set_avb_verity_enabled_state(int fd, AvbOps* ops, bool enable_verity) {
+    std::string ab_suffix = get_ab_suffix();
+
+    bool verity_enabled;
+    if (!avb_user_verity_get(ops, ab_suffix.c_str(), &verity_enabled)) {
+        WriteFdFmt(fd, "Error getting verity state\n");
+        return false;
+    }
+
+    if ((verity_enabled && enable_verity) || (!verity_enabled && !enable_verity)) {
+        WriteFdFmt(fd, "verity is already %s\n", verity_enabled ? "enabled" : "disabled");
+        return false;
+    }
+
+    if (!avb_user_verity_set(ops, ab_suffix.c_str(), enable_verity)) {
+        WriteFdFmt(fd, "Error setting verity\n");
+        return false;
+    }
+
+    WriteFdFmt(fd, "Successfully %s verity\n", enable_verity ? "enabled" : "disabled");
+    return true;
 }
 
 void set_verity_enabled_state_service(int fd, void* cookie) {
     unique_fd closer(fd);
+    bool any_changed = false;
 
     bool enable = (cookie != NULL);
     if (!kAllowDisableVerity) {
@@ -108,21 +153,37 @@
         return;
     }
 
-    // read all fstab entries at once from all sources
-    fstab = fs_mgr_read_fstab_default();
-    if (!fstab) {
-        WriteFdFmt(fd, "Failed to read fstab\nMaybe run adb root?\n");
-        return;
-    }
+    // Figure out if we're using VB1.0 or VB2.0 (aka AVB).
+    std::string vbmeta_hash = android::base::GetProperty("ro.boot.vbmeta.digest", "");
+    if (vbmeta_hash != "") {
+        // Yep, the system is using AVB (by contract, androidboot.vbmeta.hash is
+        // set by the bootloader when using AVB).
+        AvbOps* ops = avb_ops_user_new();
+        if (ops == nullptr) {
+            WriteFdFmt(fd, "Error getting AVB ops\n");
+            return;
+        }
+        if (set_avb_verity_enabled_state(fd, ops, enable)) {
+            any_changed = true;
+        }
+        avb_ops_user_free(ops);
+    } else {
+        // Not using AVB - assume VB1.0.
 
-    // Loop through entries looking for ones that vold manages.
-    bool any_changed = false;
-    for (int i = 0; i < fstab->num_entries; i++) {
-        if (fs_mgr_is_verified(&fstab->recs[i])) {
-            if (!set_verity_enabled_state(fd, fstab->recs[i].blk_device,
-                                          fstab->recs[i].mount_point,
-                                          enable)) {
-                any_changed = true;
+        // read all fstab entries at once from all sources
+        fstab = fs_mgr_read_fstab_default();
+        if (!fstab) {
+            WriteFdFmt(fd, "Failed to read fstab\nMaybe run adb root?\n");
+            return;
+        }
+
+        // Loop through entries looking for ones that vold manages.
+        for (int i = 0; i < fstab->num_entries; i++) {
+            if (fs_mgr_is_verified(&fstab->recs[i])) {
+                if (set_verity_enabled_state(fd, fstab->recs[i].blk_device,
+                                             fstab->recs[i].mount_point, enable)) {
+                    any_changed = true;
+                }
             }
         }
     }
diff --git a/fs_mgr/fs_mgr_avb_ops.cpp b/fs_mgr/fs_mgr_avb_ops.cpp
index edcfd54..caee4ec 100644
--- a/fs_mgr/fs_mgr_avb_ops.cpp
+++ b/fs_mgr/fs_mgr_avb_ops.cpp
@@ -96,7 +96,9 @@
     // We only need to provide the implementation of read_from_partition()
     // operation since that's all what is being used by the avb_slot_verify().
     // Other I/O operations are only required in bootloader but not in
-    // user-space so we set them as dummy operations.
+    // user-space so we set them as dummy operations. Also zero the entire
+    // struct so operations added in the future will be set to NULL.
+    memset(&avb_ops_, 0, sizeof(AvbOps));
     avb_ops_.read_from_partition = read_from_partition;
     avb_ops_.read_rollback_index = dummy_read_rollback_index;
     avb_ops_.validate_vbmeta_public_key = dummy_validate_vbmeta_public_key;
diff --git a/libcutils/native_handle.c b/libcutils/native_handle.c
index 9f4840a..95bbc41 100644
--- a/libcutils/native_handle.c
+++ b/libcutils/native_handle.c
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#define LOG_TAG "NativeHandle"
+#include <cutils/native_handle.h>
 
 #include <errno.h>
 #include <stdint.h>
@@ -22,15 +22,12 @@
 #include <string.h>
 #include <unistd.h>
 
-#include <android/log.h>
-#include <cutils/native_handle.h>
-
 static const int kMaxNativeFds = 1024;
 static const int kMaxNativeInts = 1024;
 
-native_handle_t* native_handle_init(char* storage, int numFds, int numInts)
-{
+native_handle_t* native_handle_init(char* storage, int numFds, int numInts) {
     if ((uintptr_t) storage % alignof(native_handle_t)) {
+        errno = EINVAL;
         return NULL;
     }
 
@@ -38,13 +35,12 @@
     handle->version = sizeof(native_handle_t);
     handle->numFds = numFds;
     handle->numInts = numInts;
-
     return handle;
 }
 
-native_handle_t* native_handle_create(int numFds, int numInts)
-{
+native_handle_t* native_handle_create(int numFds, int numInts) {
     if (numFds < 0 || numInts < 0 || numFds > kMaxNativeFds || numInts > kMaxNativeInts) {
+        errno = EINVAL;
         return NULL;
     }
 
@@ -58,14 +54,13 @@
     return h;
 }
 
-native_handle_t* native_handle_clone(const native_handle_t* handle)
-{
+native_handle_t* native_handle_clone(const native_handle_t* handle) {
     native_handle_t* clone = native_handle_create(handle->numFds, handle->numInts);
-    int i;
+    if (clone == NULL) return NULL;
 
-    for (i = 0; i < handle->numFds; i++) {
+    for (int i = 0; i < handle->numFds; i++) {
         clone->data[i] = dup(handle->data[i]);
-        if (clone->data[i] < 0) {
+        if (clone->data[i] == -1) {
             clone->numFds = i;
             native_handle_close(clone);
             native_handle_delete(clone);
@@ -74,30 +69,27 @@
     }
 
     memcpy(&clone->data[handle->numFds], &handle->data[handle->numFds],
-            sizeof(int) * handle->numInts);
+           sizeof(int) * handle->numInts);
 
     return clone;
 }
 
-int native_handle_delete(native_handle_t* h)
-{
+int native_handle_delete(native_handle_t* h) {
     if (h) {
-        if (h->version != sizeof(native_handle_t))
-            return -EINVAL;
+        if (h->version != sizeof(native_handle_t)) return -EINVAL;
         free(h);
     }
     return 0;
 }
 
-int native_handle_close(const native_handle_t* h)
-{
-    if (h->version != sizeof(native_handle_t))
-        return -EINVAL;
+int native_handle_close(const native_handle_t* h) {
+    if (h->version != sizeof(native_handle_t)) return -EINVAL;
 
+    int saved_errno = errno;
     const int numFds = h->numFds;
-    int i;
-    for (i=0 ; i<numFds ; i++) {
+    for (int i = 0; i < numFds; ++i) {
         close(h->data[i]);
     }
+    errno = saved_errno;
     return 0;
 }