Whamcloud - gitweb
EX-5199 sec: reinstate null encryption for file names
authorSebastien Buisson <sbuisson@ddn.com>
Mon, 2 May 2022 16:00:37 +0000 (18:00 +0200)
committerAndreas Dilger <adilger@whamcloud.com>
Fri, 6 May 2022 06:59:27 +0000 (06:59 +0000)
Reinstate null encryption for file names by adding a new llite
parameter named 'enable_filename_encryption', set to 0 by default.
When this parameter is 0, new empty directories configured as
encrypted ignore the filenames_encryption_mode and use
LLCRYPT_MODE_NULL instead, which is a no-op. This LLCRYPT_MODE_NULL
mode is inherited for all subdirectories and files.
When this parameter is 1, new empty directories configured as
encrypted use the normal encryption mode.

To set this parameter globally for all clients, do on the MGS:
mgs# lctl set_param -P llite.*.enable_filename_encryption=0

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: I9d726ba26cc91a51690d59a81efe3eb98ee2995c
Reviewed-on: https://review.whamcloud.com/47184
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
libcfs/include/libcfs/crypto/llcrypt.h
libcfs/libcfs/crypto/fname.c
libcfs/libcfs/crypto/hooks.c
libcfs/libcfs/crypto/policy.c
lustre/include/lustre_disk.h
lustre/llite/crypto.c
lustre/llite/file.c
lustre/llite/lproc_llite.c
lustre/obdclass/obd_mount.c

index b98e551..f1b207d 100644 (file)
@@ -753,7 +753,7 @@ static inline int llcrypt_prepare_symlink(struct inode *dir,
                                          struct llcrypt_str *disk_link)
 {
        if ((IS_ENCRYPTED(dir) &&
-            likely(llcrypt_policy_has_filename_enc(dir))) ||
+            llcrypt_policy_has_filename_enc(dir)) ||
            llcrypt_dummy_context_enabled(dir))
                return __llcrypt_prepare_symlink(dir, len, max_len, disk_link);
 
index 6769930..8b16c39 100644 (file)
@@ -291,7 +291,7 @@ int llcrypt_fname_disk_to_usr(struct inode *inode,
                return fname_decrypt(inode, iname, oname);
        }
 
-       if (unlikely(!llcrypt_policy_has_filename_enc(inode))) {
+       if (!llcrypt_policy_has_filename_enc(inode)) {
                memcpy(oname->name, iname->name, iname->len);
                oname->name[iname->len] = '\0';
                oname->len = iname->len;
@@ -387,7 +387,7 @@ int llcrypt_setup_filename(struct inode *dir, const struct qstr *iname,
        if (!lookup)
                return -ENOKEY;
 
-       if (unlikely(!llcrypt_policy_has_filename_enc(dir))) {
+       if (!llcrypt_policy_has_filename_enc(dir)) {
                fname->disk_name.name = (unsigned char *)iname->name;
                fname->disk_name.len = iname->len;
                return 0;
index 4e26fb3..3639951 100644 (file)
@@ -177,7 +177,7 @@ int __llcrypt_encrypt_symlink(struct inode *inode, const char *target,
        struct llcrypt_symlink_data *sd;
        unsigned int ciphertext_len;
 
-       if (unlikely(!llcrypt_policy_has_filename_enc(inode)))
+       if (!llcrypt_policy_has_filename_enc(inode))
                return 0;
 
        err = llcrypt_require_key(inode);
@@ -269,7 +269,7 @@ const char *llcrypt_get_symlink(struct inode *inode, const void *caddr,
         * the ciphertext length, even though this is redundant with i_size.
         */
 
-       if (unlikely(!llcrypt_policy_has_filename_enc(inode))) {
+       if (!llcrypt_policy_has_filename_enc(inode)) {
                cstr.name = (unsigned char *)caddr;
                cstr.len = strlen(cstr.name);
 
index 243b412..3b99074 100644 (file)
@@ -307,6 +307,7 @@ int llcrypt_ioctl_set_policy(struct file *filp, const void __user *arg)
        union llcrypt_policy policy;
        union llcrypt_policy existing_policy;
        struct inode *inode = file_inode(filp);
+       struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
        u8 version;
        int size;
        int ret;
@@ -334,6 +335,24 @@ int llcrypt_ioctl_set_policy(struct file *filp, const void __user *arg)
                return -EFAULT;
        policy.version = version;
 
+       /* Force file/directory name encryption policy to null if
+        * LSI_FILENAME_ENC flag is not set on sb.
+        * This can be useful for interoperability with encryption-unaware
+        * clients.
+        */
+       if (!(lsi->lsi_flags & LSI_FILENAME_ENC)) {
+               CWARN("inode %lu: forcing policy filenames_encryption_mode to null\n",
+                     inode->i_ino);
+               switch (policy.version) {
+               case LLCRYPT_POLICY_V1:
+                       policy.v1.filenames_encryption_mode = LLCRYPT_MODE_NULL;
+                       break;
+               case LLCRYPT_POLICY_V2:
+                       policy.v2.filenames_encryption_mode = LLCRYPT_MODE_NULL;
+                       break;
+               }
+       }
+
        if (!inode_owner_or_capable(&init_user_ns, inode))
                return -EACCES;
 
index 752a696..5fcd6d1 100644 (file)
@@ -146,6 +146,7 @@ struct lustre_sb_info {
 };
 
 #define LSI_UMOUNT_FAILOVER              0x00200000
+#define LSI_FILENAME_ENC                0x00800000 /* enable name encryption */
 
 #define     s2lsi(sb)        ((struct lustre_sb_info *)((sb)->s_fs_info))
 #define     s2lsi_nocast(sb) ((sb)->s_fs_info)
index 1fa0831..ff04415 100644 (file)
@@ -358,7 +358,7 @@ int ll_fname_disk_to_usr(struct inode *inode,
                }
                if (lltr.len > LLCRYPT_FNAME_MAX_UNDIGESTED_SIZE &&
                    !llcrypt_has_encryption_key(inode) &&
-                   likely(llcrypt_policy_has_filename_enc(inode))) {
+                   llcrypt_policy_has_filename_enc(inode)) {
                        digested = 1;
                        /* Without the key for long names, set the dentry name
                         * to the representing struct ll_digest_filename. It
index 6e853f5..ffd0d23 100644 (file)
@@ -4874,7 +4874,6 @@ int ll_migrate(struct inode *parent, struct file *file, struct lmv_user_md *lum,
        __u64 data_version = 0;
        size_t namelen = strlen(name);
        int lumlen = lmv_user_md_size(lum->lum_stripe_count, lum->lum_magic);
-       bool oldformat = false;
        int rc;
        ENTRY;
 
@@ -4925,20 +4924,6 @@ int ll_migrate(struct inode *parent, struct file *file, struct lmv_user_md *lum,
        if (child_inode == parent->i_sb->s_root->d_inode)
                GOTO(out_iput, rc = -EINVAL);
 
-       if (IS_ENCRYPTED(parent)) {
-               if (unlikely(!llcrypt_policy_has_filename_enc(parent)))
-                       oldformat = true;
-       } else if (IS_ENCRYPTED(child_inode) &&
-                  unlikely(!llcrypt_policy_has_filename_enc(child_inode))) {
-               oldformat = true;
-       }
-       if (unlikely(oldformat)) {
-               CDEBUG(D_SEC,
-                      "cannot migrate old format encrypted "DFID", please move to new enc dir first\n",
-                      PFID(ll_inode2fid(child_inode)));
-               GOTO(out_iput, rc = -EUCLEAN);
-       }
-
        op_data = ll_prep_md_op_data(NULL, parent, NULL, name, namelen,
                                     child_inode->i_mode, LUSTRE_OPC_ANY, NULL);
        if (IS_ERR(op_data))
index fdfd82f..7d6878c 100644 (file)
@@ -1759,6 +1759,39 @@ static ssize_t ll_nosquash_nids_seq_write(struct file *file,
 
 LDEBUGFS_SEQ_FOPS(ll_nosquash_nids);
 
+static int ll_filename_enc_seq_show(struct seq_file *m, void *v)
+{
+       struct super_block *sb = m->private;
+       struct lustre_sb_info *lsi = s2lsi(sb);
+
+       seq_printf(m, "%u\n", lsi->lsi_flags & LSI_FILENAME_ENC ? 1 : 0);
+       return 0;
+}
+
+static ssize_t ll_filename_enc_seq_write(struct file *file,
+                                        const char __user *buffer,
+                                        size_t count, loff_t *off)
+{
+       struct seq_file *m = file->private_data;
+       struct super_block *sb = m->private;
+       struct lustre_sb_info *lsi = s2lsi(sb);
+       bool val;
+       int rc;
+
+       rc = kstrtobool_from_user(buffer, count, &val);
+       if (rc)
+               return rc;
+
+       if (val)
+               lsi->lsi_flags |= LSI_FILENAME_ENC;
+       else
+               lsi->lsi_flags &= ~LSI_FILENAME_ENC;
+
+       return count;
+}
+
+LDEBUGFS_SEQ_FOPS(ll_filename_enc);
+
 static int ll_pcc_seq_show(struct seq_file *m, void *v)
 {
        struct super_block *sb = m->private;
@@ -1813,6 +1846,8 @@ struct ldebugfs_vars lprocfs_llite_obd_vars[] = {
          .fops =       &ll_nosquash_nids_fops                  },
        { .name =       "pcc",
          .fops =       &ll_pcc_fops,                           },
+       { .name =       "enable_filename_encryption",
+         .fops =       &ll_filename_enc_fops,                  },
        { NULL }
 };
 
index 3ec7d9c..240a145 100644 (file)
@@ -1629,6 +1629,8 @@ static int lustre_fill_super(struct super_block *sb, void *lmd2_data,
                bool have_client = false;
 
                CDEBUG(D_MOUNT, "Mounting client %s\n", lmd->lmd_profile);
+               /* filename encryption is disabled by default */
+               lsi->lsi_flags &= ~LSI_FILENAME_ENC;
                if (!client_fill_super)
                        request_module("lustre");
                spin_lock(&client_lock);