Commits

Anonymous committed e5032c4

Changes to encryption to work with the new filesystem manager

The new filesystem manager is in charge of mounting the block devices now,
removing much of the knowledge from init.<device>.rc. This also let us
clean up some init code dealing with encryption, so this change updates
vold to work with that. More cleanup is possible, but the main goal of the
filesystem manager was to enable e2fsck, not a full cleanup of encryption.

Change-Id: I00ea80a923d14770ed8fdd190e8840be195f8514

  • Participants
  • Parent commits 7b0bc85

Comments (0)

Files changed (2)

 
 LOCAL_SHARED_LIBRARIES := $(common_shared_libraries)
 
+LOCAL_STATIC_LIBRARIES := libfs_mgr
+
 LOCAL_MODULE_TAGS := eng tests
 
 include $(BUILD_STATIC_LIBRARY)
 
 LOCAL_SHARED_LIBRARIES := $(common_shared_libraries)
 
+LOCAL_STATIC_LIBRARIES := libfs_mgr
+
 include $(BUILD_EXECUTABLE)
 
 include $(CLEAR_VARS)
 #include <cutils/android_reboot.h>
 #include <ext4.h>
 #include <linux/kdev_t.h>
+#include <fs_mgr.h>
 #include "cryptfs.h"
 #define LOG_TAG "Cryptfs"
 #include "cutils/android_reboot.h"
 #define KEY_LEN_BYTES 16
 #define IV_LEN_BYTES 16
 
-#define KEY_LOC_PROP   "ro.crypto.keyfile.userdata"
 #define KEY_IN_FOOTER  "footer"
 
 #define EXT4_FS 1
 static char *saved_data_blkdev;
 static char *saved_mount_point;
 static int  master_key_saved = 0;
+#define FSTAB_PREFIX "/fstab."
+static char fstab_filename[PROPERTY_VALUE_MAX + sizeof(FSTAB_PREFIX)];
 
 static void ioctl_init(struct dm_ioctl *io, size_t dataSize, const char *name, unsigned flags)
 {
   return nr_sec;
 }
 
+/* Get and cache the name of the fstab file so we don't
+ * keep talking over the socket to the property service.
+ */
+static char *get_fstab_filename(void)
+{
+    if (fstab_filename[0] == 0) {
+        strcpy(fstab_filename, FSTAB_PREFIX);
+        property_get("ro.hardware", fstab_filename + sizeof(FSTAB_PREFIX) - 1, "");
+    }
+
+    return fstab_filename;
+}
+
 /* key or salt can be NULL, in which case just skip writing that value.  Useful to
  * update the failed mount count but not change the key.
  */
   char key_loc[PROPERTY_VALUE_MAX];
   struct stat statbuf;
 
-  property_get(KEY_LOC_PROP, key_loc, KEY_IN_FOOTER);
+  fs_mgr_get_crypt_info(get_fstab_filename(), key_loc, 0, sizeof(key_loc));
 
   if (!strcmp(key_loc, KEY_IN_FOOTER)) {
     fname = real_blk_name;
       return -1;
     }
   } else {
-    SLOGE("Unexpected value for" KEY_LOC_PROP "\n");
+    SLOGE("Unexpected value for crypto key location\n");
     return -1;;
   }
 
   char *fname;
   struct stat statbuf;
 
-  property_get(KEY_LOC_PROP, key_loc, KEY_IN_FOOTER);
+  fs_mgr_get_crypt_info(get_fstab_filename(), key_loc, 0, sizeof(key_loc));
 
   if (!strcmp(key_loc, KEY_IN_FOOTER)) {
     fname = real_blk_name;
       goto errout;
     }
   } else {
-    SLOGE("Unexpected value for" KEY_LOC_PROP "\n");
+    SLOGE("Unexpected value for crypto key location\n");
     return -1;;
   }
 
     return encrypt_master_key(passwd, salt, key_buf, master_key);
 }
 
-static int get_orig_mount_parms(char *mount_point, char *fs_type, char *real_blkdev,
-                                unsigned long *mnt_flags, char *fs_options)
-{
-  char mount_point2[PROPERTY_VALUE_MAX];
-  char fs_flags[PROPERTY_VALUE_MAX];
-
-  property_get("ro.crypto.fs_type", fs_type, "");
-  property_get("ro.crypto.fs_real_blkdev", real_blkdev, "");
-  property_get("ro.crypto.fs_mnt_point", mount_point2, "");
-  property_get("ro.crypto.fs_options", fs_options, "");
-  property_get("ro.crypto.fs_flags", fs_flags, "");
-  *mnt_flags = strtol(fs_flags, 0, 0);
-
-  if (strcmp(mount_point, mount_point2)) {
-    /* Consistency check.  These should match. If not, something odd happened. */
-    return -1;
-  }
-
-  return 0;
-}
-
 static int wait_and_unmount(char *mountpoint)
 {
     int i, rc;
         return -1;
     }
 
-    if (! get_orig_mount_parms(DATA_MNT_POINT, fs_type, real_blkdev, &mnt_flags, fs_options)) {
-        SLOGD("Just got orig mount parms\n");
-
-        if (! (rc = wait_and_unmount(DATA_MNT_POINT)) ) {
-            /* If that succeeded, then mount the decrypted filesystem */
-            mount(crypto_blkdev, DATA_MNT_POINT, fs_type, mnt_flags, fs_options);
+    if (! (rc = wait_and_unmount(DATA_MNT_POINT)) ) {
+        /* If that succeeded, then mount the decrypted filesystem */
+        fs_mgr_do_mount(get_fstab_filename(), DATA_MNT_POINT, crypto_blkdev, 0);
 
-            property_set("vold.decrypt", "trigger_load_persist_props");
-            /* Create necessary paths on /data */
-            if (prep_data_fs()) {
-                return -1;
-            }
+        property_set("vold.decrypt", "trigger_load_persist_props");
+        /* Create necessary paths on /data */
+        if (prep_data_fs()) {
+            return -1;
+        }
 
-            /* startup service classes main and late_start */
-            property_set("vold.decrypt", "trigger_restart_framework");
-            SLOGD("Just triggered restart_framework\n");
+        /* startup service classes main and late_start */
+        property_set("vold.decrypt", "trigger_restart_framework");
+        SLOGD("Just triggered restart_framework\n");
 
-            /* Give it a few moments to get started */
-            sleep(1);
-        }
+        /* Give it a few moments to get started */
+        sleep(1);
     }
 
     if (rc == 0) {
   unsigned char encrypted_master_key[32];
   unsigned char salt[SALT_LEN];
   char real_blkdev[MAXPATHLEN];
-  char fs_type[PROPERTY_VALUE_MAX];
-  char fs_options[PROPERTY_VALUE_MAX];
-  unsigned long mnt_flags;
   char encrypted_state[PROPERTY_VALUE_MAX];
   char key_loc[PROPERTY_VALUE_MAX];
 
     return 1;
   }
 
-  if (get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options)) {
-    SLOGE("Error reading original mount parms for mount point %s\n", mount_point);
-    return -1;
-  }
+  fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev));
 
   if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) {
-    property_get(KEY_LOC_PROP, key_loc, KEY_IN_FOOTER);
+    fs_mgr_get_crypt_info(get_fstab_filename(), key_loc, 0, sizeof(key_loc));
+
     /*
      * Only report this error if key_loc is a file and it exists.
      * If the device was never encrypted, and /data is not mountable for
   unsigned char salt[SALT_LEN];
   char crypto_blkdev[MAXPATHLEN];
   char real_blkdev[MAXPATHLEN];
-  char fs_type[PROPERTY_VALUE_MAX];
-  char fs_options[PROPERTY_VALUE_MAX];
   char tmp_mount_point[64];
-  unsigned long mnt_flags;
   unsigned int orig_failed_decrypt_count;
   char encrypted_state[PROPERTY_VALUE_MAX];
   int rc;
     return -1;
   }
 
-  if (get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options)) {
-    SLOGE("Error reading original mount parms for mount point %s\n", mount_point);
-    return -1;
-  }
+  fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev));
 
   if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) {
     SLOGE("Error getting crypt footer and key\n");
    */
   sprintf(tmp_mount_point, "%s/tmp_mnt", mount_point);
   mkdir(tmp_mount_point, 0755);
-  if ( mount(crypto_blkdev, tmp_mount_point, "ext4", MS_RDONLY, "") ) {
+  if (fs_mgr_do_mount(get_fstab_filename(), DATA_MNT_POINT, crypto_blkdev, tmp_mount_point)) {
     SLOGE("Error temp mounting decrypted block device\n");
     delete_crypto_blk_dev(label);
     crypt_ftr.failed_decrypt_count++;
     unsigned char encrypted_master_key[32], decrypted_master_key[32];
     unsigned char salt[SALT_LEN];
     char real_blkdev[MAXPATHLEN];
-    char fs_type[PROPERTY_VALUE_MAX];
-    char fs_options[PROPERTY_VALUE_MAX];
-    unsigned long mnt_flags;
     char encrypted_state[PROPERTY_VALUE_MAX];
     int rc;
 
         return -1;
     }
 
-    if (get_orig_mount_parms(saved_mount_point, fs_type, real_blkdev, &mnt_flags, fs_options)) {
-        SLOGE("Error reading original mount parms for mount point %s\n", saved_mount_point);
-        return -1;
-    }
+    fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev));
 
     if (get_crypt_ftr_and_key(real_blkdev, &crypt_ftr, encrypted_master_key, salt)) {
         SLOGE("Error getting crypt footer and key\n");
 {
     int how = 0;
     char crypto_blkdev[MAXPATHLEN], real_blkdev[MAXPATHLEN], sd_crypto_blkdev[MAXPATHLEN];
-    char fs_type[PROPERTY_VALUE_MAX], fs_options[PROPERTY_VALUE_MAX],
-         mount_point[PROPERTY_VALUE_MAX];
-    unsigned long mnt_flags, nr_sec;
+    unsigned long nr_sec;
     unsigned char master_key[KEY_LEN_BYTES], decrypted_master_key[KEY_LEN_BYTES];
     unsigned char salt[SALT_LEN];
     int rc=-1, fd, i, ret;
         goto error_unencrypted;
     }
 
-    property_get(KEY_LOC_PROP, key_loc, KEY_IN_FOOTER);
+    fs_mgr_get_crypt_info(get_fstab_filename(), key_loc, 0, sizeof(key_loc));
 
     if (!strcmp(howarg, "wipe")) {
       how = CRYPTO_ENABLE_WIPE;
       goto error_unencrypted;
     }
 
-    get_orig_mount_parms(mount_point, fs_type, real_blkdev, &mnt_flags, fs_options);
+    fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev));
 
     /* Get the size of the real block device */
     fd = open(real_blkdev, O_RDONLY);
          * /data, set a property saying we're doing inplace encryption,
          * and restart the framework.
          */
-        property_get("ro.crypto.tmpfs_options", tmpfs_options, "");
-        if (mount("tmpfs", DATA_MNT_POINT, "tmpfs", MS_NOATIME | MS_NOSUID | MS_NODEV,
-            tmpfs_options) < 0) {
+        if (fs_mgr_do_tmpfs_mount(DATA_MNT_POINT)) {
             goto error_shutting_down;
         }
         /* Tells the framework that inplace encryption is starting */
         return -1;
     }
 
-    property_get("ro.crypto.fs_real_blkdev", real_blkdev, "");
+    fs_mgr_get_crypt_info(get_fstab_filename(), 0, real_blkdev, sizeof(real_blkdev));
     if (strlen(real_blkdev) == 0) {
         SLOGE("Can't find real blkdev");
         return -1;