From: Greg Kroah-Hartman Date: Thu, 2 Oct 2014 19:55:46 +0000 (-0700) Subject: 3.10-stable patches X-Git-Tag: v3.16.4~77 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=424102977eba54f19511ac8f803756660d33c967;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: alsa-core-fix-buffer-overflow-in-snd_info_get_line.patch alsa-hda-fix-coef-setups-for-alc1150-codec.patch alsa-hda-fix-invalid-pin-powermap-without-jack-detection.patch alsa-pcm-fix-fifo_size-frame-calculation.patch arm64-ptrace-fix-compat-hardware-watchpoint-reporting.patch cfq-iosched-fix-wrong-children_weight-calculation.patch hid-logitech-dj-prevent-false-errors-to-be-shown.patch hid-magicmouse-sanity-check-report-size-in-raw_event-callback.patch hid-picolcd-sanity-check-report-size-in-raw_event-callback.patch trace-fix-epoll-hang-when-we-race-with-new-entries.patch --- diff --git a/queue-3.10/alsa-core-fix-buffer-overflow-in-snd_info_get_line.patch b/queue-3.10/alsa-core-fix-buffer-overflow-in-snd_info_get_line.patch new file mode 100644 index 00000000000..80a038f04a1 --- /dev/null +++ b/queue-3.10/alsa-core-fix-buffer-overflow-in-snd_info_get_line.patch @@ -0,0 +1,44 @@ +From ddc64b278a4dda052390b3de1b551e59acdff105 Mon Sep 17 00:00:00 2001 +From: Clemens Ladisch +Date: Thu, 21 Aug 2014 20:55:21 +0200 +Subject: ALSA: core: fix buffer overflow in snd_info_get_line() + +From: Clemens Ladisch + +commit ddc64b278a4dda052390b3de1b551e59acdff105 upstream. + +snd_info_get_line() documents that its last parameter must be one +less than the buffer size, but this API design guarantees that +(literally) every caller gets it wrong. + +Just change this parameter to have its obvious meaning. + +Reported-by: Tommi Rantala +Signed-off-by: Clemens Ladisch +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/info.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/sound/core/info.c ++++ b/sound/core/info.c +@@ -679,7 +679,7 @@ int snd_info_card_free(struct snd_card * + * snd_info_get_line - read one line from the procfs buffer + * @buffer: the procfs buffer + * @line: the buffer to store +- * @len: the max. buffer size - 1 ++ * @len: the max. buffer size + * + * Reads one line from the buffer and stores the string. + * +@@ -699,7 +699,7 @@ int snd_info_get_line(struct snd_info_bu + buffer->stop = 1; + if (c == '\n') + break; +- if (len) { ++ if (len > 1) { + len--; + *line++ = c; + } diff --git a/queue-3.10/alsa-hda-fix-coef-setups-for-alc1150-codec.patch b/queue-3.10/alsa-hda-fix-coef-setups-for-alc1150-codec.patch new file mode 100644 index 00000000000..3383ad1451f --- /dev/null +++ b/queue-3.10/alsa-hda-fix-coef-setups-for-alc1150-codec.patch @@ -0,0 +1,40 @@ +From acf08081adb5e8fe0519eb97bb49797ef52614d6 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 2 Sep 2014 07:21:56 +0200 +Subject: ALSA: hda - Fix COEF setups for ALC1150 codec + +From: Takashi Iwai + +commit acf08081adb5e8fe0519eb97bb49797ef52614d6 upstream. + +ALC1150 codec seems to need the COEF- and PLL-setups just like its +compatible ALC882 codec. Some machines (e.g. SunMicro X10SAT) show +the problem like too low output volumes unless the COEF setup is +applied. + +Reported-and-tested-by: Dana Goyette +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_realtek.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -318,6 +318,7 @@ static void alc_auto_init_amp(struct hda + case 0x10ec0885: + case 0x10ec0887: + /*case 0x10ec0889:*/ /* this causes an SPDIF problem */ ++ case 0x10ec0900: + alc889_coef_init(codec); + break; + case 0x10ec0888: +@@ -2252,6 +2253,7 @@ static int patch_alc882(struct hda_codec + switch (codec->vendor_id) { + case 0x10ec0882: + case 0x10ec0885: ++ case 0x10ec0900: + break; + default: + /* ALC883 and variants */ diff --git a/queue-3.10/alsa-hda-fix-invalid-pin-powermap-without-jack-detection.patch b/queue-3.10/alsa-hda-fix-invalid-pin-powermap-without-jack-detection.patch new file mode 100644 index 00000000000..63151ae9c48 --- /dev/null +++ b/queue-3.10/alsa-hda-fix-invalid-pin-powermap-without-jack-detection.patch @@ -0,0 +1,73 @@ +From 7a9744cb455e6faa287e148394b4b422a6f3c5c4 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Thu, 11 Sep 2014 12:59:21 +0200 +Subject: ALSA: hda - Fix invalid pin powermap without jack detection + +From: Takashi Iwai + +commit 7a9744cb455e6faa287e148394b4b422a6f3c5c4 upstream. + +When a driver is set up without the jack detection explicitly (either +by passing a model option or via a specific fixup), the pin powermap +of IDT/STAC codecs is set up wrongly, resulting in the silence +output. It's because of a logic failure in stac_init_power_map(). +It tries to avoid creating a callback for the pins that have other +auto-hp and auto-mic callbacks, but the check is done in a wrong way +at a wrong time. The stac_init_power_map() should be called after +creating other jack detection ctls, and the jack callback should be +created only for jack-detectable widgets. + +This patch fixes the check in stac_init_power_map() and its callee +at the right place, after snd_hda_gen_build_controls(). + +Reported-by: Adam Richter +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/pci/hda/patch_sigmatel.c | 17 ++++++++++++----- + 1 file changed, 12 insertions(+), 5 deletions(-) + +--- a/sound/pci/hda/patch_sigmatel.c ++++ b/sound/pci/hda/patch_sigmatel.c +@@ -539,8 +539,8 @@ static void stac_init_power_map(struct h + if (snd_hda_jack_tbl_get(codec, nid)) + continue; + if (def_conf == AC_JACK_PORT_COMPLEX && +- !(spec->vref_mute_led_nid == nid || +- is_jack_detectable(codec, nid))) { ++ spec->vref_mute_led_nid != nid && ++ is_jack_detectable(codec, nid)) { + snd_hda_jack_detect_enable_callback(codec, nid, + STAC_PWR_EVENT, + jack_update_power); +@@ -3647,11 +3647,18 @@ static int stac_parse_auto_config(struct + return err; + } + +- stac_init_power_map(codec); +- + return 0; + } + ++static int stac_build_controls(struct hda_codec *codec) ++{ ++ int err = snd_hda_gen_build_controls(codec); ++ ++ if (err < 0) ++ return err; ++ stac_init_power_map(codec); ++ return 0; ++} + + static int stac_init(struct hda_codec *codec) + { +@@ -3794,7 +3801,7 @@ static void stac_set_power_state(struct + #endif /* CONFIG_PM */ + + static const struct hda_codec_ops stac_patch_ops = { +- .build_controls = snd_hda_gen_build_controls, ++ .build_controls = stac_build_controls, + .build_pcms = snd_hda_gen_build_pcms, + .init = stac_init, + .free = stac_free, diff --git a/queue-3.10/alsa-pcm-fix-fifo_size-frame-calculation.patch b/queue-3.10/alsa-pcm-fix-fifo_size-frame-calculation.patch new file mode 100644 index 00000000000..bf583bc6584 --- /dev/null +++ b/queue-3.10/alsa-pcm-fix-fifo_size-frame-calculation.patch @@ -0,0 +1,46 @@ +From a9960e6a293e6fc3ed414643bb4e4106272e4d0a Mon Sep 17 00:00:00 2001 +From: Clemens Ladisch +Date: Sun, 21 Sep 2014 22:50:57 +0200 +Subject: ALSA: pcm: fix fifo_size frame calculation + +From: Clemens Ladisch + +commit a9960e6a293e6fc3ed414643bb4e4106272e4d0a upstream. + +The calculated frame size was wrong because snd_pcm_format_physical_width() +actually returns the number of bits, not bytes. + +Use snd_pcm_format_size() instead, which not only returns bytes, but also +simplifies the calculation. + +Fixes: 8bea869c5e56 ("ALSA: PCM midlevel: improve fifo_size handling") +Signed-off-by: Clemens Ladisch +Signed-off-by: Takashi Iwai +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/pcm_lib.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +--- a/sound/core/pcm_lib.c ++++ b/sound/core/pcm_lib.c +@@ -1782,14 +1782,16 @@ static int snd_pcm_lib_ioctl_fifo_size(s + { + struct snd_pcm_hw_params *params = arg; + snd_pcm_format_t format; +- int channels, width; ++ int channels; ++ ssize_t frame_size; + + params->fifo_size = substream->runtime->hw.fifo_size; + if (!(substream->runtime->hw.info & SNDRV_PCM_INFO_FIFO_IN_FRAMES)) { + format = params_format(params); + channels = params_channels(params); +- width = snd_pcm_format_physical_width(format); +- params->fifo_size /= width * channels; ++ frame_size = snd_pcm_format_size(format, channels); ++ if (frame_size > 0) ++ params->fifo_size /= (unsigned)frame_size; + } + return 0; + } diff --git a/queue-3.10/arm64-ptrace-fix-compat-hardware-watchpoint-reporting.patch b/queue-3.10/arm64-ptrace-fix-compat-hardware-watchpoint-reporting.patch new file mode 100644 index 00000000000..2161892a2af --- /dev/null +++ b/queue-3.10/arm64-ptrace-fix-compat-hardware-watchpoint-reporting.patch @@ -0,0 +1,49 @@ +From 27d7ff273c2aad37b28f6ff0cab2cfa35b51e648 Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Fri, 22 Aug 2014 14:13:24 +0100 +Subject: arm64: ptrace: fix compat hardware watchpoint reporting + +From: Will Deacon + +commit 27d7ff273c2aad37b28f6ff0cab2cfa35b51e648 upstream. + +I'm not sure what I was on when I wrote this, but when iterating over +the hardware watchpoint array (hbp_watch_array), our index is off by +ARM_MAX_BRP, so we walk off the end of our thread_struct... + +... except, a dodgy condition in the loop means that it never executes +at all (bp cannot be NULL). + +This patch fixes the code so that we remove the bp check and use the +correct index for accessing the watchpoint structures. + +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/include/asm/hw_breakpoint.h | 1 - + arch/arm64/kernel/ptrace.c | 3 ++- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm64/include/asm/hw_breakpoint.h ++++ b/arch/arm64/include/asm/hw_breakpoint.h +@@ -79,7 +79,6 @@ static inline void decode_ctrl_reg(u32 r + */ + #define ARM_MAX_BRP 16 + #define ARM_MAX_WRP 16 +-#define ARM_MAX_HBP_SLOTS (ARM_MAX_BRP + ARM_MAX_WRP) + + /* Virtual debug register bases. */ + #define AARCH64_DBG_REG_BVR 0 +--- a/arch/arm64/kernel/ptrace.c ++++ b/arch/arm64/kernel/ptrace.c +@@ -103,7 +103,8 @@ static void ptrace_hbptriggered(struct p + break; + } + } +- for (i = ARM_MAX_BRP; i < ARM_MAX_HBP_SLOTS && !bp; ++i) { ++ ++ for (i = 0; i < ARM_MAX_WRP; ++i) { + if (current->thread.debug.hbp_watch[i] == bp) { + info.si_errno = -((i << 1) + 1); + break; diff --git a/queue-3.10/cfq-iosched-fix-wrong-children_weight-calculation.patch b/queue-3.10/cfq-iosched-fix-wrong-children_weight-calculation.patch new file mode 100644 index 00000000000..744817cf824 --- /dev/null +++ b/queue-3.10/cfq-iosched-fix-wrong-children_weight-calculation.patch @@ -0,0 +1,88 @@ +From e15693ef18e13e3e6bffe891fe140f18b8ff6d07 Mon Sep 17 00:00:00 2001 +From: Toshiaki Makita +Date: Tue, 26 Aug 2014 20:56:36 +0900 +Subject: cfq-iosched: Fix wrong children_weight calculation + +From: Toshiaki Makita + +commit e15693ef18e13e3e6bffe891fe140f18b8ff6d07 upstream. + +cfq_group_service_tree_add() is applying new_weight at the beginning of +the function via cfq_update_group_weight(). +This actually allows weight to change between adding it to and subtracting +it from children_weight, and triggers WARN_ON_ONCE() in +cfq_group_service_tree_del(), or even causes oops by divide error during +vfr calculation in cfq_group_service_tree_add(). + +The detailed scenario is as follows: +1. Create blkio cgroups X and Y as a child of X. + Set X's weight to 500 and perform some I/O to apply new_weight. + This X's I/O completes before starting Y's I/O. +2. Y starts I/O and cfq_group_service_tree_add() is called with Y. +3. cfq_group_service_tree_add() walks up the tree during children_weight + calculation and adds parent X's weight (500) to children_weight of root. + children_weight becomes 500. +4. Set X's weight to 1000. +5. X starts I/O and cfq_group_service_tree_add() is called with X. +6. cfq_group_service_tree_add() applies its new_weight (1000). +7. I/O of Y completes and cfq_group_service_tree_del() is called with Y. +8. I/O of X completes and cfq_group_service_tree_del() is called with X. +9. cfq_group_service_tree_del() subtracts X's weight (1000) from + children_weight of root. children_weight becomes -500. + This triggers WARN_ON_ONCE(). +10. Set X's weight to 500. +11. X starts I/O and cfq_group_service_tree_add() is called with X. +12. cfq_group_service_tree_add() applies its new_weight (500) and adds it + to children_weight of root. children_weight becomes 0. Calcularion of + vfr triggers oops by divide error. + +weight should be updated right before adding it to children_weight. + +Reported-by: Ruki Sekiya +Signed-off-by: Toshiaki Makita +Acked-by: Tejun Heo +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman + +--- + block/cfq-iosched.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +--- a/block/cfq-iosched.c ++++ b/block/cfq-iosched.c +@@ -1275,12 +1275,16 @@ __cfq_group_service_tree_add(struct cfq_ + static void + cfq_update_group_weight(struct cfq_group *cfqg) + { +- BUG_ON(!RB_EMPTY_NODE(&cfqg->rb_node)); +- + if (cfqg->new_weight) { + cfqg->weight = cfqg->new_weight; + cfqg->new_weight = 0; + } ++} ++ ++static void ++cfq_update_group_leaf_weight(struct cfq_group *cfqg) ++{ ++ BUG_ON(!RB_EMPTY_NODE(&cfqg->rb_node)); + + if (cfqg->new_leaf_weight) { + cfqg->leaf_weight = cfqg->new_leaf_weight; +@@ -1299,7 +1303,7 @@ cfq_group_service_tree_add(struct cfq_rb + /* add to the service tree */ + BUG_ON(!RB_EMPTY_NODE(&cfqg->rb_node)); + +- cfq_update_group_weight(cfqg); ++ cfq_update_group_leaf_weight(cfqg); + __cfq_group_service_tree_add(st, cfqg); + + /* +@@ -1323,6 +1327,7 @@ cfq_group_service_tree_add(struct cfq_rb + */ + while ((parent = cfqg_parent(pos))) { + if (propagate) { ++ cfq_update_group_weight(pos); + propagate = !parent->nr_active++; + parent->children_weight += pos->weight; + } diff --git a/queue-3.10/hid-logitech-dj-prevent-false-errors-to-be-shown.patch b/queue-3.10/hid-logitech-dj-prevent-false-errors-to-be-shown.patch new file mode 100644 index 00000000000..d6a143d20fb --- /dev/null +++ b/queue-3.10/hid-logitech-dj-prevent-false-errors-to-be-shown.patch @@ -0,0 +1,112 @@ +From 5abfe85c1d4694d5d4bbd13ecc166262b937adf0 Mon Sep 17 00:00:00 2001 +From: Benjamin Tissoires +Date: Fri, 22 Aug 2014 16:16:05 -0400 +Subject: HID: logitech-dj: prevent false errors to be shown + +From: Benjamin Tissoires + +commit 5abfe85c1d4694d5d4bbd13ecc166262b937adf0 upstream. + +Commit "HID: logitech: perform bounds checking on device_id early +enough" unfortunately leaks some errors to dmesg which are not real +ones: +- if the report is not a DJ one, then there is not point in checking + the device_id +- the receiver (index 0) can also receive some notifications which + can be safely ignored given the current implementation + +Move out the test regarding the report_id and also discards +printing errors when the receiver got notified. + +Fixes: ad3e14d7c5268c2e24477c6ef54bbdf88add5d36 + +Reported-and-tested-by: Markus Trippelsdorf +Signed-off-by: Benjamin Tissoires +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-logitech-dj.c | 43 ++++++++++++++++++++++++------------------ + drivers/hid/hid-logitech-dj.h | 1 + 2 files changed, 26 insertions(+), 18 deletions(-) + +--- a/drivers/hid/hid-logitech-dj.c ++++ b/drivers/hid/hid-logitech-dj.c +@@ -679,7 +679,6 @@ static int logi_dj_raw_event(struct hid_ + struct dj_receiver_dev *djrcv_dev = hid_get_drvdata(hdev); + struct dj_report *dj_report = (struct dj_report *) data; + unsigned long flags; +- bool report_processed = false; + + dbg_hid("%s, size:%d\n", __func__, size); + +@@ -706,34 +705,42 @@ static int logi_dj_raw_event(struct hid_ + * device (via hid_input_report() ) and return 1 so hid-core does not do + * anything else with it. + */ ++ ++ /* case 1) */ ++ if (data[0] != REPORT_ID_DJ_SHORT) ++ return false; ++ + if ((dj_report->device_index < DJ_DEVICE_INDEX_MIN) || + (dj_report->device_index > DJ_DEVICE_INDEX_MAX)) { +- dev_err(&hdev->dev, "%s: invalid device index:%d\n", ++ /* ++ * Device index is wrong, bail out. ++ * This driver can ignore safely the receiver notifications, ++ * so ignore those reports too. ++ */ ++ if (dj_report->device_index != DJ_RECEIVER_INDEX) ++ dev_err(&hdev->dev, "%s: invalid device index:%d\n", + __func__, dj_report->device_index); + return false; + } + + spin_lock_irqsave(&djrcv_dev->lock, flags); +- if (dj_report->report_id == REPORT_ID_DJ_SHORT) { +- switch (dj_report->report_type) { +- case REPORT_TYPE_NOTIF_DEVICE_PAIRED: +- case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED: +- logi_dj_recv_queue_notification(djrcv_dev, dj_report); +- break; +- case REPORT_TYPE_NOTIF_CONNECTION_STATUS: +- if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] == +- STATUS_LINKLOSS) { +- logi_dj_recv_forward_null_report(djrcv_dev, dj_report); +- } +- break; +- default: +- logi_dj_recv_forward_report(djrcv_dev, dj_report); ++ switch (dj_report->report_type) { ++ case REPORT_TYPE_NOTIF_DEVICE_PAIRED: ++ case REPORT_TYPE_NOTIF_DEVICE_UNPAIRED: ++ logi_dj_recv_queue_notification(djrcv_dev, dj_report); ++ break; ++ case REPORT_TYPE_NOTIF_CONNECTION_STATUS: ++ if (dj_report->report_params[CONNECTION_STATUS_PARAM_STATUS] == ++ STATUS_LINKLOSS) { ++ logi_dj_recv_forward_null_report(djrcv_dev, dj_report); + } +- report_processed = true; ++ break; ++ default: ++ logi_dj_recv_forward_report(djrcv_dev, dj_report); + } + spin_unlock_irqrestore(&djrcv_dev->lock, flags); + +- return report_processed; ++ return true; + } + + static int logi_dj_probe(struct hid_device *hdev, +--- a/drivers/hid/hid-logitech-dj.h ++++ b/drivers/hid/hid-logitech-dj.h +@@ -27,6 +27,7 @@ + + #define DJ_MAX_PAIRED_DEVICES 6 + #define DJ_MAX_NUMBER_NOTIFICATIONS 8 ++#define DJ_RECEIVER_INDEX 0 + #define DJ_DEVICE_INDEX_MIN 1 + #define DJ_DEVICE_INDEX_MAX 6 + diff --git a/queue-3.10/hid-magicmouse-sanity-check-report-size-in-raw_event-callback.patch b/queue-3.10/hid-magicmouse-sanity-check-report-size-in-raw_event-callback.patch new file mode 100644 index 00000000000..46597c11aae --- /dev/null +++ b/queue-3.10/hid-magicmouse-sanity-check-report-size-in-raw_event-callback.patch @@ -0,0 +1,47 @@ +From c54def7bd64d7c0b6993336abcffb8444795bf38 Mon Sep 17 00:00:00 2001 +From: Jiri Kosina +Date: Wed, 27 Aug 2014 09:12:24 +0200 +Subject: HID: magicmouse: sanity check report size in raw_event() callback + +From: Jiri Kosina + +commit c54def7bd64d7c0b6993336abcffb8444795bf38 upstream. + +The report passed to us from transport driver could potentially be +arbitrarily large, therefore we better sanity-check it so that +magicmouse_emit_touch() gets only valid values of raw_id. + +Reported-by: Steven Vittitoe +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-magicmouse.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -290,6 +290,11 @@ static int magicmouse_raw_event(struct h + if (size < 4 || ((size - 4) % 9) != 0) + return 0; + npoints = (size - 4) / 9; ++ if (npoints > 15) { ++ hid_warn(hdev, "invalid size value (%d) for TRACKPAD_REPORT_ID\n", ++ size); ++ return 0; ++ } + msc->ntouches = 0; + for (ii = 0; ii < npoints; ii++) + magicmouse_emit_touch(msc, ii, data + ii * 9 + 4); +@@ -307,6 +312,11 @@ static int magicmouse_raw_event(struct h + if (size < 6 || ((size - 6) % 8) != 0) + return 0; + npoints = (size - 6) / 8; ++ if (npoints > 15) { ++ hid_warn(hdev, "invalid size value (%d) for MOUSE_REPORT_ID\n", ++ size); ++ return 0; ++ } + msc->ntouches = 0; + for (ii = 0; ii < npoints; ii++) + magicmouse_emit_touch(msc, ii, data + ii * 8 + 6); diff --git a/queue-3.10/hid-picolcd-sanity-check-report-size-in-raw_event-callback.patch b/queue-3.10/hid-picolcd-sanity-check-report-size-in-raw_event-callback.patch new file mode 100644 index 00000000000..8e336d3a8f0 --- /dev/null +++ b/queue-3.10/hid-picolcd-sanity-check-report-size-in-raw_event-callback.patch @@ -0,0 +1,37 @@ +From 844817e47eef14141cf59b8d5ac08dd11c0a9189 Mon Sep 17 00:00:00 2001 +From: Jiri Kosina +Date: Wed, 27 Aug 2014 09:13:15 +0200 +Subject: HID: picolcd: sanity check report size in raw_event() callback + +From: Jiri Kosina + +commit 844817e47eef14141cf59b8d5ac08dd11c0a9189 upstream. + +The report passed to us from transport driver could potentially be +arbitrarily large, therefore we better sanity-check it so that raw_data +that we hold in picolcd_pending structure are always kept within proper +bounds. + +Reported-by: Steven Vittitoe +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-picolcd_core.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/hid/hid-picolcd_core.c ++++ b/drivers/hid/hid-picolcd_core.c +@@ -350,6 +350,12 @@ static int picolcd_raw_event(struct hid_ + if (!data) + return 1; + ++ if (size > 64) { ++ hid_warn(hdev, "invalid size value (%d) for picolcd raw event\n", ++ size); ++ return 0; ++ } ++ + if (report->id == REPORT_KEY_STATE) { + if (data->input_keys) + ret = picolcd_raw_keypad(data, report, raw_data+1, size-1); diff --git a/queue-3.10/series b/queue-3.10/series index fb6761e2734..d5329d375a8 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -16,3 +16,13 @@ ibmveth-fix-endian-issues-with-rx_no_buffer-statistic.patch arm64-flush-tls-registers-during-exec.patch i2c-at91-add-bound-checking-on-smbus-block-length-bytes.patch i2c-at91-fix-a-race-condition-during-signal-handling-in-at91_do_twi_xfer.patch +trace-fix-epoll-hang-when-we-race-with-new-entries.patch +arm64-ptrace-fix-compat-hardware-watchpoint-reporting.patch +alsa-core-fix-buffer-overflow-in-snd_info_get_line.patch +alsa-hda-fix-coef-setups-for-alc1150-codec.patch +alsa-hda-fix-invalid-pin-powermap-without-jack-detection.patch +alsa-pcm-fix-fifo_size-frame-calculation.patch +cfq-iosched-fix-wrong-children_weight-calculation.patch +hid-picolcd-sanity-check-report-size-in-raw_event-callback.patch +hid-magicmouse-sanity-check-report-size-in-raw_event-callback.patch +hid-logitech-dj-prevent-false-errors-to-be-shown.patch diff --git a/queue-3.10/trace-fix-epoll-hang-when-we-race-with-new-entries.patch b/queue-3.10/trace-fix-epoll-hang-when-we-race-with-new-entries.patch new file mode 100644 index 00000000000..8cc90124c0e --- /dev/null +++ b/queue-3.10/trace-fix-epoll-hang-when-we-race-with-new-entries.patch @@ -0,0 +1,56 @@ +From 4ce97dbf50245227add17c83d87dc838e7ca79d0 Mon Sep 17 00:00:00 2001 +From: Josef Bacik +Date: Mon, 25 Aug 2014 13:59:41 -0400 +Subject: trace: Fix epoll hang when we race with new entries + +From: Josef Bacik + +commit 4ce97dbf50245227add17c83d87dc838e7ca79d0 upstream. + +Epoll on trace_pipe can sometimes hang in a weird case. If the ring buffer is +empty when we set waiters_pending but an event shows up exactly at that moment +we can miss being woken up by the ring buffers irq work. Since +ring_buffer_empty() is inherently racey we will sometimes think that the buffer +is not empty. So we don't get woken up and we don't think there are any events +even though there were some ready when we added the watch, which makes us hang. +This patch fixes this by making sure that we are actually on the wait list +before we set waiters_pending, and add a memory barrier to make sure +ring_buffer_empty() is going to be correct. + +Link: http://lkml.kernel.org/p/1408989581-23727-1-git-send-email-jbacik@fb.com + +Cc: Martin Lau +Signed-off-by: Josef Bacik +Signed-off-by: Steven Rostedt +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/ring_buffer.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +--- a/kernel/trace/ring_buffer.c ++++ b/kernel/trace/ring_buffer.c +@@ -626,8 +626,22 @@ int ring_buffer_poll_wait(struct ring_bu + work = &cpu_buffer->irq_work; + } + +- work->waiters_pending = true; + poll_wait(filp, &work->waiters, poll_table); ++ work->waiters_pending = true; ++ /* ++ * There's a tight race between setting the waiters_pending and ++ * checking if the ring buffer is empty. Once the waiters_pending bit ++ * is set, the next event will wake the task up, but we can get stuck ++ * if there's only a single event in. ++ * ++ * FIXME: Ideally, we need a memory barrier on the writer side as well, ++ * but adding a memory barrier to all events will cause too much of a ++ * performance hit in the fast path. We only need a memory barrier when ++ * the buffer goes from empty to having content. But as this race is ++ * extremely small, and it's not a problem if another event comes in, we ++ * will fix it later. ++ */ ++ smp_mb(); + + if ((cpu == RING_BUFFER_ALL_CPUS && !ring_buffer_empty(buffer)) || + (cpu != RING_BUFFER_ALL_CPUS && !ring_buffer_empty_cpu(buffer, cpu)))