fs_mgr: make is_device_secure() work even in the absence of properties.

During early mount property area is not initialized, and as a result an
'eng' build will always incorrectly be detected as a 'secure' build by
early mount code path resulting into verity error and consequent boot
loop.

The change here makes sure the is_device_secure() check works with /
without properties based on the 'eng' build based build flag so the
early mount code works fine both ways.

Bug: 35791581
Bug: 27805372

Test: Boot sailfish-{eng,userdebug} builds successfully w/ early
mount enabled

Change-Id: Icd101ccad56b669f49b60bbb3005d5be9f53b02b
Signed-off-by: Sandeep Patil <sspatil@google.com>
diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk
index f1a7ad6..2863a26 100644
--- a/fs_mgr/Android.mk
+++ b/fs_mgr/Android.mk
@@ -38,6 +38,9 @@
 ifneq (,$(filter userdebug,$(TARGET_BUILD_VARIANT)))
 LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
 endif
+ifneq (,$(filter eng,$(TARGET_BUILD_VARIANT)))
+LOCAL_CFLAGS += -DALLOW_SKIP_SECURE_CHECK=1
+endif
 include $(BUILD_STATIC_LIBRARY)
 
 include $(CLEAR_VARS)
diff --git a/fs_mgr/fs_mgr.cpp b/fs_mgr/fs_mgr.cpp
index 38bbe98..a50817e 100644
--- a/fs_mgr/fs_mgr.cpp
+++ b/fs_mgr/fs_mgr.cpp
@@ -435,16 +435,6 @@
     return ret;
 }
 
-static int device_is_secure() {
-    int ret = -1;
-    char value[PROP_VALUE_MAX];
-    ret = __system_property_get("ro.secure", value);
-    /* If error, we want to fail secure */
-    if (ret < 0)
-        return 1;
-    return strcmp(value, "0") ? 1 : 0;
-}
-
 static int device_is_force_encrypted() {
     int ret = -1;
     char value[PROP_VALUE_MAX];
@@ -673,6 +663,23 @@
     return -1;
 }
 
+bool is_device_secure() {
+    int ret = -1;
+    char value[PROP_VALUE_MAX];
+    ret = __system_property_get("ro.secure", value);
+    if (ret == 0) {
+#ifdef ALLOW_SKIP_SECURE_CHECK
+        // Allow eng builds to skip this check if the property
+        // is not readable (happens during early mount)
+        return false;
+#else
+        // If error and not an 'eng' build, we want to fail secure.
+        return true;
+#endif
+    }
+    return strcmp(value, "0") ? true : false;
+}
+
 /* When multiple fstab records share the same mount_point, it will
  * try to mount each one in turn, and ignore any duplicates after a
  * first successful mount.
@@ -750,7 +757,7 @@
                 /* Skips mounting the device. */
                 continue;
             }
-        } else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
+        } else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && is_device_secure()) {
             int rc = fs_mgr_setup_verity(&fstab->recs[i], true);
             if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
                 LINFO << "Verity disabled";
@@ -970,7 +977,7 @@
                 /* Skips mounting the device. */
                 continue;
             }
-        } else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
+        } else if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && is_device_secure()) {
             int rc = fs_mgr_setup_verity(&fstab->recs[i], true);
             if (__android_log_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
                 LINFO << "Verity disabled";
diff --git a/fs_mgr/fs_mgr_priv.h b/fs_mgr/fs_mgr_priv.h
index 3b1c56b..4e2ac8b 100644
--- a/fs_mgr/fs_mgr_priv.h
+++ b/fs_mgr/fs_mgr_priv.h
@@ -118,6 +118,7 @@
 int fs_mgr_test_access(const char *device);
 int fs_mgr_update_for_slotselect(struct fstab *fstab);
 bool is_dt_compatible();
+bool is_device_secure();
 
 __END_DECLS
 
diff --git a/fs_mgr/fs_mgr_verity.cpp b/fs_mgr/fs_mgr_verity.cpp
index 5b81a54..e8ed6a2 100644
--- a/fs_mgr/fs_mgr_verity.cpp
+++ b/fs_mgr/fs_mgr_verity.cpp
@@ -858,6 +858,13 @@
     const std::string mount_point(basename(fstab->mount_point));
     bool verified_at_boot = false;
 
+    // This is a public API and so deserves its own check to see if verity
+    // setup is needed at all.
+    if (!is_device_secure()) {
+        LINFO << "Verity setup skipped for " << mount_point;
+        return FS_MGR_SETUP_VERITY_SUCCESS;
+    }
+
     if (fec_open(&f, fstab->blk_device, O_RDONLY, FEC_VERITY_DISABLE,
             FEC_DEFAULT_ROOTS) < 0) {
         PERROR << "Failed to open '" << fstab->blk_device << "'";