From: Greg Kroah-Hartman Date: Thu, 18 Jun 2020 16:45:55 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v4.4.228~45 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=af9eb2a74c50ef0007be01653727d2a283d70baf;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: evm-fix-possible-memory-leak-in-evm_calc_hmac_or_hash.patch ext4-fix-error-pointer-dereference.patch ext4-fix-ext_max_extent-index-to-check-for-zeroed-eh_max.patch ext4-fix-race-between-ext4_sync_parent-and-rename.patch ima-directly-assign-the-ima_default_policy-pointer-to-ima_rules.patch ima-fix-ima-digest-hash-table-key-calculation.patch --- diff --git a/queue-4.14/evm-fix-possible-memory-leak-in-evm_calc_hmac_or_hash.patch b/queue-4.14/evm-fix-possible-memory-leak-in-evm_calc_hmac_or_hash.patch new file mode 100644 index 00000000000..d9dc81ce05c --- /dev/null +++ b/queue-4.14/evm-fix-possible-memory-leak-in-evm_calc_hmac_or_hash.patch @@ -0,0 +1,34 @@ +From 0c4395fb2aa77341269ea619c5419ea48171883f Mon Sep 17 00:00:00 2001 +From: Roberto Sassu +Date: Tue, 14 Apr 2020 10:01:31 +0200 +Subject: evm: Fix possible memory leak in evm_calc_hmac_or_hash() + +From: Roberto Sassu + +commit 0c4395fb2aa77341269ea619c5419ea48171883f upstream. + +Don't immediately return if the signature is portable and security.ima is +not present. Just set error so that memory allocated is freed before +returning from evm_calc_hmac_or_hash(). + +Fixes: 50b977481fce9 ("EVM: Add support for portable signature format") +Signed-off-by: Roberto Sassu +Cc: stable@vger.kernel.org +Signed-off-by: Mimi Zohar +Signed-off-by: Greg Kroah-Hartman + +--- + security/integrity/evm/evm_crypto.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/security/integrity/evm/evm_crypto.c ++++ b/security/integrity/evm/evm_crypto.c +@@ -240,7 +240,7 @@ static int evm_calc_hmac_or_hash(struct + + /* Portable EVM signatures must include an IMA hash */ + if (type == EVM_XATTR_PORTABLE_DIGSIG && !ima_present) +- return -EPERM; ++ error = -EPERM; + out: + kfree(xattr_value); + kfree(desc); diff --git a/queue-4.14/ext4-fix-error-pointer-dereference.patch b/queue-4.14/ext4-fix-error-pointer-dereference.patch new file mode 100644 index 00000000000..255f894a91a --- /dev/null +++ b/queue-4.14/ext4-fix-error-pointer-dereference.patch @@ -0,0 +1,65 @@ +From 8418897f1bf87da0cb6936489d57a4320c32c0af Mon Sep 17 00:00:00 2001 +From: Jeffle Xu +Date: Thu, 23 Apr 2020 15:46:44 +0800 +Subject: ext4: fix error pointer dereference + +From: Jeffle Xu + +commit 8418897f1bf87da0cb6936489d57a4320c32c0af upstream. + +Don't pass error pointers to brelse(). + +commit 7159a986b420 ("ext4: fix some error pointer dereferences") has fixed +some cases, fix the remaining one case. + +Once ext4_xattr_block_find()->ext4_sb_bread() failed, error pointer is +stored in @bs->bh, which will be passed to brelse() in the cleanup +routine of ext4_xattr_set_handle(). This will then cause a NULL panic +crash in __brelse(). + +BUG: unable to handle kernel NULL pointer dereference at 000000000000005b +RIP: 0010:__brelse+0x1b/0x50 +Call Trace: + ext4_xattr_set_handle+0x163/0x5d0 + ext4_xattr_set+0x95/0x110 + __vfs_setxattr+0x6b/0x80 + __vfs_setxattr_noperm+0x68/0x1b0 + vfs_setxattr+0xa0/0xb0 + setxattr+0x12c/0x1a0 + path_setxattr+0x8d/0xc0 + __x64_sys_setxattr+0x27/0x30 + do_syscall_64+0x60/0x250 + entry_SYSCALL_64_after_hwframe+0x49/0xbe + +In this case, @bs->bh stores '-EIO' actually. + +Fixes: fb265c9cb49e ("ext4: add ext4_sb_bread() to disambiguate ENOMEM cases") +Signed-off-by: Jeffle Xu +Reviewed-by: Joseph Qi +Cc: stable@kernel.org # 2.6.19 +Reviewed-by: Ritesh Harjani +Reviewed-by: Jan Kara +Link: https://lore.kernel.org/r/1587628004-95123-1-git-send-email-jefflexu@linux.alibaba.com +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/xattr.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/fs/ext4/xattr.c ++++ b/fs/ext4/xattr.c +@@ -1823,8 +1823,11 @@ ext4_xattr_block_find(struct inode *inod + if (EXT4_I(inode)->i_file_acl) { + /* The inode already has an extended attribute block. */ + bs->bh = ext4_sb_bread(sb, EXT4_I(inode)->i_file_acl, REQ_PRIO); +- if (IS_ERR(bs->bh)) +- return PTR_ERR(bs->bh); ++ if (IS_ERR(bs->bh)) { ++ error = PTR_ERR(bs->bh); ++ bs->bh = NULL; ++ return error; ++ } + ea_bdebug(bs->bh, "b_count=%d, refcount=%d", + atomic_read(&(bs->bh->b_count)), + le32_to_cpu(BHDR(bs->bh)->h_refcount)); diff --git a/queue-4.14/ext4-fix-ext_max_extent-index-to-check-for-zeroed-eh_max.patch b/queue-4.14/ext4-fix-ext_max_extent-index-to-check-for-zeroed-eh_max.patch new file mode 100644 index 00000000000..d2c057f7524 --- /dev/null +++ b/queue-4.14/ext4-fix-ext_max_extent-index-to-check-for-zeroed-eh_max.patch @@ -0,0 +1,45 @@ +From c36a71b4e35ab35340facdd6964a00956b9fef0a Mon Sep 17 00:00:00 2001 +From: Harshad Shirwadkar +Date: Mon, 20 Apr 2020 19:39:59 -0700 +Subject: ext4: fix EXT_MAX_EXTENT/INDEX to check for zeroed eh_max + +From: Harshad Shirwadkar + +commit c36a71b4e35ab35340facdd6964a00956b9fef0a upstream. + +If eh->eh_max is 0, EXT_MAX_EXTENT/INDEX would evaluate to unsigned +(-1) resulting in illegal memory accesses. Although there is no +consistent repro, we see that generic/019 sometimes crashes because of +this bug. + +Ran gce-xfstests smoke and verified that there were no regressions. + +Signed-off-by: Harshad Shirwadkar +Link: https://lore.kernel.org/r/20200421023959.20879-2-harshadshirwadkar@gmail.com +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/ext4_extents.h | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/fs/ext4/ext4_extents.h ++++ b/fs/ext4/ext4_extents.h +@@ -169,10 +169,13 @@ struct ext4_ext_path { + (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1) + #define EXT_LAST_INDEX(__hdr__) \ + (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1) +-#define EXT_MAX_EXTENT(__hdr__) \ +- (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1) ++#define EXT_MAX_EXTENT(__hdr__) \ ++ ((le16_to_cpu((__hdr__)->eh_max)) ? \ ++ ((EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)) \ ++ : 0) + #define EXT_MAX_INDEX(__hdr__) \ +- (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1) ++ ((le16_to_cpu((__hdr__)->eh_max)) ? \ ++ ((EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1)) : 0) + + static inline struct ext4_extent_header *ext_inode_hdr(struct inode *inode) + { diff --git a/queue-4.14/ext4-fix-race-between-ext4_sync_parent-and-rename.patch b/queue-4.14/ext4-fix-race-between-ext4_sync_parent-and-rename.patch new file mode 100644 index 00000000000..eb3a741634c --- /dev/null +++ b/queue-4.14/ext4-fix-race-between-ext4_sync_parent-and-rename.patch @@ -0,0 +1,109 @@ +From 08adf452e628b0e2ce9a01048cfbec52353703d7 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Wed, 6 May 2020 11:31:40 -0700 +Subject: ext4: fix race between ext4_sync_parent() and rename() + +From: Eric Biggers + +commit 08adf452e628b0e2ce9a01048cfbec52353703d7 upstream. + +'igrab(d_inode(dentry->d_parent))' without holding dentry->d_lock is +broken because without d_lock, d_parent can be concurrently changed due +to a rename(). Then if the old directory is immediately deleted, old +d_parent->inode can be NULL. That causes a NULL dereference in igrab(). + +To fix this, use dget_parent() to safely grab a reference to the parent +dentry, which pins the inode. This also eliminates the need to use +d_find_any_alias() other than for the initial inode, as we no longer +throw away the dentry at each step. + +This is an extremely hard race to hit, but it is possible. Adding a +udelay() in between the reads of ->d_parent and its ->d_inode makes it +reproducible on a no-journal filesystem using the following program: + + #include + #include + + int main() + { + if (fork()) { + for (;;) { + mkdir("dir1", 0700); + int fd = open("dir1/file", O_RDWR|O_CREAT|O_SYNC); + write(fd, "X", 1); + close(fd); + } + } else { + mkdir("dir2", 0700); + for (;;) { + rename("dir1/file", "dir2/file"); + rmdir("dir1"); + } + } + } + +Fixes: d59729f4e794 ("ext4: fix races in ext4_sync_parent()") +Cc: stable@vger.kernel.org +Signed-off-by: Eric Biggers +Link: https://lore.kernel.org/r/20200506183140.541194-1-ebiggers@kernel.org +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ext4/fsync.c | 28 +++++++++++++--------------- + 1 file changed, 13 insertions(+), 15 deletions(-) + +--- a/fs/ext4/fsync.c ++++ b/fs/ext4/fsync.c +@@ -44,30 +44,28 @@ + */ + static int ext4_sync_parent(struct inode *inode) + { +- struct dentry *dentry = NULL; +- struct inode *next; ++ struct dentry *dentry, *next; + int ret = 0; + + if (!ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) + return 0; +- inode = igrab(inode); ++ dentry = d_find_any_alias(inode); ++ if (!dentry) ++ return 0; + while (ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) { + ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY); +- dentry = d_find_any_alias(inode); +- if (!dentry) +- break; +- next = igrab(d_inode(dentry->d_parent)); ++ ++ next = dget_parent(dentry); + dput(dentry); +- if (!next) +- break; +- iput(inode); +- inode = next; ++ dentry = next; ++ inode = dentry->d_inode; ++ + /* + * The directory inode may have gone through rmdir by now. But + * the inode itself and its blocks are still allocated (we hold +- * a reference to the inode so it didn't go through +- * ext4_evict_inode()) and so we are safe to flush metadata +- * blocks and the inode. ++ * a reference to the inode via its dentry), so it didn't go ++ * through ext4_evict_inode()) and so we are safe to flush ++ * metadata blocks and the inode. + */ + ret = sync_mapping_buffers(inode->i_mapping); + if (ret) +@@ -76,7 +74,7 @@ static int ext4_sync_parent(struct inode + if (ret) + break; + } +- iput(inode); ++ dput(dentry); + return ret; + } + diff --git a/queue-4.14/ima-directly-assign-the-ima_default_policy-pointer-to-ima_rules.patch b/queue-4.14/ima-directly-assign-the-ima_default_policy-pointer-to-ima_rules.patch new file mode 100644 index 00000000000..a844adad4af --- /dev/null +++ b/queue-4.14/ima-directly-assign-the-ima_default_policy-pointer-to-ima_rules.patch @@ -0,0 +1,62 @@ +From 067a436b1b0aafa593344fddd711a755a58afb3b Mon Sep 17 00:00:00 2001 +From: Roberto Sassu +Date: Wed, 3 Jun 2020 17:08:20 +0200 +Subject: ima: Directly assign the ima_default_policy pointer to ima_rules + +From: Roberto Sassu + +commit 067a436b1b0aafa593344fddd711a755a58afb3b upstream. + +This patch prevents the following oops: + +[ 10.771813] BUG: kernel NULL pointer dereference, address: 0000000000000 +[...] +[ 10.779790] RIP: 0010:ima_match_policy+0xf7/0xb80 +[...] +[ 10.798576] Call Trace: +[ 10.798993] ? ima_lsm_policy_change+0x2b0/0x2b0 +[ 10.799753] ? inode_init_owner+0x1a0/0x1a0 +[ 10.800484] ? _raw_spin_lock+0x7a/0xd0 +[ 10.801592] ima_must_appraise.part.0+0xb6/0xf0 +[ 10.802313] ? ima_fix_xattr.isra.0+0xd0/0xd0 +[ 10.803167] ima_must_appraise+0x4f/0x70 +[ 10.804004] ima_post_path_mknod+0x2e/0x80 +[ 10.804800] do_mknodat+0x396/0x3c0 + +It occurs when there is a failure during IMA initialization, and +ima_init_policy() is not called. IMA hooks still call ima_match_policy() +but ima_rules is NULL. This patch prevents the crash by directly assigning +the ima_default_policy pointer to ima_rules when ima_rules is defined. This +wouldn't alter the existing behavior, as ima_rules is always set at the end +of ima_init_policy(). + +Cc: stable@vger.kernel.org # 3.7.x +Fixes: 07f6a79415d7d ("ima: add appraise action keywords and default rules") +Reported-by: Takashi Iwai +Signed-off-by: Roberto Sassu +Signed-off-by: Mimi Zohar +Signed-off-by: Greg Kroah-Hartman + +--- + security/integrity/ima/ima_policy.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/security/integrity/ima/ima_policy.c ++++ b/security/integrity/ima/ima_policy.c +@@ -170,7 +170,7 @@ static struct ima_rule_entry secure_boot + static LIST_HEAD(ima_default_rules); + static LIST_HEAD(ima_policy_rules); + static LIST_HEAD(ima_temp_rules); +-static struct list_head *ima_rules; ++static struct list_head *ima_rules = &ima_default_rules; + + static int ima_policy __initdata; + +@@ -468,7 +468,6 @@ void __init ima_init_policy(void) + temp_ima_appraise |= IMA_APPRAISE_POLICY; + } + +- ima_rules = &ima_default_rules; + ima_update_policy_flag(); + } + diff --git a/queue-4.14/ima-fix-ima-digest-hash-table-key-calculation.patch b/queue-4.14/ima-fix-ima-digest-hash-table-key-calculation.patch new file mode 100644 index 00000000000..2022a235306 --- /dev/null +++ b/queue-4.14/ima-fix-ima-digest-hash-table-key-calculation.patch @@ -0,0 +1,54 @@ +From 1129d31b55d509f15e72dc68e4b5c3a4d7b4da8d Mon Sep 17 00:00:00 2001 +From: Krzysztof Struczynski +Date: Tue, 28 Apr 2020 09:30:10 +0200 +Subject: ima: Fix ima digest hash table key calculation + +From: Krzysztof Struczynski + +commit 1129d31b55d509f15e72dc68e4b5c3a4d7b4da8d upstream. + +Function hash_long() accepts unsigned long, while currently only one byte +is passed from ima_hash_key(), which calculates a key for ima_htable. + +Given that hashing the digest does not give clear benefits compared to +using the digest itself, remove hash_long() and return the modulus +calculated on the first two bytes of the digest with the number of slots. +Also reduce the depth of the hash table by doubling the number of slots. + +Cc: stable@vger.kernel.org +Fixes: 3323eec921ef ("integrity: IMA as an integrity service provider") +Co-developed-by: Roberto Sassu +Signed-off-by: Roberto Sassu +Signed-off-by: Krzysztof Struczynski +Acked-by: David.Laight@aculab.com (big endian system concerns) +Signed-off-by: Mimi Zohar +Signed-off-by: Greg Kroah-Hartman + +--- + security/integrity/ima/ima.h | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/security/integrity/ima/ima.h ++++ b/security/integrity/ima/ima.h +@@ -40,7 +40,7 @@ enum tpm_pcrs { TPM_PCR0 = 0, TPM_PCR8 = + #define IMA_DIGEST_SIZE SHA1_DIGEST_SIZE + #define IMA_EVENT_NAME_LEN_MAX 255 + +-#define IMA_HASH_BITS 9 ++#define IMA_HASH_BITS 10 + #define IMA_MEASURE_HTABLE_SIZE (1 << IMA_HASH_BITS) + + #define IMA_TEMPLATE_FIELD_ID_MAX_LEN 16 +@@ -167,9 +167,10 @@ struct ima_h_table { + }; + extern struct ima_h_table ima_htable; + +-static inline unsigned long ima_hash_key(u8 *digest) ++static inline unsigned int ima_hash_key(u8 *digest) + { +- return hash_long(*digest, IMA_HASH_BITS); ++ /* there is no point in taking a hash of part of a digest */ ++ return (digest[0] | digest[1] << 8) % IMA_MEASURE_HTABLE_SIZE; + } + + #define __ima_hooks(hook) \ diff --git a/queue-4.14/series b/queue-4.14/series index 998ca6bb25c..518fc01589f 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -139,3 +139,9 @@ platform-x86-hp-wmi-convert-simple_strtoul-to-kstrto.patch string.h-fix-incompatibility-between-fortify_source-.patch btrfs-send-emit-file-capabilities-after-chown.patch mm-thp-make-the-thp-mapcount-atomic-against-__split_huge_pmd_locked.patch +ima-fix-ima-digest-hash-table-key-calculation.patch +ima-directly-assign-the-ima_default_policy-pointer-to-ima_rules.patch +evm-fix-possible-memory-leak-in-evm_calc_hmac_or_hash.patch +ext4-fix-ext_max_extent-index-to-check-for-zeroed-eh_max.patch +ext4-fix-error-pointer-dereference.patch +ext4-fix-race-between-ext4_sync_parent-and-rename.patch