From 9d195efd1722d538411ac147eeb8ada84a11c5a7 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 7 Dec 2019 13:24:33 +0100 Subject: [PATCH] 4.14-stable patches added patches: fuse-verify-attributes.patch fuse-verify-nlink.patch sched-fair-scale-bandwidth-quota-and-period-without-losing-quota-period-ratio-precision.patch tcp-exit-if-nothing-to-retransmit-on-rto-timeout.patch --- queue-4.14/fuse-verify-attributes.patch | 121 +++++++++++++++ queue-4.14/fuse-verify-nlink.patch | 32 ++++ ...emory-corruption-in-case-more-than-3.patch | 140 ------------------ ...-losing-quota-period-ratio-precision.patch | 107 +++++++++++++ queue-4.14/series | 5 +- ...nothing-to-retransmit-on-rto-timeout.patch | 74 +++++++++ 6 files changed, 338 insertions(+), 141 deletions(-) create mode 100644 queue-4.14/fuse-verify-attributes.patch create mode 100644 queue-4.14/fuse-verify-nlink.patch delete mode 100644 queue-4.14/media-coda-fix-memory-corruption-in-case-more-than-3.patch create mode 100644 queue-4.14/sched-fair-scale-bandwidth-quota-and-period-without-losing-quota-period-ratio-precision.patch create mode 100644 queue-4.14/tcp-exit-if-nothing-to-retransmit-on-rto-timeout.patch diff --git a/queue-4.14/fuse-verify-attributes.patch b/queue-4.14/fuse-verify-attributes.patch new file mode 100644 index 00000000000..5129c014591 --- /dev/null +++ b/queue-4.14/fuse-verify-attributes.patch @@ -0,0 +1,121 @@ +From eb59bd17d2fa6e5e84fba61a5ebdea984222e6d5 Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Tue, 12 Nov 2019 11:49:04 +0100 +Subject: fuse: verify attributes + +From: Miklos Szeredi + +commit eb59bd17d2fa6e5e84fba61a5ebdea984222e6d5 upstream. + +If a filesystem returns negative inode sizes, future reads on the file were +causing the cpu to spin on truncate_pagecache. + +Create a helper to validate the attributes. This now does two things: + + - check the file mode + - check if the file size fits in i_size without overflowing + +Reported-by: Arijit Banerjee +Fixes: d8a5ba45457e ("[PATCH] FUSE - core") +Cc: # v2.6.14 +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/dir.c | 24 +++++++++++++++++------- + fs/fuse/fuse_i.h | 2 ++ + 2 files changed, 19 insertions(+), 7 deletions(-) + +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -234,7 +234,8 @@ static int fuse_dentry_revalidate(struct + kfree(forget); + if (ret == -ENOMEM) + goto out; +- if (ret || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) ++ if (ret || fuse_invalid_attr(&outarg.attr) || ++ (outarg.attr.mode ^ inode->i_mode) & S_IFMT) + goto invalid; + + forget_all_cached_acls(inode); +@@ -297,6 +298,12 @@ int fuse_valid_type(int m) + S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m); + } + ++bool fuse_invalid_attr(struct fuse_attr *attr) ++{ ++ return !fuse_valid_type(attr->mode) || ++ attr->size > LLONG_MAX; ++} ++ + int fuse_lookup_name(struct super_block *sb, u64 nodeid, const struct qstr *name, + struct fuse_entry_out *outarg, struct inode **inode) + { +@@ -328,7 +335,7 @@ int fuse_lookup_name(struct super_block + err = -EIO; + if (!outarg->nodeid) + goto out_put_forget; +- if (!fuse_valid_type(outarg->attr.mode)) ++ if (fuse_invalid_attr(&outarg->attr)) + goto out_put_forget; + + *inode = fuse_iget(sb, outarg->nodeid, outarg->generation, +@@ -451,7 +458,8 @@ static int fuse_create_open(struct inode + goto out_free_ff; + + err = -EIO; +- if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid)) ++ if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid) || ++ fuse_invalid_attr(&outentry.attr)) + goto out_free_ff; + + ff->fh = outopen.fh; +@@ -557,7 +565,7 @@ static int create_new_entry(struct fuse_ + goto out_put_forget_req; + + err = -EIO; +- if (invalid_nodeid(outarg.nodeid)) ++ if (invalid_nodeid(outarg.nodeid) || fuse_invalid_attr(&outarg.attr)) + goto out_put_forget_req; + + if ((outarg.attr.mode ^ mode) & S_IFMT) +@@ -911,7 +919,8 @@ static int fuse_do_getattr(struct inode + args.out.args[0].value = &outarg; + err = fuse_simple_request(fc, &args); + if (!err) { +- if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) { ++ if (fuse_invalid_attr(&outarg.attr) || ++ (inode->i_mode ^ outarg.attr.mode) & S_IFMT) { + make_bad_inode(inode); + err = -EIO; + } else { +@@ -1215,7 +1224,7 @@ static int fuse_direntplus_link(struct f + + if (invalid_nodeid(o->nodeid)) + return -EIO; +- if (!fuse_valid_type(o->attr.mode)) ++ if (fuse_invalid_attr(&o->attr)) + return -EIO; + + fc = get_fuse_conn(dir); +@@ -1692,7 +1701,8 @@ int fuse_do_setattr(struct dentry *dentr + goto error; + } + +- if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) { ++ if (fuse_invalid_attr(&outarg.attr) || ++ (inode->i_mode ^ outarg.attr.mode) & S_IFMT) { + make_bad_inode(inode); + err = -EIO; + goto error; +--- a/fs/fuse/fuse_i.h ++++ b/fs/fuse/fuse_i.h +@@ -896,6 +896,8 @@ void fuse_ctl_remove_conn(struct fuse_co + */ + int fuse_valid_type(int m); + ++bool fuse_invalid_attr(struct fuse_attr *attr); ++ + /** + * Is current process allowed to perform filesystem operation? + */ diff --git a/queue-4.14/fuse-verify-nlink.patch b/queue-4.14/fuse-verify-nlink.patch new file mode 100644 index 00000000000..eed1e48b48c --- /dev/null +++ b/queue-4.14/fuse-verify-nlink.patch @@ -0,0 +1,32 @@ +From c634da718db9b2fac201df2ae1b1b095344ce5eb Mon Sep 17 00:00:00 2001 +From: Miklos Szeredi +Date: Tue, 12 Nov 2019 11:49:04 +0100 +Subject: fuse: verify nlink + +From: Miklos Szeredi + +commit c634da718db9b2fac201df2ae1b1b095344ce5eb upstream. + +When adding a new hard link, make sure that i_nlink doesn't overflow. + +Fixes: ac45d61357e8 ("fuse: fix nlink after unlink") +Cc: # v3.4 +Signed-off-by: Miklos Szeredi +Signed-off-by: Greg Kroah-Hartman + +--- + fs/fuse/dir.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/fuse/dir.c ++++ b/fs/fuse/dir.c +@@ -830,7 +830,8 @@ static int fuse_link(struct dentry *entr + + spin_lock(&fc->lock); + fi->attr_version = ++fc->attr_version; +- inc_nlink(inode); ++ if (likely(inode->i_nlink < UINT_MAX)) ++ inc_nlink(inode); + spin_unlock(&fc->lock); + fuse_invalidate_attr(inode); + fuse_update_ctime(inode); diff --git a/queue-4.14/media-coda-fix-memory-corruption-in-case-more-than-3.patch b/queue-4.14/media-coda-fix-memory-corruption-in-case-more-than-3.patch deleted file mode 100644 index 3e6b2a858eb..00000000000 --- a/queue-4.14/media-coda-fix-memory-corruption-in-case-more-than-3.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 0139af208d3499abd38af388a359691015e605a3 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Tue, 6 Nov 2018 05:40:54 -0500 -Subject: media: coda: fix memory corruption in case more than 32 instances are - opened - -From: Philipp Zabel - -[ Upstream commit 649cfc2bdfeeb98ff7d8fdff0af3f8fb9c8da50f ] - -The ffz() return value is undefined if the instance mask does not -contain any zeros. If it returned 32, the following set_bit would -corrupt the debugfs_root pointer. -Switch to IDA for context index allocation. This also removes the -artificial 32 instance limit for all except CodaDx6. - -Signed-off-by: Philipp Zabel -Signed-off-by: Hans Verkuil -Signed-off-by: Mauro Carvalho Chehab -Signed-off-by: Sasha Levin ---- - drivers/media/platform/coda/coda-common.c | 26 +++++++++-------------- - drivers/media/platform/coda/coda.h | 3 ++- - 2 files changed, 12 insertions(+), 17 deletions(-) - -diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c -index 5b87c488ee111..ab5d00a4eb342 100644 ---- a/drivers/media/platform/coda/coda-common.c -+++ b/drivers/media/platform/coda/coda-common.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1931,17 +1932,6 @@ int coda_decoder_queue_init(void *priv, struct vb2_queue *src_vq, - return coda_queue_init(priv, dst_vq); - } - --static int coda_next_free_instance(struct coda_dev *dev) --{ -- int idx = ffz(dev->instance_mask); -- -- if ((idx < 0) || -- (dev->devtype->product == CODA_DX6 && idx > CODADX6_MAX_INSTANCES)) -- return -EBUSY; -- -- return idx; --} -- - /* - * File operations - */ -@@ -1950,7 +1940,8 @@ static int coda_open(struct file *file) - { - struct video_device *vdev = video_devdata(file); - struct coda_dev *dev = video_get_drvdata(vdev); -- struct coda_ctx *ctx = NULL; -+ struct coda_ctx *ctx; -+ unsigned int max = ~0; - char *name; - int ret; - int idx; -@@ -1959,12 +1950,13 @@ static int coda_open(struct file *file) - if (!ctx) - return -ENOMEM; - -- idx = coda_next_free_instance(dev); -+ if (dev->devtype->product == CODA_DX6) -+ max = CODADX6_MAX_INSTANCES - 1; -+ idx = ida_alloc_max(&dev->ida, max, GFP_KERNEL); - if (idx < 0) { - ret = idx; - goto err_coda_max; - } -- set_bit(idx, &dev->instance_mask); - - name = kasprintf(GFP_KERNEL, "context%d", idx); - if (!name) { -@@ -2072,8 +2064,8 @@ err_clk_per: - err_pm_get: - v4l2_fh_del(&ctx->fh); - v4l2_fh_exit(&ctx->fh); -- clear_bit(ctx->idx, &dev->instance_mask); - err_coda_name_init: -+ ida_free(&dev->ida, ctx->idx); - err_coda_max: - kfree(ctx); - return ret; -@@ -2115,7 +2107,7 @@ static int coda_release(struct file *file) - pm_runtime_put_sync(&dev->plat_dev->dev); - v4l2_fh_del(&ctx->fh); - v4l2_fh_exit(&ctx->fh); -- clear_bit(ctx->idx, &dev->instance_mask); -+ ida_free(&dev->ida, ctx->idx); - if (ctx->ops->release) - ctx->ops->release(ctx); - debugfs_remove_recursive(ctx->debugfs_entry); -@@ -2558,6 +2550,7 @@ static int coda_probe(struct platform_device *pdev) - - mutex_init(&dev->dev_mutex); - mutex_init(&dev->coda_mutex); -+ ida_init(&dev->ida); - - dev->debugfs_root = debugfs_create_dir("coda", NULL); - if (!dev->debugfs_root) -@@ -2645,6 +2638,7 @@ static int coda_remove(struct platform_device *pdev) - coda_free_aux_buf(dev, &dev->tempbuf); - coda_free_aux_buf(dev, &dev->workbuf); - debugfs_remove_recursive(dev->debugfs_root); -+ ida_destroy(&dev->ida); - return 0; - } - -diff --git a/drivers/media/platform/coda/coda.h b/drivers/media/platform/coda/coda.h -index 389a882cc3dab..2b187f83e5447 100644 ---- a/drivers/media/platform/coda/coda.h -+++ b/drivers/media/platform/coda/coda.h -@@ -16,6 +16,7 @@ - #define __CODA_H__ - - #include -+#include - #include - #include - #include -@@ -94,7 +95,7 @@ struct coda_dev { - struct workqueue_struct *workqueue; - struct v4l2_m2m_dev *m2m_dev; - struct list_head instances; -- unsigned long instance_mask; -+ struct ida ida; - struct dentry *debugfs_root; - }; - --- -2.20.1 - diff --git a/queue-4.14/sched-fair-scale-bandwidth-quota-and-period-without-losing-quota-period-ratio-precision.patch b/queue-4.14/sched-fair-scale-bandwidth-quota-and-period-without-losing-quota-period-ratio-precision.patch new file mode 100644 index 00000000000..3122d5d2311 --- /dev/null +++ b/queue-4.14/sched-fair-scale-bandwidth-quota-and-period-without-losing-quota-period-ratio-precision.patch @@ -0,0 +1,107 @@ +From 4929a4e6faa0f13289a67cae98139e727f0d4a97 Mon Sep 17 00:00:00 2001 +From: Xuewei Zhang +Date: Thu, 3 Oct 2019 17:12:43 -0700 +Subject: sched/fair: Scale bandwidth quota and period without losing quota/period ratio precision + +From: Xuewei Zhang + +commit 4929a4e6faa0f13289a67cae98139e727f0d4a97 upstream. + +The quota/period ratio is used to ensure a child task group won't get +more bandwidth than the parent task group, and is calculated as: + + normalized_cfs_quota() = [(quota_us << 20) / period_us] + +If the quota/period ratio was changed during this scaling due to +precision loss, it will cause inconsistency between parent and child +task groups. + +See below example: + +A userspace container manager (kubelet) does three operations: + + 1) Create a parent cgroup, set quota to 1,000us and period to 10,000us. + 2) Create a few children cgroups. + 3) Set quota to 1,000us and period to 10,000us on a child cgroup. + +These operations are expected to succeed. However, if the scaling of +147/128 happens before step 3, quota and period of the parent cgroup +will be changed: + + new_quota: 1148437ns, 1148us + new_period: 11484375ns, 11484us + +And when step 3 comes in, the ratio of the child cgroup will be +104857, which will be larger than the parent cgroup ratio (104821), +and will fail. + +Scaling them by a factor of 2 will fix the problem. + +Tested-by: Phil Auld +Signed-off-by: Xuewei Zhang +Signed-off-by: Peter Zijlstra (Intel) +Acked-by: Phil Auld +Cc: Anton Blanchard +Cc: Ben Segall +Cc: Dietmar Eggemann +Cc: Juri Lelli +Cc: Linus Torvalds +Cc: Mel Gorman +Cc: Peter Zijlstra +Cc: Steven Rostedt +Cc: Thomas Gleixner +Cc: Vincent Guittot +Fixes: 2e8e19226398 ("sched/fair: Limit sched_cfs_period_timer() loop to avoid hard lockup") +Link: https://lkml.kernel.org/r/20191004001243.140897-1-xueweiz@google.com +Signed-off-by: Ingo Molnar +Signed-off-by: Greg Kroah-Hartman + + +--- + kernel/sched/fair.c | 34 +++++++++++++++++++++------------- + 1 file changed, 21 insertions(+), 13 deletions(-) + +--- a/kernel/sched/fair.c ++++ b/kernel/sched/fair.c +@@ -4655,20 +4655,28 @@ static enum hrtimer_restart sched_cfs_pe + if (++count > 3) { + u64 new, old = ktime_to_ns(cfs_b->period); + +- new = (old * 147) / 128; /* ~115% */ +- new = min(new, max_cfs_quota_period); ++ /* ++ * Grow period by a factor of 2 to avoid losing precision. ++ * Precision loss in the quota/period ratio can cause __cfs_schedulable ++ * to fail. ++ */ ++ new = old * 2; ++ if (new < max_cfs_quota_period) { ++ cfs_b->period = ns_to_ktime(new); ++ cfs_b->quota *= 2; + +- cfs_b->period = ns_to_ktime(new); +- +- /* since max is 1s, this is limited to 1e9^2, which fits in u64 */ +- cfs_b->quota *= new; +- cfs_b->quota = div64_u64(cfs_b->quota, old); +- +- pr_warn_ratelimited( +- "cfs_period_timer[cpu%d]: period too short, scaling up (new cfs_period_us %lld, cfs_quota_us = %lld)\n", +- smp_processor_id(), +- div_u64(new, NSEC_PER_USEC), +- div_u64(cfs_b->quota, NSEC_PER_USEC)); ++ pr_warn_ratelimited( ++ "cfs_period_timer[cpu%d]: period too short, scaling up (new cfs_period_us = %lld, cfs_quota_us = %lld)\n", ++ smp_processor_id(), ++ div_u64(new, NSEC_PER_USEC), ++ div_u64(cfs_b->quota, NSEC_PER_USEC)); ++ } else { ++ pr_warn_ratelimited( ++ "cfs_period_timer[cpu%d]: period too short, but cannot scale up without losing precision (cfs_period_us = %lld, cfs_quota_us = %lld)\n", ++ smp_processor_id(), ++ div_u64(old, NSEC_PER_USEC), ++ div_u64(cfs_b->quota, NSEC_PER_USEC)); ++ } + + /* reset count so we don't come right back in here */ + count = 0; diff --git a/queue-4.14/series b/queue-4.14/series index 9b08654e6f9..f0b79ce6556 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -56,7 +56,6 @@ math-emu-soft-fp.h-_fp_round_zero-cast-0-to-void-to-.patch rtc-max8997-fix-the-returned-value-in-case-of-error-.patch rtc-dt-binding-abx80x-fix-resistance-scale.patch arm-dts-exynos-use-samsung-soc-specific-compatible-f.patch -media-coda-fix-memory-corruption-in-case-more-than-3.patch media-pulse8-cec-return-0-when-invalidating-the-logi.patch media-cec-report-vendor-id-after-initialization.patch dmaengine-coh901318-fix-a-double-lock-bug.patch @@ -121,3 +120,7 @@ usb-mtu3-fix-dbginfo-in-qmu_tx_zlp_error_handler.patch arm-dts-sunxi-fix-pmu-compatible-strings.patch media-vimc-fix-start-stream-when-link-is-disabled.patch net-aquantia-fix-rss-table-and-key-sizes.patch +tcp-exit-if-nothing-to-retransmit-on-rto-timeout.patch +sched-fair-scale-bandwidth-quota-and-period-without-losing-quota-period-ratio-precision.patch +fuse-verify-nlink.patch +fuse-verify-attributes.patch diff --git a/queue-4.14/tcp-exit-if-nothing-to-retransmit-on-rto-timeout.patch b/queue-4.14/tcp-exit-if-nothing-to-retransmit-on-rto-timeout.patch new file mode 100644 index 00000000000..50767aa8cc1 --- /dev/null +++ b/queue-4.14/tcp-exit-if-nothing-to-retransmit-on-rto-timeout.patch @@ -0,0 +1,74 @@ +From edumazet@google.com Sat Dec 7 12:55:03 2019 +From: Eric Dumazet +Date: Fri, 6 Dec 2019 10:20:16 -0800 +Subject: tcp: exit if nothing to retransmit on RTO timeout +To: Greg Kroah-Hartman +Cc: "David S . Miller" , netdev , Eric Dumazet , Eric Dumazet , Yuchung Cheng , Neal Cardwell , Soheil Hassas Yeganeh +Message-ID: <20191206182016.137529-1-edumazet@google.com> + +From: Eric Dumazet + +Two upstream commits squashed together for v4.14 stable : + + commit 88f8598d0a302a08380eadefd09b9f5cb1c4c428 upstream. + + Previously TCP only warns if its RTO timer fires and the + retransmission queue is empty, but it'll cause null pointer + reference later on. It's better to avoid such catastrophic failure + and simply exit with a warning. + +Squashed with "tcp: refactor tcp_retransmit_timer()" : + + commit 0d580fbd2db084a5c96ee9c00492236a279d5e0f upstream. + + It appears linux-4.14 stable needs a backport of commit + 88f8598d0a30 ("tcp: exit if nothing to retransmit on RTO timeout") + + Since tcp_rtx_queue_empty() is not in pre 4.15 kernels, + let's refactor tcp_retransmit_timer() to only use tcp_rtx_queue_head() + +Signed-off-by: Yuchung Cheng +Signed-off-by: Eric Dumazet +Reviewed-by: Neal Cardwell +Reviewed-by: Soheil Hassas Yeganeh +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_timer.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/net/ipv4/tcp_timer.c ++++ b/net/ipv4/tcp_timer.c +@@ -413,6 +413,7 @@ void tcp_retransmit_timer(struct sock *s + struct tcp_sock *tp = tcp_sk(sk); + struct net *net = sock_net(sk); + struct inet_connection_sock *icsk = inet_csk(sk); ++ struct sk_buff *skb; + + if (tp->fastopen_rsk) { + WARN_ON_ONCE(sk->sk_state != TCP_SYN_RECV && +@@ -423,10 +424,13 @@ void tcp_retransmit_timer(struct sock *s + */ + return; + } ++ + if (!tp->packets_out) +- goto out; ++ return; + +- WARN_ON(tcp_write_queue_empty(sk)); ++ skb = tcp_rtx_queue_head(sk); ++ if (WARN_ON_ONCE(!skb)) ++ return; + + tp->tlp_high_seq = 0; + +@@ -459,7 +463,7 @@ void tcp_retransmit_timer(struct sock *s + goto out; + } + tcp_enter_loss(sk); +- tcp_retransmit_skb(sk, tcp_write_queue_head(sk), 1); ++ tcp_retransmit_skb(sk, skb, 1); + __sk_dst_reset(sk); + goto out_reset_timer; + } -- 2.47.3