From: Greg Kroah-Hartman Date: Thu, 18 Jun 2020 16:45:41 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.4.228~46 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2c0d821cfd17175223c012b178fccb52a1aa301f;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: 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-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.9/evm-fix-possible-memory-leak-in-evm_calc_hmac_or_hash.patch b/queue-4.9/evm-fix-possible-memory-leak-in-evm_calc_hmac_or_hash.patch new file mode 100644 index 00000000000..d9dc81ce05c --- /dev/null +++ b/queue-4.9/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.9/ext4-fix-ext_max_extent-index-to-check-for-zeroed-eh_max.patch b/queue-4.9/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.9/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.9/ext4-fix-race-between-ext4_sync_parent-and-rename.patch b/queue-4.9/ext4-fix-race-between-ext4_sync_parent-and-rename.patch new file mode 100644 index 00000000000..2605d4ffba0 --- /dev/null +++ b/queue-4.9/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 +@@ -43,30 +43,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) +@@ -75,7 +73,7 @@ static int ext4_sync_parent(struct inode + if (ret) + break; + } +- iput(inode); ++ dput(dentry); + return ret; + } + diff --git a/queue-4.9/ima-directly-assign-the-ima_default_policy-pointer-to-ima_rules.patch b/queue-4.9/ima-directly-assign-the-ima_default_policy-pointer-to-ima_rules.patch new file mode 100644 index 00000000000..368391840b1 --- /dev/null +++ b/queue-4.9/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 +@@ -150,7 +150,7 @@ static struct ima_rule_entry default_app + 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; + +@@ -429,7 +429,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.9/ima-fix-ima-digest-hash-table-key-calculation.patch b/queue-4.9/ima-fix-ima-digest-hash-table-key-calculation.patch new file mode 100644 index 00000000000..c4784fcf70b --- /dev/null +++ b/queue-4.9/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 +@@ -36,7 +36,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 +@@ -136,9 +136,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; + } + + enum ima_hooks { diff --git a/queue-4.9/series b/queue-4.9/series index 967f389ace1..b3188f09f4b 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -96,3 +96,8 @@ spi-dw-return-any-value-retrieved-from-the-dma_trans.patch cpuidle-fix-three-reference-count-leaks.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-race-between-ext4_sync_parent-and-rename.patch