Whamcloud - gitweb
AOSP: ANDROID: e2fsck: Do not mutate encrypted names
authorDaniel Rosenberg <drosen@google.com>
Fri, 12 Jun 2020 11:11:38 +0000 (04:11 -0700)
committerTheodore Ts'o <tytso@mit.edu>
Thu, 28 Jan 2021 04:35:15 +0000 (23:35 -0500)
We can't mutate a name without the key, as this will at best cause the
name to become gibberish, and at worst may introduce invalid characters
or even fail to be unique after decoding, so drop duplicates instead.
Files lost in this way will be reconnected to lost+found

Fixes: dbff534ec685 ("e2fsck: suppress bad name checks for encrypted directories")
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Google-Bug-Id: 138322712
Test: f_dup_de_crypt
Change-Id: I8d6cc3984872868a845fafabc554abdd86351fcc
From AOSP commit: 80b85f8a0b2ba7090a927f692ff9d2097ffd8d1f

e2fsck/problem.c
e2fsck/problem.h
e2fsck/rehash.c
tests/f_dup_de_crypt/expect.1 [new file with mode: 0644]
tests/f_dup_de_crypt/expect.2 [new file with mode: 0644]
tests/f_dup_de_crypt/image.gz [new file with mode: 0644]
tests/f_dup_de_crypt/name [new file with mode: 0644]

index 78d6689..f8882a5 100644 (file)
@@ -1779,6 +1779,11 @@ static struct e2fsck_problem problem_table[] = {
          N_("Encrypted @E is too short.\n"),
          PROMPT_CLEAR, 0, 0, 0, 0 },
 
+        /* Non-unique filename found, but can't rename */
+        { PR_2_NON_UNIQUE_FILE_NO_RENAME,
+          N_("Duplicate filename @E found.  "),
+          PROMPT_CLEAR, 0, 0, 0, 0 },
+
        /* Pass 3 errors */
 
        /* Pass 3: Checking directory connectivity */
index 7a7294d..7e144ca 100644 (file)
@@ -1017,6 +1017,18 @@ struct problem_context {
 /* Encrypted directory entry is too short */
 #define PR_2_BAD_ENCRYPTED_NAME                0x020050
 
+/* Encrypted directory contains unencrypted file */
+#define PR_2_UNENCRYPTED_FILE          0x020051
+
+/* Encrypted directory contains file with different encryption policy */
+#define PR_2_INCONSISTENT_ENCRYPTION_POLICY    0x020052
+
+/* Encoded directory entry has illegal characters in its name */
+#define PR_2_BAD_ENCODED_NAME          0x020053
+
+/* Non-unique filename found, but can't rename */
+#define PR_2_NON_UNIQUE_FILE_NO_RENAME 0x020054
+
 /*
  * Pass 3 errors
  */
index 30e510a..0d218e8 100644 (file)
@@ -416,6 +416,15 @@ static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
                        fixed++;
                        continue;
                }
+               /* Can't alter encrypted name without key, so just drop it */
+               if (fd->inode->i_flags & EXT4_ENCRYPT_FL) {
+                       if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE_NO_RENAME, &pctx)) {
+                               e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
+                               ent->dir->inode = 0;
+                               fixed++;
+                               continue;
+                       }
+               }
                new_len = ext2fs_dirent_name_len(ent->dir);
                if (new_len == 0) {
                         /* should never happen */
diff --git a/tests/f_dup_de_crypt/expect.1 b/tests/f_dup_de_crypt/expect.1
new file mode 100644 (file)
index 0000000..03e0ad6
--- /dev/null
@@ -0,0 +1,18 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Duplicate entry '+M-^AT^EM-1M-^CM-/)*M-L^RM-^L^@M-WM-)M-+' found.
+       Marking /test (12) to be rebuilt.
+
+Pass 3: Checking directory connectivity
+Pass 3A: Optimizing directories
+Duplicate filename entry '+M-^AT^EM-1M-^CM-/)*M-L^RM-^L^@M-WM-)M-+' in /test (12) found.  Clear? yes
+
+Pass 4: Checking reference counts
+Unattached inode 13
+Connect to /lost+found? yes
+
+Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
+test_filesys: 14/16 files (0.0% non-contiguous), 26/60 blocks
+Exit status is 1
diff --git a/tests/f_dup_de_crypt/expect.2 b/tests/f_dup_de_crypt/expect.2
new file mode 100644 (file)
index 0000000..cfca772
--- /dev/null
@@ -0,0 +1,7 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 14/16 files (0.0% non-contiguous), 26/60 blocks
+Exit status is 0
diff --git a/tests/f_dup_de_crypt/image.gz b/tests/f_dup_de_crypt/image.gz
new file mode 100644 (file)
index 0000000..07a44d7
Binary files /dev/null and b/tests/f_dup_de_crypt/image.gz differ
diff --git a/tests/f_dup_de_crypt/name b/tests/f_dup_de_crypt/name
new file mode 100644 (file)
index 0000000..aff30a8
--- /dev/null
@@ -0,0 +1 @@
+duplicate directory entries for encrypted dirs