Whamcloud - gitweb
LU-15855 enc: enc-unaware clients get ENOKEY if file not found 49/47349/2
authorSebastien Buisson <sbuisson@ddn.com>
Fri, 13 May 2022 15:03:22 +0000 (17:03 +0200)
committerOleg Drokin <green@whamcloud.com>
Mon, 27 Jun 2022 04:57:28 +0000 (04:57 +0000)
To reduce issues with applications running on clients without keys
or without fscrypt support that check for the existence of a file in
an encrypted directory, return -ENOKEY instead of -ENOENT.
For encryption-unaware clients, this is done on server side in the
mdt layer, by checking if clients have the OBD_CONNECT2_ENCRYPT
connection flag.
For clients without the key, this is done in llite when the searched
filename is not in encoded form.

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: I9a3b7af3a856b7fc7222c61a308ad23168869d57
Reviewed-on: https://review.whamcloud.com/47349
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: John L. Hammond <jhammond@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/crypto.c
lustre/mdt/mdt_handler.c

index 18698d6..acd7f16 100644 (file)
@@ -251,21 +251,26 @@ int ll_setup_filename(struct inode *dir, const struct qstr *iname,
                fid->f_ver = 0;
        }
        rc = llcrypt_setup_filename(dir, &dname, lookup, fname);
-       if (rc == -ENOENT && lookup &&
-           ((is_root_inode(dir) && iname->len == strlen(dot_fscrypt_name) &&
-             strncmp(iname->name, dot_fscrypt_name, iname->len) == 0) ||
-            (!llcrypt_has_encryption_key(dir) &&
-             unlikely(filename_is_volatile(iname->name, iname->len, NULL))))) {
-               /* In case of subdir mount of an encrypted directory, we allow
-                * lookup of /.fscrypt directory.
-                */
-               /* For purpose of migration or mirroring without enc key, we
-                * allow lookup of volatile file without enc context.
-                */
-               memset(fname, 0, sizeof(struct llcrypt_name));
-               fname->disk_name.name = (unsigned char *)iname->name;
-               fname->disk_name.len = iname->len;
-               rc = 0;
+       if (rc == -ENOENT && lookup) {
+               if (((is_root_inode(dir) &&
+                    iname->len == strlen(dot_fscrypt_name) &&
+                    strncmp(iname->name, dot_fscrypt_name, iname->len) == 0) ||
+                    (!llcrypt_has_encryption_key(dir) &&
+                     unlikely(filename_is_volatile(iname->name,
+                                                   iname->len, NULL))))) {
+                       /* In case of subdir mount of an encrypted directory,
+                        * we allow lookup of /.fscrypt directory.
+                        */
+                       /* For purpose of migration or mirroring without enc key
+                        * we allow lookup of volatile file without enc context.
+                        */
+                       memset(fname, 0, sizeof(struct llcrypt_name));
+                       fname->disk_name.name = (unsigned char *)iname->name;
+                       fname->disk_name.len = iname->len;
+                       rc = 0;
+               } else if (!llcrypt_has_encryption_key(dir)) {
+                       rc = -ENOKEY;
+               }
        }
        if (rc)
                return rc;
index 69cd0bb..8b62753 100644 (file)
@@ -2396,6 +2396,15 @@ out_child:
 unlock_parent:
        if (lhp)
                mdt_object_unlock(info, parent, lhp, 1);
+       if (rc == -ENOENT) {
+               /* return -ENOKEY instead of -ENOENT to encryption-unaware
+                * client if trying to access an encrypted file
+                */
+               int rc2 = mdt_check_enc(info, parent);
+
+               if (rc2)
+                       rc = rc2;
+       }
        return rc;
 }
 
@@ -4570,13 +4579,14 @@ static int mdt_intent_getattr(enum ldlm_intent_flags it_opc,
        rc = mdt_getattr_name_lock(info, lhc, child_bits, ldlm_rep);
        ldlm_rep->lock_policy_res2 = clear_serious(rc);
 
-        if (mdt_get_disposition(ldlm_rep, DISP_LOOKUP_NEG))
-                ldlm_rep->lock_policy_res2 = 0;
-        if (!mdt_get_disposition(ldlm_rep, DISP_LOOKUP_POS) ||
-            ldlm_rep->lock_policy_res2) {
-                lhc->mlh_reg_lh.cookie = 0ull;
-                GOTO(out_ucred, rc = ELDLM_LOCK_ABORTED);
-        }
+       if (mdt_get_disposition(ldlm_rep, DISP_LOOKUP_NEG) &&
+           ldlm_rep->lock_policy_res2 != -ENOKEY)
+               ldlm_rep->lock_policy_res2 = 0;
+       if (!mdt_get_disposition(ldlm_rep, DISP_LOOKUP_POS) ||
+           ldlm_rep->lock_policy_res2) {
+               lhc->mlh_reg_lh.cookie = 0ull;
+               GOTO(out_ucred, rc = ELDLM_LOCK_ABORTED);
+       }
 
        rc = mdt_intent_lock_replace(info, lockp, lhc, flags, rc);
         EXIT;