Verify that it's OK to run the various cryptfs commands

Maintain and query some internal state to know if it's OK to run
the various cryptfs commands.  Do not allow enablecrypto to run if
the device is already encrypted.  Do no allow restart to run if
we have already run it before or if the password has not been
validated.  Do not allow checkpw to run if not encrypted, or it
has already validated the password.

This is an extra layer of safety on top of the checks up in the
UI code agains possible DoS attacks on the device.

Change-Id: I9afc8d42773020e82a512e6b637feede101d1362
diff --git a/cryptfs.c b/cryptfs.c
index a6f5b4b..5df9cb0 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -528,6 +528,18 @@
     unsigned long mnt_flags;
     struct stat statbuf;
     int rc = -1, i;
+    static int restart_successful = 0;
+
+    /* Validate that it's OK to call this routine */
+    if (! key_sha1_saved) {
+        SLOGE("Encrypted filesystem not validated, aborting");
+        return -1;
+    }
+
+    if (restart_successful) {
+        SLOGE("System already restarted with encrypted disk, aborting");
+        return -1;
+    }
 
     /* Here is where we shut down the framework.  The init scripts
      * start all services in one of three classes: core, main or late_start.
@@ -580,6 +592,10 @@
         }
     }
 
+    if (rc == 0) {
+        restart_successful = 1;
+    }
+
     return rc;
 }
 
@@ -595,8 +611,15 @@
   char tmp_mount_point[64];
   unsigned long mnt_flags;
   unsigned int orig_failed_decrypt_count;
+  char encrypted_state[32];
   int rc;
 
+  property_get("ro.crypto.state", encrypted_state, "");
+  if ( key_sha1_saved || strcmp(encrypted_state, "encrypted") ) {
+    SLOGE("encrypted fs already validated or not running with encryption, aborting");
+    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;
@@ -816,6 +839,13 @@
     int rc=-1, fd, i;
     struct crypt_mnt_ftr crypt_ftr;
     char tmpfs_options[80];
+    char encrypted_state[32];
+
+    property_get("ro.crypto.state", encrypted_state, "");
+    if (strcmp(encrypted_state, "unencrypted")) {
+        SLOGE("Device is already running encrypted, aborting");
+        return -1;
+    }
 
     if (!strcmp(howarg, "wipe")) {
       how = CRYPTO_ENABLE_WIPE;
@@ -932,7 +962,7 @@
 
     /* This is only allowed after we've successfully decrypted the master key */
     if (! key_sha1_saved) {
-        SLOGE("Key not saved");
+        SLOGE("Key not saved, aborting");
         return -1;
     }