Revert "Revert "Enable verity on userdebug, and add disable-verity to adb""
This reverts commit 152d2d4234ba89e0c20c4af13e291b6049a7bc33.
Fixed build error, and also fixed memory leak spotted from warning.
Bug: 17691572
Change-Id: I23b5ba537f7b557432041d4338b38b9be434e981
diff --git a/fs_mgr/Android.mk b/fs_mgr/Android.mk
index 7cffc37..61bf1ee 100644
--- a/fs_mgr/Android.mk
+++ b/fs_mgr/Android.mk
@@ -13,6 +13,10 @@
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_CFLAGS := -Werror
+ifneq (,$(filter userdebug,$(TARGET_BUILD_VARIANT)))
+LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
+endif
+
include $(BUILD_STATIC_LIBRARY)
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index 91e6c33..40878c1 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -245,6 +245,16 @@
return strcmp(value, "1") ? 0 : 1;
}
+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;
+}
+
/*
* Tries to mount any of the consecutive fstab entries that match
* the mountpoint of the one given by fstab->recs[start_idx].
@@ -350,9 +360,11 @@
wait_for_file(fstab->recs[i].blk_device, WAIT_TIMEOUT);
}
- if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
- !device_is_debuggable()) {
- if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
+ if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
+ int rc = fs_mgr_setup_verity(&fstab->recs[i]);
+ if (device_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
+ INFO("Verity disabled");
+ } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
ERROR("Could not set up verified partition, skipping!\n");
continue;
}
@@ -467,9 +479,11 @@
fstab->recs[i].mount_point);
}
- if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
- !device_is_debuggable()) {
- if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
+ if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) && device_is_secure()) {
+ int rc = fs_mgr_setup_verity(&fstab->recs[i]);
+ if (device_is_debuggable() && rc == FS_MGR_SETUP_VERITY_DISABLED) {
+ INFO("Verity disabled");
+ } else if (rc != FS_MGR_SETUP_VERITY_SUCCESS) {
ERROR("Could not set up verified partition, skipping!\n");
continue;
}
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index 3f84179..ab8f128 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -418,6 +418,11 @@
return fstab->fs_mgr_flags & MF_NONREMOVABLE;
}
+int fs_mgr_is_verified(struct fstab_rec *fstab)
+{
+ return fstab->fs_mgr_flags & MF_VERIFY;
+}
+
int fs_mgr_is_encryptable(struct fstab_rec *fstab)
{
return fstab->fs_mgr_flags & (MF_CRYPT | MF_FORCECRYPT);
diff --git a/fs_mgr/fs_mgr_priv_verity.h b/fs_mgr/fs_mgr_priv_verity.h
index 6193784..f90e596 100644
--- a/fs_mgr/fs_mgr_priv_verity.h
+++ b/fs_mgr/fs_mgr_priv_verity.h
@@ -14,4 +14,7 @@
* limitations under the License.
*/
-int fs_mgr_setup_verity(struct fstab_rec *fstab);
\ No newline at end of file
+#define FS_MGR_SETUP_VERITY_DISABLED -2
+#define FS_MGR_SETUP_VERITY_FAIL -1
+#define FS_MGR_SETUP_VERITY_SUCCESS 0
+int fs_mgr_setup_verity(struct fstab_rec *fstab);
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index b79a4a8..bcd9094 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -43,7 +43,6 @@
#include "fs_mgr_priv_verity.h"
#define VERITY_METADATA_SIZE 32768
-#define VERITY_METADATA_MAGIC_NUMBER 0xb001b001
#define VERITY_TABLE_RSA_KEY "/verity_key"
extern struct fs_info info;
@@ -155,7 +154,9 @@
uint64_t device_length;
int protocol_version;
FILE *device;
- int retval = -1;
+ int retval = FS_MGR_SETUP_VERITY_FAIL;
+ *signature = 0;
+ *table = 0;
device = fopen(block_device, "r");
if (!device) {
@@ -178,8 +179,18 @@
ERROR("Couldn't read magic number!\n");
goto out;
}
+
+#ifdef ALLOW_ADBD_DISABLE_VERITY
+ if (magic_number == VERITY_METADATA_MAGIC_DISABLE) {
+ retval = FS_MGR_SETUP_VERITY_DISABLED;
+ INFO("Attempt to cleanly disable verity - only works in USERDEBUG");
+ goto out;
+ }
+#endif
+
if (magic_number != VERITY_METADATA_MAGIC_NUMBER) {
- ERROR("Couldn't find verity metadata at offset %"PRIu64"!\n", device_length);
+ ERROR("Couldn't find verity metadata at offset %"PRIu64"!\n",
+ device_length);
goto out;
}
@@ -201,14 +212,12 @@
}
if (!fread(*signature, RSANUMBYTES, 1, device)) {
ERROR("Couldn't read signature from verity metadata!\n");
- free(*signature);
goto out;
}
// get the size of the table
if (!fread(&table_length, sizeof(int), 1, device)) {
ERROR("Couldn't get the size of the verity table from metadata!\n");
- free(*signature);
goto out;
}
@@ -221,16 +230,22 @@
}
if (!fgets(*table, table_length, device)) {
ERROR("Couldn't read the verity table from metadata!\n");
- free(*table);
- free(*signature);
goto out;
}
- retval = 0;
+ retval = FS_MGR_SETUP_VERITY_SUCCESS;
out:
if (device)
fclose(device);
+
+ if (retval != FS_MGR_SETUP_VERITY_SUCCESS) {
+ free(*table);
+ free(*signature);
+ *table = 0;
+ *signature = 0;
+ }
+
return retval;
}
@@ -358,10 +373,11 @@
int fs_mgr_setup_verity(struct fstab_rec *fstab) {
int retval = -1;
+ int fd = -1;
- char *verity_blk_name;
- char *verity_table;
- char *verity_table_signature;
+ char *verity_blk_name = 0;
+ char *verity_table = 0;
+ char *verity_table_signature = 0;
char buffer[DM_BUF_SIZE];
struct dm_ioctl *io = (struct dm_ioctl *) buffer;
@@ -378,11 +394,19 @@
return retval;
}
+ // read the verity block at the end of the block device
+ // send error code up the chain so we can detect attempts to disable verity
+ retval = read_verity_metadata(fstab->blk_device,
+ &verity_table_signature,
+ &verity_table);
+ if (retval < 0) {
+ goto out;
+ }
+
// get the device mapper fd
- int fd;
if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
ERROR("Error opening device mapper (%s)", strerror(errno));
- return retval;
+ goto out;;
}
// create the device
@@ -397,13 +421,6 @@
goto out;
}
- // read the verity block at the end of the block device
- if (read_verity_metadata(fstab->blk_device,
- &verity_table_signature,
- &verity_table) < 0) {
- goto out;
- }
-
// verify the signature on the table
if (verify_table(verity_table_signature,
verity_table,
@@ -424,6 +441,7 @@
// assign the new verity block device as the block device
free(fstab->blk_device);
fstab->blk_device = verity_blk_name;
+ verity_blk_name = 0;
// make sure we've set everything up properly
if (test_access(fstab->blk_device) < 0) {
@@ -434,6 +452,13 @@
retval = set_verified_property(mount_point);
out:
- close(fd);
+ if (fd != -1) {
+ close(fd);
+ }
+
+ free (verity_table);
+ free (verity_table_signature);
+ free (verity_blk_name);
+
return retval;
}
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 0c7eb20..5e2ff41 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -20,6 +20,13 @@
#include <stdint.h>
#include <linux/dm-ioctl.h>
+// Magic number at start of verity metadata
+#define VERITY_METADATA_MAGIC_NUMBER 0xb001b001
+
+// Replacement magic number at start of verity metadata to cleanly
+// turn verity off in userdebug builds.
+#define VERITY_METADATA_MAGIC_DISABLE 0x46464f56 // "VOFF"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -74,6 +81,7 @@
struct fstab_rec *fs_mgr_get_entry_for_mount_point(struct fstab *fstab, const char *path);
int fs_mgr_is_voldmanaged(struct fstab_rec *fstab);
int fs_mgr_is_nonremovable(struct fstab_rec *fstab);
+int fs_mgr_is_verified(struct fstab_rec *fstab);
int fs_mgr_is_encryptable(struct fstab_rec *fstab);
int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab);
int fs_mgr_swapon_all(struct fstab *fstab);