From a42eee2fe5aa0e86e7d451ff74caf30bbac9357e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 4 Mar 2021 15:34:20 +0100 Subject: [PATCH] 4.14-stable patches added patches: jfs-more-checks-for-invalid-superblock.patch media-mceusb-sanity-check-for-prescaler-value.patch mm-hugetlb.c-fix-unnecessary-address-expansion-of-pmd-sharing.patch net-fix-up-truesize-of-cloned-skb-in-skb_prepare_for_shift.patch smackfs-restrict-bytes-count-in-smackfs-write-functions.patch xfs-fix-assert-failure-in-xfs_setattr_size.patch --- ...s-more-checks-for-invalid-superblock.patch | 82 +++++++++++++ ...usb-sanity-check-for-prescaler-value.patch | 42 +++++++ ...ary-address-expansion-of-pmd-sharing.patch | 83 ++++++++++++++ ...-cloned-skb-in-skb_prepare_for_shift.patch | 54 +++++++++ queue-4.14/series | 6 + ...tes-count-in-smackfs-write-functions.patch | 108 ++++++++++++++++++ ...x-assert-failure-in-xfs_setattr_size.patch | 35 ++++++ 7 files changed, 410 insertions(+) create mode 100644 queue-4.14/jfs-more-checks-for-invalid-superblock.patch create mode 100644 queue-4.14/media-mceusb-sanity-check-for-prescaler-value.patch create mode 100644 queue-4.14/mm-hugetlb.c-fix-unnecessary-address-expansion-of-pmd-sharing.patch create mode 100644 queue-4.14/net-fix-up-truesize-of-cloned-skb-in-skb_prepare_for_shift.patch create mode 100644 queue-4.14/smackfs-restrict-bytes-count-in-smackfs-write-functions.patch create mode 100644 queue-4.14/xfs-fix-assert-failure-in-xfs_setattr_size.patch diff --git a/queue-4.14/jfs-more-checks-for-invalid-superblock.patch b/queue-4.14/jfs-more-checks-for-invalid-superblock.patch new file mode 100644 index 00000000000..09a4a2be88a --- /dev/null +++ b/queue-4.14/jfs-more-checks-for-invalid-superblock.patch @@ -0,0 +1,82 @@ +From 3bef198f1b17d1bb89260bad947ef084c0a2d1a6 Mon Sep 17 00:00:00 2001 +From: Randy Dunlap +Date: Fri, 18 Dec 2020 12:17:16 -0800 +Subject: JFS: more checks for invalid superblock + +From: Randy Dunlap + +commit 3bef198f1b17d1bb89260bad947ef084c0a2d1a6 upstream. + +syzbot is feeding invalid superblock data to JFS for mount testing. +JFS does not check several of the fields -- just assumes that they +are good since the JFS_MAGIC and version fields are good. + +In this case (syzbot reproducer), we have s_l2bsize == 0xda0c, +pad == 0xf045, and s_state == 0x50, all of which are invalid IMO. +Having s_l2bsize == 0xda0c causes this UBSAN warning: + UBSAN: shift-out-of-bounds in fs/jfs/jfs_mount.c:373:25 + shift exponent -9716 is negative + +s_l2bsize can be tested for correctness. pad can be tested for non-0 +and punted. s_state can be tested for its valid values and punted. + +Do those 3 tests and if any of them fails, report the superblock as +invalid/corrupt and let fsck handle it. + +With this patch, chkSuper() says this when JFS_DEBUG is enabled: + jfs_mount: Mount Failure: superblock is corrupt! + Mount JFS Failure: -22 + jfs_mount failed w/return code = -22 + +The obvious problem with this method is that next week there could +be another syzbot test that uses different fields for invalid values, +this making this like a game of whack-a-mole. + +syzkaller link: https://syzkaller.appspot.com/bug?extid=36315852ece4132ec193 + +Reported-by: syzbot+36315852ece4132ec193@syzkaller.appspotmail.com +Reported-by: kernel test robot # v2 +Signed-off-by: Randy Dunlap +Signed-off-by: Dave Kleikamp +Cc: jfs-discussion@lists.sourceforge.net +Signed-off-by: Greg Kroah-Hartman +--- + fs/jfs/jfs_filsys.h | 1 + + fs/jfs/jfs_mount.c | 10 ++++++++++ + 2 files changed, 11 insertions(+) + +--- a/fs/jfs/jfs_filsys.h ++++ b/fs/jfs/jfs_filsys.h +@@ -281,5 +281,6 @@ + * fsck() must be run to repair + */ + #define FM_EXTENDFS 0x00000008 /* file system extendfs() in progress */ ++#define FM_STATE_MAX 0x0000000f /* max value of s_state */ + + #endif /* _H_JFS_FILSYS */ +--- a/fs/jfs/jfs_mount.c ++++ b/fs/jfs/jfs_mount.c +@@ -49,6 +49,7 @@ + + #include + #include ++#include + + #include "jfs_incore.h" + #include "jfs_filsys.h" +@@ -378,6 +379,15 @@ static int chkSuper(struct super_block * + sbi->bsize = bsize; + sbi->l2bsize = le16_to_cpu(j_sb->s_l2bsize); + ++ /* check some fields for possible corruption */ ++ if (sbi->l2bsize != ilog2((u32)bsize) || ++ j_sb->pad != 0 || ++ le32_to_cpu(j_sb->s_state) > FM_STATE_MAX) { ++ rc = -EINVAL; ++ jfs_err("jfs_mount: Mount Failure: superblock is corrupt!"); ++ goto out; ++ } ++ + /* + * For now, ignore s_pbsize, l2bfactor. All I/O going through buffer + * cache. diff --git a/queue-4.14/media-mceusb-sanity-check-for-prescaler-value.patch b/queue-4.14/media-mceusb-sanity-check-for-prescaler-value.patch new file mode 100644 index 00000000000..ed1c63a1d88 --- /dev/null +++ b/queue-4.14/media-mceusb-sanity-check-for-prescaler-value.patch @@ -0,0 +1,42 @@ +From 9dec0f48a75e0dadca498002d25ef4e143e60194 Mon Sep 17 00:00:00 2001 +From: Sean Young +Date: Tue, 19 Jan 2021 14:53:50 +0100 +Subject: media: mceusb: sanity check for prescaler value + +From: Sean Young + +commit 9dec0f48a75e0dadca498002d25ef4e143e60194 upstream. + +prescaler larger than 8 would mean the carrier is at most 152Hz, +which does not make sense for IR carriers. + +Reported-by: syzbot+6d31bf169a8265204b8d@syzkaller.appspotmail.com +Signed-off-by: Sean Young +Signed-off-by: Mauro Carvalho Chehab +Signed-off-by: Greg Kroah-Hartman +--- + drivers/media/rc/mceusb.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/media/rc/mceusb.c ++++ b/drivers/media/rc/mceusb.c +@@ -630,11 +630,18 @@ static void mceusb_dev_printdata(struct + data[0], data[1]); + break; + case MCE_RSP_EQIRCFS: ++ if (!data[0] && !data[1]) { ++ dev_dbg(dev, "%s: no carrier", inout); ++ break; ++ } ++ // prescaler should make sense ++ if (data[0] > 8) ++ break; + period = DIV_ROUND_CLOSEST((1U << data[0] * 2) * + (data[1] + 1), 10); + if (!period) + break; +- carrier = (1000 * 1000) / period; ++ carrier = USEC_PER_SEC / period; + dev_dbg(dev, "%s carrier of %u Hz (period %uus)", + inout, carrier, period); + break; diff --git a/queue-4.14/mm-hugetlb.c-fix-unnecessary-address-expansion-of-pmd-sharing.patch b/queue-4.14/mm-hugetlb.c-fix-unnecessary-address-expansion-of-pmd-sharing.patch new file mode 100644 index 00000000000..910f447b8ee --- /dev/null +++ b/queue-4.14/mm-hugetlb.c-fix-unnecessary-address-expansion-of-pmd-sharing.patch @@ -0,0 +1,83 @@ +From a1ba9da8f0f9a37d900ff7eff66482cf7de8015e Mon Sep 17 00:00:00 2001 +From: Li Xinhai +Date: Wed, 24 Feb 2021 12:06:54 -0800 +Subject: mm/hugetlb.c: fix unnecessary address expansion of pmd sharing + +From: Li Xinhai + +commit a1ba9da8f0f9a37d900ff7eff66482cf7de8015e upstream. + +The current code would unnecessarily expand the address range. Consider +one example, (start, end) = (1G-2M, 3G+2M), and (vm_start, vm_end) = +(1G-4M, 3G+4M), the expected adjustment should be keep (1G-2M, 3G+2M) +without expand. But the current result will be (1G-4M, 3G+4M). Actually, +the range (1G-4M, 1G) and (3G, 3G+4M) would never been involved in pmd +sharing. + +After this patch, we will check that the vma span at least one PUD aligned +size and the start,end range overlap the aligned range of vma. + +With above example, the aligned vma range is (1G, 3G), so if (start, end) +range is within (1G-4M, 1G), or within (3G, 3G+4M), then no adjustment to +both start and end. Otherwise, we will have chance to adjust start +downwards or end upwards without exceeding (vm_start, vm_end). + +Mike: + +: The 'adjusted range' is used for calls to mmu notifiers and cache(tlb) +: flushing. Since the current code unnecessarily expands the range in some +: cases, more entries than necessary would be flushed. This would/could +: result in performance degradation. However, this is highly dependent on +: the user runtime. Is there a combination of vma layout and calls to +: actually hit this issue? If the issue is hit, will those entries +: unnecessarily flushed be used again and need to be unnecessarily reloaded? + +Link: https://lkml.kernel.org/r/20210104081631.2921415-1-lixinhai.lxh@gmail.com +Fixes: 75802ca66354 ("mm/hugetlb: fix calculation of adjust_range_if_pmd_sharing_possible") +Signed-off-by: Li Xinhai +Suggested-by: Mike Kravetz +Reviewed-by: Mike Kravetz +Cc: Peter Xu +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman +--- + mm/hugetlb.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +--- a/mm/hugetlb.c ++++ b/mm/hugetlb.c +@@ -4631,21 +4631,23 @@ static bool vma_shareable(struct vm_area + void adjust_range_if_pmd_sharing_possible(struct vm_area_struct *vma, + unsigned long *start, unsigned long *end) + { +- unsigned long a_start, a_end; ++ unsigned long v_start = ALIGN(vma->vm_start, PUD_SIZE), ++ v_end = ALIGN_DOWN(vma->vm_end, PUD_SIZE); + +- if (!(vma->vm_flags & VM_MAYSHARE)) ++ /* ++ * vma need span at least one aligned PUD size and the start,end range ++ * must at least partialy within it. ++ */ ++ if (!(vma->vm_flags & VM_MAYSHARE) || !(v_end > v_start) || ++ (*end <= v_start) || (*start >= v_end)) + return; + + /* Extend the range to be PUD aligned for a worst case scenario */ +- a_start = ALIGN_DOWN(*start, PUD_SIZE); +- a_end = ALIGN(*end, PUD_SIZE); ++ if (*start > v_start) ++ *start = ALIGN_DOWN(*start, PUD_SIZE); + +- /* +- * Intersect the range with the vma range, since pmd sharing won't be +- * across vma after all +- */ +- *start = max(vma->vm_start, a_start); +- *end = min(vma->vm_end, a_end); ++ if (*end < v_end) ++ *end = ALIGN(*end, PUD_SIZE); + } + + /* diff --git a/queue-4.14/net-fix-up-truesize-of-cloned-skb-in-skb_prepare_for_shift.patch b/queue-4.14/net-fix-up-truesize-of-cloned-skb-in-skb_prepare_for_shift.patch new file mode 100644 index 00000000000..2601a8c503d --- /dev/null +++ b/queue-4.14/net-fix-up-truesize-of-cloned-skb-in-skb_prepare_for_shift.patch @@ -0,0 +1,54 @@ +From 097b9146c0e26aabaa6ff3e5ea536a53f5254a79 Mon Sep 17 00:00:00 2001 +From: Marco Elver +Date: Mon, 1 Feb 2021 17:04:20 +0100 +Subject: net: fix up truesize of cloned skb in skb_prepare_for_shift() + +From: Marco Elver + +commit 097b9146c0e26aabaa6ff3e5ea536a53f5254a79 upstream. + +Avoid the assumption that ksize(kmalloc(S)) == ksize(kmalloc(S)): when +cloning an skb, save and restore truesize after pskb_expand_head(). This +can occur if the allocator decides to service an allocation of the same +size differently (e.g. use a different size class, or pass the +allocation on to KFENCE). + +Because truesize is used for bookkeeping (such as sk_wmem_queued), a +modified truesize of a cloned skb may result in corrupt bookkeeping and +relevant warnings (such as in sk_stream_kill_queues()). + +Link: https://lkml.kernel.org/r/X9JR/J6dMMOy1obu@elver.google.com +Reported-by: syzbot+7b99aafdcc2eedea6178@syzkaller.appspotmail.com +Suggested-by: Eric Dumazet +Signed-off-by: Marco Elver +Signed-off-by: Eric Dumazet +Link: https://lore.kernel.org/r/20210201160420.2826895-1-elver@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/core/skbuff.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -3089,7 +3089,19 @@ EXPORT_SYMBOL(skb_split); + */ + static int skb_prepare_for_shift(struct sk_buff *skb) + { +- return skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC); ++ int ret = 0; ++ ++ if (skb_cloned(skb)) { ++ /* Save and restore truesize: pskb_expand_head() may reallocate ++ * memory where ksize(kmalloc(S)) != ksize(kmalloc(S)), but we ++ * cannot change truesize at this point. ++ */ ++ unsigned int save_truesize = skb->truesize; ++ ++ ret = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); ++ skb->truesize = save_truesize; ++ } ++ return ret; + } + + /** diff --git a/queue-4.14/series b/queue-4.14/series index 75eff1046b0..37c4428194c 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -8,3 +8,9 @@ arm64-module-set-plt-section-addresses-to-0x0.patch arm64-avoid-redundant-type-conversions-in-xchg-and-cmpxchg.patch arm64-cmpxchg-use-k-instead-of-l-for-ll-sc-immediate-constraint.patch arm64-use-correct-ll-sc-atomic-constraints.patch +jfs-more-checks-for-invalid-superblock.patch +media-mceusb-sanity-check-for-prescaler-value.patch +xfs-fix-assert-failure-in-xfs_setattr_size.patch +smackfs-restrict-bytes-count-in-smackfs-write-functions.patch +net-fix-up-truesize-of-cloned-skb-in-skb_prepare_for_shift.patch +mm-hugetlb.c-fix-unnecessary-address-expansion-of-pmd-sharing.patch diff --git a/queue-4.14/smackfs-restrict-bytes-count-in-smackfs-write-functions.patch b/queue-4.14/smackfs-restrict-bytes-count-in-smackfs-write-functions.patch new file mode 100644 index 00000000000..e0a29d64417 --- /dev/null +++ b/queue-4.14/smackfs-restrict-bytes-count-in-smackfs-write-functions.patch @@ -0,0 +1,108 @@ +From 7ef4c19d245f3dc233fd4be5acea436edd1d83d8 Mon Sep 17 00:00:00 2001 +From: Sabyrzhan Tasbolatov +Date: Thu, 28 Jan 2021 17:58:01 +0600 +Subject: smackfs: restrict bytes count in smackfs write functions + +From: Sabyrzhan Tasbolatov + +commit 7ef4c19d245f3dc233fd4be5acea436edd1d83d8 upstream. + +syzbot found WARNINGs in several smackfs write operations where +bytes count is passed to memdup_user_nul which exceeds +GFP MAX_ORDER. Check count size if bigger than PAGE_SIZE. + +Per smackfs doc, smk_write_net4addr accepts any label or -CIPSO, +smk_write_net6addr accepts any label or -DELETE. I couldn't find +any general rule for other label lengths except SMK_LABELLEN, +SMK_LONGLABEL, SMK_CIPSOMAX which are documented. + +Let's constrain, in general, smackfs label lengths for PAGE_SIZE. +Although fuzzer crashes write to smackfs/netlabel on 0x400000 length. + +Here is a quick way to reproduce the WARNING: +python -c "print('A' * 0x400000)" > /sys/fs/smackfs/netlabel + +Reported-by: syzbot+a71a442385a0b2815497@syzkaller.appspotmail.com +Signed-off-by: Sabyrzhan Tasbolatov +Signed-off-by: Casey Schaufler +Signed-off-by: Greg Kroah-Hartman +--- + security/smack/smackfs.c | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +--- a/security/smack/smackfs.c ++++ b/security/smack/smackfs.c +@@ -1191,7 +1191,7 @@ static ssize_t smk_write_net4addr(struct + return -EPERM; + if (*ppos != 0) + return -EINVAL; +- if (count < SMK_NETLBLADDRMIN) ++ if (count < SMK_NETLBLADDRMIN || count > PAGE_SIZE - 1) + return -EINVAL; + + data = memdup_user_nul(buf, count); +@@ -1451,7 +1451,7 @@ static ssize_t smk_write_net6addr(struct + return -EPERM; + if (*ppos != 0) + return -EINVAL; +- if (count < SMK_NETLBLADDRMIN) ++ if (count < SMK_NETLBLADDRMIN || count > PAGE_SIZE - 1) + return -EINVAL; + + data = memdup_user_nul(buf, count); +@@ -1858,6 +1858,10 @@ static ssize_t smk_write_ambient(struct + if (!smack_privileged(CAP_MAC_ADMIN)) + return -EPERM; + ++ /* Enough data must be present */ ++ if (count == 0 || count > PAGE_SIZE) ++ return -EINVAL; ++ + data = memdup_user_nul(buf, count); + if (IS_ERR(data)) + return PTR_ERR(data); +@@ -2029,6 +2033,9 @@ static ssize_t smk_write_onlycap(struct + if (!smack_privileged(CAP_MAC_ADMIN)) + return -EPERM; + ++ if (count > PAGE_SIZE) ++ return -EINVAL; ++ + data = memdup_user_nul(buf, count); + if (IS_ERR(data)) + return PTR_ERR(data); +@@ -2116,6 +2123,9 @@ static ssize_t smk_write_unconfined(stru + if (!smack_privileged(CAP_MAC_ADMIN)) + return -EPERM; + ++ if (count > PAGE_SIZE) ++ return -EINVAL; ++ + data = memdup_user_nul(buf, count); + if (IS_ERR(data)) + return PTR_ERR(data); +@@ -2669,6 +2679,10 @@ static ssize_t smk_write_syslog(struct f + if (!smack_privileged(CAP_MAC_ADMIN)) + return -EPERM; + ++ /* Enough data must be present */ ++ if (count == 0 || count > PAGE_SIZE) ++ return -EINVAL; ++ + data = memdup_user_nul(buf, count); + if (IS_ERR(data)) + return PTR_ERR(data); +@@ -2761,10 +2775,13 @@ static ssize_t smk_write_relabel_self(st + return -EPERM; + + /* ++ * No partial write. + * Enough data must be present. + */ + if (*ppos != 0) + return -EINVAL; ++ if (count == 0 || count > PAGE_SIZE) ++ return -EINVAL; + + data = memdup_user_nul(buf, count); + if (IS_ERR(data)) diff --git a/queue-4.14/xfs-fix-assert-failure-in-xfs_setattr_size.patch b/queue-4.14/xfs-fix-assert-failure-in-xfs_setattr_size.patch new file mode 100644 index 00000000000..0f70a75c41a --- /dev/null +++ b/queue-4.14/xfs-fix-assert-failure-in-xfs_setattr_size.patch @@ -0,0 +1,35 @@ +From 88a9e03beef22cc5fabea344f54b9a0dfe63de08 Mon Sep 17 00:00:00 2001 +From: Yumei Huang +Date: Fri, 22 Jan 2021 16:48:19 -0800 +Subject: xfs: Fix assert failure in xfs_setattr_size() + +From: Yumei Huang + +commit 88a9e03beef22cc5fabea344f54b9a0dfe63de08 upstream. + +An assert failure is triggered by syzkaller test due to +ATTR_KILL_PRIV is not cleared before xfs_setattr_size. +As ATTR_KILL_PRIV is not checked/used by xfs_setattr_size, +just remove it from the assert. + +Signed-off-by: Yumei Huang +Reviewed-by: Brian Foster +Reviewed-by: Christoph Hellwig +Reviewed-by: Darrick J. Wong +Signed-off-by: Darrick J. Wong +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_iops.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/xfs/xfs_iops.c ++++ b/fs/xfs/xfs_iops.c +@@ -835,7 +835,7 @@ xfs_setattr_size( + ASSERT(xfs_isilocked(ip, XFS_MMAPLOCK_EXCL)); + ASSERT(S_ISREG(inode->i_mode)); + ASSERT((iattr->ia_valid & (ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_ATIME_SET| +- ATTR_MTIME_SET|ATTR_KILL_PRIV|ATTR_TIMES_SET)) == 0); ++ ATTR_MTIME_SET|ATTR_TIMES_SET)) == 0); + + oldsize = inode->i_size; + newsize = iattr->ia_size; -- 2.47.3