Merge tag 'timers-urgent-2020-12-27' of git://git.kernel.org/pub/scm/linux/kernel...
[linux-2.6-microblaze.git] / fs / crypto / policy.c
index 4441d99..a51cef6 100644 (file)
@@ -175,7 +175,10 @@ static bool fscrypt_supported_v2_policy(const struct fscrypt_policy_v2 *policy,
                return false;
        }
 
-       if (policy->flags & ~FSCRYPT_POLICY_FLAGS_VALID) {
+       if (policy->flags & ~(FSCRYPT_POLICY_FLAGS_PAD_MASK |
+                             FSCRYPT_POLICY_FLAG_DIRECT_KEY |
+                             FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 |
+                             FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) {
                fscrypt_warn(inode, "Unsupported encryption flags (0x%02x)",
                             policy->flags);
                return false;
@@ -587,7 +590,7 @@ EXPORT_SYMBOL_GPL(fscrypt_ioctl_get_nonce);
 int fscrypt_has_permitted_context(struct inode *parent, struct inode *child)
 {
        union fscrypt_policy parent_policy, child_policy;
-       int err;
+       int err, err1, err2;
 
        /* No restrictions on file types which are never encrypted */
        if (!S_ISREG(child->i_mode) && !S_ISDIR(child->i_mode) &&
@@ -617,19 +620,25 @@ int fscrypt_has_permitted_context(struct inode *parent, struct inode *child)
         * In any case, if an unexpected error occurs, fall back to "forbidden".
         */
 
-       err = fscrypt_get_encryption_info(parent);
+       err = fscrypt_get_encryption_info(parent, true);
        if (err)
                return 0;
-       err = fscrypt_get_encryption_info(child);
+       err = fscrypt_get_encryption_info(child, true);
        if (err)
                return 0;
 
-       err = fscrypt_get_policy(parent, &parent_policy);
-       if (err)
-               return 0;
+       err1 = fscrypt_get_policy(parent, &parent_policy);
+       err2 = fscrypt_get_policy(child, &child_policy);
 
-       err = fscrypt_get_policy(child, &child_policy);
-       if (err)
+       /*
+        * Allow the case where the parent and child both have an unrecognized
+        * encryption policy, so that files with an unrecognized encryption
+        * policy can be deleted.
+        */
+       if (err1 == -EINVAL && err2 == -EINVAL)
+               return 1;
+
+       if (err1 || err2)
                return 0;
 
        return fscrypt_policies_equal(&parent_policy, &child_policy);