From: Sebastien Buisson Date: Fri, 13 May 2022 15:03:22 +0000 (+0200) Subject: LU-15855 enc: enc-unaware clients get ENOKEY if file not found X-Git-Tag: 2.15.51~94 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=00898697f998c095e6dab3dd27e347cb1150ee8c;p=fs%2Flustre-release.git LU-15855 enc: enc-unaware clients get ENOKEY if file not found 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 Change-Id: I9a3b7af3a856b7fc7222c61a308ad23168869d57 Reviewed-on: https://review.whamcloud.com/47349 Tested-by: jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: John L. Hammond Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- diff --git a/lustre/llite/crypto.c b/lustre/llite/crypto.c index 18698d6..acd7f16 100644 --- a/lustre/llite/crypto.c +++ b/lustre/llite/crypto.c @@ -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; diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 69cd0bb..8b62753 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -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;