From 4231fab66eab3e984499bf0c6bd4514692a409fa Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Thu, 6 Jan 2022 14:19:02 -0700 Subject: [PATCH] LU-13717 sec: make client encryption compatible with ext4 In order to benefit from encrypted file handling implemented in e2fsprogs, we need to adjust the way Lustre deals with encryption context of files. First, the encryption context needs to be stored in an xattr named "encryption.c" instead of "security.c". But neither llite nor ldiskfs has an xattr handler for this "encryption." xattr type. So we need to export ldiskfs_xattr_get and ldiskfs_xattr_set_handle symbols for this to work. Second, we set the LDISKFS_ENCRYPT_FL flag on files for which we set the 'encryption.c' xattr. But we just keep this flag for on-disk inodes, and make sure the flag is cleared for in-memory inodes. The purpose is to help e2fsprogs with encrypted files handling, while not disturbing Lustre server side with the encryption flag (servers are not supposed to know about it for Lustre client-side encryption). To maintain compatibility with 2.14 in which encryption context is stored in "security.c" xattr, we try to fetch enc context from this xattr if getting it from "encryption.c" fails. On client side, in all cases everything looks like encryption context is stored in "encryption.c". Signed-off-by: Sebastien Buisson Change-Id: I784ec530f0dfdd2743169ba2326ff6c5cdd4e85a Reviewed-on: https://review.whamcloud.com/45211 Tested-by: jenkins Tested-by: Maloo Reviewed-by: James Simmons Reviewed-by: Li Dongyang Reviewed-by: Oleg Drokin --- .../patches/linux-5.4/ext4-enc-flag.patch | 54 ++++++++++++++++++ .../patches/linux-5.8/ext4-enc-flag.patch | 54 ++++++++++++++++++ .../patches/rhel7.9/ext4-enc-flag.patch | 32 +++++++++++ .../patches/rhel8.4/ext4-enc-flag.patch | 55 ++++++++++++++++++ .../patches/rhel8.5/ext4-enc-flag.patch | 54 ++++++++++++++++++ .../patches/rhel8/ext4-enc-flag.patch | 55 ++++++++++++++++++ .../series/ldiskfs-3.10-rhel7.6.series | 1 + .../series/ldiskfs-3.10-rhel7.7.series | 1 + .../series/ldiskfs-3.10-rhel7.8.series | 1 + .../series/ldiskfs-3.10-rhel7.9.series | 1 + .../series/ldiskfs-4.18-rhel8.1.series | 1 + .../series/ldiskfs-4.18-rhel8.2.series | 1 + .../series/ldiskfs-4.18-rhel8.3.series | 1 + .../series/ldiskfs-4.18-rhel8.4.series | 1 + .../series/ldiskfs-4.18-rhel8.5.series | 1 + .../series/ldiskfs-4.18-rhel8.series | 1 + .../kernel_patches/series/ldiskfs-5.10.0-ml.series | 1 + .../series/ldiskfs-5.4.0-42-ubuntu20.series | 1 + .../series/ldiskfs-5.4.0-66-ubuntu20.series | 1 + .../series/ldiskfs-5.4.0-80-ubuntu20.series | 1 + .../series/ldiskfs-5.4.0-90-ubuntu20.series | 1 + .../kernel_patches/series/ldiskfs-5.4.0-ml.series | 1 + .../series/ldiskfs-5.4.136-ml.series | 1 + .../kernel_patches/series/ldiskfs-5.4.21-ml.series | 1 + .../series/ldiskfs-5.8.0-53-ubuntu20.series | 1 + .../series/ldiskfs-5.8.0-63-ubuntu20.series | 1 + .../kernel_patches/series/ldiskfs-5.8.0-ml.series | 1 + .../kernel_patches/series/ldiskfs-5.9.0-ml.series | 1 + lustre/include/uapi/linux/lustre/lustre_idl.h | 4 +- lustre/llite/crypto.c | 42 +++++--------- lustre/llite/llite_internal.h | 8 +-- lustre/llite/xattr.c | 65 ++++++++++------------ lustre/mdt/mdt_lib.c | 6 ++ lustre/osd-ldiskfs/osd_handler.c | 36 +++++++++++- lustre/tests/sanity-sec.sh | 44 +++++++++++---- 35 files changed, 446 insertions(+), 85 deletions(-) create mode 100644 ldiskfs/kernel_patches/patches/linux-5.4/ext4-enc-flag.patch create mode 100644 ldiskfs/kernel_patches/patches/linux-5.8/ext4-enc-flag.patch create mode 100644 ldiskfs/kernel_patches/patches/rhel7.9/ext4-enc-flag.patch create mode 100644 ldiskfs/kernel_patches/patches/rhel8.4/ext4-enc-flag.patch create mode 100644 ldiskfs/kernel_patches/patches/rhel8.5/ext4-enc-flag.patch create mode 100644 ldiskfs/kernel_patches/patches/rhel8/ext4-enc-flag.patch diff --git a/ldiskfs/kernel_patches/patches/linux-5.4/ext4-enc-flag.patch b/ldiskfs/kernel_patches/patches/linux-5.4/ext4-enc-flag.patch new file mode 100644 index 0000000..6deddd7 --- /dev/null +++ b/ldiskfs/kernel_patches/patches/linux-5.4/ext4-enc-flag.patch @@ -0,0 +1,54 @@ +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) diff --git a/ldiskfs/kernel_patches/patches/linux-5.8/ext4-enc-flag.patch b/ldiskfs/kernel_patches/patches/linux-5.8/ext4-enc-flag.patch new file mode 100644 index 0000000..d8f2b22 --- /dev/null +++ b/ldiskfs/kernel_patches/patches/linux-5.8/ext4-enc-flag.patch @@ -0,0 +1,54 @@ +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) diff --git a/ldiskfs/kernel_patches/patches/rhel7.9/ext4-enc-flag.patch b/ldiskfs/kernel_patches/patches/rhel7.9/ext4-enc-flag.patch new file mode 100644 index 0000000..75814a1 --- /dev/null +++ b/ldiskfs/kernel_patches/patches/rhel7.9/ext4-enc-flag.patch @@ -0,0 +1,32 @@ +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); diff --git a/ldiskfs/kernel_patches/patches/rhel8.4/ext4-enc-flag.patch b/ldiskfs/kernel_patches/patches/rhel8.4/ext4-enc-flag.patch new file mode 100644 index 0000000..7256e8f --- /dev/null +++ b/ldiskfs/kernel_patches/patches/rhel8.4/ext4-enc-flag.patch @@ -0,0 +1,55 @@ +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) + diff --git a/ldiskfs/kernel_patches/patches/rhel8.5/ext4-enc-flag.patch b/ldiskfs/kernel_patches/patches/rhel8.5/ext4-enc-flag.patch new file mode 100644 index 0000000..811a6ef --- /dev/null +++ b/ldiskfs/kernel_patches/patches/rhel8.5/ext4-enc-flag.patch @@ -0,0 +1,54 @@ +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) diff --git a/ldiskfs/kernel_patches/patches/rhel8/ext4-enc-flag.patch b/ldiskfs/kernel_patches/patches/rhel8/ext4-enc-flag.patch new file mode 100644 index 0000000..12f4873 --- /dev/null +++ b/ldiskfs/kernel_patches/patches/rhel8/ext4-enc-flag.patch @@ -0,0 +1,55 @@ +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) + diff --git a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.6.series b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.6.series index e4cc884..19caf50 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.6.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.6.series @@ -51,3 +51,4 @@ base/ext4-no-max-dir-size-limit-for-iam-objects.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.7.series b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.7.series index b883ee9..73e01c9 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.7.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.7.series @@ -51,3 +51,4 @@ base/ext4-no-max-dir-size-limit-for-iam-objects.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.8.series b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.8.series index 72d308f..3415561 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.8.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.8.series @@ -44,3 +44,4 @@ base/ext4-no-max-dir-size-limit-for-iam-objects.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.9.series b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.9.series index a50604c..f6d1ddf 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.9.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-3.10-rhel7.9.series @@ -44,3 +44,4 @@ base/ext4-no-max-dir-size-limit-for-iam-objects.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.1.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.1.series index d34d03d..2b9b8be 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.1.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.1.series @@ -28,3 +28,4 @@ rhel8/ext4-xattr-disable-credits-check.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.2.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.2.series index 02d29aa..ffcd76b 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.2.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.2.series @@ -28,3 +28,4 @@ rhel8/ext4-xattr-disable-credits-check.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.3.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.3.series index 3a0ce31..9dffa05 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.3.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.3.series @@ -28,3 +28,4 @@ rhel8.3/ext4-xattr-disable-credits-check.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.4.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.4.series index 9528ef5..f5b966c 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.4.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.4.series @@ -28,3 +28,4 @@ rhel8.3/ext4-xattr-disable-credits-check.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.5.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.5.series index 9528ef5..a739214 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.5.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.5.series @@ -28,3 +28,4 @@ rhel8.3/ext4-xattr-disable-credits-check.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.series b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.series index f013041..1f9a593 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-4.18-rhel8.series @@ -30,3 +30,4 @@ base/ext4-no-max-dir-size-limit-for-iam-objects.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.10.0-ml.series b/ldiskfs/kernel_patches/series/ldiskfs-5.10.0-ml.series index 6add51a..0331faa 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.10.0-ml.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.10.0-ml.series @@ -27,3 +27,4 @@ linux-5.9/ext4-simple-blockalloc.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-42-ubuntu20.series b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-42-ubuntu20.series index cd90a53..4843c9b 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-42-ubuntu20.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-42-ubuntu20.series @@ -29,3 +29,4 @@ rhel8/ext4-xattr-disable-credits-check.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-66-ubuntu20.series b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-66-ubuntu20.series index 067d3fc..e9d7770 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-66-ubuntu20.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-66-ubuntu20.series @@ -29,3 +29,4 @@ rhel8/ext4-xattr-disable-credits-check.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-80-ubuntu20.series b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-80-ubuntu20.series index 556a59d..105612b 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-80-ubuntu20.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-80-ubuntu20.series @@ -29,3 +29,4 @@ linux-5.4/ext4-xattr-disable-credits-check.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-90-ubuntu20.series b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-90-ubuntu20.series index 26f1a70f..da2b6ee 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-90-ubuntu20.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-90-ubuntu20.series @@ -29,3 +29,4 @@ linux-5.4/ext4-xattr-disable-credits-check.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-ml.series b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-ml.series index 4407f21..424ae1c 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-ml.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.4.0-ml.series @@ -29,3 +29,4 @@ rhel8/ext4-xattr-disable-credits-check.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.4.136-ml.series b/ldiskfs/kernel_patches/series/ldiskfs-5.4.136-ml.series index 668b6b1..834806c 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.4.136-ml.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.4.136-ml.series @@ -29,3 +29,4 @@ linux-5.4/ext4-xattr-disable-credits-check.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.4.21-ml.series b/ldiskfs/kernel_patches/series/ldiskfs-5.4.21-ml.series index cd90a53..4843c9b 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.4.21-ml.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.4.21-ml.series @@ -29,3 +29,4 @@ rhel8/ext4-xattr-disable-credits-check.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-53-ubuntu20.series b/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-53-ubuntu20.series index fae39d6..1278d70 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-53-ubuntu20.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-53-ubuntu20.series @@ -29,3 +29,4 @@ 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 base/ext4-projid-xattrs.patch +linux-5.8/ext4-enc-flag.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-63-ubuntu20.series b/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-63-ubuntu20.series index c60c85f..d056622 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-63-ubuntu20.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-63-ubuntu20.series @@ -28,4 +28,5 @@ ubuntu2004/ext4-simple-blockalloc.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 diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-ml.series b/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-ml.series index 4d3c0f4..879ce71 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-ml.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.8.0-ml.series @@ -29,3 +29,4 @@ 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 base/ext4-projid-xattrs.patch +linux-5.8/ext4-enc-flag.patch diff --git a/ldiskfs/kernel_patches/series/ldiskfs-5.9.0-ml.series b/ldiskfs/kernel_patches/series/ldiskfs-5.9.0-ml.series index aa62e8d..da34423 100644 --- a/ldiskfs/kernel_patches/series/ldiskfs-5.9.0-ml.series +++ b/ldiskfs/kernel_patches/series/ldiskfs-5.9.0-ml.series @@ -28,3 +28,4 @@ linux-5.9/ext4-simple-blockalloc.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 diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index 175cf1f..e58dc92 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -1198,6 +1198,7 @@ struct lov_mds_md_v1 { /* LOV EA mds/wire data (little-endian) */ #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" @@ -1213,7 +1214,8 @@ struct lov_mds_md_v1 { /* LOV EA mds/wire data (little-endian) */ #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. */ diff --git a/lustre/llite/crypto.c b/lustre/llite/crypto.c index cc80aea..3d7b63e 100644 --- a/lustre/llite/crypto.c +++ b/lustre/llite/crypto.c @@ -33,29 +33,13 @@ 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)) @@ -92,15 +76,15 @@ int ll_set_encflags(struct inode *inode, void *encctx, __u32 encctxlen, * 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) { @@ -121,12 +105,16 @@ static int ll_set_context(struct inode *inode, const void *ctx, size_t len, 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); } diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index bc3aff9..ff41517 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -416,8 +416,6 @@ enum ll_file_flags { 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, @@ -1297,11 +1295,6 @@ struct ll_cl_context { 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 { @@ -1413,6 +1406,7 @@ extern const struct xattr_handler *ll_xattr_handlers[]; #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, diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index 6325c8a..cc7839f 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -146,15 +146,14 @@ static int ll_xattr_set_common(const struct xattr_handler *handler, 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); @@ -379,18 +378,12 @@ int ll_xattr_list(struct inode *inode, const char *name, int type, void *buffer, 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"))) { @@ -623,7 +616,6 @@ static int ll_xattr_get(const struct xattr_handler *handler, 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(); @@ -653,38 +645,37 @@ ssize_t ll_listxattr(struct dentry *dentry, char *buffer, size_t size) 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; diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index 0fc378b..39fcb2a 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -2016,6 +2016,12 @@ int mdt_pack_encctx_in_reply(struct mdt_thread_info *info, 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", diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index d206292..0577ba9 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -4491,8 +4491,18 @@ static int osd_xattr_get(const struct lu_env *env, struct dt_object *dt, 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) { @@ -4860,7 +4870,27 @@ static int osd_xattr_set(const struct lu_env *env, struct dt_object *dt, 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 && diff --git a/lustre/tests/sanity-sec.sh b/lustre/tests/sanity-sec.sh index d6edcc6..ca9da83 100755 --- a/lustre/tests/sanity-sec.sh +++ b/lustre/tests/sanity-sec.sh @@ -3745,7 +3745,7 @@ trace_cmd() { [ $? -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 @@ -3774,7 +3774,7 @@ test_49() { 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 @@ -3801,7 +3801,7 @@ test_49() { 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 @@ -4435,10 +4435,14 @@ test_57() { 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 @@ -4448,28 +4452,48 @@ test_57() { 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 -- 1.8.3.1