Revert "Revert "adb: support /oem partition""

This reverts commit 6084a0124f868c7ec43f6c415a27a168f27ff694.

The original build breakage is fixed by (a) building the verity
code for eng builds as well as userdebug builds and (b) moving
the exported remount service functions into a new header file.

Change-Id: Ice0c4f97d4db38ab7eb333c7a6e56bbd11123f5b
diff --git a/adb/Android.mk b/adb/Android.mk
index 7cfbcb9..8d38077 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -199,7 +199,7 @@
 LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
 endif
 
-ifneq (,$(filter userdebug,$(TARGET_BUILD_VARIANT)))
+ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
 LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
 endif
 
diff --git a/adb/adb.h b/adb/adb.h
index 1aeac6b..749515c 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -298,9 +298,6 @@
 
 #if !ADB_HOST
 void framebuffer_service(int fd, void *cookie);
-// Allow enable-verity to write to system and vendor block devices
-int make_block_device_writable(const char* dev);
-void remount_service(int fd, void *cookie);
 void set_verity_enabled_state_service(int fd, void* cookie);
 #endif
 
diff --git a/adb/commandline.cpp b/adb/commandline.cpp
index ecaab83..4538b04 100644
--- a/adb/commandline.cpp
+++ b/adb/commandline.cpp
@@ -43,7 +43,8 @@
 static int do_cmd(transport_type ttype, const char* serial, const char *cmd, ...);
 
 int find_sync_dirs(const char *srcarg,
-        char **android_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out);
+        char **system_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out,
+        char **oem_srcdir_out);
 int install_app(transport_type transport, const char* serial, int argc,
                 const char** argv);
 int install_multiple_app(transport_type transport, const char* serial, int argc,
@@ -206,7 +207,7 @@
         "  adb get-serialno             - prints: <serial-number>\n"
         "  adb get-devpath              - prints: <device-path>\n"
         "  adb status-window            - continuously print device status for a specified device\n"
-        "  adb remount                  - remounts the /system and /vendor (if present) partitions on the device read-write\n"
+        "  adb remount                  - remounts the /system, /vendor (if present) and /oem (if present) partitions on the device read-write\n"
         "  adb reboot [bootloader|recovery] - reboots the device, optionally into the bootloader or recovery program\n"
         "  adb reboot-bootloader        - reboots the device into the bootloader\n"
         "  adb root                     - restarts the adbd daemon with root permissions\n"
@@ -222,9 +223,9 @@
         "adb sync notes: adb sync [ <directory> ]\n"
         "  <localdir> can be interpreted in several ways:\n"
         "\n"
-        "  - If <directory> is not specified, /system, /vendor (if present), and /data partitions will be updated.\n"
+        "  - If <directory> is not specified, /system, /vendor (if present), /oem (if present) and /data partitions will be updated.\n"
         "\n"
-        "  - If it is \"system\", \"vendor\" or \"data\", only the corresponding partition\n"
+        "  - If it is \"system\", \"vendor\", \"oem\" or \"data\", only the corresponding partition\n"
         "    is updated.\n"
         "\n"
         "environmental variables:\n"
@@ -1633,7 +1634,8 @@
     }
     else if (!strcmp(argv[0], "sync")) {
         const char* srcarg;
-        char *android_srcpath, *data_srcpath, *vendor_srcpath;
+        char *system_srcpath, *data_srcpath, *vendor_srcpath, *oem_srcpath;
+
         int listonly = 0;
 
         int ret;
@@ -1653,18 +1655,22 @@
         } else {
             return usage();
         }
-        ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath, &vendor_srcpath);
+        ret = find_sync_dirs(srcarg, &system_srcpath, &data_srcpath, &vendor_srcpath,
+                &oem_srcpath);
         if (ret != 0) return usage();
 
-        if (android_srcpath != NULL)
-            ret = do_sync_sync(android_srcpath, "/system", listonly);
+        if (system_srcpath != NULL)
+            ret = do_sync_sync(system_srcpath, "/system", listonly);
         if (ret == 0 && vendor_srcpath != NULL)
             ret = do_sync_sync(vendor_srcpath, "/vendor", listonly);
+        if(ret == 0 && oem_srcpath != NULL)
+            ret = do_sync_sync(oem_srcpath, "/oem", listonly);
         if (ret == 0 && data_srcpath != NULL)
             ret = do_sync_sync(data_srcpath, "/data", listonly);
 
-        free(android_srcpath);
+        free(system_srcpath);
         free(vendor_srcpath);
+        free(oem_srcpath);
         free(data_srcpath);
         return ret;
     }
@@ -1770,49 +1776,60 @@
 }
 
 int find_sync_dirs(const char *srcarg,
-        char **android_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out)
+        char **system_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out,
+        char **oem_srcdir_out)
 {
-    char *android_srcdir = NULL, *data_srcdir = NULL, *vendor_srcdir = NULL;
+    char *system_srcdir = NULL, *data_srcdir = NULL, *vendor_srcdir = NULL, *oem_srcdir = NULL;
     struct stat st;
 
     if(srcarg == NULL) {
-        android_srcdir = product_file("system");
+        system_srcdir = product_file("system");
         data_srcdir = product_file("data");
         vendor_srcdir = product_file("vendor");
-        /* Check if vendor partition exists */
+        oem_srcdir = product_file("oem");
+        // Check if vendor partition exists.
         if (lstat(vendor_srcdir, &st) || !S_ISDIR(st.st_mode))
             vendor_srcdir = NULL;
+        // Check if oem partition exists.
+        if (lstat(oem_srcdir, &st) || !S_ISDIR(st.st_mode))
+            oem_srcdir = NULL;
     } else {
-        /* srcarg may be "data", "system" or NULL.
-         * if srcarg is NULL, then both data and system are synced
-         */
+        // srcarg may be "data", "system", "vendor", "oem" or NULL.
+        // If srcarg is NULL, then all partitions are synced.
         if(strcmp(srcarg, "system") == 0) {
-            android_srcdir = product_file("system");
+            system_srcdir = product_file("system");
         } else if(strcmp(srcarg, "data") == 0) {
             data_srcdir = product_file("data");
         } else if(strcmp(srcarg, "vendor") == 0) {
             vendor_srcdir = product_file("vendor");
+        } else if(strcmp(srcarg, "oem") == 0) {
+            oem_srcdir = product_file("oem");
         } else {
-            /* It's not "system", "vendor", or "data".
-             */
+            // It's not "system", "data", "vendor", or "oem".
             return 1;
         }
     }
 
-    if(android_srcdir_out != NULL)
-        *android_srcdir_out = android_srcdir;
+    if(system_srcdir_out != NULL)
+        *system_srcdir_out = system_srcdir;
     else
-        free(android_srcdir);
+        free(system_srcdir);
 
     if(vendor_srcdir_out != NULL)
         *vendor_srcdir_out = vendor_srcdir;
     else
         free(vendor_srcdir);
 
+    if(oem_srcdir_out != NULL)
+        *oem_srcdir_out = oem_srcdir;
+    else
+        free(oem_srcdir);
+
     if(data_srcdir_out != NULL)
-            *data_srcdir_out = data_srcdir;
-        else
-            free(data_srcdir);
+        *data_srcdir_out = data_srcdir;
+    else
+        free(data_srcdir);
+
     return 0;
 }
 
diff --git a/adb/file_sync_service.cpp b/adb/file_sync_service.cpp
index 2864b38..ac01678 100644
--- a/adb/file_sync_service.cpp
+++ b/adb/file_sync_service.cpp
@@ -33,15 +33,11 @@
 #include "file_sync_service.h"
 #include "private/android_filesystem_config.h"
 
-/* TODO: use fs_config to configure permissions on /data */
-static bool is_on_system(const char *name) {
-    const char *SYSTEM = "/system/";
-    return (strncmp(SYSTEM, name, strlen(SYSTEM)) == 0);
-}
-
-static bool is_on_vendor(const char *name) {
-    const char *VENDOR = "/vendor/";
-    return (strncmp(VENDOR, name, strlen(VENDOR)) == 0);
+static bool should_use_fs_config(const char* path) {
+    // TODO: use fs_config to configure permissions on /data.
+    return strncmp("/system/", path, strlen("/system/")) == 0 ||
+           strncmp("/vendor/", path, strlen("/vendor/")) == 0 ||
+           strncmp("/oem/", path, strlen("/oem/")) == 0;
 }
 
 static int mkdirs(char *name)
@@ -59,7 +55,7 @@
         x = adb_dirstart(x);
         if(x == 0) return 0;
         *x = 0;
-        if (is_on_system(name) || is_on_vendor(name)) {
+        if (should_use_fs_config(name)) {
             fs_config(name, 1, &uid, &gid, &mode, &cap);
         }
         ret = adb_mkdir(name, mode);
@@ -368,7 +364,7 @@
     if(*tmp == '/') {
         tmp++;
     }
-    if (is_on_system(path) || is_on_vendor(path)) {
+    if (should_use_fs_config(path)) {
         fs_config(tmp, 0, &uid, &gid, &mode, &cap);
     }
     return handle_send_file(s, path, uid, gid, mode, buffer, do_unlink);
diff --git a/adb/remount_service.cpp b/adb/remount_service.cpp
index 414b316..a83d5b1 100644
--- a/adb/remount_service.cpp
+++ b/adb/remount_service.cpp
@@ -23,6 +23,8 @@
 #include <sys/mount.h>
 #include <unistd.h>
 
+#include <string>
+
 #include "sysdeps.h"
 
 #define  TRACE_TAG  TRACE_ADB
@@ -32,10 +34,10 @@
 
 static int system_ro = 1;
 static int vendor_ro = 1;
+static int oem_ro = 1;
 
 /* Returns the device used to mount a directory in /proc/mounts */
-static char *find_mount(const char *dir)
-{
+static std::string find_mount(const char *dir) {
     FILE* fp;
     struct mntent* mentry;
     char* device = NULL;
@@ -45,7 +47,7 @@
     }
     while ((mentry = getmntent(fp)) != NULL) {
         if (strcmp(dir, mentry->mnt_dir) == 0) {
-            device = strdup(mentry->mnt_fsname);
+            device = mentry->mnt_fsname;
             break;
         }
     }
@@ -53,64 +55,53 @@
     return device;
 }
 
-static int hasVendorPartition()
-{
-    struct stat info;
-    if (!lstat("/vendor", &info))
-        if ((info.st_mode & S_IFMT) == S_IFDIR)
-          return true;
-    return false;
+static bool has_partition(const char* path) {
+    struct stat sb;
+    return (lstat(path, &sb) == 0 && S_ISDIR(sb.st_mode));
 }
 
-int make_block_device_writable(const char* dev)
-{
-    int fd = -1;
+int make_block_device_writable(const std::string& dev) {
+    int fd = unix_open(dev.c_str(), O_RDONLY | O_CLOEXEC);
+    if (fd == -1) {
+        return -1;
+    }
+
+    int result = -1;
     int OFF = 0;
-    int rc = -1;
-
-    if (!dev)
-        goto errout;
-
-    fd = unix_open(dev, O_RDONLY | O_CLOEXEC);
-    if (fd < 0)
-        goto errout;
-
-    if (ioctl(fd, BLKROSET, &OFF)) {
-        goto errout;
+    if (!ioctl(fd, BLKROSET, &OFF)) {
+        result = 0;
     }
+    adb_close(fd);
 
-    rc = 0;
-
-errout:
-    if (fd >= 0) {
-        adb_close(fd);
-    }
-    return rc;
+    return result;
 }
 
-/* Init mounts /system as read only, remount to enable writes. */
-static int remount(const char* dir, int* dir_ro)
-{
-    char *dev = 0;
-    int rc = -1;
-
-    dev = find_mount(dir);
-
-    if (!dev || make_block_device_writable(dev)) {
-        goto errout;
+// Init mounts /system as read only, remount to enable writes.
+static int remount(const char* dir, int* dir_ro) {
+    std::string dev(find_mount(dir));
+    if (dev.empty() || make_block_device_writable(dev)) {
+        return -1;
     }
 
-    rc = mount(dev, dir, "none", MS_REMOUNT, NULL);
+    int rc = mount(dev.c_str(), dir, "none", MS_REMOUNT, NULL);
     *dir_ro = rc;
-
-errout:
-    free(dev);
     return rc;
 }
 
-void remount_service(int fd, void *cookie)
-{
-    char buffer[200];
+static bool remount_partition(int fd, const char* partition, int* ro) {
+  if (!has_partition(partition)) {
+    return true;
+  }
+  if (remount(partition, ro)) {
+    char buf[200];
+    snprintf(buf, sizeof(buf), "remount of %s failed: %s\n", partition, strerror(errno));
+    WriteStringFully(fd, buf);
+    return false;
+  }
+  return true;
+}
+
+void remount_service(int fd, void* cookie) {
     char prop_buf[PROPERTY_VALUE_MAX];
 
     if (getuid() != 0) {
@@ -133,6 +124,7 @@
     if (system_verified || vendor_verified) {
         // Allow remount but warn of likely bad effects
         bool both = system_verified && vendor_verified;
+        char buffer[200];
         snprintf(buffer, sizeof(buffer),
                  "dm_verity is enabled on the %s%s%s partition%s.\n",
                  system_verified ? "system" : "",
@@ -147,23 +139,12 @@
         WriteStringFully(fd, buffer);
     }
 
-    if (remount("/system", &system_ro)) {
-        snprintf(buffer, sizeof(buffer), "remount of system failed: %s\n",strerror(errno));
-        WriteStringFully(fd, buffer);
-    }
+    bool success = true;
+    success &= remount_partition(fd, "/system", &system_ro);
+    success &= remount_partition(fd, "/vendor", &vendor_ro);
+    success &= remount_partition(fd, "/oem", &oem_ro);
 
-    if (hasVendorPartition()) {
-        if (remount("/vendor", &vendor_ro)) {
-            snprintf(buffer, sizeof(buffer), "remount of vendor failed: %s\n",strerror(errno));
-            WriteStringFully(fd, buffer);
-        }
-    }
-
-    if (!system_ro && (!vendor_ro || !hasVendorPartition()))
-        WriteStringFully(fd, "remount succeeded\n");
-    else {
-        WriteStringFully(fd, "remount failed\n");
-    }
+    WriteStringFully(fd, success ? "remount succeeded\n" : "remount failed\n");
 
     adb_close(fd);
 }
diff --git a/adb/remount_service.h b/adb/remount_service.h
new file mode 100644
index 0000000..e1763cf
--- /dev/null
+++ b/adb/remount_service.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _REMOUNT_SERVICE_H_
+#define _REMOUNT_SERVICE_H_
+
+#include <string>
+
+int make_block_device_writable(const std::string&);
+void remount_service(int, void*);
+
+#endif
diff --git a/adb/services.cpp b/adb/services.cpp
index 600eb30..e7bf6b0 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -38,6 +38,7 @@
 #include "adb.h"
 #include "adb_io.h"
 #include "file_sync_service.h"
+#include "remount_service.h"
 #include "transport.h"
 
 typedef struct stinfo stinfo;
diff --git a/adb/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp
index 85637f2..139b074 100644
--- a/adb/set_verity_enable_state_service.cpp
+++ b/adb/set_verity_enable_state_service.cpp
@@ -26,6 +26,7 @@
 #include "cutils/properties.h"
 #include "ext4_sb.h"
 #include "fs_mgr.h"
+#include "remount_service.h"
 #include "sysdeps.h"
 
 #define FSTAB_PREFIX "/fstab."