--- /dev/null
+diff -wur a/fs/ext4/inode.c b/fs/ext4/inode.c
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4766,8 +4766,9 @@ void ext4_set_inode_flags(struct inod
+ new_fl |= S_DIRSYNC;
+ if (ext4_should_use_dax(inode))
+ new_fl |= S_DAX;
+- if (flags & EXT4_ENCRYPT_FL)
++ if (flags & EXT4_ENCRYPT_FL &&
++ unlikely(test_opt(inode->i_sb, DIRDATA) != EXT4_MOUNT_DIRDATA))
+ new_fl |= S_ENCRYPTED;
+ if (flags & EXT4_CASEFOLD_FL)
+ new_fl |= S_CASEFOLD;
+ if (flags & EXT4_VERITY_FL)
+@@ -5753,8 +5757,9 @@ int ext4_getattr(const struct path *p
+ stat->attributes |= STATX_ATTR_APPEND;
+ if (flags & EXT4_COMPR_FL)
+ stat->attributes |= STATX_ATTR_COMPRESSED;
+- if (flags & EXT4_ENCRYPT_FL)
++ if (flags & EXT4_ENCRYPT_FL &&
++ unlikely(test_opt(inode->i_sb, DIRDATA) != EXT4_MOUNT_DIRDATA))
+ stat->attributes |= STATX_ATTR_ENCRYPTED;
+ if (flags & EXT4_IMMUTABLE_FL)
+ stat->attributes |= STATX_ATTR_IMMUTABLE;
+ if (flags & EXT4_NODUMP_FL)
+diff -wur a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -654,6 +654,7 @@
+ up_read(&EXT4_I(inode)->xattr_sem);
+ return error;
+ }
++EXPORT_SYMBOL(ext4_xattr_get);
+
+ static int
+ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
+@@ -2413,12 +2415,17 @@
+ ext4_handle_sync(handle);
+ }
+
++ if (!error && name_index == EXT4_XATTR_INDEX_ENCRYPTION &&
++ strcmp(name, "c") == 0)
++ EXT4_I(inode)->i_flags |= EXT4_ENCRYPT_FL;
++
+ cleanup:
+ brelse(is.iloc.bh);
+ brelse(bs.bh);
+ ext4_write_unlock_xattr(inode, &no_expand);
+ return error;
+ }
++EXPORT_SYMBOL(ext4_xattr_set_handle);
+
+ int ext4_xattr_set_credits(struct inode *inode, size_t value_len,
+ bool is_create, int *credits)
--- /dev/null
+diff -wur a/fs/ext4/inode.c b/fs/ext4/inode.c
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4766,8 +4766,9 @@ void ext4_set_inode_flags(struct inod
+ if (init && ext4_should_enable_dax(inode))
+ new_fl |= S_DAX;
+
+- if (flags & EXT4_ENCRYPT_FL)
++ if (flags & EXT4_ENCRYPT_FL &&
++ unlikely(test_opt(inode->i_sb, DIRDATA) != EXT4_MOUNT_DIRDATA))
+ new_fl |= S_ENCRYPTED;
+ if (flags & EXT4_CASEFOLD_FL)
+ new_fl |= S_CASEFOLD;
+ if (flags & EXT4_VERITY_FL)
+@@ -5753,8 +5757,9 @@ int ext4_getattr(const struct path *p
+ stat->attributes |= STATX_ATTR_APPEND;
+ if (flags & EXT4_COMPR_FL)
+ stat->attributes |= STATX_ATTR_COMPRESSED;
+- if (flags & EXT4_ENCRYPT_FL)
++ if (flags & EXT4_ENCRYPT_FL &&
++ unlikely(test_opt(inode->i_sb, DIRDATA) != EXT4_MOUNT_DIRDATA))
+ stat->attributes |= STATX_ATTR_ENCRYPTED;
+ if (flags & EXT4_IMMUTABLE_FL)
+ stat->attributes |= STATX_ATTR_IMMUTABLE;
+ if (flags & EXT4_NODUMP_FL)
+diff -wur a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -654,6 +654,7 @@
+ up_read(&EXT4_I(inode)->xattr_sem);
+ return error;
+ }
++EXPORT_SYMBOL(ext4_xattr_get);
+
+ static int
+ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
+@@ -2425,12 +2425,17 @@
+ ext4_handle_sync(handle);
+ }
+
++ if (!error && name_index == EXT4_XATTR_INDEX_ENCRYPTION &&
++ strcmp(name, "c") == 0)
++ EXT4_I(inode)->i_flags |= EXT4_ENCRYPT_FL;
++
+ cleanup:
+ brelse(is.iloc.bh);
+ brelse(bs.bh);
+ ext4_write_unlock_xattr(inode, &no_expand);
+ return error;
+ }
++EXPORT_SYMBOL(ext4_xattr_set_handle);
+
+ int ext4_xattr_set_credits(struct inode *inode, size_t value_len,
+ bool is_create, int *credits)
--- /dev/null
+diff -wur a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -654,6 +654,7 @@
+ up_read(&EXT4_I(inode)->xattr_sem);
+ return error;
+ }
++EXPORT_SYMBOL(ext4_xattr_get);
+
+ static int
+ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
+@@ -1197,6 +1197,7 @@
+ up_write(&EXT4_I(inode)->xattr_sem);
+ return error;
+ }
++EXPORT_SYMBOL(ext4_xattr_set_handle);
+
+ /*
+ * ext4_xattr_set()
+diff -wur a/fs/ext4/xattr.h b/fs/ext4/xattr.h
+--- a/fs/ext4/xattr.h
++++ b/fs/ext4/xattr.h
+@@ -121,6 +121,9 @@
+ extern const struct xattr_handler ext4_xattr_acl_default_handler;
+ extern const struct xattr_handler ext4_xattr_security_handler;
+
++#define LDISKFS_XATTR_INDEX_ENCRYPTION 9
++#define LDISKFS_XATTR_NAME_ENCRYPTION_CONTEXT "c"
++
+ extern ssize_t ext4_listxattr(struct dentry *, char *, size_t);
+
+ extern int ext4_xattr_get(struct inode *, int, const char *, void *, size_t);
--- /dev/null
+diff -wur a/fs/ext4/inode.c b/fs/ext4/inode.c
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4766,8 +4766,9 @@ void ext4_set_inode_flags(struct inod
+ if (init && ext4_should_enable_dax(inode))
+ new_fl |= S_DAX;
+
+- if (flags & EXT4_ENCRYPT_FL)
++ if (flags & EXT4_ENCRYPT_FL &&
++ unlikely(test_opt(inode->i_sb, DIRDATA) != EXT4_MOUNT_DIRDATA))
+ new_fl |= S_ENCRYPTED;
+ inode_set_flags(inode, new_fl,
+ S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX|
+ S_ENCRYPTED);
+@@ -5753,8 +5757,9 @@ int ext4_getattr(const struct path *p
+ stat->attributes |= STATX_ATTR_APPEND;
+ if (flags & EXT4_COMPR_FL)
+ stat->attributes |= STATX_ATTR_COMPRESSED;
+- if (flags & EXT4_ENCRYPT_FL)
++ if (flags & EXT4_ENCRYPT_FL &&
++ unlikely(test_opt(inode->i_sb, DIRDATA) != EXT4_MOUNT_DIRDATA))
+ stat->attributes |= STATX_ATTR_ENCRYPTED;
+ if (flags & EXT4_IMMUTABLE_FL)
+ stat->attributes |= STATX_ATTR_IMMUTABLE;
+ if (flags & EXT4_NODUMP_FL)
+diff -wur a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -654,6 +654,7 @@
+ up_read(&EXT4_I(inode)->xattr_sem);
+ return error;
+ }
++EXPORT_SYMBOL(ext4_xattr_get);
+
+ static int
+ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
+@@ -2413,13 +2415,18 @@
+ ext4_handle_sync(handle);
+ }
+
++ if (!error && name_index == EXT4_XATTR_INDEX_ENCRYPTION &&
++ strcmp(name, "c") == 0)
++ EXT4_I(inode)->i_flags |= EXT4_ENCRYPT_FL;
++
+ cleanup:
+ brelse(is.iloc.bh);
+ brelse(bs.bh);
+ ext4_write_unlock_xattr(inode, &no_expand);
+ return error;
+ }
++EXPORT_SYMBOL(ext4_xattr_set_handle);
+
+ int ext4_xattr_set_credits(struct inode *inode, size_t value_len,
+ bool is_create, int *credits)
+
--- /dev/null
+diff -wur a/fs/ext4/inode.c b/fs/ext4/inode.c
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4766,8 +4766,9 @@ void ext4_set_inode_flags(struct inod
+ if (init && ext4_should_enable_dax(inode))
+ new_fl |= S_DAX;
+
+- if (flags & EXT4_ENCRYPT_FL)
++ if (flags & EXT4_ENCRYPT_FL &&
++ unlikely(test_opt(inode->i_sb, DIRDATA) != EXT4_MOUNT_DIRDATA))
+ new_fl |= S_ENCRYPTED;
+ inode_set_flags(inode, new_fl,
+ S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX|
+ S_ENCRYPTED);
+@@ -5753,8 +5757,9 @@ int ext4_getattr(const struct path *p
+ stat->attributes |= STATX_ATTR_APPEND;
+ if (flags & EXT4_COMPR_FL)
+ stat->attributes |= STATX_ATTR_COMPRESSED;
+- if (flags & EXT4_ENCRYPT_FL)
++ if (flags & EXT4_ENCRYPT_FL &&
++ unlikely(test_opt(inode->i_sb, DIRDATA) != EXT4_MOUNT_DIRDATA))
+ stat->attributes |= STATX_ATTR_ENCRYPTED;
+ if (flags & EXT4_IMMUTABLE_FL)
+ stat->attributes |= STATX_ATTR_IMMUTABLE;
+ if (flags & EXT4_NODUMP_FL)
+diff -wur a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -654,6 +654,7 @@
+ up_read(&EXT4_I(inode)->xattr_sem);
+ return error;
+ }
++EXPORT_SYMBOL(ext4_xattr_get);
+
+ static int
+ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
+@@ -2413,12 +2413,17 @@ retry_inode:
+ ext4_handle_sync(handle);
+ }
+
++ if (!error && name_index == EXT4_XATTR_INDEX_ENCRYPTION &&
++ strcmp(name, "c") == 0)
++ EXT4_I(inode)->i_flags |= EXT4_ENCRYPT_FL;
++
+ cleanup:
+ brelse(is.iloc.bh);
+ brelse(bs.bh);
+ ext4_write_unlock_xattr(inode, &no_expand);
+ return error;
+ }
++EXPORT_SYMBOL(ext4_xattr_set_handle);
+
+ int ext4_xattr_set_credits(struct inode *inode, size_t value_len,
+ bool is_create, int *credits)
--- /dev/null
+diff -wur a/fs/ext4/inode.c b/fs/ext4/inode.c
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4766,8 +4766,9 @@ void ext4_set_inode_flags(struct inod
+ new_fl |= S_DIRSYNC;
+ if (ext4_should_use_dax(inode))
+ new_fl |= S_DAX;
+- if (flags & EXT4_ENCRYPT_FL)
++ if (flags & EXT4_ENCRYPT_FL &&
++ unlikely(test_opt(inode->i_sb, DIRDATA) != EXT4_MOUNT_DIRDATA))
+ new_fl |= S_ENCRYPTED;
+ inode_set_flags(inode, new_fl,
+ S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC|S_DAX|
+ S_ENCRYPTED);
+@@ -5753,8 +5757,9 @@ int ext4_getattr(const struct path *p
+ stat->attributes |= STATX_ATTR_APPEND;
+ if (flags & EXT4_COMPR_FL)
+ stat->attributes |= STATX_ATTR_COMPRESSED;
+- if (flags & EXT4_ENCRYPT_FL)
++ if (flags & EXT4_ENCRYPT_FL &&
++ unlikely(test_opt(inode->i_sb, DIRDATA) != EXT4_MOUNT_DIRDATA))
+ stat->attributes |= STATX_ATTR_ENCRYPTED;
+ if (flags & EXT4_IMMUTABLE_FL)
+ stat->attributes |= STATX_ATTR_IMMUTABLE;
+ if (flags & EXT4_NODUMP_FL)
+diff -wur a/fs/ext4/xattr.c b/fs/ext4/xattr.c
+--- a/fs/ext4/xattr.c
++++ b/fs/ext4/xattr.c
+@@ -654,6 +654,7 @@
+ up_read(&EXT4_I(inode)->xattr_sem);
+ return error;
+ }
++EXPORT_SYMBOL(ext4_xattr_get);
+
+ static int
+ ext4_xattr_list_entries(struct dentry *dentry, struct ext4_xattr_entry *entry,
+@@ -2413,13 +2415,18 @@
+ ext4_handle_sync(handle);
+ }
+
++ if (!error && name_index == EXT4_XATTR_INDEX_ENCRYPTION &&
++ strcmp(name, "c") == 0)
++ EXT4_I(inode)->i_flags |= EXT4_ENCRYPT_FL;
++
+ cleanup:
+ brelse(is.iloc.bh);
+ brelse(bs.bh);
+ ext4_write_unlock_xattr(inode, &no_expand);
+ return error;
+ }
++EXPORT_SYMBOL(ext4_xattr_set_handle);
+
+ int ext4_xattr_set_credits(struct inode *inode, size_t value_len,
+ bool is_create, int *credits)
+
rhel7.6/ext4-dquot-commit-speedup.patch
rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch
rhel7.6/ext4-projid-xattrs.patch
+rhel7.9/ext4-enc-flag.patch
rhel7.6/ext4-dquot-commit-speedup.patch
rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch
rhel7.6/ext4-projid-xattrs.patch
+rhel7.9/ext4-enc-flag.patch
rhel7.6/ext4-dquot-commit-speedup.patch
rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch
rhel7.6/ext4-projid-xattrs.patch
+rhel7.9/ext4-enc-flag.patch
rhel7.6/ext4-dquot-commit-speedup.patch
rhel7.7/ext4-ialloc-uid-gid-and-pass-owner-down.patch
rhel7.6/ext4-projid-xattrs.patch
+rhel7.9/ext4-enc-flag.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+rhel8/linux-5.4/ext4-enc-flag.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+rhel8/ext4-enc-flag.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+rhel8/ext4-enc-flag.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+rhel8.4/ext4-enc-flag.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+rhel8.5/ext4-enc-flag.patch
base/ext4-reset-exts-for-gcc10.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
ubuntu18/ext4-projid-xattrs.patch
+rhel8/ext4-enc-flag.patch
rhel8.3/ext4-xattr-disable-credits-check.patch
linux-5.8/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+linux-5.8/ext4-enc-flag.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+linux-5.4/ext4-enc-flag.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+linux-5.4/ext4-enc-flag.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+linux-5.4/ext4-enc-flag.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+linux-5.4/ext4-enc-flag.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+linux-5.4/ext4-enc-flag.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+linux-5.4/ext4-enc-flag.patch
base/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+linux-5.4/ext4-enc-flag.patch
linux-5.8/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+linux-5.8/ext4-enc-flag.patch
ubuntu2004/ext4-xattr-disable-credits-check.patch
linux-5.8/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
+base/ext4-projid-xattrs.patch
linux-5.8/ext4-enc-flag.patch
linux-5.8/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+linux-5.8/ext4-enc-flag.patch
linux-5.8/ext4-no-max-dir-size-limit-for-iam-objects.patch
rhel8/ext4-ialloc-uid-gid-and-pass-owner-down.patch
base/ext4-projid-xattrs.patch
+linux-5.8/ext4-enc-flag.patch
#define XATTR_USER_PREFIX "user."
#define XATTR_TRUSTED_PREFIX "trusted."
#define XATTR_SECURITY_PREFIX "security."
+#define XATTR_ENCRYPTION_PREFIX "encryption."
#define XATTR_NAME_SOM "trusted.som"
#define XATTR_NAME_LOV "trusted.lov"
#define XATTR_NAME_DUMMY "trusted.dummy"
#define XATTR_NAME_PROJID "trusted.projid"
-#define LL_XATTR_NAME_ENCRYPTION_CONTEXT XATTR_SECURITY_PREFIX"c"
+#define LL_XATTR_NAME_ENCRYPTION_CONTEXT_OLD XATTR_SECURITY_PREFIX"c"
+#define LL_XATTR_NAME_ENCRYPTION_CONTEXT XATTR_ENCRYPTION_PREFIX"c"
#define XATTR_NAME_LFSCK_NAMESPACE "trusted.lfsck_ns"
#define XATTR_NAME_MAX_LEN 32 /* increase this, if there is longer name. */
static int ll_get_context(struct inode *inode, void *ctx, size_t len)
{
- struct dentry *dentry = d_find_any_alias(inode);
- struct lu_env *env;
- __u16 refcheck;
int rc;
- env = cl_env_get(&refcheck);
- if (IS_ERR(env))
- return PTR_ERR(env);
-
- /* Set lcc_getencctx=1 to allow this thread to read
- * LL_XATTR_NAME_ENCRYPTION_CONTEXT xattr, as requested by llcrypt.
+ /* Get enc context xattr directly instead of going through the VFS,
+ * as there is no xattr handler for "encryption.".
*/
- ll_cl_add(inode, env, NULL, LCC_RW);
- ll_env_info(env)->lti_io_ctx.lcc_getencctx = 1;
-
- rc = ll_vfs_getxattr(dentry, inode, LL_XATTR_NAME_ENCRYPTION_CONTEXT,
- ctx, len);
-
- ll_cl_remove(inode, env);
- cl_env_put(env, &refcheck);
-
- if (dentry)
- dput(dentry);
+ rc = ll_xattr_list(inode, LL_XATTR_NAME_ENCRYPTION_CONTEXT,
+ XATTR_ENCRYPTION_T, ctx, len, OBD_MD_FLXATTR);
/* used as encryption unit size */
if (S_ISREG(inode->i_mode))
* op_data, so that it will be sent along to the server with the request that
* the caller is preparing, thus saving a setxattr request.
* - inode is not NULL:
- * normal case in which passed fs_data is a struct dentry *, letting proceed
- * with setxattr operation.
+ * normal case, letting proceed with setxattr operation.
* This use case should only be used when explicitly setting a new encryption
* policy on an existing, empty directory.
*/
static int ll_set_context(struct inode *inode, const void *ctx, size_t len,
void *fs_data)
{
- struct dentry *dentry;
+ struct ptlrpc_request *req = NULL;
+ struct ll_sb_info *sbi;
int rc;
if (inode == NULL) {
if (is_root_inode(inode))
return -EPERM;
- dentry = (struct dentry *)fs_data;
- set_bit(LLIF_SET_ENC_CTX, &ll_i2info(inode)->lli_flags);
- rc = ll_vfs_setxattr(dentry, inode, LL_XATTR_NAME_ENCRYPTION_CONTEXT,
- ctx, len, XATTR_CREATE);
+ sbi = ll_i2sbi(inode);
+ /* Send setxattr request to lower layers directly instead of going
+ * through the VFS, as there is no xattr handler for "encryption.".
+ */
+ rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode),
+ OBD_MD_FLXATTR, LL_XATTR_NAME_ENCRYPTION_CONTEXT,
+ ctx, len, XATTR_CREATE, ll_i2suppgid(inode), &req);
if (rc)
return rc;
+ ptlrpc_req_finished(req);
return ll_set_encflags(inode, (void *)ctx, len, false);
}
LLIF_UPDATE_ATIME = 4,
/* foreign file/dir can be unlinked unconditionnaly */
LLIF_FOREIGN_REMOVABLE = 5,
- /* setting encryption context in progress */
- LLIF_SET_ENC_CTX = 6,
/* Xattr cache is filled */
LLIF_XATTR_CACHE_FILLED = 7,
struct cl_io *lcc_io;
struct cl_page *lcc_page;
enum lcc_type lcc_type;
- /**
- * Get encryption context operation in progress,
- * allow getxattr of LL_XATTR_NAME_ENCRYPTION_CONTEXT xattr
- */
- unsigned lcc_getencctx:1;
};
struct ll_thread_info {
#define XATTR_ACL_DEFAULT_T 5
#define XATTR_LUSTRE_T 6
#define XATTR_OTHER_T 7
+#define XATTR_ENCRYPTION_T 9
ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size);
int ll_xattr_list(struct inode *inode, const char *name, int type,
RETURN(-EPERM);
}
- /* Setting LL_XATTR_NAME_ENCRYPTION_CONTEXT xattr is only allowed
- * when defining an encryption policy on a directory, ie when it
- * comes from ll_set_context().
- * When new files/dirs are created in an encrypted dir, the xattr
- * is set directly in the create request.
+ /* This check is required for compatibility with 2.14, in which
+ * encryption context is stored in security.c xattr.
+ * Setting the encryption context should only be possible by llcrypt
+ * when defining an encryption policy on a directory.
+ * When new files/dirs are created in an encrypted dir, the enc
+ * context is set directly in the create request.
*/
- if (handler->flags == XATTR_SECURITY_T &&
- !strcmp(name, "c") &&
- !test_and_clear_bit(LLIF_SET_ENC_CTX, &ll_i2info(inode)->lli_flags))
+ if (handler->flags == XATTR_SECURITY_T && strcmp(name, "c") == 0)
RETURN(-EPERM);
fullname = kasprintf(GFP_KERNEL, "%s%s", xattr_prefix(handler), name);
int rc;
ENTRY;
- /* Getting LL_XATTR_NAME_ENCRYPTION_CONTEXT xattr is only allowed
- * when it comes from ll_get_context(), ie when llcrypt needs to
- * know the encryption context.
- * Otherwise, any direct reading of this xattr returns -EPERM.
+ /* This check is required for compatibility with 2.14, in which
+ * encryption context is stored in security.c xattr. Accessing the
+ * encryption context should only be possible by llcrypt.
*/
- if (type == XATTR_SECURITY_T &&
- !strcmp(name, LL_XATTR_NAME_ENCRYPTION_CONTEXT)) {
- struct ll_cl_context *lcc = ll_cl_find(inode);
-
- if (!lcc || !lcc->lcc_getencctx)
- GOTO(out_xattr, rc = -EPERM);
- }
+ if (type == XATTR_SECURITY_T && strcmp(name, "security.c") == 0)
+ GOTO(out_xattr, rc = -EPERM);
if (sbi->ll_xattr_cache_enabled && type != XATTR_ACL_ACCESS_T &&
(type != XATTR_SECURITY_T || strcmp(name, "security.selinux"))) {
ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size)
{
- struct inode *dir = d_inode(dentry->d_parent);
struct inode *inode = dentry->d_inode;
struct ll_sb_info *sbi = ll_i2sbi(inode);
ktime_t kstart = ktime_get();
rem = rc;
while (rem > 0) {
+ const struct xattr_handler *xh = get_xattr_type(xattr_name);
bool hide_xattr = false;
- /* Listing xattrs should not expose
- * LL_XATTR_NAME_ENCRYPTION_CONTEXT xattr, unless it comes
- * from llcrypt.
- */
- if (get_xattr_type(xattr_name)->flags == XATTR_SECURITY_T &&
- !strcmp(xattr_name, LL_XATTR_NAME_ENCRYPTION_CONTEXT)) {
- struct ll_cl_context *lcc = ll_cl_find(inode);
-
- if (!lcc || !lcc->lcc_getencctx)
- hide_xattr = true;
- }
-
/* Hide virtual project id xattr from the list when
* parent has the inherit flag and the same project id,
* so project id won't be messed up by copying the xattrs
* when mv to a tree with different project id.
*/
- if (get_xattr_type(xattr_name)->flags == XATTR_TRUSTED_T &&
+ if (xh && xh->flags == XATTR_TRUSTED_T &&
strcmp(xattr_name, XATTR_NAME_PROJID) == 0) {
- if (ll_i2info(inode)->lli_projid ==
- ll_i2info(dir)->lli_projid &&
+ struct inode *dir = d_inode(dentry->d_parent);
+
+ if ((ll_i2info(inode)->lli_projid ==
+ ll_i2info(dir)->lli_projid) &&
test_bit(LLIF_PROJECT_INHERIT,
&ll_i2info(dir)->lli_flags))
hide_xattr = true;
+ } else if (xh && xh->flags == XATTR_SECURITY_T &&
+ strcmp(xattr_name, "security.c") == 0) {
+ /* Listing xattrs should not expose encryption
+ * context. There is no handler defined for
+ * XATTR_ENCRYPTION_PREFIX, so this test is just
+ * needed for compatibility with 2.14, in which
+ * encryption context is stored in security.c xattr.
+ */
+ hide_xattr = true;
}
len = strnlen(xattr_name, rem - 1) + 1;
rem -= len;
- if (!xattr_type_filter(sbi, hide_xattr ? NULL :
- get_xattr_type(xattr_name))) {
+ if (!xattr_type_filter(sbi, hide_xattr ? NULL : xh)) {
/* Skip OK xattr type, leave it in buffer. */
xattr_name += len;
continue;
mdt_object_child(child),
buffer,
LL_XATTR_NAME_ENCRYPTION_CONTEXT);
+ if (unlikely(rc == -ENODATA))
+ /* For compatibility with 2.14 */
+ rc = mo_xattr_get(info->mti_env,
+ mdt_object_child(child),
+ buffer,
+ LL_XATTR_NAME_ENCRYPTION_CONTEXT_OLD);
if (rc >= 0) {
CDEBUG(D_SEC,
"found encryption ctx of size %d for "DFID"\n",
ol->ol_comp_id = 0;
}
} else {
- rc = __osd_xattr_get(inode, dentry, name,
- buf->lb_buf, buf->lb_len);
+ /* Get enc context xattr directly from ldiskfs instead of going
+ * through the VFS, as there is no xattr handler for
+ * "encryption.".
+ */
+ if (strcmp(name, LL_XATTR_NAME_ENCRYPTION_CONTEXT) == 0)
+ rc = ldiskfs_xattr_get(inode,
+ LDISKFS_XATTR_INDEX_ENCRYPTION,
+ LDISKFS_XATTR_NAME_ENCRYPTION_CONTEXT,
+ buf->lb_buf, buf->lb_len);
+ else
+ rc = __osd_xattr_get(inode, dentry, name,
+ buf->lb_buf, buf->lb_len);
}
if (cache_xattr) {
if (fl & LU_XATTR_CREATE)
fs_flags |= XATTR_CREATE;
- rc = __osd_xattr_set(info, inode, name, buf->lb_buf, len, fs_flags);
+ if (strcmp(name, LL_XATTR_NAME_ENCRYPTION_CONTEXT) == 0) {
+ /* Set enc context xattr directly in ldiskfs instead of going
+ * through the VFS, as there is no xattr handler for
+ * "encryption.".
+ */
+ struct osd_thandle *oth = container_of(handle,
+ struct osd_thandle,
+ ot_super);
+
+ if (!oth->ot_handle)
+ /* this should be already part of a transaction */
+ RETURN(-EPROTO);
+
+ rc = ldiskfs_xattr_set_handle(oth->ot_handle, inode,
+ LDISKFS_XATTR_INDEX_ENCRYPTION,
+ LDISKFS_XATTR_NAME_ENCRYPTION_CONTEXT,
+ buf->lb_buf, len, fs_flags);
+ } else {
+ rc = __osd_xattr_set(info, inode, name,
+ buf->lb_buf, len, fs_flags);
+ }
osd_trans_exec_check(env, handle, OSD_OT_XATTR_SET);
if (rc == 0 &&
[ $? -eq 0 ] || error "$cmd failed"
if [ -z "$MATCHING_STRING" ]; then
- $LCTL dk | grep -E "get xattr 'security.c'|get xattrs"
+ $LCTL dk | grep -E "get xattr 'encryption.c'|get xattrs"
else
$LCTL dk | grep -E "$MATCHING_STRING"
fi
trace_cmd cat $dirname/f1
dd if=/dev/zero of=$dirname/f1 bs=1M count=10 conv=fsync
sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
- MATCHING_STRING="get xattr 'security.c'" \
+ MATCHING_STRING="get xattr 'encryption.c'" \
trace_cmd $TRUNCATE $dirname/f1 10240
trace_cmd $LFS setstripe -E -1 -S 4M $dirname/f2
sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
trace_cmd cat $dirname/f1
dd if=/dev/zero of=$dirname/f1 bs=1M count=10 conv=fsync
sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
- MATCHING_STRING="get xattr 'security.c'" \
+ MATCHING_STRING="get xattr 'encryption.c'" \
trace_cmd $TRUNCATE $dirname/f1 10240
trace_cmd $LFS setstripe -E -1 -S 4M $dirname/f2
sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
mkdir $DIR/$tdir
mkdir $testdir
setfattr -n security.c -v myval $testdir &&
- error "setting xattr on $testdir should have failed (1)"
+ error "setting xattr on $testdir should have failed (1.1)"
+ setfattr -n encryption.c -v myval $testdir &&
+ error "setting xattr on $testdir should have failed (1.2)"
touch $testfile
setfattr -n security.c -v myval $testfile &&
- error "setting xattr on $testfile should have failed (1)"
+ error "setting xattr on $testfile should have failed (1.1)"
+ setfattr -n encryption.c -v myval $testfile &&
+ error "setting xattr on $testfile should have failed (1.2)"
rm -rf $DIR/$tdir
mkdir $testdir
if [ $(getfattr -n security.c $testdir 2>&1 |
grep -ci "Operation not permitted") -eq 0 ]; then
- error "getting xattr on $testdir should have failed"
+ error "getting xattr on $testdir should have failed (1.1)"
+ fi
+ if [ $(getfattr -n encryption.c $testdir 2>&1 |
+ grep -ci "Operation not supported") -eq 0 ]; then
+ error "getting xattr on $testdir should have failed (1.2)"
fi
getfattr -d -m - $testdir 2>&1 | grep security\.c &&
error "listing xattrs on $testdir should not expose security.c"
+ getfattr -d -m - $testdir 2>&1 | grep encryption\.c &&
+ error "listing xattrs on $testdir should not expose encryption.c"
if [ $(setfattr -n security.c -v myval $testdir 2>&1 |
grep -ci "Operation not permitted") -eq 0 ]; then
- error "setting xattr on $testdir should have failed (2)"
+ error "setting xattr on $testdir should have failed (2.1)"
+ fi
+ if [ $(setfattr -n encryption.c -v myval $testdir 2>&1 |
+ grep -ci "Operation not supported") -eq 0 ]; then
+ error "setting xattr on $testdir should have failed (2.2)"
fi
touch $testfile
if [ $(getfattr -n security.c $testfile 2>&1 |
grep -ci "Operation not permitted") -eq 0 ]; then
- error "getting xattr on $testfile should have failed"
+ error "getting xattr on $testfile should have failed (1.1)"
+ fi
+ if [ $(getfattr -n encryption.c $testfile 2>&1 |
+ grep -ci "Operation not supported") -eq 0 ]; then
+ error "getting xattr on $testfile should have failed (1.2)"
fi
getfattr -d -m - $testfile 2>&1 | grep security\.c &&
error "listing xattrs on $testfile should not expose security.c"
+ getfattr -d -m - $testfile 2>&1 | grep encryption\.c &&
+ error "listing xattrs on $testfile should not expose encryption.c"
if [ $(setfattr -n security.c -v myval $testfile 2>&1 |
grep -ci "Operation not permitted") -eq 0 ]; then
- error "setting xattr on $testfile should have failed (2)"
+ error "setting xattr on $testfile should have failed (2.1)"
+ fi
+ if [ $(setfattr -n encryption.c -v myval $testfile 2>&1 |
+ grep -ci "Operation not supported") -eq 0 ]; then
+ error "setting xattr on $testfile should have failed (2.2)"
fi
return 0
}
-run_test 57 "security.c xattr protection"
+run_test 57 "security.c/encryption.c xattr protection"
test_58() {
local testdir=$DIR/$tdir/mytestdir