summaryrefslogtreecommitdiffstats
path: root/fs_mgr
diff options
context:
space:
mode:
Diffstat (limited to 'fs_mgr')
-rw-r--r--fs_mgr/fs_mgr.c102
-rw-r--r--fs_mgr/fs_mgr_verity.c31
2 files changed, 107 insertions, 26 deletions
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index dcda005..c91033a 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -54,6 +54,32 @@
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
+/**
+ * TODO - Remove to enable always on encryption for all devices
+ * This limits the machines on which this feature is enabled
+ * Remove call from fs_mgr_mount_all as well
+ */
+static const char* serial_numbers[] = {
+ "039b83b8437e9637",
+ 0
+};
+
+static int serial_matches()
+{
+ char tmp[PROP_VALUE_MAX];
+ *tmp = 0;
+ __system_property_get("ro.serialno", tmp);
+
+ const char** i;
+ for (i = serial_numbers; *i; ++i) {
+ if (!strcmp(*i, tmp)) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
/*
* gettime() - returns the time in seconds of the system's monotonic clock or
* zero on error.
@@ -208,16 +234,25 @@ static int fs_match(char *in1, char *in2)
return ret;
}
+static int device_is_debuggable() {
+ int ret = -1;
+ char value[PROP_VALUE_MAX];
+ ret = __system_property_get("ro.debuggable", value);
+ if (ret < 0)
+ return ret;
+ return strcmp(value, "1") ? 0 : 1;
+}
+
int fs_mgr_mount_all(struct fstab *fstab)
{
int i = 0;
- int encrypted = 0;
- int ret = -1;
+ int encryptable = 0;
+ int error_count = 0;
int mret;
int mount_errno;
if (!fstab) {
- return ret;
+ return -1;
}
for (i = 0; i < fstab->num_entries; i++) {
@@ -242,7 +277,8 @@ int fs_mgr_mount_all(struct fstab *fstab)
fstab->recs[i].mount_point);
}
- if (fstab->recs[i].fs_mgr_flags & MF_VERIFY) {
+ if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
+ !device_is_debuggable()) {
if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
ERROR("Could not set up verified partition, skipping!");
continue;
@@ -250,47 +286,62 @@ int fs_mgr_mount_all(struct fstab *fstab)
}
mret = __mount(fstab->recs[i].blk_device, fstab->recs[i].mount_point,
- fstab->recs[i].fs_type, fstab->recs[i].flags,
- fstab->recs[i].fs_options);
+ fstab->recs[i].fs_type, fstab->recs[i].flags,
+ fstab->recs[i].fs_options);
if (!mret) {
+ /* If this is encryptable, need to trigger encryption */
+ if ((fstab->recs[i].fs_mgr_flags & MF_CRYPT)) {
+ if (serial_matches() && umount(fstab->recs[i].mount_point) == 0) {
+ if (!encryptable) {
+ encryptable = 2;
+ } else {
+ ERROR("Only one encryptable/encrypted partition supported");
+ encryptable = 1;
+ }
+ } else {
+ INFO("Could not umount %s - allow continue unencrypted",
+ fstab->recs[i].mount_point);
+ continue;
+ }
+ }
+
/* Success! Go get the next one */
continue;
}
/* back up errno as partition_wipe clobbers the value */
mount_errno = errno;
-
- /* mount(2) returned an error, check if it's encrypted and deal with it */
- if ((fstab->recs[i].fs_mgr_flags & MF_CRYPT) &&
+ /* mount(2) returned an error, check if it's encryptable and deal with it */
+ if (mount_errno != EBUSY && mount_errno != EACCES &&
+ (fstab->recs[i].fs_mgr_flags & MF_CRYPT) &&
!partition_wiped(fstab->recs[i].blk_device)) {
/* Need to mount a tmpfs at this mountpoint for now, and set
* properties that vold will query later for decrypting
*/
if (mount("tmpfs", fstab->recs[i].mount_point, "tmpfs",
- MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS) < 0) {
- ERROR("Cannot mount tmpfs filesystem for encrypted fs at %s error: %s\n",
- fstab->recs[i].mount_point, strerror(errno));
- goto out;
+ MS_NOATIME | MS_NOSUID | MS_NODEV, CRYPTO_TMPFS_OPTIONS) < 0) {
+ ERROR("Cannot mount tmpfs filesystem for encryptable fs at %s error: %s\n",
+ fstab->recs[i].mount_point, strerror(errno));
+ ++error_count;
+ continue;
}
- encrypted = 1;
+ encryptable = 1;
} else {
ERROR("Failed to mount an un-encryptable or wiped partition on"
- "%s at %s options: %s error: %s\n",
- fstab->recs[i].blk_device, fstab->recs[i].mount_point,
- fstab->recs[i].fs_options, strerror(mount_errno));
- goto out;
+ "%s at %s options: %s error: %s\n",
+ fstab->recs[i].blk_device, fstab->recs[i].mount_point,
+ fstab->recs[i].fs_options, strerror(mount_errno));
+ ++error_count;
+ continue;
}
}
- if (encrypted) {
- ret = 1;
+ if (error_count) {
+ return -1;
} else {
- ret = 0;
+ return encryptable;
}
-
-out:
- return ret;
}
/* If tmp_mount_point is non-null, mount the filesystem there. This is for the
@@ -332,7 +383,8 @@ int fs_mgr_do_mount(struct fstab *fstab, char *n_name, char *n_blk_device,
fstab->recs[i].mount_point);
}
- if (fstab->recs[i].fs_mgr_flags & MF_VERIFY) {
+ if ((fstab->recs[i].fs_mgr_flags & MF_VERIFY) &&
+ !device_is_debuggable()) {
if (fs_mgr_setup_verity(&fstab->recs[i]) < 0) {
ERROR("Could not set up verified partition, skipping!");
continue;
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index 40bc2ec..aa3b1dd 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -30,6 +30,7 @@
#include <time.h>
#include <private/android_filesystem_config.h>
+#include <cutils/properties.h>
#include <logwrap/logwrap.h>
#include "mincrypt/rsa.h"
@@ -335,6 +336,26 @@ static int test_access(char *device) {
return -1;
}
+static int set_verified_property(char *name) {
+ int ret;
+ char *key;
+ ret = asprintf(&key, "partition.%s.verified", name);
+ if (ret < 0) {
+ ERROR("Error formatting verified property");
+ return ret;
+ }
+ ret = PROP_NAME_MAX - strlen(key);
+ if (ret < 0) {
+ ERROR("Verified property name is too long");
+ return -1;
+ }
+ ret = property_set(key, "1");
+ if (ret < 0)
+ ERROR("Error setting verified property %s: %d", key, ret);
+ free(key);
+ return ret;
+}
+
int fs_mgr_setup_verity(struct fstab_rec *fstab) {
int retval = -1;
@@ -351,6 +372,13 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) {
io->flags |= 1;
io->target_count = 1;
+ // check to ensure that the verity device is ext4
+ // TODO: support non-ext4 filesystems
+ if (strcmp(fstab->fs_type, "ext4")) {
+ ERROR("Cannot verify non-ext4 device (%s)", fstab->fs_type);
+ return retval;
+ }
+
// get the device mapper fd
int fd;
if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) {
@@ -403,7 +431,8 @@ int fs_mgr_setup_verity(struct fstab_rec *fstab) {
goto out;
}
- retval = 0;
+ // set the property indicating that the partition is verified
+ retval = set_verified_property(mount_point);
out:
close(fd);