@@ -389,6 +389,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
fname->usr_fname = iname;
if (!IS_ENCRYPTED(dir) || fscrypt_is_dot_dotdot(iname)) {
+unencrypted:
fname->disk_name.name = (unsigned char *)iname->name;
fname->disk_name.len = iname->len;
return 0;
@@ -424,8 +425,16 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
* user-supplied name
*/
- if (iname->len > FSCRYPT_NOKEY_NAME_MAX_ENCODED)
+ if (iname->len > FSCRYPT_NOKEY_NAME_MAX_ENCODED) {
+ /*
+ * This isn't a valid nokey name, but it could be an unencrypted
+ * name if the filesystem allows partially encrypted
+ * directories.
+ */
+ if (dir->i_sb->s_cop->flags & FS_CFLG_ALLOW_PARTIAL)
+ goto unencrypted;
return -ENOENT;
+ }
fname->crypto_buf.name = kmalloc(FSCRYPT_NOKEY_NAME_MAX, GFP_KERNEL);
if (fname->crypto_buf.name == NULL)
@@ -436,6 +445,12 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
if (ret < (int)offsetof(struct fscrypt_nokey_name, bytes[1]) ||
(ret > offsetof(struct fscrypt_nokey_name, sha256) &&
ret != FSCRYPT_NOKEY_NAME_MAX)) {
+ /* Again, this could be an unencrypted name. */
+ if (dir->i_sb->s_cop->flags & FS_CFLG_ALLOW_PARTIAL) {
+ kfree(fname->crypto_buf.name);
+ fname->crypto_buf.name = NULL;
+ goto unencrypted;
+ }
ret = -ENOENT;
goto errout;
}
@@ -102,6 +102,8 @@ struct fscrypt_nokey_name {
* pages for writes and therefore won't need the fscrypt bounce page pool.
*/
#define FS_CFLG_OWN_PAGES (1U << 1)
+/* The filesystem allows partially encrypted directories/files. */
+#define FS_CFLG_ALLOW_PARTIAL (1U << 2)
/* Crypto operations for filesystems */
struct fscrypt_operations {