From 8be8b0c33175bf48a5fd1a7e863ad48e8329e694 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 18 May 2017 14:22:09 +0200 Subject: [PATCH] 3.18-stable patches added patches: af_unix-guard-against-other-sk-in-unix_dgram_sendmsg.patch alsa-seq-fix-race-at-timer-setup-and-close.patch alsa-timer-fix-leak-in-events-via-snd_timer_user_ccallback.patch alsa-timer-fix-leak-in-events-via-snd_timer_user_tinterrupt.patch alsa-timer-fix-leak-in-sndrv_timer_ioctl_params.patch alsa-timer-fix-race-among-timer-ioctls.patch cdc_ncm-do-not-call-usbnet_link_change-from-cdc_ncm_bind.patch hid-core-prevent-out-of-bound-readings.patch ipv6-sctp-add-rcu-protection-around-np-opt.patch ipv6-sctp-fix-lockdep-splat-in-sctp_v6_get_dst.patch net-ipv6-add-sysctl-option-accept_ra_min_hop_limit.patch ppp-defer-netns-reference-release-for-ppp-channel.patch sched-panic-on-corrupted-stack-end.patch sg-fix-double-free-when-drives-detach-during-sg_io.patch --- ...ainst-other-sk-in-unix_dgram_sendmsg.patch | 52 +++++++ ...eq-fix-race-at-timer-setup-and-close.patch | 39 +++++ ...-events-via-snd_timer_user_ccallback.patch | 35 +++++ ...events-via-snd_timer_user_tinterrupt.patch | 35 +++++ ...fix-leak-in-sndrv_timer_ioctl_params.patch | 35 +++++ ...sa-timer-fix-race-among-timer-ioctls.patch | 123 +++++++++++++++ ...usbnet_link_change-from-cdc_ncm_bind.patch | 86 +++++++++++ ...d-core-prevent-out-of-bound-readings.patch | 49 ++++++ ...ctp-add-rcu-protection-around-np-opt.patch | 68 +++++++++ ...fix-lockdep-splat-in-sctp_v6_get_dst.patch | 44 ++++++ ...ysctl-option-accept_ra_min_hop_limit.patch | 144 ++++++++++++++++++ ...ns-reference-release-for-ppp-channel.patch | 57 +++++++ .../sched-panic-on-corrupted-stack-end.patch | 38 +++++ queue-3.18/series | 14 ++ ...free-when-drives-detach-during-sg_io.patch | 72 +++++++++ 15 files changed, 891 insertions(+) create mode 100644 queue-3.18/af_unix-guard-against-other-sk-in-unix_dgram_sendmsg.patch create mode 100644 queue-3.18/alsa-seq-fix-race-at-timer-setup-and-close.patch create mode 100644 queue-3.18/alsa-timer-fix-leak-in-events-via-snd_timer_user_ccallback.patch create mode 100644 queue-3.18/alsa-timer-fix-leak-in-events-via-snd_timer_user_tinterrupt.patch create mode 100644 queue-3.18/alsa-timer-fix-leak-in-sndrv_timer_ioctl_params.patch create mode 100644 queue-3.18/alsa-timer-fix-race-among-timer-ioctls.patch create mode 100644 queue-3.18/cdc_ncm-do-not-call-usbnet_link_change-from-cdc_ncm_bind.patch create mode 100644 queue-3.18/hid-core-prevent-out-of-bound-readings.patch create mode 100644 queue-3.18/ipv6-sctp-add-rcu-protection-around-np-opt.patch create mode 100644 queue-3.18/ipv6-sctp-fix-lockdep-splat-in-sctp_v6_get_dst.patch create mode 100644 queue-3.18/net-ipv6-add-sysctl-option-accept_ra_min_hop_limit.patch create mode 100644 queue-3.18/ppp-defer-netns-reference-release-for-ppp-channel.patch create mode 100644 queue-3.18/sched-panic-on-corrupted-stack-end.patch create mode 100644 queue-3.18/sg-fix-double-free-when-drives-detach-during-sg_io.patch diff --git a/queue-3.18/af_unix-guard-against-other-sk-in-unix_dgram_sendmsg.patch b/queue-3.18/af_unix-guard-against-other-sk-in-unix_dgram_sendmsg.patch new file mode 100644 index 00000000000..f528ed918f1 --- /dev/null +++ b/queue-3.18/af_unix-guard-against-other-sk-in-unix_dgram_sendmsg.patch @@ -0,0 +1,52 @@ +From a5527dda344fff0514b7989ef7a755729769daa1 Mon Sep 17 00:00:00 2001 +From: Rainer Weikusat +Date: Thu, 11 Feb 2016 19:37:27 +0000 +Subject: af_unix: Guard against other == sk in unix_dgram_sendmsg + +From: Rainer Weikusat + +commit a5527dda344fff0514b7989ef7a755729769daa1 upstream. + +The unix_dgram_sendmsg routine use the following test + +if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) { + +to determine if sk and other are in an n:1 association (either +established via connect or by using sendto to send messages to an +unrelated socket identified by address). This isn't correct as the +specified address could have been bound to the sending socket itself or +because this socket could have been connected to itself by the time of +the unix_peer_get but disconnected before the unix_state_lock(other). In +both cases, the if-block would be entered despite other == sk which +might either block the sender unintentionally or lead to trying to unlock +the same spin lock twice for a non-blocking send. Add a other != sk +check to guard against this. + +Fixes: 7d267278a9ec ("unix: avoid use-after-free in ep_remove_wait_queue") +Reported-By: Philipp Hahn +Signed-off-by: Rainer Weikusat +Tested-by: Philipp Hahn +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + net/unix/af_unix.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -1722,7 +1722,12 @@ restart_locked: + goto out_unlock; + } + +- if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) { ++ /* other == sk && unix_peer(other) != sk if ++ * - unix_peer(sk) == NULL, destination address bound to sk ++ * - unix_peer(sk) == sk by time of get but disconnected before lock ++ */ ++ if (other != sk && ++ unlikely(unix_peer(other) != sk && unix_recvq_full(other))) { + if (timeo) { + timeo = unix_wait_for_peer(other, timeo); + diff --git a/queue-3.18/alsa-seq-fix-race-at-timer-setup-and-close.patch b/queue-3.18/alsa-seq-fix-race-at-timer-setup-and-close.patch new file mode 100644 index 00000000000..7d8012f2802 --- /dev/null +++ b/queue-3.18/alsa-seq-fix-race-at-timer-setup-and-close.patch @@ -0,0 +1,39 @@ +From 3567eb6af614dac436c4b16a8d426f9faed639b3 Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Tue, 12 Jan 2016 15:36:27 +0100 +Subject: ALSA: seq: Fix race at timer setup and close + +From: Takashi Iwai + +commit 3567eb6af614dac436c4b16a8d426f9faed639b3 upstream. + +ALSA sequencer code has an open race between the timer setup ioctl and +the close of the client. This was triggered by syzkaller fuzzer, and +a use-after-free was caught there as a result. + +This patch papers over it by adding a proper queue->timer_mutex lock +around the timer-related calls in the relevant code path. + +Reported-by: Dmitry Vyukov +Tested-by: Dmitry Vyukov +Signed-off-by: Takashi Iwai +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/seq/seq_queue.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/sound/core/seq/seq_queue.c ++++ b/sound/core/seq/seq_queue.c +@@ -142,8 +142,10 @@ static struct snd_seq_queue *queue_new(i + static void queue_delete(struct snd_seq_queue *q) + { + /* stop and release the timer */ ++ mutex_lock(&q->timer_mutex); + snd_seq_timer_stop(q->timer); + snd_seq_timer_close(q); ++ mutex_unlock(&q->timer_mutex); + /* wait until access free */ + snd_use_lock_sync(&q->use_lock); + /* release resources... */ diff --git a/queue-3.18/alsa-timer-fix-leak-in-events-via-snd_timer_user_ccallback.patch b/queue-3.18/alsa-timer-fix-leak-in-events-via-snd_timer_user_ccallback.patch new file mode 100644 index 00000000000..122dc853bc3 --- /dev/null +++ b/queue-3.18/alsa-timer-fix-leak-in-events-via-snd_timer_user_ccallback.patch @@ -0,0 +1,35 @@ +From 9a47e9cff994f37f7f0dbd9ae23740d0f64f9fe6 Mon Sep 17 00:00:00 2001 +From: Kangjie Lu +Date: Tue, 3 May 2016 16:44:20 -0400 +Subject: ALSA: timer: Fix leak in events via snd_timer_user_ccallback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kangjie Lu + +commit 9a47e9cff994f37f7f0dbd9ae23740d0f64f9fe6 upstream. + +The stack object “r1” has a total size of 32 bytes. Its field +“event” and “val” both contain 4 bytes padding. These 8 bytes +padding bytes are sent to user without being initialized. + +Signed-off-by: Kangjie Lu +Signed-off-by: Takashi Iwai +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/timer.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -1260,6 +1260,7 @@ static void snd_timer_user_ccallback(str + tu->tstamp = *tstamp; + if ((tu->filter & (1 << event)) == 0 || !tu->tread) + return; ++ memset(&r1, 0, sizeof(r1)); + r1.event = event; + r1.tstamp = *tstamp; + r1.val = resolution; diff --git a/queue-3.18/alsa-timer-fix-leak-in-events-via-snd_timer_user_tinterrupt.patch b/queue-3.18/alsa-timer-fix-leak-in-events-via-snd_timer_user_tinterrupt.patch new file mode 100644 index 00000000000..9ea6cb6c130 --- /dev/null +++ b/queue-3.18/alsa-timer-fix-leak-in-events-via-snd_timer_user_tinterrupt.patch @@ -0,0 +1,35 @@ +From e4ec8cc8039a7063e24204299b462bd1383184a5 Mon Sep 17 00:00:00 2001 +From: Kangjie Lu +Date: Tue, 3 May 2016 16:44:32 -0400 +Subject: ALSA: timer: Fix leak in events via snd_timer_user_tinterrupt +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kangjie Lu + +commit e4ec8cc8039a7063e24204299b462bd1383184a5 upstream. + +The stack object “r1” has a total size of 32 bytes. Its field +“event” and “val” both contain 4 bytes padding. These 8 bytes +padding bytes are sent to user without being initialized. + +Signed-off-by: Kangjie Lu +Signed-off-by: Takashi Iwai +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/timer.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -1295,6 +1295,7 @@ static void snd_timer_user_tinterrupt(st + } + if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) && + tu->last_resolution != resolution) { ++ memset(&r1, 0, sizeof(r1)); + r1.event = SNDRV_TIMER_EVENT_RESOLUTION; + r1.tstamp = tstamp; + r1.val = resolution; diff --git a/queue-3.18/alsa-timer-fix-leak-in-sndrv_timer_ioctl_params.patch b/queue-3.18/alsa-timer-fix-leak-in-sndrv_timer_ioctl_params.patch new file mode 100644 index 00000000000..ceb1feeddc1 --- /dev/null +++ b/queue-3.18/alsa-timer-fix-leak-in-sndrv_timer_ioctl_params.patch @@ -0,0 +1,35 @@ +From cec8f96e49d9be372fdb0c3836dcf31ec71e457e Mon Sep 17 00:00:00 2001 +From: Kangjie Lu +Date: Tue, 3 May 2016 16:44:07 -0400 +Subject: ALSA: timer: Fix leak in SNDRV_TIMER_IOCTL_PARAMS +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Kangjie Lu + +commit cec8f96e49d9be372fdb0c3836dcf31ec71e457e upstream. + +The stack object “tread” has a total size of 32 bytes. Its field +“event” and “val” both contain 4 bytes padding. These 8 bytes +padding bytes are sent to user without being initialized. + +Signed-off-by: Kangjie Lu +Signed-off-by: Takashi Iwai +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/timer.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -1759,6 +1759,7 @@ static int snd_timer_user_params(struct + if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) { + if (tu->tread) { + struct snd_timer_tread tread; ++ memset(&tread, 0, sizeof(tread)); + tread.event = SNDRV_TIMER_EVENT_EARLY; + tread.tstamp.tv_sec = 0; + tread.tstamp.tv_nsec = 0; diff --git a/queue-3.18/alsa-timer-fix-race-among-timer-ioctls.patch b/queue-3.18/alsa-timer-fix-race-among-timer-ioctls.patch new file mode 100644 index 00000000000..4338145236c --- /dev/null +++ b/queue-3.18/alsa-timer-fix-race-among-timer-ioctls.patch @@ -0,0 +1,123 @@ +From af368027a49a751d6ff4ee9e3f9961f35bb4fede Mon Sep 17 00:00:00 2001 +From: Takashi Iwai +Date: Wed, 13 Jan 2016 17:48:01 +0100 +Subject: ALSA: timer: Fix race among timer ioctls + +From: Takashi Iwai + +commit af368027a49a751d6ff4ee9e3f9961f35bb4fede upstream. + +ALSA timer ioctls have an open race and this may lead to a +use-after-free of timer instance object. A simplistic fix is to make +each ioctl exclusive. We have already tread_sem for controlling the +tread, and extend this as a global mutex to be applied to each ioctl. + +The downside is, of course, the worse concurrency. But these ioctls +aren't to be parallel accessible, in anyway, so it should be fine to +serialize there. + +Reported-by: Dmitry Vyukov +Tested-by: Dmitry Vyukov +Signed-off-by: Takashi Iwai +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + sound/core/timer.c | 32 +++++++++++++++++++------------- + 1 file changed, 19 insertions(+), 13 deletions(-) + +--- a/sound/core/timer.c ++++ b/sound/core/timer.c +@@ -77,7 +77,7 @@ struct snd_timer_user { + struct timespec tstamp; /* trigger tstamp */ + wait_queue_head_t qchange_sleep; + struct fasync_struct *fasync; +- struct mutex tread_sem; ++ struct mutex ioctl_lock; + }; + + /* list of timers */ +@@ -1342,7 +1342,7 @@ static int snd_timer_user_open(struct in + return -ENOMEM; + spin_lock_init(&tu->qlock); + init_waitqueue_head(&tu->qchange_sleep); +- mutex_init(&tu->tread_sem); ++ mutex_init(&tu->ioctl_lock); + tu->ticks = 1; + tu->queue_size = 128; + tu->queue = kmalloc(tu->queue_size * sizeof(struct snd_timer_read), +@@ -1362,8 +1362,10 @@ static int snd_timer_user_release(struct + if (file->private_data) { + tu = file->private_data; + file->private_data = NULL; ++ mutex_lock(&tu->ioctl_lock); + if (tu->timeri) + snd_timer_close(tu->timeri); ++ mutex_unlock(&tu->ioctl_lock); + kfree(tu->queue); + kfree(tu->tqueue); + kfree(tu); +@@ -1601,7 +1603,6 @@ static int snd_timer_user_tselect(struct + int err = 0; + + tu = file->private_data; +- mutex_lock(&tu->tread_sem); + if (tu->timeri) { + snd_timer_close(tu->timeri); + tu->timeri = NULL; +@@ -1645,7 +1646,6 @@ static int snd_timer_user_tselect(struct + } + + __err: +- mutex_unlock(&tu->tread_sem); + return err; + } + +@@ -1861,7 +1861,7 @@ enum { + SNDRV_TIMER_IOCTL_PAUSE_OLD = _IO('T', 0x23), + }; + +-static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, ++static long __snd_timer_user_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) + { + struct snd_timer_user *tu; +@@ -1878,17 +1878,11 @@ static long snd_timer_user_ioctl(struct + { + int xarg; + +- mutex_lock(&tu->tread_sem); +- if (tu->timeri) { /* too late */ +- mutex_unlock(&tu->tread_sem); ++ if (tu->timeri) /* too late */ + return -EBUSY; +- } +- if (get_user(xarg, p)) { +- mutex_unlock(&tu->tread_sem); ++ if (get_user(xarg, p)) + return -EFAULT; +- } + tu->tread = xarg ? 1 : 0; +- mutex_unlock(&tu->tread_sem); + return 0; + } + case SNDRV_TIMER_IOCTL_GINFO: +@@ -1921,6 +1915,18 @@ static long snd_timer_user_ioctl(struct + return -ENOTTY; + } + ++static long snd_timer_user_ioctl(struct file *file, unsigned int cmd, ++ unsigned long arg) ++{ ++ struct snd_timer_user *tu = file->private_data; ++ long ret; ++ ++ mutex_lock(&tu->ioctl_lock); ++ ret = __snd_timer_user_ioctl(file, cmd, arg); ++ mutex_unlock(&tu->ioctl_lock); ++ return ret; ++} ++ + static int snd_timer_user_fasync(int fd, struct file * file, int on) + { + struct snd_timer_user *tu; diff --git a/queue-3.18/cdc_ncm-do-not-call-usbnet_link_change-from-cdc_ncm_bind.patch b/queue-3.18/cdc_ncm-do-not-call-usbnet_link_change-from-cdc_ncm_bind.patch new file mode 100644 index 00000000000..6ec7945be0f --- /dev/null +++ b/queue-3.18/cdc_ncm-do-not-call-usbnet_link_change-from-cdc_ncm_bind.patch @@ -0,0 +1,86 @@ +From 4d06dd537f95683aba3651098ae288b7cbff8274 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= +Date: Mon, 7 Mar 2016 21:15:36 +0100 +Subject: cdc_ncm: do not call usbnet_link_change from cdc_ncm_bind +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Bjørn Mork + +commit 4d06dd537f95683aba3651098ae288b7cbff8274 upstream. + +usbnet_link_change will call schedule_work and should be +avoided if bind is failing. Otherwise we will end up with +scheduled work referring to a netdev which has gone away. + +Instead of making the call conditional, we can just defer +it to usbnet_probe, using the driver_info flag made for +this purpose. + +Fixes: 8a34b0ae8778 ("usbnet: cdc_ncm: apply usbnet_link_change") +Reported-by: Andrey Konovalov +Suggested-by: Linus Torvalds +Signed-off-by: Bjørn Mork +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/cdc_ncm.c | 20 +++++--------------- + 1 file changed, 5 insertions(+), 15 deletions(-) + +--- a/drivers/net/usb/cdc_ncm.c ++++ b/drivers/net/usb/cdc_ncm.c +@@ -952,23 +952,12 @@ EXPORT_SYMBOL_GPL(cdc_ncm_select_altsett + + static int cdc_ncm_bind(struct usbnet *dev, struct usb_interface *intf) + { +- int ret; +- + /* MBIM backwards compatible function? */ + if (cdc_ncm_select_altsetting(intf) != CDC_NCM_COMM_ALTSETTING_NCM) + return -ENODEV; + + /* The NCM data altsetting is fixed */ +- ret = cdc_ncm_bind_common(dev, intf, CDC_NCM_DATA_ALTSETTING_NCM); +- +- /* +- * We should get an event when network connection is "connected" or +- * "disconnected". Set network connection in "disconnected" state +- * (carrier is OFF) during attach, so the IP network stack does not +- * start IPv6 negotiation and more. +- */ +- usbnet_link_change(dev, 0, 0); +- return ret; ++ return cdc_ncm_bind_common(dev, intf, CDC_NCM_DATA_ALTSETTING_NCM); + } + + static void cdc_ncm_align_tail(struct sk_buff *skb, size_t modulus, size_t remainder, size_t max) +@@ -1510,7 +1499,8 @@ static void cdc_ncm_status(struct usbnet + + static const struct driver_info cdc_ncm_info = { + .description = "CDC NCM", +- .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET, ++ .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET ++ | FLAG_LINK_INTR, + .bind = cdc_ncm_bind, + .unbind = cdc_ncm_unbind, + .manage_power = usbnet_manage_power, +@@ -1523,7 +1513,7 @@ static const struct driver_info cdc_ncm_ + static const struct driver_info wwan_info = { + .description = "Mobile Broadband Network Device", + .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET +- | FLAG_WWAN, ++ | FLAG_LINK_INTR | FLAG_WWAN, + .bind = cdc_ncm_bind, + .unbind = cdc_ncm_unbind, + .manage_power = usbnet_manage_power, +@@ -1536,7 +1526,7 @@ static const struct driver_info wwan_inf + static const struct driver_info wwan_noarp_info = { + .description = "Mobile Broadband Network Device (NO ARP)", + .flags = FLAG_POINTTOPOINT | FLAG_NO_SETINT | FLAG_MULTI_PACKET +- | FLAG_WWAN | FLAG_NOARP, ++ | FLAG_LINK_INTR | FLAG_WWAN | FLAG_NOARP, + .bind = cdc_ncm_bind, + .unbind = cdc_ncm_unbind, + .manage_power = usbnet_manage_power, diff --git a/queue-3.18/hid-core-prevent-out-of-bound-readings.patch b/queue-3.18/hid-core-prevent-out-of-bound-readings.patch new file mode 100644 index 00000000000..de92f33740c --- /dev/null +++ b/queue-3.18/hid-core-prevent-out-of-bound-readings.patch @@ -0,0 +1,49 @@ +From 50220dead1650609206efe91f0cc116132d59b3f Mon Sep 17 00:00:00 2001 +From: Benjamin Tissoires +Date: Tue, 19 Jan 2016 12:34:58 +0100 +Subject: HID: core: prevent out-of-bound readings + +From: Benjamin Tissoires + +commit 50220dead1650609206efe91f0cc116132d59b3f upstream. + +Plugging a Logitech DJ receiver with KASAN activated raises a bunch of +out-of-bound readings. + +The fields are allocated up to MAX_USAGE, meaning that potentially, we do +not have enough fields to fit the incoming values. +Add checks and silence KASAN. + +Signed-off-by: Benjamin Tissoires +Signed-off-by: Jiri Kosina +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/hid/hid-core.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/hid/hid-core.c ++++ b/drivers/hid/hid-core.c +@@ -1213,6 +1213,7 @@ static void hid_input_field(struct hid_d + /* Ignore report if ErrorRollOver */ + if (!(field->flags & HID_MAIN_ITEM_VARIABLE) && + value[n] >= min && value[n] <= max && ++ value[n] - min < field->maxusage && + field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) + goto exit; + } +@@ -1225,11 +1226,13 @@ static void hid_input_field(struct hid_d + } + + if (field->value[n] >= min && field->value[n] <= max ++ && field->value[n] - min < field->maxusage + && field->usage[field->value[n] - min].hid + && search(value, field->value[n], count)) + hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt); + + if (value[n] >= min && value[n] <= max ++ && value[n] - min < field->maxusage + && field->usage[value[n] - min].hid + && search(field->value, value[n], count)) + hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt); diff --git a/queue-3.18/ipv6-sctp-add-rcu-protection-around-np-opt.patch b/queue-3.18/ipv6-sctp-add-rcu-protection-around-np-opt.patch new file mode 100644 index 00000000000..e1312aa0026 --- /dev/null +++ b/queue-3.18/ipv6-sctp-add-rcu-protection-around-np-opt.patch @@ -0,0 +1,68 @@ +From c836a8ba93869d6a0290a6ae0047fbef09066871 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 2 Dec 2015 21:48:14 -0800 +Subject: ipv6: sctp: add rcu protection around np->opt + +From: Eric Dumazet + +commit c836a8ba93869d6a0290a6ae0047fbef09066871 upstream. + +This patch completes the work I did in commit 45f6fad84cc3 +("ipv6: add complete rcu protection around np->opt"), as I missed +sctp part. + +This simply makes sure np->opt is used with proper RCU locking +and accessors. + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + net/sctp/ipv6.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -209,6 +209,7 @@ static int sctp_v6_xmit(struct sk_buff * + struct sock *sk = skb->sk; + struct ipv6_pinfo *np = inet6_sk(sk); + struct flowi6 *fl6 = &transport->fl.u.ip6; ++ int res; + + pr_debug("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", __func__, skb, + skb->len, &fl6->saddr, &fl6->daddr); +@@ -220,7 +221,10 @@ static int sctp_v6_xmit(struct sk_buff * + + SCTP_INC_STATS(sock_net(sk), SCTP_MIB_OUTSCTPPACKS); + +- return ip6_xmit(sk, skb, fl6, np->opt, np->tclass); ++ rcu_read_lock(); ++ res = ip6_xmit(sk, skb, fl6, rcu_dereference(np->opt), np->tclass); ++ rcu_read_unlock(); ++ return res; + } + + /* Returns the dst cache entry for the given source and destination ip +@@ -262,7 +266,10 @@ static void sctp_v6_get_dst(struct sctp_ + pr_debug("src=%pI6 - ", &fl6->saddr); + } + +- final_p = fl6_update_dst(fl6, np->opt, &final); ++ rcu_read_lock(); ++ final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); ++ rcu_read_unlock(); ++ + dst = ip6_dst_lookup_flow(sk, fl6, final_p); + if (!asoc || saddr) + goto out; +@@ -321,7 +328,7 @@ static void sctp_v6_get_dst(struct sctp_ + if (baddr) { + fl6->saddr = baddr->v6.sin6_addr; + fl6->fl6_sport = baddr->v6.sin6_port; +- final_p = fl6_update_dst(fl6, np->opt, &final); ++ final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); + dst = ip6_dst_lookup_flow(sk, fl6, final_p); + } + diff --git a/queue-3.18/ipv6-sctp-fix-lockdep-splat-in-sctp_v6_get_dst.patch b/queue-3.18/ipv6-sctp-fix-lockdep-splat-in-sctp_v6_get_dst.patch new file mode 100644 index 00000000000..095082dbbed --- /dev/null +++ b/queue-3.18/ipv6-sctp-fix-lockdep-splat-in-sctp_v6_get_dst.patch @@ -0,0 +1,44 @@ +From 69ce6487dcd364245a3d26322fc8f4ffd1e8d947 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 7 Dec 2015 08:25:21 -0800 +Subject: ipv6: sctp: fix lockdep splat in sctp_v6_get_dst() + +From: Eric Dumazet + +commit 69ce6487dcd364245a3d26322fc8f4ffd1e8d947 upstream. + +While cooking the sctp np->opt rcu fixes, I forgot to move +one rcu_read_unlock() after the added rcu_dereference() in +sctp_v6_get_dst() + +This gave lockdep warnings reported by Dave Jones. + +Fixes: c836a8ba9386 ("ipv6: sctp: add rcu protection around np->opt") +Reported-by: Dave Jones +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + net/sctp/ipv6.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -323,14 +323,13 @@ static void sctp_v6_get_dst(struct sctp_ + } + } + } +- rcu_read_unlock(); +- + if (baddr) { + fl6->saddr = baddr->v6.sin6_addr; + fl6->fl6_sport = baddr->v6.sin6_port; + final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final); + dst = ip6_dst_lookup_flow(sk, fl6, final_p); + } ++ rcu_read_unlock(); + + out: + if (!IS_ERR_OR_NULL(dst)) { diff --git a/queue-3.18/net-ipv6-add-sysctl-option-accept_ra_min_hop_limit.patch b/queue-3.18/net-ipv6-add-sysctl-option-accept_ra_min_hop_limit.patch new file mode 100644 index 00000000000..b3108cfd53d --- /dev/null +++ b/queue-3.18/net-ipv6-add-sysctl-option-accept_ra_min_hop_limit.patch @@ -0,0 +1,144 @@ +From 8013d1d7eafb0589ca766db6b74026f76b7f5cb4 Mon Sep 17 00:00:00 2001 +From: Hangbin Liu +Date: Thu, 30 Jul 2015 14:28:42 +0800 +Subject: net/ipv6: add sysctl option accept_ra_min_hop_limit + +From: Hangbin Liu + +commit 8013d1d7eafb0589ca766db6b74026f76b7f5cb4 upstream. + +Commit 6fd99094de2b ("ipv6: Don't reduce hop limit for an interface") +disabled accept hop limit from RA if it is smaller than the current hop +limit for security stuff. But this behavior kind of break the RFC definition. + +RFC 4861, 6.3.4. Processing Received Router Advertisements + A Router Advertisement field (e.g., Cur Hop Limit, Reachable Time, + and Retrans Timer) may contain a value denoting that it is + unspecified. In such cases, the parameter should be ignored and the + host should continue using whatever value it is already using. + + If the received Cur Hop Limit value is non-zero, the host SHOULD set + its CurHopLimit variable to the received value. + +So add sysctl option accept_ra_min_hop_limit to let user choose the minimum +hop limit value they can accept from RA. And set default to 1 to meet RFC +standards. + +Signed-off-by: Hangbin Liu +Acked-by: YOSHIFUJI Hideaki +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/networking/ip-sysctl.txt | 8 ++++++++ + include/linux/ipv6.h | 1 + + include/uapi/linux/ipv6.h | 1 + + net/ipv6/addrconf.c | 10 ++++++++++ + net/ipv6/ndisc.c | 16 +++++++--------- + 5 files changed, 27 insertions(+), 9 deletions(-) + +--- a/Documentation/networking/ip-sysctl.txt ++++ b/Documentation/networking/ip-sysctl.txt +@@ -1256,6 +1256,14 @@ accept_ra_from_local - BOOLEAN + disabled if accept_ra_from_local is disabled + on a specific interface. + ++accept_ra_min_hop_limit - INTEGER ++ Minimum hop limit Information in Router Advertisement. ++ ++ Hop limit Information in Router Advertisement less than this ++ variable shall be ignored. ++ ++ Default: 1 ++ + accept_ra_pinfo - BOOLEAN + Learn Prefix Information in Router Advertisement. + +--- a/include/linux/ipv6.h ++++ b/include/linux/ipv6.h +@@ -29,6 +29,7 @@ struct ipv6_devconf { + __s32 max_desync_factor; + __s32 max_addresses; + __s32 accept_ra_defrtr; ++ __s32 accept_ra_min_hop_limit; + __s32 accept_ra_pinfo; + #ifdef CONFIG_IPV6_ROUTER_PREF + __s32 accept_ra_rtr_pref; +--- a/include/uapi/linux/ipv6.h ++++ b/include/uapi/linux/ipv6.h +@@ -164,6 +164,7 @@ enum { + DEVCONF_MLDV2_UNSOLICITED_REPORT_INTERVAL, + DEVCONF_SUPPRESS_FRAG_NDISC, + DEVCONF_ACCEPT_RA_FROM_LOCAL, ++ DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT, + DEVCONF_MAX + }; + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -188,6 +188,7 @@ static struct ipv6_devconf ipv6_devconf + .max_addresses = IPV6_MAX_ADDRESSES, + .accept_ra_defrtr = 1, + .accept_ra_from_local = 0, ++ .accept_ra_min_hop_limit= 1, + .accept_ra_pinfo = 1, + #ifdef CONFIG_IPV6_ROUTER_PREF + .accept_ra_rtr_pref = 1, +@@ -225,6 +226,7 @@ static struct ipv6_devconf ipv6_devconf_ + .max_addresses = IPV6_MAX_ADDRESSES, + .accept_ra_defrtr = 1, + .accept_ra_from_local = 0, ++ .accept_ra_min_hop_limit= 1, + .accept_ra_pinfo = 1, + #ifdef CONFIG_IPV6_ROUTER_PREF + .accept_ra_rtr_pref = 1, +@@ -4321,6 +4323,7 @@ static inline void ipv6_store_devconf(st + array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor; + array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses; + array[DEVCONF_ACCEPT_RA_DEFRTR] = cnf->accept_ra_defrtr; ++ array[DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT] = cnf->accept_ra_min_hop_limit; + array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo; + #ifdef CONFIG_IPV6_ROUTER_PREF + array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref; +@@ -5135,6 +5138,13 @@ static struct addrconf_sysctl_table + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec, ++ }, ++ { ++ .procname = "accept_ra_min_hop_limit", ++ .data = &ipv6_devconf.accept_ra_min_hop_limit, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec, + }, + { + .procname = "accept_ra_pinfo", +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -1214,18 +1214,16 @@ static void ndisc_router_discovery(struc + + if (rt) + rt6_set_expires(rt, jiffies + (HZ * lifetime)); +- if (ra_msg->icmph.icmp6_hop_limit) { +- /* Only set hop_limit on the interface if it is higher than +- * the current hop_limit. +- */ +- if (in6_dev->cnf.hop_limit < ra_msg->icmph.icmp6_hop_limit) { ++ if (in6_dev->cnf.accept_ra_min_hop_limit < 256 && ++ ra_msg->icmph.icmp6_hop_limit) { ++ if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) { + in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit; ++ if (rt) ++ dst_metric_set(&rt->dst, RTAX_HOPLIMIT, ++ ra_msg->icmph.icmp6_hop_limit); + } else { +- ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than current\n"); ++ ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than minimum\n"); + } +- if (rt) +- dst_metric_set(&rt->dst, RTAX_HOPLIMIT, +- ra_msg->icmph.icmp6_hop_limit); + } + + skip_defrtr: diff --git a/queue-3.18/ppp-defer-netns-reference-release-for-ppp-channel.patch b/queue-3.18/ppp-defer-netns-reference-release-for-ppp-channel.patch new file mode 100644 index 00000000000..2f503ac338c --- /dev/null +++ b/queue-3.18/ppp-defer-netns-reference-release-for-ppp-channel.patch @@ -0,0 +1,57 @@ +From 205e1e255c479f3fd77446415706463b282f94e4 Mon Sep 17 00:00:00 2001 +From: WANG Cong +Date: Tue, 5 Jul 2016 22:12:36 -0700 +Subject: ppp: defer netns reference release for ppp channel + +From: WANG Cong + +commit 205e1e255c479f3fd77446415706463b282f94e4 upstream. + +Matt reported that we have a NULL pointer dereference +in ppp_pernet() from ppp_connect_channel(), +i.e. pch->chan_net is NULL. + +This is due to that a parallel ppp_unregister_channel() +could happen while we are in ppp_connect_channel(), during +which pch->chan_net set to NULL. Since we need a reference +to net per channel, it makes sense to sync the refcnt +with the life time of the channel, therefore we should +release this reference when we destroy it. + +Fixes: 1f461dcdd296 ("ppp: take reference on channels netns") +Reported-by: Matt Bennett +Cc: Paul Mackerras +Cc: linux-ppp@vger.kernel.org +Cc: Guillaume Nault +Cc: Cyrill Gorcunov +Signed-off-by: Cong Wang +Reviewed-by: Cyrill Gorcunov +Signed-off-by: David S. Miller +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/net/ppp/ppp_generic.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/net/ppp/ppp_generic.c ++++ b/drivers/net/ppp/ppp_generic.c +@@ -2342,8 +2342,6 @@ ppp_unregister_channel(struct ppp_channe + spin_lock_bh(&pn->all_channels_lock); + list_del(&pch->list); + spin_unlock_bh(&pn->all_channels_lock); +- put_net(pch->chan_net); +- pch->chan_net = NULL; + + pch->file.dead = 1; + wake_up_interruptible(&pch->file.rwait); +@@ -2960,6 +2958,9 @@ ppp_disconnect_channel(struct channel *p + */ + static void ppp_destroy_channel(struct channel *pch) + { ++ put_net(pch->chan_net); ++ pch->chan_net = NULL; ++ + atomic_dec(&channel_count); + + if (!pch->file.dead) { diff --git a/queue-3.18/sched-panic-on-corrupted-stack-end.patch b/queue-3.18/sched-panic-on-corrupted-stack-end.patch new file mode 100644 index 00000000000..b522f04a77b --- /dev/null +++ b/queue-3.18/sched-panic-on-corrupted-stack-end.patch @@ -0,0 +1,38 @@ +From 29d6455178a09e1dc340380c582b13356227e8df Mon Sep 17 00:00:00 2001 +From: Jann Horn +Date: Wed, 1 Jun 2016 11:55:07 +0200 +Subject: sched: panic on corrupted stack end + +From: Jann Horn + +commit 29d6455178a09e1dc340380c582b13356227e8df upstream. + +Until now, hitting this BUG_ON caused a recursive oops (because oops +handling involves do_exit(), which calls into the scheduler, which in +turn raises an oops), which caused stuff below the stack to be +overwritten until a panic happened (e.g. via an oops in interrupt +context, caused by the overwritten CPU index in the thread_info). + +Just panic directly. + +Signed-off-by: Jann Horn +Signed-off-by: Linus Torvalds +[AmitP: Minor refactoring of upstream changes for linux-3.18.y] +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman +--- + kernel/sched/core.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -2709,7 +2709,8 @@ static noinline void __schedule_bug(stru + static inline void schedule_debug(struct task_struct *prev) + { + #ifdef CONFIG_SCHED_STACK_END_CHECK +- BUG_ON(unlikely(task_stack_end_corrupted(prev))); ++ if (task_stack_end_corrupted(prev)) ++ panic("corrupted stack end detected inside scheduler\n"); + #endif + /* + * Test if we are atomic. Since do_exit() needs to call into diff --git a/queue-3.18/series b/queue-3.18/series index 399b28357b7..1092049fbbd 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -34,3 +34,17 @@ perf-fix-race-in-swevent-hash.patch asn.1-fix-non-match-detection-failure-on-data-overrun.patch keys-fix-asn.1-indefinite-length-object-parsing.patch ext4-fix-potential-use-after-free-in-__ext4_journal_stop.patch +sg-fix-double-free-when-drives-detach-during-sg_io.patch +net-ipv6-add-sysctl-option-accept_ra_min_hop_limit.patch +ipv6-sctp-add-rcu-protection-around-np-opt.patch +ipv6-sctp-fix-lockdep-splat-in-sctp_v6_get_dst.patch +af_unix-guard-against-other-sk-in-unix_dgram_sendmsg.patch +ppp-defer-netns-reference-release-for-ppp-channel.patch +hid-core-prevent-out-of-bound-readings.patch +cdc_ncm-do-not-call-usbnet_link_change-from-cdc_ncm_bind.patch +sched-panic-on-corrupted-stack-end.patch +alsa-seq-fix-race-at-timer-setup-and-close.patch +alsa-timer-fix-race-among-timer-ioctls.patch +alsa-timer-fix-leak-in-sndrv_timer_ioctl_params.patch +alsa-timer-fix-leak-in-events-via-snd_timer_user_ccallback.patch +alsa-timer-fix-leak-in-events-via-snd_timer_user_tinterrupt.patch diff --git a/queue-3.18/sg-fix-double-free-when-drives-detach-during-sg_io.patch b/queue-3.18/sg-fix-double-free-when-drives-detach-during-sg_io.patch new file mode 100644 index 00000000000..499ece82fd4 --- /dev/null +++ b/queue-3.18/sg-fix-double-free-when-drives-detach-during-sg_io.patch @@ -0,0 +1,72 @@ +From f3951a3709ff50990bf3e188c27d346792103432 Mon Sep 17 00:00:00 2001 +From: Calvin Owens +Date: Fri, 30 Oct 2015 16:57:00 -0700 +Subject: sg: Fix double-free when drives detach during SG_IO + +From: Calvin Owens + +commit f3951a3709ff50990bf3e188c27d346792103432 upstream. + +In sg_common_write(), we free the block request and return -ENODEV if +the device is detached in the middle of the SG_IO ioctl(). + +Unfortunately, sg_finish_rem_req() also tries to free srp->rq, so we +end up freeing rq->cmd in the already free rq object, and then free +the object itself out from under the current user. + +This ends up corrupting random memory via the list_head on the rq +object. The most common crash trace I saw is this: + + ------------[ cut here ]------------ + kernel BUG at block/blk-core.c:1420! + Call Trace: + [] blk_put_request+0x5b/0x80 + [] sg_finish_rem_req+0x6b/0x120 [sg] + [] sg_common_write.isra.14+0x459/0x5a0 [sg] + [] ? selinux_file_alloc_security+0x48/0x70 + [] sg_new_write.isra.17+0x195/0x2d0 [sg] + [] sg_ioctl+0x644/0xdb0 [sg] + [] do_vfs_ioctl+0x90/0x520 + [] ? file_has_perm+0x97/0xb0 + [] SyS_ioctl+0x91/0xb0 + [] tracesys+0xdd/0xe2 + RIP [] __blk_put_request+0x154/0x1a0 + +The solution is straightforward: just set srp->rq to NULL in the +failure branch so that sg_finish_rem_req() doesn't attempt to re-free +it. + +Additionally, since sg_rq_end_io() will never be called on the object +when this happens, we need to free memory backing ->cmd if it isn't +embedded in the object itself. + +KASAN was extremely helpful in finding the root cause of this bug. + +Signed-off-by: Calvin Owens +Acked-by: Douglas Gilbert +Signed-off-by: Martin K. Petersen +Signed-off-by: Amit Pundir +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/scsi/sg.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -791,8 +791,14 @@ sg_common_write(Sg_fd * sfp, Sg_request + return k; /* probably out of space --> ENOMEM */ + } + if (atomic_read(&sdp->detaching)) { +- if (srp->bio) ++ if (srp->bio) { ++ if (srp->rq->cmd != srp->rq->__cmd) ++ kfree(srp->rq->cmd); ++ + blk_end_request_all(srp->rq, -EIO); ++ srp->rq = NULL; ++ } ++ + sg_finish_rem_req(srp); + return -ENODEV; + } -- 2.47.3