add patch fix-overflow-when-updating-superblock-backups
[ext4-patch-queue.git] / add-dummy-key-mount-option
blob58310ef2282d248bab31b1a85aab2a30f0b3e046
1 ext4: add dummy_encryption mount option
3 Ted lost his saving throw vs ecryptfs key management, so use a dummy
4 key for testing purposes.  It appears the ecryptfs userspace ABI is
5 mysteriously kconfig dependent, or there is some mysterious silent
6 failure if you are missing some kconfig option.  This also allows us
7 to avoid bloating the kvm-xfstests image with ecryptfs-utils.
9 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
10 ---
11  fs/ext4/crypto.c | 38 +++++++++++++++++++++++++++++++++++++-
12  fs/ext4/ext4.h   |  1 +
13  fs/ext4/super.c  |  8 +++++++-
14  3 files changed, 45 insertions(+), 2 deletions(-)
16 diff --git a/fs/ext4/crypto.c b/fs/ext4/crypto.c
17 index 0428608..f909bd0 100644
18 --- a/fs/ext4/crypto.c
19 +++ b/fs/ext4/crypto.c
20 @@ -40,6 +40,7 @@ static mempool_t *ext4_bounce_page_pool = NULL;
22  static LIST_HEAD(ext4_free_crypto_ctxs);
23  static DEFINE_SPINLOCK(ext4_crypto_ctx_lock);
24 +static struct ext4_encryption_key dummy_key;
26  /* TODO(mhalcrow): Remove for release */
27  atomic_t ext4_dbg_pages = ATOMIC_INIT(0);
28 @@ -1109,6 +1110,26 @@ static void ext4_generate_encryption_key(const struct dentry *dentry)
29         get_random_bytes(key->raw, key->size);
30  }
32 +/*
33 + * Ted lost his saving throw vs ecryptfs key management, so use a
34 + * dummy key for testing purposes.  It appears the ecryptfs userspace
35 + * ABI is mysteriously kconfig dependent, or there is some mysterious
36 + * silent failure if you are missing some kconfig option.  This also
37 + * allows us to avoid bloating the kvm-xfstests image with
38 + * ecryptfs-utils.
39 + */
40 +static void generate_dummy_key(struct inode *inode)
42 +       int i;
44 +       dummy_key.mode = EXT4_SB(inode->i_sb)->s_default_encryption_mode;
45 +       dummy_key.size = ext4_encryption_key_size(dummy_key.mode);
46 +       for (i = 0; i < dummy_key.size; i++) {
47 +               dummy_key.raw[i] = "NSAKEY"[i % 6];
48 +       }
52  /**
53   * ext4_set_crypto_key() - Generates and sets the encryption key for the inode
54   * @dentry: The dentry for the encryption key.
55 @@ -1129,6 +1150,13 @@ int ext4_set_crypto_key(struct dentry *dentry)
56         struct ext4_inode_info *ei = EXT4_I(inode);
57         int res = 0;
59 +       if (test_opt2(inode->i_sb, DUMMY_ENCRYPTION)) {
60 +               if (unlikely(dummy_key.mode) == 0)
61 +                       generate_dummy_key(inode);
62 +               ei->i_encryption_key = dummy_key;
63 +               return 0;
64 +       }
66  try_again:
67         ext4_generate_encryption_key(dentry);
68         res = ext4_wrap_key(wrapped_key_packet, &wrapped_key_packet_size,
69 @@ -1209,8 +1237,16 @@ int ext4_get_crypto_key(const struct file *file)
70                                    wrapped_key_packet_size);
71         struct inode *inode = file->f_mapping->host;
72         struct ext4_inode_info *ei = EXT4_I(inode);
73 -       int res = ext4_get_root_packet(inode, root_packet, &root_packet_size);
74 +       int res;
76 +       if (test_opt2(inode->i_sb, DUMMY_ENCRYPTION)) {
77 +               if (unlikely(dummy_key.mode) == 0)
78 +                       generate_dummy_key(inode);
79 +               ei->i_encryption_key = dummy_key;
80 +               return 0;
81 +       }
83 +       res = ext4_get_root_packet(inode, root_packet, &root_packet_size);
84         if (res)
85                 goto out;
86         res = ext4_unwrap_key(wrapped_key_packet,
87 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
88 index 9f679f0..bc762a9 100644
89 --- a/fs/ext4/ext4.h
90 +++ b/fs/ext4/ext4.h
91 @@ -1011,6 +1011,7 @@ struct ext4_inode_info {
92                                                       blocks */
93  #define EXT4_MOUNT2_HURD_COMPAT                0x00000004 /* Support HURD-castrated
94                                                       file systems */
95 +#define EXT4_MOUNT2_DUMMY_ENCRYPTION   0x80000000 /* Use dummy encryption */
97  #define clear_opt(sb, opt)             EXT4_SB(sb)->s_mount_opt &= \
98                                                 ~EXT4_MOUNT_##opt
99 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
100 index 1aa0d53..d2d5028 100644
101 --- a/fs/ext4/super.c
102 +++ b/fs/ext4/super.c
103 @@ -1169,7 +1169,7 @@ enum {
104         Opt_inode_readahead_blks, Opt_journal_ioprio,
105         Opt_dioread_nolock, Opt_dioread_lock,
106         Opt_discard, Opt_nodiscard, Opt_init_itable, Opt_noinit_itable,
107 -       Opt_max_dir_size_kb, Opt_encrypt_key_sig,
108 +       Opt_max_dir_size_kb, Opt_encrypt_key_sig, Opt_dummy_encryption
109  };
111  static const match_table_t tokens = {
112 @@ -1246,6 +1246,7 @@ static const match_table_t tokens = {
113         {Opt_noinit_itable, "noinit_itable"},
114         {Opt_max_dir_size_kb, "max_dir_size_kb=%u"},
115         {Opt_encrypt_key_sig, "encrypt_key_sig=%s"},
116 +       {Opt_dummy_encryption, "dummy_encryption" },
117         {Opt_removed, "check=none"},    /* mount option from ext2/3 */
118         {Opt_removed, "nocheck"},       /* mount option from ext2/3 */
119         {Opt_removed, "reservation"},   /* mount option from ext2/3 */
120 @@ -1445,6 +1446,7 @@ static const struct mount_opts {
121         {Opt_jqfmt_vfsv1, QFMT_VFS_V1, MOPT_QFMT},
122         {Opt_max_dir_size_kb, 0, MOPT_GTE0},
123         {Opt_encrypt_key_sig, 0, MOPT_STRING},
124 +       {Opt_dummy_encryption, 0, 0},
125         {Opt_err, 0, 0}
126  };
128 @@ -1568,6 +1570,10 @@ static int handle_mount_opt(struct super_block *sb, char *opt, int token,
129                        ECRYPTFS_SIG_SIZE_HEX);
130                 sbi->s_default_encryption_wrapper_desc.wrapping_key_sig[
131                         ECRYPTFS_SIG_SIZE_HEX] = '\0';
132 +       } else if (token == Opt_dummy_encryption) {
133 +               sbi->s_default_encryption_mode =
134 +                       EXT4_ENCRYPTION_MODE_AES_256_XTS;
135 +               set_opt2(sb, DUMMY_ENCRYPTION);
136         } else if (token == Opt_stripe) {
137                 sbi->s_stripe = arg;
138         } else if (token == Opt_resuid) {