From: Greg Kroah-Hartman Date: Thu, 4 Mar 2021 14:34:04 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.4.260~51 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8120a62eeb4ebc5dd8ab93f4922d09674c329617;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: jfs-more-checks-for-invalid-superblock.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 --- diff --git a/queue-4.9/jfs-more-checks-for-invalid-superblock.patch b/queue-4.9/jfs-more-checks-for-invalid-superblock.patch new file mode 100644 index 00000000000..09a4a2be88a --- /dev/null +++ b/queue-4.9/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.9/net-fix-up-truesize-of-cloned-skb-in-skb_prepare_for_shift.patch b/queue-4.9/net-fix-up-truesize-of-cloned-skb-in-skb_prepare_for_shift.patch new file mode 100644 index 00000000000..c0cdde23ca1 --- /dev/null +++ b/queue-4.9/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 +@@ -2673,7 +2673,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.9/series b/queue-4.9/series index aefecce5f3d..0f76e8198ab 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -15,3 +15,7 @@ arm64-remove-redundant-mov-from-ll-sc-cmpxchg.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 +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 diff --git a/queue-4.9/smackfs-restrict-bytes-count-in-smackfs-write-functions.patch b/queue-4.9/smackfs-restrict-bytes-count-in-smackfs-write-functions.patch new file mode 100644 index 00000000000..8e55d2cd8b1 --- /dev/null +++ b/queue-4.9/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 +@@ -1186,7 +1186,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); +@@ -1446,7 +1446,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); +@@ -1853,6 +1853,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); +@@ -2024,6 +2028,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); +@@ -2111,6 +2118,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); +@@ -2664,6 +2674,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); +@@ -2756,10 +2770,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.9/xfs-fix-assert-failure-in-xfs_setattr_size.patch b/queue-4.9/xfs-fix-assert-failure-in-xfs_setattr_size.patch new file mode 100644 index 00000000000..da05fdc6fa7 --- /dev/null +++ b/queue-4.9/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 +@@ -820,7 +820,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;