From: Greg Kroah-Hartman Date: Sat, 15 Jun 2019 16:11:46 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v5.1.11~39 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=80ae7e1e91b0fb3fb3cafd3d4881baa923bb4d84;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: asoc-cs42xx8-add-regcache-mask-dirty.patch asoc-fsl_asrc-fix-the-issue-about-unsupported-rate.patch bcache-fix-stack-corruption-by-preceding_key.patch cgroup-use-css_tryget-instead-of-css_tryget_online-in-task_get_css.patch drm-i915-sdvo-implement-proper-hdmi-audio-support-for-sdvo.patch fs-ocfs2-fix-race-in-ocfs2_dentry_attach_lock.patch i2c-acorn-fix-i2c-warning.patch iommu-arm-smmu-avoid-constant-zero-in-tlbi-writes.patch media-v4l2-ioctl-clear-fields-in-s_parm.patch mm-list_lru.c-fix-memory-leak-in-__memcg_init_list_lru_node.patch mm-vmscan.c-fix-trying-to-reclaim-unevictable-lru-page.patch ptrace-restore-smp_rmb-in-__ptrace_may_access.patch signal-ptrace-don-t-leak-unitialized-kernel-memory-with-ptrace_peek_siginfo.patch --- diff --git a/queue-4.14/asoc-cs42xx8-add-regcache-mask-dirty.patch b/queue-4.14/asoc-cs42xx8-add-regcache-mask-dirty.patch new file mode 100644 index 00000000000..8c4606a7537 --- /dev/null +++ b/queue-4.14/asoc-cs42xx8-add-regcache-mask-dirty.patch @@ -0,0 +1,34 @@ +From ad6eecbfc01c987e0253371f274c3872042e4350 Mon Sep 17 00:00:00 2001 +From: "S.j. Wang" +Date: Thu, 16 May 2019 06:04:29 +0000 +Subject: ASoC: cs42xx8: Add regcache mask dirty + +From: S.j. Wang + +commit ad6eecbfc01c987e0253371f274c3872042e4350 upstream. + +Add regcache_mark_dirty before regcache_sync for power +of codec may be lost at suspend, then all the register +need to be reconfigured. + +Fixes: 0c516b4ff85c ("ASoC: cs42xx8: Add codec driver +support for CS42448/CS42888") +Cc: +Signed-off-by: Shengjiu Wang +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/codecs/cs42xx8.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/soc/codecs/cs42xx8.c ++++ b/sound/soc/codecs/cs42xx8.c +@@ -559,6 +559,7 @@ static int cs42xx8_runtime_resume(struct + msleep(5); + + regcache_cache_only(cs42xx8->regmap, false); ++ regcache_mark_dirty(cs42xx8->regmap); + + ret = regcache_sync(cs42xx8->regmap); + if (ret) { diff --git a/queue-4.14/asoc-fsl_asrc-fix-the-issue-about-unsupported-rate.patch b/queue-4.14/asoc-fsl_asrc-fix-the-issue-about-unsupported-rate.patch new file mode 100644 index 00000000000..9f75b038266 --- /dev/null +++ b/queue-4.14/asoc-fsl_asrc-fix-the-issue-about-unsupported-rate.patch @@ -0,0 +1,40 @@ +From b06c58c2a1eed571ea2a6640fdb85b7b00196b1e Mon Sep 17 00:00:00 2001 +From: "S.j. Wang" +Date: Wed, 15 May 2019 06:42:18 +0000 +Subject: ASoC: fsl_asrc: Fix the issue about unsupported rate + +From: S.j. Wang + +commit b06c58c2a1eed571ea2a6640fdb85b7b00196b1e upstream. + +When the output sample rate is [8kHz, 30kHz], the limitation +of the supported ratio range is [1/24, 8]. In the driver +we use (8kHz, 30kHz) instead of [8kHz, 30kHz]. +So this patch is to fix this issue and the potential rounding +issue with divider. + +Fixes: fff6e03c7b65 ("ASoC: fsl_asrc: add support for 8-30kHz +output sample rate") +Cc: +Signed-off-by: Shengjiu Wang +Acked-by: Nicolin Chen +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman + +--- + sound/soc/fsl/fsl_asrc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/sound/soc/fsl/fsl_asrc.c ++++ b/sound/soc/fsl/fsl_asrc.c +@@ -286,8 +286,8 @@ static int fsl_asrc_config_pair(struct f + return -EINVAL; + } + +- if ((outrate > 8000 && outrate < 30000) && +- (outrate/inrate > 24 || inrate/outrate > 8)) { ++ if ((outrate >= 8000 && outrate <= 30000) && ++ (outrate > 24 * inrate || inrate > 8 * outrate)) { + pair_err("exceed supported ratio range [1/24, 8] for \ + inrate/outrate: %d/%d\n", inrate, outrate); + return -EINVAL; diff --git a/queue-4.14/bcache-fix-stack-corruption-by-preceding_key.patch b/queue-4.14/bcache-fix-stack-corruption-by-preceding_key.patch new file mode 100644 index 00000000000..564c4ac8274 --- /dev/null +++ b/queue-4.14/bcache-fix-stack-corruption-by-preceding_key.patch @@ -0,0 +1,127 @@ +From 31b90956b124240aa8c63250243ae1a53585c5e2 Mon Sep 17 00:00:00 2001 +From: Coly Li +Date: Mon, 10 Jun 2019 06:13:34 +0800 +Subject: bcache: fix stack corruption by PRECEDING_KEY() + +From: Coly Li + +commit 31b90956b124240aa8c63250243ae1a53585c5e2 upstream. + +Recently people report bcache code compiled with gcc9 is broken, one of +the buggy behavior I observe is that two adjacent 4KB I/Os should merge +into one but they don't. Finally it turns out to be a stack corruption +caused by macro PRECEDING_KEY(). + +See how PRECEDING_KEY() is defined in bset.h, +437 #define PRECEDING_KEY(_k) \ +438 ({ \ +439 struct bkey *_ret = NULL; \ +440 \ +441 if (KEY_INODE(_k) || KEY_OFFSET(_k)) { \ +442 _ret = &KEY(KEY_INODE(_k), KEY_OFFSET(_k), 0); \ +443 \ +444 if (!_ret->low) \ +445 _ret->high--; \ +446 _ret->low--; \ +447 } \ +448 \ +449 _ret; \ +450 }) + +At line 442, _ret points to address of a on-stack variable combined by +KEY(), the life range of this on-stack variable is in line 442-446, +once _ret is returned to bch_btree_insert_key(), the returned address +points to an invalid stack address and this address is overwritten in +the following called bch_btree_iter_init(). Then argument 'search' of +bch_btree_iter_init() points to some address inside stackframe of +bch_btree_iter_init(), exact address depends on how the compiler +allocates stack space. Now the stack is corrupted. + +Fixes: 0eacac22034c ("bcache: PRECEDING_KEY()") +Signed-off-by: Coly Li +Reviewed-by: Rolf Fokkens +Reviewed-by: Pierre JUHEN +Tested-by: Shenghui Wang +Tested-by: Pierre JUHEN +Cc: Kent Overstreet +Cc: Nix +Cc: stable@vger.kernel.org +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/md/bcache/bset.c | 16 +++++++++++++--- + drivers/md/bcache/bset.h | 34 ++++++++++++++++++++-------------- + 2 files changed, 33 insertions(+), 17 deletions(-) + +--- a/drivers/md/bcache/bset.c ++++ b/drivers/md/bcache/bset.c +@@ -825,12 +825,22 @@ unsigned bch_btree_insert_key(struct btr + struct bset *i = bset_tree_last(b)->data; + struct bkey *m, *prev = NULL; + struct btree_iter iter; ++ struct bkey preceding_key_on_stack = ZERO_KEY; ++ struct bkey *preceding_key_p = &preceding_key_on_stack; + + BUG_ON(b->ops->is_extents && !KEY_SIZE(k)); + +- m = bch_btree_iter_init(b, &iter, b->ops->is_extents +- ? PRECEDING_KEY(&START_KEY(k)) +- : PRECEDING_KEY(k)); ++ /* ++ * If k has preceding key, preceding_key_p will be set to address ++ * of k's preceding key; otherwise preceding_key_p will be set ++ * to NULL inside preceding_key(). ++ */ ++ if (b->ops->is_extents) ++ preceding_key(&START_KEY(k), &preceding_key_p); ++ else ++ preceding_key(k, &preceding_key_p); ++ ++ m = bch_btree_iter_init(b, &iter, preceding_key_p); + + if (b->ops->insert_fixup(b, k, &iter, replace_key)) + return status; +--- a/drivers/md/bcache/bset.h ++++ b/drivers/md/bcache/bset.h +@@ -418,20 +418,26 @@ static inline bool bch_cut_back(const st + return __bch_cut_back(where, k); + } + +-#define PRECEDING_KEY(_k) \ +-({ \ +- struct bkey *_ret = NULL; \ +- \ +- if (KEY_INODE(_k) || KEY_OFFSET(_k)) { \ +- _ret = &KEY(KEY_INODE(_k), KEY_OFFSET(_k), 0); \ +- \ +- if (!_ret->low) \ +- _ret->high--; \ +- _ret->low--; \ +- } \ +- \ +- _ret; \ +-}) ++/* ++ * Pointer '*preceding_key_p' points to a memory object to store preceding ++ * key of k. If the preceding key does not exist, set '*preceding_key_p' to ++ * NULL. So the caller of preceding_key() needs to take care of memory ++ * which '*preceding_key_p' pointed to before calling preceding_key(). ++ * Currently the only caller of preceding_key() is bch_btree_insert_key(), ++ * and it points to an on-stack variable, so the memory release is handled ++ * by stackframe itself. ++ */ ++static inline void preceding_key(struct bkey *k, struct bkey **preceding_key_p) ++{ ++ if (KEY_INODE(k) || KEY_OFFSET(k)) { ++ (**preceding_key_p) = KEY(KEY_INODE(k), KEY_OFFSET(k), 0); ++ if (!(*preceding_key_p)->low) ++ (*preceding_key_p)->high--; ++ (*preceding_key_p)->low--; ++ } else { ++ (*preceding_key_p) = NULL; ++ } ++} + + static inline bool bch_ptr_invalid(struct btree_keys *b, const struct bkey *k) + { diff --git a/queue-4.14/cgroup-use-css_tryget-instead-of-css_tryget_online-in-task_get_css.patch b/queue-4.14/cgroup-use-css_tryget-instead-of-css_tryget_online-in-task_get_css.patch new file mode 100644 index 00000000000..2243a5c5bfa --- /dev/null +++ b/queue-4.14/cgroup-use-css_tryget-instead-of-css_tryget_online-in-task_get_css.patch @@ -0,0 +1,88 @@ +From 18fa84a2db0e15b02baa5d94bdb5bd509175d2f6 Mon Sep 17 00:00:00 2001 +From: Tejun Heo +Date: Wed, 29 May 2019 13:46:25 -0700 +Subject: cgroup: Use css_tryget() instead of css_tryget_online() in task_get_css() + +From: Tejun Heo + +commit 18fa84a2db0e15b02baa5d94bdb5bd509175d2f6 upstream. + +A PF_EXITING task can stay associated with an offline css. If such +task calls task_get_css(), it can get stuck indefinitely. This can be +triggered by BSD process accounting which writes to a file with +PF_EXITING set when racing against memcg disable as in the backtrace +at the end. + +After this change, task_get_css() may return a css which was already +offline when the function was called. None of the existing users are +affected by this change. + + INFO: rcu_sched self-detected stall on CPU + INFO: rcu_sched detected stalls on CPUs/tasks: + ... + NMI backtrace for cpu 0 + ... + Call Trace: + + dump_stack+0x46/0x68 + nmi_cpu_backtrace.cold.2+0x13/0x57 + nmi_trigger_cpumask_backtrace+0xba/0xca + rcu_dump_cpu_stacks+0x9e/0xce + rcu_check_callbacks.cold.74+0x2af/0x433 + update_process_times+0x28/0x60 + tick_sched_timer+0x34/0x70 + __hrtimer_run_queues+0xee/0x250 + hrtimer_interrupt+0xf4/0x210 + smp_apic_timer_interrupt+0x56/0x110 + apic_timer_interrupt+0xf/0x20 + + RIP: 0010:balance_dirty_pages_ratelimited+0x28f/0x3d0 + ... + btrfs_file_write_iter+0x31b/0x563 + __vfs_write+0xfa/0x140 + __kernel_write+0x4f/0x100 + do_acct_process+0x495/0x580 + acct_process+0xb9/0xdb + do_exit+0x748/0xa00 + do_group_exit+0x3a/0xa0 + get_signal+0x254/0x560 + do_signal+0x23/0x5c0 + exit_to_usermode_loop+0x5d/0xa0 + prepare_exit_to_usermode+0x53/0x80 + retint_user+0x8/0x8 + +Signed-off-by: Tejun Heo +Cc: stable@vger.kernel.org # v4.2+ +Fixes: ec438699a9ae ("cgroup, block: implement task_get_css() and use it in bio_associate_current()") +Signed-off-by: Greg Kroah-Hartman + +--- + include/linux/cgroup.h | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/include/linux/cgroup.h ++++ b/include/linux/cgroup.h +@@ -484,7 +484,7 @@ static inline struct cgroup_subsys_state + * + * Find the css for the (@task, @subsys_id) combination, increment a + * reference on and return it. This function is guaranteed to return a +- * valid css. ++ * valid css. The returned css may already have been offlined. + */ + static inline struct cgroup_subsys_state * + task_get_css(struct task_struct *task, int subsys_id) +@@ -494,7 +494,13 @@ task_get_css(struct task_struct *task, i + rcu_read_lock(); + while (true) { + css = task_css(task, subsys_id); +- if (likely(css_tryget_online(css))) ++ /* ++ * Can't use css_tryget_online() here. A task which has ++ * PF_EXITING set may stay associated with an offline css. ++ * If such task calls this function, css_tryget_online() ++ * will keep failing. ++ */ ++ if (likely(css_tryget(css))) + break; + cpu_relax(); + } diff --git a/queue-4.14/drm-i915-sdvo-implement-proper-hdmi-audio-support-for-sdvo.patch b/queue-4.14/drm-i915-sdvo-implement-proper-hdmi-audio-support-for-sdvo.patch new file mode 100644 index 00000000000..ec847fcb680 --- /dev/null +++ b/queue-4.14/drm-i915-sdvo-implement-proper-hdmi-audio-support-for-sdvo.patch @@ -0,0 +1,187 @@ +From d74408f528261f900dddb9778f61b5c5a7a6249c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= +Date: Tue, 9 Apr 2019 17:40:49 +0300 +Subject: drm/i915/sdvo: Implement proper HDMI audio support for SDVO +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ville Syrjälä + +commit d74408f528261f900dddb9778f61b5c5a7a6249c upstream. + +Our SDVO audio support is pretty bogus. We can't push audio over the +SDVO bus, so trying to enable audio in the SDVO control register doesn't +do anything. In fact it looks like the SDVO encoder will always mix in +the audio coming over HDA, and there's no (at least documented) way to +disable that from our side. So HDMI audio does work currently on gen4 +but only by luck really. On gen3 it got broken by the referenced commit. +And what has always been missing on every platform is the ELD. + +To pass the ELD to the audio driver we need to write it to magic buffer +in the SDVO encoder hardware which then gets pulled out via HDA in the +other end. Ie. pretty much the same thing we had for native HDMI before +we started to just pass the ELD between the drivers. This sort of +explains why we even have that silly hardware buffer with native HDMI. + +$ cat /proc/asound/card0/eld#1.0 +-monitor_present 0 +-eld_valid 0 ++monitor_present 1 ++eld_valid 1 ++monitor_name LG TV ++connection_type HDMI ++... + +This also fixes our state readout since we can now query the SDVO +encoder about the state of the "ELD valid" and "presence detect" +bits. As mentioned those don't actually control whether audio +gets sent over the HDMI cable, but it's the best we can do. And with +the state checker appeased we can re-enable HDMI audio for gen3. + +Cc: stable@vger.kernel.org +Cc: Daniel Vetter +Cc: zardam@gmail.com +Tested-by: zardam@gmail.com +Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108976 +Fixes: de44e256b92c ("drm/i915/sdvo: Shut up state checker with hdmi cards on gen3") +Signed-off-by: Ville Syrjälä +Link: https://patchwork.freedesktop.org/patch/msgid/20190409144054.24561-3-ville.syrjala@linux.intel.com +Reviewed-by: Imre Deak +(cherry picked from commit dc49a56bd43bb04982e64b44436831da801d0237) +Signed-off-by: Jani Nikula +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/gpu/drm/i915/intel_sdvo.c | 58 ++++++++++++++++++++++++++------- + drivers/gpu/drm/i915/intel_sdvo_regs.h | 3 + + 2 files changed, 50 insertions(+), 11 deletions(-) + +--- a/drivers/gpu/drm/i915/intel_sdvo.c ++++ b/drivers/gpu/drm/i915/intel_sdvo.c +@@ -928,6 +928,13 @@ static bool intel_sdvo_set_colorimetry(s + return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1); + } + ++static bool intel_sdvo_set_audio_state(struct intel_sdvo *intel_sdvo, ++ u8 audio_state) ++{ ++ return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_AUDIO_STAT, ++ &audio_state, 1); ++} ++ + #if 0 + static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo) + { +@@ -1359,11 +1366,6 @@ static void intel_sdvo_pre_enable(struct + else + sdvox |= SDVO_PIPE_SEL(crtc->pipe); + +- if (crtc_state->has_audio) { +- WARN_ON_ONCE(INTEL_GEN(dev_priv) < 4); +- sdvox |= SDVO_AUDIO_ENABLE; +- } +- + if (INTEL_GEN(dev_priv) >= 4) { + /* done in crtc_mode_set as the dpll_md reg must be written early */ + } else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) || +@@ -1492,8 +1494,13 @@ static void intel_sdvo_get_config(struct + if (sdvox & HDMI_COLOR_RANGE_16_235) + pipe_config->limited_color_range = true; + +- if (sdvox & SDVO_AUDIO_ENABLE) +- pipe_config->has_audio = true; ++ if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_AUDIO_STAT, ++ &val, 1)) { ++ u8 mask = SDVO_AUDIO_ELD_VALID | SDVO_AUDIO_PRESENCE_DETECT; ++ ++ if ((val & mask) == mask) ++ pipe_config->has_audio = true; ++ } + + if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE, + &val, 1)) { +@@ -1506,6 +1513,32 @@ static void intel_sdvo_get_config(struct + pipe_config->pixel_multiplier, encoder_pixel_multiplier); + } + ++static void intel_sdvo_disable_audio(struct intel_sdvo *intel_sdvo) ++{ ++ intel_sdvo_set_audio_state(intel_sdvo, 0); ++} ++ ++static void intel_sdvo_enable_audio(struct intel_sdvo *intel_sdvo, ++ const struct intel_crtc_state *crtc_state, ++ const struct drm_connector_state *conn_state) ++{ ++ const struct drm_display_mode *adjusted_mode = ++ &crtc_state->base.adjusted_mode; ++ struct drm_connector *connector = conn_state->connector; ++ u8 *eld = connector->eld; ++ ++ eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2; ++ ++ intel_sdvo_set_audio_state(intel_sdvo, 0); ++ ++ intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_ELD, ++ SDVO_HBUF_TX_DISABLED, ++ eld, drm_eld_size(eld)); ++ ++ intel_sdvo_set_audio_state(intel_sdvo, SDVO_AUDIO_ELD_VALID | ++ SDVO_AUDIO_PRESENCE_DETECT); ++} ++ + static void intel_disable_sdvo(struct intel_encoder *encoder, + struct intel_crtc_state *old_crtc_state, + struct drm_connector_state *conn_state) +@@ -1515,6 +1548,9 @@ static void intel_disable_sdvo(struct in + struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); + u32 temp; + ++ if (old_crtc_state->has_audio) ++ intel_sdvo_disable_audio(intel_sdvo); ++ + intel_sdvo_set_active_outputs(intel_sdvo, 0); + if (0) + intel_sdvo_set_encoder_power_state(intel_sdvo, +@@ -1598,6 +1634,9 @@ static void intel_enable_sdvo(struct int + intel_sdvo_set_encoder_power_state(intel_sdvo, + DRM_MODE_DPMS_ON); + intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output); ++ ++ if (pipe_config->has_audio) ++ intel_sdvo_enable_audio(intel_sdvo, pipe_config, conn_state); + } + + static enum drm_mode_status +@@ -2468,7 +2507,6 @@ static bool + intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) + { + struct drm_encoder *encoder = &intel_sdvo->base.base; +- struct drm_i915_private *dev_priv = to_i915(encoder->dev); + struct drm_connector *connector; + struct intel_encoder *intel_encoder = to_intel_encoder(encoder); + struct intel_connector *intel_connector; +@@ -2504,9 +2542,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *i + encoder->encoder_type = DRM_MODE_ENCODER_TMDS; + connector->connector_type = DRM_MODE_CONNECTOR_DVID; + +- /* gen3 doesn't do the hdmi bits in the SDVO register */ +- if (INTEL_GEN(dev_priv) >= 4 && +- intel_sdvo_is_hdmi_connector(intel_sdvo, device)) { ++ if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) { + connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; + intel_sdvo->is_hdmi = true; + } +--- a/drivers/gpu/drm/i915/intel_sdvo_regs.h ++++ b/drivers/gpu/drm/i915/intel_sdvo_regs.h +@@ -707,6 +707,9 @@ struct intel_sdvo_enhancements_arg { + #define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90 + #define SDVO_CMD_SET_AUDIO_STAT 0x91 + #define SDVO_CMD_GET_AUDIO_STAT 0x92 ++ #define SDVO_AUDIO_ELD_VALID (1 << 0) ++ #define SDVO_AUDIO_PRESENCE_DETECT (1 << 1) ++ #define SDVO_AUDIO_CP_READY (1 << 2) + #define SDVO_CMD_SET_HBUF_INDEX 0x93 + #define SDVO_HBUF_INDEX_ELD 0 + #define SDVO_HBUF_INDEX_AVI_IF 1 diff --git a/queue-4.14/fs-ocfs2-fix-race-in-ocfs2_dentry_attach_lock.patch b/queue-4.14/fs-ocfs2-fix-race-in-ocfs2_dentry_attach_lock.patch new file mode 100644 index 00000000000..0ca2264a7ea --- /dev/null +++ b/queue-4.14/fs-ocfs2-fix-race-in-ocfs2_dentry_attach_lock.patch @@ -0,0 +1,97 @@ +From be99ca2716972a712cde46092c54dee5e6192bf8 Mon Sep 17 00:00:00 2001 +From: Wengang Wang +Date: Thu, 13 Jun 2019 15:56:01 -0700 +Subject: fs/ocfs2: fix race in ocfs2_dentry_attach_lock() + +From: Wengang Wang + +commit be99ca2716972a712cde46092c54dee5e6192bf8 upstream. + +ocfs2_dentry_attach_lock() can be executed in parallel threads against the +same dentry. Make that race safe. The race is like this: + + thread A thread B + +(A1) enter ocfs2_dentry_attach_lock, +seeing dentry->d_fsdata is NULL, +and no alias found by +ocfs2_find_local_alias, so kmalloc +a new ocfs2_dentry_lock structure +to local variable "dl", dl1 + + ..... + + (B1) enter ocfs2_dentry_attach_lock, + seeing dentry->d_fsdata is NULL, + and no alias found by + ocfs2_find_local_alias so kmalloc + a new ocfs2_dentry_lock structure + to local variable "dl", dl2. + + ...... + +(A2) set dentry->d_fsdata with dl1, +call ocfs2_dentry_lock() and increase +dl1->dl_lockres.l_ro_holders to 1 on +success. + ...... + + (B2) set dentry->d_fsdata with dl2 + call ocfs2_dentry_lock() and increase + dl2->dl_lockres.l_ro_holders to 1 on + success. + + ...... + +(A3) call ocfs2_dentry_unlock() +and decrease +dl2->dl_lockres.l_ro_holders to 0 +on success. + .... + + (B3) call ocfs2_dentry_unlock(), + decreasing + dl2->dl_lockres.l_ro_holders, but + see it's zero now, panic + +Link: http://lkml.kernel.org/r/20190529174636.22364-1-wen.gang.wang@oracle.com +Signed-off-by: Wengang Wang +Reported-by: Daniel Sobe +Tested-by: Daniel Sobe +Reviewed-by: Changwei Ge +Reviewed-by: Joseph Qi +Cc: Mark Fasheh +Cc: Joel Becker +Cc: Junxiao Bi +Cc: Gang He +Cc: Jun Piao +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ocfs2/dcache.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +--- a/fs/ocfs2/dcache.c ++++ b/fs/ocfs2/dcache.c +@@ -310,6 +310,18 @@ int ocfs2_dentry_attach_lock(struct dent + + out_attach: + spin_lock(&dentry_attach_lock); ++ if (unlikely(dentry->d_fsdata && !alias)) { ++ /* d_fsdata is set by a racing thread which is doing ++ * the same thing as this thread is doing. Leave the racing ++ * thread going ahead and we return here. ++ */ ++ spin_unlock(&dentry_attach_lock); ++ iput(dl->dl_inode); ++ ocfs2_lock_res_free(&dl->dl_lockres); ++ kfree(dl); ++ return 0; ++ } ++ + dentry->d_fsdata = dl; + dl->dl_count++; + spin_unlock(&dentry_attach_lock); diff --git a/queue-4.14/i2c-acorn-fix-i2c-warning.patch b/queue-4.14/i2c-acorn-fix-i2c-warning.patch new file mode 100644 index 00000000000..7d73487c063 --- /dev/null +++ b/queue-4.14/i2c-acorn-fix-i2c-warning.patch @@ -0,0 +1,33 @@ +From ca21f851cc9643af049226d57fabc3c883ea648e Mon Sep 17 00:00:00 2001 +From: Russell King +Date: Tue, 11 Jun 2019 17:48:18 +0100 +Subject: i2c: acorn: fix i2c warning + +From: Russell King + +commit ca21f851cc9643af049226d57fabc3c883ea648e upstream. + +The Acorn i2c driver (for RiscPC) triggers the "i2c adapter has no name" +warning in the I2C core driver, resulting in the RTC being inaccessible. +Fix this. + +Fixes: 2236baa75f70 ("i2c: Sanity checks on adapter registration") +Signed-off-by: Russell King +Signed-off-by: Wolfram Sang +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/i2c/busses/i2c-acorn.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/i2c/busses/i2c-acorn.c ++++ b/drivers/i2c/busses/i2c-acorn.c +@@ -83,6 +83,7 @@ static struct i2c_algo_bit_data ioc_data + + static struct i2c_adapter ioc_ops = { + .nr = 0, ++ .name = "ioc", + .algo_data = &ioc_data, + }; + diff --git a/queue-4.14/iommu-arm-smmu-avoid-constant-zero-in-tlbi-writes.patch b/queue-4.14/iommu-arm-smmu-avoid-constant-zero-in-tlbi-writes.patch new file mode 100644 index 00000000000..2043691d7be --- /dev/null +++ b/queue-4.14/iommu-arm-smmu-avoid-constant-zero-in-tlbi-writes.patch @@ -0,0 +1,77 @@ +From 4e4abae311e4b44aaf61f18a826fd7136037f199 Mon Sep 17 00:00:00 2001 +From: Robin Murphy +Date: Mon, 3 Jun 2019 14:15:37 +0200 +Subject: iommu/arm-smmu: Avoid constant zero in TLBI writes + +From: Robin Murphy + +commit 4e4abae311e4b44aaf61f18a826fd7136037f199 upstream. + +Apparently, some Qualcomm arm64 platforms which appear to expose their +SMMU global register space are still, in fact, using a hypervisor to +mediate it by trapping and emulating register accesses. Sadly, some +deployed versions of said trapping code have bugs wherein they go +horribly wrong for stores using r31 (i.e. XZR/WZR) as the source +register. + +While this can be mitigated for GCC today by tweaking the constraints +for the implementation of writel_relaxed(), to avoid any potential +arms race with future compilers more aggressively optimising register +allocation, the simple way is to just remove all the problematic +constant zeros. For the write-only TLB operations, the actual value is +irrelevant anyway and any old nearby variable will provide a suitable +GPR to encode. The one point at which we really do need a zero to clear +a context bank happens before any of the TLB maintenance where crashes +have been reported, so is apparently not a problem... :/ + +Reported-by: AngeloGioacchino Del Regno +Tested-by: Marc Gonzalez +Signed-off-by: Robin Murphy +Signed-off-by: Marc Gonzalez +Acked-by: Will Deacon +Cc: stable@vger.kernel.org +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/arm-smmu.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +--- a/drivers/iommu/arm-smmu.c ++++ b/drivers/iommu/arm-smmu.c +@@ -56,6 +56,15 @@ + #include "io-pgtable.h" + #include "arm-smmu-regs.h" + ++/* ++ * Apparently, some Qualcomm arm64 platforms which appear to expose their SMMU ++ * global register space are still, in fact, using a hypervisor to mediate it ++ * by trapping and emulating register accesses. Sadly, some deployed versions ++ * of said trapping code have bugs wherein they go horribly wrong for stores ++ * using r31 (i.e. XZR/WZR) as the source register. ++ */ ++#define QCOM_DUMMY_VAL -1 ++ + #define ARM_MMU500_ACTLR_CPRE (1 << 1) + + #define ARM_MMU500_ACR_CACHE_LOCK (1 << 26) +@@ -404,7 +413,7 @@ static void __arm_smmu_tlb_sync(struct a + { + unsigned int spin_cnt, delay; + +- writel_relaxed(0, sync); ++ writel_relaxed(QCOM_DUMMY_VAL, sync); + for (delay = 1; delay < TLB_LOOP_TIMEOUT; delay *= 2) { + for (spin_cnt = TLB_SPIN_COUNT; spin_cnt > 0; spin_cnt--) { + if (!(readl_relaxed(status) & sTLBGSTATUS_GSACTIVE)) +@@ -1635,8 +1644,8 @@ static void arm_smmu_device_reset(struct + } + + /* Invalidate the TLB, just in case */ +- writel_relaxed(0, gr0_base + ARM_SMMU_GR0_TLBIALLH); +- writel_relaxed(0, gr0_base + ARM_SMMU_GR0_TLBIALLNSNH); ++ writel_relaxed(QCOM_DUMMY_VAL, gr0_base + ARM_SMMU_GR0_TLBIALLH); ++ writel_relaxed(QCOM_DUMMY_VAL, gr0_base + ARM_SMMU_GR0_TLBIALLNSNH); + + reg = readl_relaxed(ARM_SMMU_GR0_NS(smmu) + ARM_SMMU_GR0_sCR0); + diff --git a/queue-4.14/media-v4l2-ioctl-clear-fields-in-s_parm.patch b/queue-4.14/media-v4l2-ioctl-clear-fields-in-s_parm.patch new file mode 100644 index 00000000000..f183748fb7a --- /dev/null +++ b/queue-4.14/media-v4l2-ioctl-clear-fields-in-s_parm.patch @@ -0,0 +1,52 @@ +From 8a7c5594c02022ca5fa7fb603e11b3e1feb76ed5 Mon Sep 17 00:00:00 2001 +From: Hans Verkuil +Date: Sat, 12 May 2018 10:44:02 -0400 +Subject: media: v4l2-ioctl: clear fields in s_parm + +From: Hans Verkuil + +commit 8a7c5594c02022ca5fa7fb603e11b3e1feb76ed5 upstream. + +Zero the reserved capture/output array. + +Zero the extendedmode (it is never used in drivers). + +Clear all flags in capture/outputmode except for V4L2_MODE_HIGHQUALITY, +as that is the only valid flag. + +Signed-off-by: Hans Verkuil +Reviewed-by: Hans de Goede +Signed-off-by: Mauro Carvalho Chehab +Cc: Naresh Kamboju +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/media/v4l2-core/v4l2-ioctl.c | 17 ++++++++++++++++- + 1 file changed, 16 insertions(+), 1 deletion(-) + +--- a/drivers/media/v4l2-core/v4l2-ioctl.c ++++ b/drivers/media/v4l2-core/v4l2-ioctl.c +@@ -1945,7 +1945,22 @@ static int v4l_s_parm(const struct v4l2_ + struct v4l2_streamparm *p = arg; + int ret = check_fmt(file, p->type); + +- return ret ? ret : ops->vidioc_s_parm(file, fh, p); ++ if (ret) ++ return ret; ++ ++ /* Note: extendedmode is never used in drivers */ ++ if (V4L2_TYPE_IS_OUTPUT(p->type)) { ++ memset(p->parm.output.reserved, 0, ++ sizeof(p->parm.output.reserved)); ++ p->parm.output.extendedmode = 0; ++ p->parm.output.outputmode &= V4L2_MODE_HIGHQUALITY; ++ } else { ++ memset(p->parm.capture.reserved, 0, ++ sizeof(p->parm.capture.reserved)); ++ p->parm.capture.extendedmode = 0; ++ p->parm.capture.capturemode &= V4L2_MODE_HIGHQUALITY; ++ } ++ return ops->vidioc_s_parm(file, fh, p); + } + + static int v4l_queryctrl(const struct v4l2_ioctl_ops *ops, diff --git a/queue-4.14/mm-list_lru.c-fix-memory-leak-in-__memcg_init_list_lru_node.patch b/queue-4.14/mm-list_lru.c-fix-memory-leak-in-__memcg_init_list_lru_node.patch new file mode 100644 index 00000000000..5132b6cd876 --- /dev/null +++ b/queue-4.14/mm-list_lru.c-fix-memory-leak-in-__memcg_init_list_lru_node.patch @@ -0,0 +1,71 @@ +From 3510955b327176fd4cbab5baa75b449f077722a2 Mon Sep 17 00:00:00 2001 +From: Shakeel Butt +Date: Thu, 13 Jun 2019 15:55:49 -0700 +Subject: mm/list_lru.c: fix memory leak in __memcg_init_list_lru_node + +From: Shakeel Butt + +commit 3510955b327176fd4cbab5baa75b449f077722a2 upstream. + +Syzbot reported following memory leak: + +ffffffffda RBX: 0000000000000003 RCX: 0000000000441f79 +BUG: memory leak +unreferenced object 0xffff888114f26040 (size 32): + comm "syz-executor626", pid 7056, jiffies 4294948701 (age 39.410s) + hex dump (first 32 bytes): + 40 60 f2 14 81 88 ff ff 40 60 f2 14 81 88 ff ff @`......@`...... + 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + backtrace: + slab_post_alloc_hook mm/slab.h:439 [inline] + slab_alloc mm/slab.c:3326 [inline] + kmem_cache_alloc_trace+0x13d/0x280 mm/slab.c:3553 + kmalloc include/linux/slab.h:547 [inline] + __memcg_init_list_lru_node+0x58/0xf0 mm/list_lru.c:352 + memcg_init_list_lru_node mm/list_lru.c:375 [inline] + memcg_init_list_lru mm/list_lru.c:459 [inline] + __list_lru_init+0x193/0x2a0 mm/list_lru.c:626 + alloc_super+0x2e0/0x310 fs/super.c:269 + sget_userns+0x94/0x2a0 fs/super.c:609 + sget+0x8d/0xb0 fs/super.c:660 + mount_nodev+0x31/0xb0 fs/super.c:1387 + fuse_mount+0x2d/0x40 fs/fuse/inode.c:1236 + legacy_get_tree+0x27/0x80 fs/fs_context.c:661 + vfs_get_tree+0x2e/0x120 fs/super.c:1476 + do_new_mount fs/namespace.c:2790 [inline] + do_mount+0x932/0xc50 fs/namespace.c:3110 + ksys_mount+0xab/0x120 fs/namespace.c:3319 + __do_sys_mount fs/namespace.c:3333 [inline] + __se_sys_mount fs/namespace.c:3330 [inline] + __x64_sys_mount+0x26/0x30 fs/namespace.c:3330 + do_syscall_64+0x76/0x1a0 arch/x86/entry/common.c:301 + entry_SYSCALL_64_after_hwframe+0x44/0xa9 + +This is a simple off by one bug on the error path. + +Link: http://lkml.kernel.org/r/20190528043202.99980-1-shakeelb@google.com +Fixes: 60d3fd32a7a9 ("list_lru: introduce per-memcg lists") +Reported-by: syzbot+f90a420dfe2b1b03cb2c@syzkaller.appspotmail.com +Signed-off-by: Shakeel Butt +Acked-by: Michal Hocko +Reviewed-by: Kirill Tkhai +Cc: [4.0+] +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/list_lru.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/list_lru.c ++++ b/mm/list_lru.c +@@ -313,7 +313,7 @@ static int __memcg_init_list_lru_node(st + } + return 0; + fail: +- __memcg_destroy_list_lru_node(memcg_lrus, begin, i - 1); ++ __memcg_destroy_list_lru_node(memcg_lrus, begin, i); + return -ENOMEM; + } + diff --git a/queue-4.14/mm-vmscan.c-fix-trying-to-reclaim-unevictable-lru-page.patch b/queue-4.14/mm-vmscan.c-fix-trying-to-reclaim-unevictable-lru-page.patch new file mode 100644 index 00000000000..40f1651a1f0 --- /dev/null +++ b/queue-4.14/mm-vmscan.c-fix-trying-to-reclaim-unevictable-lru-page.patch @@ -0,0 +1,79 @@ +From a58f2cef26e1ca44182c8b22f4f4395e702a5795 Mon Sep 17 00:00:00 2001 +From: Minchan Kim +Date: Thu, 13 Jun 2019 15:56:15 -0700 +Subject: mm/vmscan.c: fix trying to reclaim unevictable LRU page + +From: Minchan Kim + +commit a58f2cef26e1ca44182c8b22f4f4395e702a5795 upstream. + +There was the below bug report from Wu Fangsuo. + +On the CMA allocation path, isolate_migratepages_range() could isolate +unevictable LRU pages and reclaim_clean_page_from_list() can try to +reclaim them if they are clean file-backed pages. + + page:ffffffbf02f33b40 count:86 mapcount:84 mapping:ffffffc08fa7a810 index:0x24 + flags: 0x19040c(referenced|uptodate|arch_1|mappedtodisk|unevictable|mlocked) + raw: 000000000019040c ffffffc08fa7a810 0000000000000024 0000005600000053 + raw: ffffffc009b05b20 ffffffc009b05b20 0000000000000000 ffffffc09bf3ee80 + page dumped because: VM_BUG_ON_PAGE(PageLRU(page) || PageUnevictable(page)) + page->mem_cgroup:ffffffc09bf3ee80 + ------------[ cut here ]------------ + kernel BUG at /home/build/farmland/adroid9.0/kernel/linux/mm/vmscan.c:1350! + Internal error: Oops - BUG: 0 [#1] PREEMPT SMP + Modules linked in: + CPU: 0 PID: 7125 Comm: syz-executor Tainted: G S 4.14.81 #3 + Hardware name: ASR AQUILAC EVB (DT) + task: ffffffc00a54cd00 task.stack: ffffffc009b00000 + PC is at shrink_page_list+0x1998/0x3240 + LR is at shrink_page_list+0x1998/0x3240 + pc : [] lr : [] pstate: 60400045 + sp : ffffffc009b05940 + .. + shrink_page_list+0x1998/0x3240 + reclaim_clean_pages_from_list+0x3c0/0x4f0 + alloc_contig_range+0x3bc/0x650 + cma_alloc+0x214/0x668 + ion_cma_allocate+0x98/0x1d8 + ion_alloc+0x200/0x7e0 + ion_ioctl+0x18c/0x378 + do_vfs_ioctl+0x17c/0x1780 + SyS_ioctl+0xac/0xc0 + +Wu found it's due to commit ad6b67041a45 ("mm: remove SWAP_MLOCK in +ttu"). Before that, unevictable pages go to cull_mlocked so that we +can't reach the VM_BUG_ON_PAGE line. + +To fix the issue, this patch filters out unevictable LRU pages from the +reclaim_clean_pages_from_list in CMA. + +Link: http://lkml.kernel.org/r/20190524071114.74202-1-minchan@kernel.org +Fixes: ad6b67041a45 ("mm: remove SWAP_MLOCK in ttu") +Signed-off-by: Minchan Kim +Reported-by: Wu Fangsuo +Debugged-by: Wu Fangsuo +Tested-by: Wu Fangsuo +Reviewed-by: Andrew Morton +Acked-by: Michal Hocko +Cc: Pankaj Suryawanshi +Cc: [4.12+] +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + mm/vmscan.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/mm/vmscan.c ++++ b/mm/vmscan.c +@@ -1393,7 +1393,7 @@ unsigned long reclaim_clean_pages_from_l + + list_for_each_entry_safe(page, next, page_list, lru) { + if (page_is_file_cache(page) && !PageDirty(page) && +- !__PageMovable(page)) { ++ !__PageMovable(page) && !PageUnevictable(page)) { + ClearPageActive(page); + list_move(&page->lru, &clean_pages); + } diff --git a/queue-4.14/ptrace-restore-smp_rmb-in-__ptrace_may_access.patch b/queue-4.14/ptrace-restore-smp_rmb-in-__ptrace_may_access.patch new file mode 100644 index 00000000000..18afb5f1343 --- /dev/null +++ b/queue-4.14/ptrace-restore-smp_rmb-in-__ptrace_may_access.patch @@ -0,0 +1,63 @@ +From f6581f5b55141a95657ef5742cf6a6bfa20a109f Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Wed, 29 May 2019 13:31:57 +0200 +Subject: ptrace: restore smp_rmb() in __ptrace_may_access() + +From: Jann Horn + +commit f6581f5b55141a95657ef5742cf6a6bfa20a109f upstream. + +Restore the read memory barrier in __ptrace_may_access() that was deleted +a couple years ago. Also add comments on this barrier and the one it pairs +with to explain why they're there (as far as I understand). + +Fixes: bfedb589252c ("mm: Add a user_ns owner to mm_struct and fix ptrace permission checks") +Cc: stable@vger.kernel.org +Acked-by: Kees Cook +Acked-by: Oleg Nesterov +Signed-off-by: Jann Horn +Signed-off-by: Eric W. Biederman +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/cred.c | 9 +++++++++ + kernel/ptrace.c | 10 ++++++++++ + 2 files changed, 19 insertions(+) + +--- a/kernel/cred.c ++++ b/kernel/cred.c +@@ -448,6 +448,15 @@ int commit_creds(struct cred *new) + if (task->mm) + set_dumpable(task->mm, suid_dumpable); + task->pdeath_signal = 0; ++ /* ++ * If a task drops privileges and becomes nondumpable, ++ * the dumpability change must become visible before ++ * the credential change; otherwise, a __ptrace_may_access() ++ * racing with this change may be able to attach to a task it ++ * shouldn't be able to attach to (as if the task had dropped ++ * privileges without becoming nondumpable). ++ * Pairs with a read barrier in __ptrace_may_access(). ++ */ + smp_wmb(); + } + +--- a/kernel/ptrace.c ++++ b/kernel/ptrace.c +@@ -323,6 +323,16 @@ static int __ptrace_may_access(struct ta + return -EPERM; + ok: + rcu_read_unlock(); ++ /* ++ * If a task drops privileges and becomes nondumpable (through a syscall ++ * like setresuid()) while we are trying to access it, we must ensure ++ * that the dumpability is read after the credentials; otherwise, ++ * we may be able to attach to a task that we shouldn't be able to ++ * attach to (as if the task had dropped privileges without becoming ++ * nondumpable). ++ * Pairs with a write barrier in commit_creds(). ++ */ ++ smp_rmb(); + mm = task->mm; + if (mm && + ((get_dumpable(mm) != SUID_DUMP_USER) && diff --git a/queue-4.14/series b/queue-4.14/series index e11ff97a410..003109803a8 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -6,3 +6,16 @@ alsa-oxfw-allow-pcm-capture-for-stanton-scs.1m.patch alsa-hda-realtek-update-headset-mode-for-alc256.patch alsa-firewire-motu-fix-destruction-of-data-for-isochronous-resources.patch libata-extend-quirks-for-the-st1000lm024-drives-with-nolpm-quirk.patch +mm-list_lru.c-fix-memory-leak-in-__memcg_init_list_lru_node.patch +fs-ocfs2-fix-race-in-ocfs2_dentry_attach_lock.patch +mm-vmscan.c-fix-trying-to-reclaim-unevictable-lru-page.patch +signal-ptrace-don-t-leak-unitialized-kernel-memory-with-ptrace_peek_siginfo.patch +ptrace-restore-smp_rmb-in-__ptrace_may_access.patch +media-v4l2-ioctl-clear-fields-in-s_parm.patch +iommu-arm-smmu-avoid-constant-zero-in-tlbi-writes.patch +i2c-acorn-fix-i2c-warning.patch +bcache-fix-stack-corruption-by-preceding_key.patch +cgroup-use-css_tryget-instead-of-css_tryget_online-in-task_get_css.patch +asoc-cs42xx8-add-regcache-mask-dirty.patch +asoc-fsl_asrc-fix-the-issue-about-unsupported-rate.patch +drm-i915-sdvo-implement-proper-hdmi-audio-support-for-sdvo.patch diff --git a/queue-4.14/signal-ptrace-don-t-leak-unitialized-kernel-memory-with-ptrace_peek_siginfo.patch b/queue-4.14/signal-ptrace-don-t-leak-unitialized-kernel-memory-with-ptrace_peek_siginfo.patch new file mode 100644 index 00000000000..add3d21b3f8 --- /dev/null +++ b/queue-4.14/signal-ptrace-don-t-leak-unitialized-kernel-memory-with-ptrace_peek_siginfo.patch @@ -0,0 +1,72 @@ +From f6e2aa91a46d2bc79fce9b93a988dbe7655c90c0 Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Tue, 28 May 2019 18:46:37 -0500 +Subject: signal/ptrace: Don't leak unitialized kernel memory with PTRACE_PEEK_SIGINFO + +From: Eric W. Biederman + +commit f6e2aa91a46d2bc79fce9b93a988dbe7655c90c0 upstream. + +Recently syzbot in conjunction with KMSAN reported that +ptrace_peek_siginfo can copy an uninitialized siginfo to userspace. +Inspecting ptrace_peek_siginfo confirms this. + +The problem is that off when initialized from args.off can be +initialized to a negaive value. At which point the "if (off >= 0)" +test to see if off became negative fails because off started off +negative. + +Prevent the core problem by adding a variable found that is only true +if a siginfo is found and copied to a temporary in preparation for +being copied to userspace. + +Prevent args.off from being truncated when being assigned to off by +testing that off is <= the maximum possible value of off. Convert off +to an unsigned long so that we should not have to truncate args.off, +we have well defined overflow behavior so if we add another check we +won't risk fighting undefined compiler behavior, and so that we have a +type whose maximum value is easy to test for. + +Cc: Andrei Vagin +Cc: stable@vger.kernel.org +Reported-by: syzbot+0d602a1b0d8c95bdf299@syzkaller.appspotmail.com +Fixes: 84c751bd4aeb ("ptrace: add ability to retrieve signals without removing from a queue (v4)") +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/ptrace.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/kernel/ptrace.c ++++ b/kernel/ptrace.c +@@ -704,6 +704,10 @@ static int ptrace_peek_siginfo(struct ta + if (arg.nr < 0) + return -EINVAL; + ++ /* Ensure arg.off fits in an unsigned long */ ++ if (arg.off > ULONG_MAX) ++ return 0; ++ + if (arg.flags & PTRACE_PEEKSIGINFO_SHARED) + pending = &child->signal->shared_pending; + else +@@ -711,7 +715,8 @@ static int ptrace_peek_siginfo(struct ta + + for (i = 0; i < arg.nr; ) { + siginfo_t info; +- s32 off = arg.off + i; ++ unsigned long off = arg.off + i; ++ bool found = false; + + spin_lock_irq(&child->sighand->siglock); + list_for_each_entry(q, &pending->list, list) { +@@ -722,7 +727,7 @@ static int ptrace_peek_siginfo(struct ta + } + spin_unlock_irq(&child->sighand->siglock); + +- if (off >= 0) /* beyond the end of the list */ ++ if (!found) /* beyond the end of the list */ + break; + + #ifdef CONFIG_COMPAT