OSDN Git Service

e2fsck: update encryption support to match upstream
authorTheodore Ts'o <tytso@google.com>
Mon, 26 Oct 2015 02:19:04 +0000 (22:19 -0400)
committerTheodore Ts'o <tytso@google.com>
Mon, 26 Oct 2015 02:33:01 +0000 (22:33 -0400)
Update the android branch's e2fsck encryption support to fix corrupted
encrypted directories and to support the encryption file system feature
being set in the superblock.

Change-Id: I61949ee58df938c018e9ebc278593ce9332f6f50
Signed-off-by: "Theodore Ts'o" <tytso@google.com>
e2fsck/e2fsck.c
e2fsck/pass2.c
e2fsck/problem.c
e2fsck/problem.h
lib/ext2fs/ext2_fs.h
lib/ext2fs/ext2fs.h

index 3693124..1be6b5e 100644 (file)
@@ -139,6 +139,10 @@ errcode_t e2fsck_reset_context(e2fsck_t ctx)
                ext2fs_free_mem(&ctx->invalid_inode_table_flag);
                ctx->invalid_inode_table_flag = 0;
        }
+       if (ctx->encrypted_dirs) {
+               ext2fs_u32_list_free(ctx->encrypted_dirs);
+               ctx->encrypted_dirs = 0;
+       }
 
        /* Clear statistic counters */
        ctx->fs_directory_count = 0;
index b606657..16a4da7 100644 (file)
@@ -464,19 +464,32 @@ static int check_name(e2fsck_t ctx,
        int     ret = 0;
 
        for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
-               if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
-                       if (fixup < 0) {
-                               fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
-                       }
-                       if (fixup) {
-                               dirent->name[i] = '.';
-                               ret = 1;
-                       }
-               }
+               if (dirent->name[i] != '/' && dirent->name[i] != '\0')
+                       continue;
+               if (fixup < 0)
+                       fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
+               if (fixup == 0)
+                       return 0;
+               dirent->name[i] = '.';
+               ret = 1;
        }
        return ret;
 }
 
+static int encrypted_check_name(e2fsck_t ctx,
+                               struct ext2_dir_entry *dirent,
+                               struct problem_context *pctx)
+{
+       if ((dirent->name_len & 0xff) < EXT4_CRYPTO_BLOCK_SIZE) {
+               if (fix_problem(ctx, PR_2_BAD_ENCRYPTED_NAME, pctx)) {
+                       dirent->inode = 0;
+                       return 1;
+               }
+               ext2fs_unmark_valid(ctx->fs);
+       }
+       return 0;
+}
+
 /*
  * Check the directory filetype (if present)
  */
@@ -1041,6 +1054,12 @@ out_htree:
                if (!encrypted && check_name(ctx, dirent, &cd->pctx))
                        dir_modified++;
 
+               if (encrypted && (dot_state) > 1 &&
+                   encrypted_check_name(ctx, dirent, &cd->pctx)) {
+                       dir_modified++;
+                       goto next;
+               }
+
                if (check_filetype(ctx, dirent, ino, &cd->pctx))
                        dir_modified++;
 
index 2fdc8d2..833115a 100644 (file)
@@ -1391,6 +1391,11 @@ static struct e2fsck_problem problem_table[] = {
          N_("i_file_acl_hi @F %N, @s zero.\n"),
          PROMPT_CLEAR, PR_PREEN_OK },
 
+       /* Encrypted directory entry is too short */
+       { PR_2_BAD_ENCRYPTED_NAME,
+         N_("Encrypted @E is too short.\n"),
+         PROMPT_CLEAR, 0 },
+
        /* Pass 3 errors */
 
        /* Pass 3: Checking directory connectivity */
index 240326e..aea5abc 100644 (file)
@@ -833,6 +833,9 @@ struct problem_context {
 /* i_file_acl_hi should be zero */
 #define PR_2_I_FILE_ACL_HI_ZERO                0x020048
 
+/* Encrypted directory entry is too short */
+#define PR_2_BAD_ENCRYPTED_NAME                0x020050
+
 /*
  * Pass 3 errors
  */
index 6847b46..fad7118 100644 (file)
@@ -550,6 +550,7 @@ struct ext2_inode_large {
 #define EXT4_MAX_KEY_SIZE                      64
 
 #define EXT4_KEY_DESCRIPTOR_SIZE               8
+#define EXT4_CRYPTO_BLOCK_SIZE                 16
 
 /* Password derivation constants */
 #define EXT4_MAX_PASSPHRASE_SIZE               1024
index e013fbb..7f3b792 100644 (file)
@@ -536,6 +536,9 @@ typedef struct ext2_icount *ext2_icount_t;
          if ((struct)->magic != (code)) return (code)
 
 
+#define EXT2FS_SHA256_LENGTH 32
+#define EXT2FS_DIGEST_SIZE EXT2FS_SHA256_LENGTH
+
 /*
  * For ext2 compression support
  */