--- /dev/null
+From a5527dda344fff0514b7989ef7a755729769daa1 Mon Sep 17 00:00:00 2001
+From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
+Date: Thu, 11 Feb 2016 19:37:27 +0000
+Subject: af_unix: Guard against other == sk in unix_dgram_sendmsg
+
+From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
+
+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 <pmhahn@pmhahn.de>
+Signed-off-by: Rainer Weikusat <rweikusat@mobileactivedefense.com>
+Tested-by: Philipp Hahn <pmhahn@pmhahn.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+
--- /dev/null
+From 3567eb6af614dac436c4b16a8d426f9faed639b3 Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Tue, 12 Jan 2016 15:36:27 +0100
+Subject: ALSA: seq: Fix race at timer setup and close
+
+From: Takashi Iwai <tiwai@suse.de>
+
+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 <dvyukov@google.com>
+Tested-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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... */
--- /dev/null
+From 9a47e9cff994f37f7f0dbd9ae23740d0f64f9fe6 Mon Sep 17 00:00:00 2001
+From: Kangjie Lu <kangjielu@gmail.com>
+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 <kangjielu@gmail.com>
+
+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 <kjlu@gatech.edu>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From e4ec8cc8039a7063e24204299b462bd1383184a5 Mon Sep 17 00:00:00 2001
+From: Kangjie Lu <kangjielu@gmail.com>
+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 <kangjielu@gmail.com>
+
+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 <kjlu@gatech.edu>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From cec8f96e49d9be372fdb0c3836dcf31ec71e457e Mon Sep 17 00:00:00 2001
+From: Kangjie Lu <kangjielu@gmail.com>
+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 <kangjielu@gmail.com>
+
+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 <kjlu@gatech.edu>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From af368027a49a751d6ff4ee9e3f9961f35bb4fede Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Wed, 13 Jan 2016 17:48:01 +0100
+Subject: ALSA: timer: Fix race among timer ioctls
+
+From: Takashi Iwai <tiwai@suse.de>
+
+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 <dvyukov@google.com>
+Tested-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
--- /dev/null
+From 4d06dd537f95683aba3651098ae288b7cbff8274 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= <bjorn@mork.no>
+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 <bjorn@mork.no>
+
+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 <andreyknvl@gmail.com>
+Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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,
--- /dev/null
+From 50220dead1650609206efe91f0cc116132d59b3f Mon Sep 17 00:00:00 2001
+From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+Date: Tue, 19 Jan 2016 12:34:58 +0100
+Subject: HID: core: prevent out-of-bound readings
+
+From: Benjamin Tissoires <benjamin.tissoires@redhat.com>
+
+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 <benjamin.tissoires@redhat.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
--- /dev/null
+From c836a8ba93869d6a0290a6ae0047fbef09066871 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 2 Dec 2015 21:48:14 -0800
+Subject: ipv6: sctp: add rcu protection around np->opt
+
+From: Eric Dumazet <edumazet@google.com>
+
+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 <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+ }
+
--- /dev/null
+From 69ce6487dcd364245a3d26322fc8f4ffd1e8d947 Mon Sep 17 00:00:00 2001
+From: Eric Dumazet <edumazet@google.com>
+Date: Mon, 7 Dec 2015 08:25:21 -0800
+Subject: ipv6: sctp: fix lockdep splat in sctp_v6_get_dst()
+
+From: Eric Dumazet <edumazet@google.com>
+
+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 <davej@codemonkey.org.uk>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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)) {
--- /dev/null
+From 8013d1d7eafb0589ca766db6b74026f76b7f5cb4 Mon Sep 17 00:00:00 2001
+From: Hangbin Liu <liuhangbin@gmail.com>
+Date: Thu, 30 Jul 2015 14:28:42 +0800
+Subject: net/ipv6: add sysctl option accept_ra_min_hop_limit
+
+From: Hangbin Liu <liuhangbin@gmail.com>
+
+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 <liuhangbin@gmail.com>
+Acked-by: YOSHIFUJI Hideaki <hideaki.yoshifuji@miraclelinux.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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:
--- /dev/null
+From 205e1e255c479f3fd77446415706463b282f94e4 Mon Sep 17 00:00:00 2001
+From: WANG Cong <xiyou.wangcong@gmail.com>
+Date: Tue, 5 Jul 2016 22:12:36 -0700
+Subject: ppp: defer netns reference release for ppp channel
+
+From: WANG Cong <xiyou.wangcong@gmail.com>
+
+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 <Matt.Bennett@alliedtelesis.co.nz>
+Cc: Paul Mackerras <paulus@samba.org>
+Cc: linux-ppp@vger.kernel.org
+Cc: Guillaume Nault <g.nault@alphalink.fr>
+Cc: Cyrill Gorcunov <gorcunov@openvz.org>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Cyrill Gorcunov <gorcunov@openvz.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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) {
--- /dev/null
+From 29d6455178a09e1dc340380c582b13356227e8df Mon Sep 17 00:00:00 2001
+From: Jann Horn <jannh@google.com>
+Date: Wed, 1 Jun 2016 11:55:07 +0200
+Subject: sched: panic on corrupted stack end
+
+From: Jann Horn <jannh@google.com>
+
+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 <jannh@google.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+[AmitP: Minor refactoring of upstream changes for linux-3.18.y]
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
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
--- /dev/null
+From f3951a3709ff50990bf3e188c27d346792103432 Mon Sep 17 00:00:00 2001
+From: Calvin Owens <calvinowens@fb.com>
+Date: Fri, 30 Oct 2015 16:57:00 -0700
+Subject: sg: Fix double-free when drives detach during SG_IO
+
+From: Calvin Owens <calvinowens@fb.com>
+
+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:
+ [<ffffffff81281eab>] blk_put_request+0x5b/0x80
+ [<ffffffffa0069e5b>] sg_finish_rem_req+0x6b/0x120 [sg]
+ [<ffffffffa006bcb9>] sg_common_write.isra.14+0x459/0x5a0 [sg]
+ [<ffffffff8125b328>] ? selinux_file_alloc_security+0x48/0x70
+ [<ffffffffa006bf95>] sg_new_write.isra.17+0x195/0x2d0 [sg]
+ [<ffffffffa006cef4>] sg_ioctl+0x644/0xdb0 [sg]
+ [<ffffffff81170f80>] do_vfs_ioctl+0x90/0x520
+ [<ffffffff81258967>] ? file_has_perm+0x97/0xb0
+ [<ffffffff811714a1>] SyS_ioctl+0x91/0xb0
+ [<ffffffff81602afb>] tracesys+0xdd/0xe2
+ RIP [<ffffffff81281e04>] __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 <calvinowens@fb.com>
+Acked-by: Douglas Gilbert <dgilbert@interlog.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Amit Pundir <amit.pundir@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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;
+ }