From c540c394861bc33a0c4cf5f3b24519e82c1db39c Mon Sep 17 00:00:00 2001 From: Kmods SIG Date: Jan 13 2022 23:40:15 +0000 Subject: Switch to EL kernel source and versioning --- diff --git a/.gitignore b/.gitignore index b94ef16..d00ca97 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/ecryptfs-5.10.tar.xz +SOURCES/ecryptfs-4.18.0-277.el8.tar.xz diff --git a/.kmod-ecryptfs.metadata b/.kmod-ecryptfs.metadata index 7db5b9f..0954767 100644 --- a/.kmod-ecryptfs.metadata +++ b/.kmod-ecryptfs.metadata @@ -1 +1 @@ -483f2ad31e8ca4f4b6bacc6474ce5149a4172c99 SOURCES/ecryptfs-5.10.tar.xz +9e8584ef405757e211bc6c23585e153fde30b6b5 SOURCES/ecryptfs-4.18.0-277.el8.tar.xz diff --git a/SOURCES/0001-ecryptfs_rename-verify-that-lower-dentries-are-still.patch b/SOURCES/0001-ecryptfs_rename-verify-that-lower-dentries-are-still.patch new file mode 100644 index 0000000..1470ca7 --- /dev/null +++ b/SOURCES/0001-ecryptfs_rename-verify-that-lower-dentries-are-still.patch @@ -0,0 +1,42 @@ +From 74dd7c97ea2ab08b41925ab2f472db573accda89 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Tue, 9 Oct 2018 23:32:41 -0400 +Subject: [Backport 74dd7c97ea2a] ecryptfs_rename(): verify that lower dentries + are still OK after lock_rename() + +We get lower layer dentries, find their parents, do lock_rename() and +proceed to vfs_rename(). However, we do not check that dentries still +have the same parents and are not unlinked. Need to check that... + +Signed-off-by: Al Viro +--- + src/inode.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/src/inode.c b/src/inode.c +index 49121e5a8de228acfb1ea126250e5ad94e4ec812..5c36ceecb5c12828ceb84a39d19c86b69713b937 100644 +--- a/src/inode.c ++++ b/src/inode.c +@@ -593,11 +593,16 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, + lower_new_dir_dentry = dget_parent(lower_new_dentry); + target_inode = d_inode(new_dentry); + trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); ++ rc = -EINVAL; ++ if (lower_old_dentry->d_parent != lower_old_dir_dentry) ++ goto out_lock; ++ if (lower_new_dentry->d_parent != lower_new_dir_dentry) ++ goto out_lock; ++ if (d_unhashed(lower_old_dentry) || d_unhashed(lower_new_dentry)) ++ goto out_lock; + /* source should not be ancestor of target */ +- if (trap == lower_old_dentry) { +- rc = -EINVAL; ++ if (trap == lower_old_dentry) + goto out_lock; +- } + /* target should not be ancestor of source */ + if (trap == lower_new_dentry) { + rc = -ENOTEMPTY; +-- +2.31.1 + diff --git a/SOURCES/0002-crypto-shash-remove-shash_desc-flags.patch b/SOURCES/0002-crypto-shash-remove-shash_desc-flags.patch new file mode 100644 index 0000000..f8518a1 --- /dev/null +++ b/SOURCES/0002-crypto-shash-remove-shash_desc-flags.patch @@ -0,0 +1,60 @@ +From 877b5691f27a1aec0d9b53095a323e45c30069e2 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Sun, 14 Apr 2019 17:37:09 -0700 +Subject: [Backport 877b5691f27a] crypto: shash - remove shash_desc::flags + +The flags field in 'struct shash_desc' never actually does anything. +The only ostensibly supported flag is CRYPTO_TFM_REQ_MAY_SLEEP. +However, no shash algorithm ever sleeps, making this flag a no-op. + +With this being the case, inevitably some users who can't sleep wrongly +pass MAY_SLEEP. These would all need to be fixed if any shash algorithm +actually started sleeping. For example, the shash_ahash_*() functions, +which wrap a shash algorithm with the ahash API, pass through MAY_SLEEP +from the ahash API to the shash API. However, the shash functions are +called under kmap_atomic(), so actually they're assumed to never sleep. + +Even if it turns out that some users do need preemption points while +hashing large buffers, we could easily provide a helper function +crypto_shash_update_large() which divides the data into smaller chunks +and calls crypto_shash_update() and cond_resched() for each chunk. It's +not necessary to have a flag in 'struct shash_desc', nor is it necessary +to make individual shash algorithms aware of this at all. + +Therefore, remove shash_desc::flags, and document that the +crypto_shash_*() functions can be called from any context. + +Signed-off-by: Eric Biggers +Signed-off-by: Herbert Xu +--- + src/crypto.c | 1 - + src/keystore.c | 1 - + 2 files changed, 2 deletions(-) + +diff --git a/src/crypto.c b/src/crypto.c +index f664da55234e93b18194237e9995a16c70f1334d..491cf5baa8c23b5f97254f4d5cb43d32e3339f8f 100644 +--- a/src/crypto.c ++++ b/src/crypto.c +@@ -68,7 +68,6 @@ static int ecryptfs_hash_digest(struct crypto_shash *tfm, + int err; + + desc->tfm = tfm; +- desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; + err = crypto_shash_digest(desc, src, len, dst); + shash_desc_zero(desc); + return err; +diff --git a/src/keystore.c b/src/keystore.c +index e74fe84d0886879c04cc26297f0e8b27db8281a6..90fbac5d485b3a79728f342e81e2bcdaa8b0e552 100644 +--- a/src/keystore.c ++++ b/src/keystore.c +@@ -769,7 +769,6 @@ ecryptfs_write_tag_70_packet(char *dest, size_t *remaining_bytes, + } + + s->hash_desc->tfm = s->hash_tfm; +- s->hash_desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; + + rc = crypto_shash_digest(s->hash_desc, + (u8 *)s->auth_tok->token.password.session_key_encryption_key, +-- +2.31.1 + diff --git a/SOURCES/0003-eCryptfs-fix-a-couple-type-promotion-bugs.patch b/SOURCES/0003-eCryptfs-fix-a-couple-type-promotion-bugs.patch new file mode 100644 index 0000000..e9fef7e --- /dev/null +++ b/SOURCES/0003-eCryptfs-fix-a-couple-type-promotion-bugs.patch @@ -0,0 +1,50 @@ +From 0bdf8a8245fdea6f075a5fede833a5fcf1b3466c Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 4 Jul 2018 12:35:56 +0300 +Subject: [Backport 0bdf8a8245fd] eCryptfs: fix a couple type promotion bugs + +ECRYPTFS_SIZE_AND_MARKER_BYTES is type size_t, so if "rc" is negative +that gets type promoted to a high positive value and treated as success. + +Fixes: 778aeb42a708 ("eCryptfs: Cleanup and optimize ecryptfs_lookup_interpose()") +Signed-off-by: Dan Carpenter +[tyhicks: Use "if/else if" rather than "if/if"] +Cc: stable@vger.kernel.org +Signed-off-by: Tyler Hicks +--- + src/crypto.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/src/crypto.c b/src/crypto.c +index 4dd842f728465591cc7982d635f544c0084b064a..708f931c36f14adace91af82229a6043386c9baf 100644 +--- a/src/crypto.c ++++ b/src/crypto.c +@@ -1018,8 +1018,10 @@ int ecryptfs_read_and_validate_header_region(struct inode *inode) + + rc = ecryptfs_read_lower(file_size, 0, ECRYPTFS_SIZE_AND_MARKER_BYTES, + inode); +- if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES) +- return rc >= 0 ? -EINVAL : rc; ++ if (rc < 0) ++ return rc; ++ else if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES) ++ return -EINVAL; + rc = ecryptfs_validate_marker(marker); + if (!rc) + ecryptfs_i_size_init(file_size, inode); +@@ -1381,8 +1383,10 @@ int ecryptfs_read_and_validate_xattr_region(struct dentry *dentry, + ecryptfs_inode_to_lower(inode), + ECRYPTFS_XATTR_NAME, file_size, + ECRYPTFS_SIZE_AND_MARKER_BYTES); +- if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES) +- return rc >= 0 ? -EINVAL : rc; ++ if (rc < 0) ++ return rc; ++ else if (rc < ECRYPTFS_SIZE_AND_MARKER_BYTES) ++ return -EINVAL; + rc = ecryptfs_validate_marker(marker); + if (!rc) + ecryptfs_i_size_init(file_size, inode); +-- +2.31.1 + diff --git a/SOURCES/0004-eCryptfs-fix-permission-denied-with-ecryptfs_xattr-m.patch b/SOURCES/0004-eCryptfs-fix-permission-denied-with-ecryptfs_xattr-m.patch new file mode 100644 index 0000000..b54693f --- /dev/null +++ b/SOURCES/0004-eCryptfs-fix-permission-denied-with-ecryptfs_xattr-m.patch @@ -0,0 +1,62 @@ +From d43388dea04b18f516bd7c837d9222fe7309b12d Mon Sep 17 00:00:00 2001 +From: Robbie Ko +Date: Tue, 21 Aug 2018 16:17:40 +0800 +Subject: [Backport d43388dea04b] eCryptfs: fix permission denied with + ecryptfs_xattr mount option when create readonly file + +When the ecryptfs_xattr mount option is turned on, the ecryptfs +metadata will be written to xattr via vfs_setxattr, which will +check the WRITE permissions. + +However, this will cause denial of permission when creating a +file withoug write permission. + +So fix this by calling __vfs_setxattr directly to skip permission +check. + +Signed-off-by: Robbie Ko +[tyhicks: Copy up lower inode attributes when successful] +Signed-off-by: Tyler Hicks +--- + src/crypto.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/src/crypto.c b/src/crypto.c +index 708f931c36f14adace91af82229a6043386c9baf..bc2376726090b403ed3fa8d043efa07c6b45c23a 100644 +--- a/src/crypto.c ++++ b/src/crypto.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + #include "ecryptfs_kernel.h" + + #define DECRYPT 0 +@@ -1131,9 +1132,21 @@ ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, + char *page_virt, size_t size) + { + int rc; ++ struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); ++ struct inode *lower_inode = d_inode(lower_dentry); + +- rc = ecryptfs_setxattr(ecryptfs_dentry, ecryptfs_inode, +- ECRYPTFS_XATTR_NAME, page_virt, size, 0); ++ if (!(lower_inode->i_opflags & IOP_XATTR)) { ++ rc = -EOPNOTSUPP; ++ goto out; ++ } ++ ++ inode_lock(lower_inode); ++ rc = __vfs_setxattr(lower_dentry, lower_inode, ECRYPTFS_XATTR_NAME, ++ page_virt, size, 0); ++ if (!rc && ecryptfs_inode) ++ fsstack_copy_attr_all(ecryptfs_inode, lower_inode); ++ inode_unlock(lower_inode); ++out: + return rc; + } + +-- +2.31.1 + diff --git a/SOURCES/0005-ecryptfs-fix-unlink-and-rmdir-in-face-of-underlying-.patch b/SOURCES/0005-ecryptfs-fix-unlink-and-rmdir-in-face-of-underlying-.patch new file mode 100644 index 0000000..673ffdd --- /dev/null +++ b/SOURCES/0005-ecryptfs-fix-unlink-and-rmdir-in-face-of-underlying-.patch @@ -0,0 +1,169 @@ +From bcf0d9d4b76976f892154efdfc509b256fd898e8 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sun, 3 Nov 2019 12:07:15 -0500 +Subject: [Backport bcf0d9d4b769] ecryptfs: fix unlink and rmdir in face of + underlying fs modifications + +A problem similar to the one caught in commit 74dd7c97ea2a ("ecryptfs_rename(): +verify that lower dentries are still OK after lock_rename()") exists for +unlink/rmdir as well. + +Instead of playing with dget_parent() of underlying dentry of victim +and hoping it's the same as underlying dentry of our directory, +do the following: + * find the underlying dentry of victim + * find the underlying directory of victim's parent (stable +since the victim is ecryptfs dentry and inode of its parent is +held exclusive by the caller). + * lock the inode of dentry underlying the victim's parent + * check that underlying dentry of victim is still hashed and +has the right parent - it can be moved, but it can't be moved to/from +the directory we are holding exclusive. So while ->d_parent itself +might not be stable, the result of comparison is. + +If the check passes, everything is fine - underlying directory is locked, +underlying victim is still a child of that directory and we can go ahead +and feed them to vfs_unlink(). As in the current mainline we need to +pin the underlying dentry of victim, so that it wouldn't go negative under +us, but that's the only temporary reference that needs to be grabbed there. +Underlying dentry of parent won't go away (it's pinned by the parent, +which is held by caller), so there's no need to grab it. + +The same problem (with the same solution) exists for rmdir. Moreover, +rename gets simpler and more robust with the same "don't bother with +dget_parent()" approach. + +Fixes: 74dd7c97ea2 "ecryptfs_rename(): verify that lower dentries are still OK after lock_rename()" +Signed-off-by: Al Viro +--- + src/inode.c | 65 ++++++++++++++++++++++++++++----------------- + 1 file changed, 40 insertions(+), 25 deletions(-) + +diff --git a/src/inode.c b/src/inode.c +index 18426f4855f11b3e561f1cc35ee381fac3f2cfcc..a905d5f4f3b0726303595e39ba40309d68baa422 100644 +--- a/src/inode.c ++++ b/src/inode.c +@@ -128,13 +128,20 @@ static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry, + struct inode *inode) + { + struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); +- struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); + struct dentry *lower_dir_dentry; ++ struct inode *lower_dir_inode; + int rc; + +- dget(lower_dentry); +- lower_dir_dentry = lock_parent(lower_dentry); +- rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL); ++ lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); ++ lower_dir_inode = d_inode(lower_dir_dentry); ++ inode_lock_nested(lower_dir_inode, I_MUTEX_PARENT); ++ dget(lower_dentry); // don't even try to make the lower negative ++ if (lower_dentry->d_parent != lower_dir_dentry) ++ rc = -EINVAL; ++ else if (d_unhashed(lower_dentry)) ++ rc = -EINVAL; ++ else ++ rc = vfs_unlink(lower_dir_inode, lower_dentry, NULL); + if (rc) { + printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); + goto out_unlock; +@@ -142,10 +149,11 @@ static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry, + fsstack_copy_attr_times(dir, lower_dir_inode); + set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink); + inode->i_ctime = dir->i_ctime; +- d_drop(dentry); + out_unlock: +- unlock_dir(lower_dir_dentry); + dput(lower_dentry); ++ inode_unlock(lower_dir_inode); ++ if (!rc) ++ d_drop(dentry); + return rc; + } + +@@ -512,22 +520,30 @@ static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry) + { + struct dentry *lower_dentry; + struct dentry *lower_dir_dentry; ++ struct inode *lower_dir_inode; + int rc; + + lower_dentry = ecryptfs_dentry_to_lower(dentry); +- dget(dentry); +- lower_dir_dentry = lock_parent(lower_dentry); +- dget(lower_dentry); +- rc = vfs_rmdir(d_inode(lower_dir_dentry), lower_dentry); +- dput(lower_dentry); +- if (!rc && d_really_is_positive(dentry)) ++ lower_dir_dentry = ecryptfs_dentry_to_lower(dentry->d_parent); ++ lower_dir_inode = d_inode(lower_dir_dentry); ++ ++ inode_lock_nested(lower_dir_inode, I_MUTEX_PARENT); ++ dget(lower_dentry); // don't even try to make the lower negative ++ if (lower_dentry->d_parent != lower_dir_dentry) ++ rc = -EINVAL; ++ else if (d_unhashed(lower_dentry)) ++ rc = -EINVAL; ++ else ++ rc = vfs_rmdir(lower_dir_inode, lower_dentry); ++ if (!rc) { + clear_nlink(d_inode(dentry)); +- fsstack_copy_attr_times(dir, d_inode(lower_dir_dentry)); +- set_nlink(dir, d_inode(lower_dir_dentry)->i_nlink); +- unlock_dir(lower_dir_dentry); ++ fsstack_copy_attr_times(dir, lower_dir_inode); ++ set_nlink(dir, lower_dir_inode->i_nlink); ++ } ++ dput(lower_dentry); ++ inode_unlock(lower_dir_inode); + if (!rc) + d_drop(dentry); +- dput(dentry); + return rc; + } + +@@ -565,20 +581,22 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, + struct dentry *lower_new_dentry; + struct dentry *lower_old_dir_dentry; + struct dentry *lower_new_dir_dentry; +- struct dentry *trap = NULL; ++ struct dentry *trap; + struct inode *target_inode; + + if (flags) + return -EINVAL; + ++ lower_old_dir_dentry = ecryptfs_dentry_to_lower(old_dentry->d_parent); ++ lower_new_dir_dentry = ecryptfs_dentry_to_lower(new_dentry->d_parent); ++ + lower_old_dentry = ecryptfs_dentry_to_lower(old_dentry); + lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry); +- dget(lower_old_dentry); +- dget(lower_new_dentry); +- lower_old_dir_dentry = dget_parent(lower_old_dentry); +- lower_new_dir_dentry = dget_parent(lower_new_dentry); ++ + target_inode = d_inode(new_dentry); ++ + trap = lock_rename(lower_old_dir_dentry, lower_new_dir_dentry); ++ dget(lower_new_dentry); + rc = -EINVAL; + if (lower_old_dentry->d_parent != lower_old_dir_dentry) + goto out_lock; +@@ -606,11 +624,8 @@ ecryptfs_rename(struct inode *old_dir, struct dentry *old_dentry, + if (new_dir != old_dir) + fsstack_copy_attr_all(old_dir, d_inode(lower_old_dir_dentry)); + out_lock: +- unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); +- dput(lower_new_dir_dentry); +- dput(lower_old_dir_dentry); + dput(lower_new_dentry); +- dput(lower_old_dentry); ++ unlock_rename(lower_old_dir_dentry, lower_new_dir_dentry); + return rc; + } + +-- +2.31.1 + diff --git a/SOURCES/0006-ecryptfs_lookup_interpose-lower_dentry-d_inode-is-no.patch b/SOURCES/0006-ecryptfs_lookup_interpose-lower_dentry-d_inode-is-no.patch new file mode 100644 index 0000000..52cabfb --- /dev/null +++ b/SOURCES/0006-ecryptfs_lookup_interpose-lower_dentry-d_inode-is-no.patch @@ -0,0 +1,51 @@ +From e72b9dd6a5f17d0fb51f16f8685f3004361e83d0 Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sun, 3 Nov 2019 13:45:04 -0500 +Subject: [Backport e72b9dd6a5f1] ecryptfs_lookup_interpose(): + lower_dentry->d_inode is not stable + +lower_dentry can't go from positive to negative (we have it pinned), +but it *can* go from negative to positive. So fetching ->d_inode +into a local variable, doing a blocking allocation, checking that +now ->d_inode is non-NULL and feeding the value we'd fetched +earlier to a function that won't accept NULL is not a good idea. + +Cc: stable@vger.kernel.org +Signed-off-by: Al Viro +--- + src/inode.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/src/inode.c b/src/inode.c +index a905d5f4f3b0726303595e39ba40309d68baa422..3c229872135987fb4d0a1a36a910651d5f37a08b 100644 +--- a/src/inode.c ++++ b/src/inode.c +@@ -319,7 +319,7 @@ static int ecryptfs_i_size_read(struct dentry *dentry, struct inode *inode) + static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry, + struct dentry *lower_dentry) + { +- struct inode *inode, *lower_inode = d_inode(lower_dentry); ++ struct inode *inode, *lower_inode; + struct ecryptfs_dentry_info *dentry_info; + struct vfsmount *lower_mnt; + int rc = 0; +@@ -339,7 +339,15 @@ static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry, + dentry_info->lower_path.mnt = lower_mnt; + dentry_info->lower_path.dentry = lower_dentry; + +- if (d_really_is_negative(lower_dentry)) { ++ /* ++ * negative dentry can go positive under us here - its parent is not ++ * locked. That's OK and that could happen just as we return from ++ * ecryptfs_lookup() anyway. Just need to be careful and fetch ++ * ->d_inode only once - it's not stable here. ++ */ ++ lower_inode = READ_ONCE(lower_dentry->d_inode); ++ ++ if (!lower_inode) { + /* We want to add because we couldn't find in lower */ + d_add(dentry, NULL); + return NULL; +-- +2.31.1 + diff --git a/SOURCES/0007-ecryptfs_lookup_interpose-lower_dentry-d_parent-is-n.patch b/SOURCES/0007-ecryptfs_lookup_interpose-lower_dentry-d_parent-is-n.patch new file mode 100644 index 0000000..14e0d42 --- /dev/null +++ b/SOURCES/0007-ecryptfs_lookup_interpose-lower_dentry-d_parent-is-n.patch @@ -0,0 +1,59 @@ +From 762c69685ff7ad5ad7fee0656671e20a0c9c864d Mon Sep 17 00:00:00 2001 +From: Al Viro +Date: Sun, 3 Nov 2019 13:55:43 -0500 +Subject: [Backport 762c69685ff7] ecryptfs_lookup_interpose(): + lower_dentry->d_parent is not stable either + +We need to get the underlying dentry of parent; sure, absent the races +it is the parent of underlying dentry, but there's nothing to prevent +losing a timeslice to preemtion in the middle of evaluation of +lower_dentry->d_parent->d_inode, having another process move lower_dentry +around and have its (ex)parent not pinned anymore and freed on memory +pressure. Then we regain CPU and try to fetch ->d_inode from memory +that is freed by that point. + +dentry->d_parent *is* stable here - it's an argument of ->lookup() and +we are guaranteed that it won't be moved anywhere until we feed it +to d_add/d_splice_alias. So we safely go that way to get to its +underlying dentry. + +Cc: stable@vger.kernel.org # since 2009 or so +Signed-off-by: Al Viro +--- + src/inode.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/inode.c b/src/inode.c +index 3c229872135987fb4d0a1a36a910651d5f37a08b..e23752d9a79f3d255345177db1b66950ae8e6607 100644 +--- a/src/inode.c ++++ b/src/inode.c +@@ -319,9 +319,9 @@ static int ecryptfs_i_size_read(struct dentry *dentry, struct inode *inode) + static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry, + struct dentry *lower_dentry) + { ++ struct path *path = ecryptfs_dentry_to_lower_path(dentry->d_parent); + struct inode *inode, *lower_inode; + struct ecryptfs_dentry_info *dentry_info; +- struct vfsmount *lower_mnt; + int rc = 0; + + dentry_info = kmem_cache_alloc(ecryptfs_dentry_info_cache, GFP_KERNEL); +@@ -330,13 +330,12 @@ static struct dentry *ecryptfs_lookup_interpose(struct dentry *dentry, + return ERR_PTR(-ENOMEM); + } + +- lower_mnt = mntget(ecryptfs_dentry_to_lower_mnt(dentry->d_parent)); + fsstack_copy_attr_atime(d_inode(dentry->d_parent), +- d_inode(lower_dentry->d_parent)); ++ d_inode(path->dentry)); + BUG_ON(!d_count(lower_dentry)); + + ecryptfs_set_dentry_private(dentry, dentry_info); +- dentry_info->lower_path.mnt = lower_mnt; ++ dentry_info->lower_path.mnt = mntget(path->mnt); + dentry_info->lower_path.dentry = lower_dentry; + + /* +-- +2.31.1 + diff --git a/SOURCES/0008-ecryptfs-fix-a-memory-leak-bug-in-parse_tag_1_packet.patch b/SOURCES/0008-ecryptfs-fix-a-memory-leak-bug-in-parse_tag_1_packet.patch new file mode 100644 index 0000000..7680af3 --- /dev/null +++ b/SOURCES/0008-ecryptfs-fix-a-memory-leak-bug-in-parse_tag_1_packet.patch @@ -0,0 +1,35 @@ +From fe2e082f5da5b4a0a92ae32978f81507ef37ec66 Mon Sep 17 00:00:00 2001 +From: Wenwen Wang +Date: Tue, 20 Aug 2019 00:16:40 -0500 +Subject: [Backport fe2e082f5da5] ecryptfs: fix a memory leak bug in + parse_tag_1_packet() + +In parse_tag_1_packet(), if tag 1 packet contains a key larger than +ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES, no cleanup is executed, leading to a +memory leak on the allocated 'auth_tok_list_item'. To fix this issue, go to +the label 'out_free' to perform the cleanup work. + +Cc: stable@vger.kernel.org +Fixes: dddfa461fc89 ("[PATCH] eCryptfs: Public key; packet management") +Signed-off-by: Wenwen Wang +Signed-off-by: Tyler Hicks +--- + src/keystore.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/keystore.c b/src/keystore.c +index 216fbe6a4837caf9eabb728689730a0bad97324d..4dc09638de8fa5e7bce61ca48fc7a76a4d40fc4c 100644 +--- a/src/keystore.c ++++ b/src/keystore.c +@@ -1304,7 +1304,7 @@ parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat, + printk(KERN_WARNING "Tag 1 packet contains key larger " + "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES\n"); + rc = -EINVAL; +- goto out; ++ goto out_free; + } + memcpy((*new_auth_tok)->session_key.encrypted_key, + &data[(*packet_size)], (body_size - (ECRYPTFS_SIG_SIZE + 2))); +-- +2.31.1 + diff --git a/SOURCES/0009-ecryptfs-fix-a-memory-leak-bug-in-ecryptfs_init_mess.patch b/SOURCES/0009-ecryptfs-fix-a-memory-leak-bug-in-ecryptfs_init_mess.patch new file mode 100644 index 0000000..8c67219 --- /dev/null +++ b/SOURCES/0009-ecryptfs-fix-a-memory-leak-bug-in-ecryptfs_init_mess.patch @@ -0,0 +1,34 @@ +From b4a81b87a4cfe2bb26a4a943b748d96a43ef20e8 Mon Sep 17 00:00:00 2001 +From: Wenwen Wang +Date: Tue, 20 Aug 2019 00:33:54 -0500 +Subject: [Backport b4a81b87a4cf] ecryptfs: fix a memory leak bug in + ecryptfs_init_messaging() + +In ecryptfs_init_messaging(), if the allocation for 'ecryptfs_msg_ctx_arr' +fails, the previously allocated 'ecryptfs_daemon_hash' is not deallocated, +leading to a memory leak bug. To fix this issue, free +'ecryptfs_daemon_hash' before returning the error. + +Cc: stable@vger.kernel.org +Fixes: 88b4a07e6610 ("[PATCH] eCryptfs: Public key transport mechanism") +Signed-off-by: Wenwen Wang +Signed-off-by: Tyler Hicks +--- + src/messaging.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/messaging.c b/src/messaging.c +index d668e60b85b556dd27b08a345a222688b795257c..c05ca39aa4494f9077768fc9e04b21d817a3401b 100644 +--- a/src/messaging.c ++++ b/src/messaging.c +@@ -379,6 +379,7 @@ int __init ecryptfs_init_messaging(void) + * ecryptfs_message_buf_len), + GFP_KERNEL); + if (!ecryptfs_msg_ctx_arr) { ++ kfree(ecryptfs_daemon_hash); + rc = -ENOMEM; + goto out; + } +-- +2.31.1 + diff --git a/SOURCES/0010-ecryptfs-fix-kernel-panic-with-null-dev_name.patch b/SOURCES/0010-ecryptfs-fix-kernel-panic-with-null-dev_name.patch new file mode 100644 index 0000000..202bfe8 --- /dev/null +++ b/SOURCES/0010-ecryptfs-fix-kernel-panic-with-null-dev_name.patch @@ -0,0 +1,40 @@ +From 9046625511ad8dfbc8c6c2de16b3532c43d68d48 Mon Sep 17 00:00:00 2001 +From: Jeffrey Mitchell +Date: Fri, 26 Feb 2021 15:00:23 -0600 +Subject: [Backport 9046625511ad] ecryptfs: fix kernel panic with null dev_name + +When mounting eCryptfs, a null "dev_name" argument to ecryptfs_mount() +causes a kernel panic if the parsed options are valid. The easiest way to +reproduce this is to call mount() from userspace with an existing +eCryptfs mount's options and a "source" argument of 0. + +Error out if "dev_name" is null in ecryptfs_mount() + +Fixes: 237fead61998 ("[PATCH] ecryptfs: fs/Makefile and fs/Kconfig") +Cc: stable@vger.kernel.org +Signed-off-by: Jeffrey Mitchell +Signed-off-by: Tyler Hicks +--- + src/main.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/src/main.c b/src/main.c +index 77b96737b1ffbdeea6d22294530e85ce05464dde..d66bbd2df191e5cf69310243a711dd341e3822c7 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -492,6 +492,12 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags + goto out; + } + ++ if (!dev_name) { ++ rc = -EINVAL; ++ err = "Device name cannot be null"; ++ goto out; ++ } ++ + rc = ecryptfs_parse_options(sbi, raw_data, &check_ruid); + if (rc) { + err = "Error parsing options"; +-- +2.31.1 + diff --git a/SOURCES/0011-fs-ecryptfs-remove-BUG_ON-from-crypt_scatterlist.patch b/SOURCES/0011-fs-ecryptfs-remove-BUG_ON-from-crypt_scatterlist.patch new file mode 100644 index 0000000..8a3748a --- /dev/null +++ b/SOURCES/0011-fs-ecryptfs-remove-BUG_ON-from-crypt_scatterlist.patch @@ -0,0 +1,43 @@ +From c6052f09c14bf0ecdd582662e022eb716f9b8022 Mon Sep 17 00:00:00 2001 +From: Phillip Potter +Date: Mon, 3 May 2021 13:57:16 +0200 +Subject: [Backport c6052f09c14b] fs: ecryptfs: remove BUG_ON from + crypt_scatterlist + +crypt_stat memory itself is allocated when inode is created, in +ecryptfs_alloc_inode, which returns NULL on failure and is handled +by callers, which would prevent us getting to this point. It then +calls ecryptfs_init_crypt_stat which allocates crypt_stat->tfm +checking for and likewise handling allocation failure. Finally, +crypt_stat->flags has ECRYPTFS_STRUCT_INITIALIZED merged into it +in ecryptfs_init_crypt_stat as well. + +Simply put, the conditions that the BUG_ON checks for will never +be triggered, as to even get to this function, the relevant conditions +will have already been fulfilled (or the inode allocation would fail in +the first place and thus no call to this function or those above it). + +Cc: Tyler Hicks +Signed-off-by: Phillip Potter +Link: https://lore.kernel.org/r/20210503115736.2104747-50-gregkh@linuxfoundation.org +Signed-off-by: Greg Kroah-Hartman +--- + src/crypto.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/crypto.c b/src/crypto.c +index b1aa993784f777b53cd7d9c126f78e0f20bf5de7..e3f5d7f3c8a0ad12eb04be0c89b1b63910b31d6d 100644 +--- a/src/crypto.c ++++ b/src/crypto.c +@@ -296,8 +296,6 @@ static int crypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, + struct extent_crypt_result ecr; + int rc = 0; + +- BUG_ON(!crypt_stat || !crypt_stat->tfm +- || !(crypt_stat->flags & ECRYPTFS_STRUCT_INITIALIZED)); + if (unlikely(ecryptfs_verbosity > 0)) { + ecryptfs_printk(KERN_DEBUG, "Key size [%zd]; key:\n", + crypt_stat->key_size); +-- +2.31.1 + diff --git a/SOURCES/9999-enable-ecryptfs.patch b/SOURCES/9999-enable-ecryptfs.patch new file mode 100644 index 0000000..d0df537 --- /dev/null +++ b/SOURCES/9999-enable-ecryptfs.patch @@ -0,0 +1,5 @@ +--- a/src/Makefile ++++ b/src/Makefile +@@ -5 +5 @@ +-obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o ++obj-m += ecryptfs.o diff --git a/SPECS/kmod-ecryptfs.spec b/SPECS/kmod-ecryptfs.spec index 1cce812..1444b4b 100644 --- a/SPECS/kmod-ecryptfs.spec +++ b/SPECS/kmod-ecryptfs.spec @@ -1,5 +1,7 @@ %global pkg ecryptfs +%global driver_version 4.18.0-277.el8 + %global kernel_version 4.18.0-348.el8 %global _use_internal_dependency_generator 0 @@ -18,14 +20,26 @@ Name: kmod-%{pkg} -Version: 5.10 +Version: 4.18.0.277 Release: 1%{?dist} Summary: Encrypted filesystem that operates on the VFS layer License: GPLv2 URL: https://www.kernel.org/ -Source0: %{pkg}-%{version}.tar.xz +Source0: %{pkg}-%{driver_version}.tar.xz +Patch1: 0001-ecryptfs_rename-verify-that-lower-dentries-are-still.patch +Patch2: 0002-crypto-shash-remove-shash_desc-flags.patch +Patch3: 0003-eCryptfs-fix-a-couple-type-promotion-bugs.patch +Patch4: 0004-eCryptfs-fix-permission-denied-with-ecryptfs_xattr-m.patch +Patch5: 0005-ecryptfs-fix-unlink-and-rmdir-in-face-of-underlying-.patch +Patch6: 0006-ecryptfs_lookup_interpose-lower_dentry-d_inode-is-no.patch +Patch7: 0007-ecryptfs_lookup_interpose-lower_dentry-d_parent-is-n.patch +Patch8: 0008-ecryptfs-fix-a-memory-leak-bug-in-parse_tag_1_packet.patch +Patch9: 0009-ecryptfs-fix-a-memory-leak-bug-in-ecryptfs_init_mess.patch +Patch10: 0010-ecryptfs-fix-kernel-panic-with-null-dev_name.patch +Patch11: 0011-fs-ecryptfs-remove-BUG_ON-from-crypt_scatterlist.patch +Patch9999: 9999-enable-ecryptfs.patch ExclusiveArch: x86_64 aarch64 @@ -65,7 +79,7 @@ formatted with the Encrypted filesystem that operates on the VFS layer. %prep -%autosetup -p1 -n %{pkg}-%{version} +%autosetup -p1 -n %{pkg}-%{driver_version} %build @@ -127,5 +141,6 @@ fi %changelog -* Thu Jan 06 2022 Peter Georg - 5.10-1 -- Initial kABI tracking kmod package (kernel >= 4.18.0-348.el8) +* Wed Jan 12 2022 Kmods SIG - 4.18.0.277-1 +- Switch to EL kernel source and versioning +- kABI tracking kmod package (kernel >= 4.18.0-348.el8)