commit:     41033c2db3e1f066508325a49e17c53e24013843
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sun Jan 31 15:36:20 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sun Jan 31 15:36:20 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=41033c2d

Linux patch 3.18.26. Removal of redundant patchset.

 0000_README                                        |    8 +-
 1025_linux-3.18.26.patch                           | 1763 ++++++++++++++++++++
 ...ing-refleak-in-join-session-CVE-2016-0728.patch |   81 -
 3 files changed, 1767 insertions(+), 85 deletions(-)

diff --git a/0000_README b/0000_README
index 3fe5eec..728c863 100644
--- a/0000_README
+++ b/0000_README
@@ -143,6 +143,10 @@ Patch:  1024_linux-3.18.25.patch
 From:   http://www.kernel.org
 Desc:   Linux 3.18.25
 
+Patch:  1025_linux-3.18.26.patch
+From:   http://www.kernel.org
+Desc:   Linux 3.18.26
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.
@@ -151,10 +155,6 @@ Patch:  
1510_fs-enable-link-security-restrictions-by-default.patch
 From:   
http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/
 Desc:   Enable link security restrictions by default
 
-Patch:  1520_keyring-refleak-in-join-session-CVE-2016-0728.patch
-From:   https://bugs.gentoo.org/show_bug.cgi?id=572384
-Desc:   Ensure that thread joining a session keyring does not leak the keyring 
reference. CVE-2016-0728.
-
 Patch:  1700_ARM-dts-patch-to-support-popoplug-e02.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=508248
 Desc:   ARM: dts: Add support for Pogoplug E02.

diff --git a/1025_linux-3.18.26.patch b/1025_linux-3.18.26.patch
new file mode 100644
index 0000000..5ad05b0
--- /dev/null
+++ b/1025_linux-3.18.26.patch
@@ -0,0 +1,1763 @@
+diff --git a/Makefile b/Makefile
+index 6df25277ea44..03b0c3fb5bfd 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 3
+ PATCHLEVEL = 18
+-SUBLEVEL = 25
++SUBLEVEL = 26
+ EXTRAVERSION =
+ NAME = Diseased Newt
+ 
+diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
+index 8f51d6e3883e..c546a93c0f8a 100644
+--- a/drivers/block/rbd.c
++++ b/drivers/block/rbd.c
+@@ -3394,6 +3394,7 @@ static void rbd_handle_request(struct rbd_device 
*rbd_dev, struct request *rq)
+               goto err_rq;
+       }
+       img_request->rq = rq;
++      snapc = NULL; /* img_request consumes a ref */
+ 
+       if (op_type == OBJ_OP_DISCARD)
+               result = rbd_img_request_fill(img_request, OBJ_REQUEST_NODATA,
+@@ -5172,41 +5173,36 @@ out_err:
+ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev)
+ {
+       struct rbd_device *parent = NULL;
+-      struct rbd_spec *parent_spec;
+-      struct rbd_client *rbdc;
+       int ret;
+ 
+       if (!rbd_dev->parent_spec)
+               return 0;
+-      /*
+-       * We need to pass a reference to the client and the parent
+-       * spec when creating the parent rbd_dev.  Images related by
+-       * parent/child relationships always share both.
+-       */
+-      parent_spec = rbd_spec_get(rbd_dev->parent_spec);
+-      rbdc = __rbd_get_client(rbd_dev->rbd_client);
+ 
+-      ret = -ENOMEM;
+-      parent = rbd_dev_create(rbdc, parent_spec);
+-      if (!parent)
++      parent = rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec);
++      if (!parent) {
++              ret = -ENOMEM;
+               goto out_err;
++      }
++
++      /*
++       * Images related by parent/child relationships always share
++       * rbd_client and spec/parent_spec, so bump their refcounts.
++       */
++      __rbd_get_client(rbd_dev->rbd_client);
++      rbd_spec_get(rbd_dev->parent_spec);
+ 
+       ret = rbd_dev_image_probe(parent, false);
+       if (ret < 0)
+               goto out_err;
++
+       rbd_dev->parent = parent;
+       atomic_set(&rbd_dev->parent_ref, 1);
+-
+       return 0;
++
+ out_err:
+-      if (parent) {
+-              rbd_dev_unparent(rbd_dev);
++      rbd_dev_unparent(rbd_dev);
++      if (parent)
+               rbd_dev_destroy(parent);
+-      } else {
+-              rbd_put_client(rbdc);
+-              rbd_spec_put(parent_spec);
+-      }
+-
+       return ret;
+ }
+ 
+diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
+index a66a3217f1d9..f047d7c2b643 100644
+--- a/drivers/firewire/ohci.c
++++ b/drivers/firewire/ohci.c
+@@ -3682,6 +3682,11 @@ static int pci_probe(struct pci_dev *dev,
+ 
+       reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0);
+       ohci->it_context_support = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet);
++      /* JMicron JMB38x often shows 0 at first read, just ignore it */
++      if (!ohci->it_context_support) {
++              ohci_notice(ohci, "overriding IsoXmitIntMask\n");
++              ohci->it_context_support = 0xf;
++      }
+       reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0);
+       ohci->it_context_mask = ohci->it_context_support;
+       ohci->n_it = hweight32(ohci->it_context_mask);
+diff --git a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c 
b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+index 72fb86b9aa24..067f2cb9b215 100644
+--- a/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
++++ b/drivers/net/ethernet/atheros/atl1c/atl1c_main.c
+@@ -1014,13 +1014,12 @@ static int atl1c_setup_ring_resources(struct 
atl1c_adapter *adapter)
+               sizeof(struct atl1c_recv_ret_status) * rx_desc_count +
+               8 * 4;
+ 
+-      ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
+-                              &ring_header->dma);
++      ring_header->desc = dma_zalloc_coherent(&pdev->dev, ring_header->size,
++                                              &ring_header->dma, GFP_KERNEL);
+       if (unlikely(!ring_header->desc)) {
+-              dev_err(&pdev->dev, "pci_alloc_consistend failed\n");
++              dev_err(&pdev->dev, "could not get memory for DMA buffer\n");
+               goto err_nomem;
+       }
+-      memset(ring_header->desc, 0, ring_header->size);
+       /* init TPD ring */
+ 
+       tpd_ring[0].dma = roundup(ring_header->dma, 8);
+diff --git a/drivers/net/ethernet/qualcomm/qca_spi.c 
b/drivers/net/ethernet/qualcomm/qca_spi.c
+index 2c811f66d5ac..f77b58911558 100644
+--- a/drivers/net/ethernet/qualcomm/qca_spi.c
++++ b/drivers/net/ethernet/qualcomm/qca_spi.c
+@@ -737,9 +737,8 @@ qcaspi_netdev_tx_timeout(struct net_device *dev)
+       netdev_info(qca->net_dev, "Transmit timeout at %ld, latency %ld\n",
+                   jiffies, jiffies - dev->trans_start);
+       qca->net_dev->stats.tx_errors++;
+-      /* wake the queue if there is room */
+-      if (qcaspi_tx_ring_has_space(&qca->txr))
+-              netif_wake_queue(dev);
++      /* Trigger tx queue flush and QCA7000 reset */
++      qca->sync = QCASPI_SYNC_UNKNOWN;
+ }
+ 
+ static int
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c 
b/drivers/net/ethernet/renesas/sh_eth.c
+index b5db6b3f939f..b474dbfcdb4f 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -1417,6 +1417,7 @@ static int sh_eth_rx(struct net_device *ndev, u32 
intr_status, int *quota)
+               if (mdp->cd->shift_rd0)
+                       desc_status >>= 16;
+ 
++              skb = mdp->rx_skbuff[entry];
+               if (desc_status & (RD_RFS1 | RD_RFS2 | RD_RFS3 | RD_RFS4 |
+                                  RD_RFS5 | RD_RFS6 | RD_RFS10)) {
+                       ndev->stats.rx_errors++;
+@@ -1432,12 +1433,11 @@ static int sh_eth_rx(struct net_device *ndev, u32 
intr_status, int *quota)
+                               ndev->stats.rx_missed_errors++;
+                       if (desc_status & RD_RFS10)
+                               ndev->stats.rx_over_errors++;
+-              } else {
++              } else  if (skb) {
+                       if (!mdp->cd->hw_swap)
+                               sh_eth_soft_swap(
+                                       phys_to_virt(ALIGN(rxdesc->addr, 4)),
+                                       pkt_len + 2);
+-                      skb = mdp->rx_skbuff[entry];
+                       mdp->rx_skbuff[entry] = NULL;
+                       if (mdp->cd->rpadir)
+                               skb_reserve(skb, NET_IP_ALIGN);
+diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
+index 1dc628ffce2b..0710214df2bf 100644
+--- a/drivers/net/ppp/pptp.c
++++ b/drivers/net/ppp/pptp.c
+@@ -420,6 +420,9 @@ static int pptp_bind(struct socket *sock, struct sockaddr 
*uservaddr,
+       struct pptp_opt *opt = &po->proto.pptp;
+       int error = 0;
+ 
++      if (sockaddr_len < sizeof(struct sockaddr_pppox))
++              return -EINVAL;
++
+       lock_sock(sk);
+ 
+       opt->src_addr = sp->sa_addr.pptp;
+@@ -441,6 +444,9 @@ static int pptp_connect(struct socket *sock, struct 
sockaddr *uservaddr,
+       struct flowi4 fl4;
+       int error = 0;
+ 
++      if (sockaddr_len < sizeof(struct sockaddr_pppox))
++              return -EINVAL;
++
+       if (sp->sa_protocol != PX_PROTO_PPTP)
+               return -EINVAL;
+ 
+diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c 
b/drivers/net/wireless/iwlwifi/iwl-7000.c
+index 9dfd1d1106d7..655ecf982394 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
+@@ -69,8 +69,8 @@
+ #include "iwl-agn-hw.h"
+ 
+ /* Highest firmware API version supported */
+-#define IWL7260_UCODE_API_MAX 10
+-#define IWL3160_UCODE_API_MAX 10
++#define IWL7260_UCODE_API_MAX 12
++#define IWL3160_UCODE_API_MAX 12
+ 
+ /* Oldest version we won't warn about */
+ #define IWL7260_UCODE_API_OK  9
+@@ -103,7 +103,7 @@
+ #define IWL7265_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode"
+ 
+ #define IWL7265D_FW_PRE "iwlwifi-7265D-"
+-#define IWL7265D_MODULE_FIRMWARE(api) IWL7265_FW_PRE __stringify(api) ".ucode"
++#define IWL7265D_MODULE_FIRMWARE(api) IWL7265D_FW_PRE __stringify(api) 
".ucode"
+ 
+ #define NVM_HW_SECTION_NUM_FAMILY_7000                0
+ 
+diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c 
b/drivers/net/wireless/iwlwifi/iwl-8000.c
+index d2b7234b1c73..d727ad324d17 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
++++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
+@@ -69,7 +69,7 @@
+ #include "iwl-agn-hw.h"
+ 
+ /* Highest firmware API version supported */
+-#define IWL8000_UCODE_API_MAX 10
++#define IWL8000_UCODE_API_MAX 12
+ 
+ /* Oldest version we won't warn about */
+ #define IWL8000_UCODE_API_OK  8
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index 7d8c3d4ede20..0ecf393a7973 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1860,6 +1860,11 @@ static const struct usb_device_id acm_ids[] = {
+       },
+ #endif
+ 
++      /* Exclude Infineon Flash Loader utility */
++      { USB_DEVICE(0x058b, 0x0041),
++      .driver_info = IGNORE_DEVICE,
++      },
++
+       /* control interfaces without any protocol set */
+       { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
+               USB_CDC_PROTO_NONE) },
+diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c
+index b9ddf0c1ffe5..894894f2ff93 100644
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -115,7 +115,8 @@ static void usb_parse_ss_endpoint_companion(struct device 
*ddev, int cfgno,
+                  USB_SS_MULT(desc->bmAttributes) > 3) {
+               dev_warn(ddev, "Isoc endpoint has Mult of %d in "
+                               "config %d interface %d altsetting %d ep %d: "
+-                              "setting to 3\n", desc->bmAttributes + 1,
++                              "setting to 3\n",
++                              USB_SS_MULT(desc->bmAttributes),
+                               cfgno, inum, asnum, ep->desc.bEndpointAddress);
+               ep->ss_ep_comp.bmAttributes = 2;
+       }
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 2222899c4b69..88e6e5debbe9 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -124,6 +124,10 @@ struct usb_hub *usb_hub_to_struct_hub(struct usb_device 
*hdev)
+ 
+ static int usb_device_supports_lpm(struct usb_device *udev)
+ {
++      /* Some devices have trouble with LPM */
++      if (udev->quirks & USB_QUIRK_NO_LPM)
++              return 0;
++
+       /* USB 2.1 (and greater) devices indicate LPM support through
+        * their USB 2.0 Extended Capabilities BOS descriptor.
+        */
+@@ -4498,6 +4502,8 @@ hub_port_init (struct usb_hub *hub, struct usb_device 
*udev, int port1,
+               goto fail;
+       }
+ 
++      usb_detect_quirks(udev);
++
+       if (udev->wusb == 0 && le16_to_cpu(udev->descriptor.bcdUSB) >= 0x0201) {
+               retval = usb_get_bos_descriptor(udev);
+               if (!retval) {
+@@ -4692,7 +4698,6 @@ static void hub_port_connect(struct usb_hub *hub, int 
port1, u16 portstatus,
+               if (status < 0)
+                       goto loop;
+ 
+-              usb_detect_quirks(udev);
+               if (udev->quirks & USB_QUIRK_DELAY_INIT)
+                       msleep(1000);
+ 
+@@ -5324,9 +5329,6 @@ static int usb_reset_and_verify_device(struct usb_device 
*udev)
+       if (udev->usb2_hw_lpm_enabled == 1)
+               usb_set_usb2_hardware_lpm(udev, 0);
+ 
+-      bos = udev->bos;
+-      udev->bos = NULL;
+-
+       /* Disable LPM and LTM while we reset the device and reinstall the alt
+        * settings.  Device-initiated LPM settings, and system exit latency
+        * settings are cleared when the device is reset, so we have to set
+@@ -5335,15 +5337,18 @@ static int usb_reset_and_verify_device(struct 
usb_device *udev)
+       ret = usb_unlocked_disable_lpm(udev);
+       if (ret) {
+               dev_err(&udev->dev, "%s Failed to disable LPM\n.", __func__);
+-              goto re_enumerate;
++              goto re_enumerate_no_bos;
+       }
+       ret = usb_disable_ltm(udev);
+       if (ret) {
+               dev_err(&udev->dev, "%s Failed to disable LTM\n.",
+                               __func__);
+-              goto re_enumerate;
++              goto re_enumerate_no_bos;
+       }
+ 
++      bos = udev->bos;
++      udev->bos = NULL;
++
+       for (i = 0; i < SET_CONFIG_TRIES; ++i) {
+ 
+               /* ep0 maxpacket size may change; let the HCD know about it.
+@@ -5440,10 +5445,11 @@ done:
+       return 0;
+ 
+ re_enumerate:
+-      /* LPM state doesn't matter when we're about to destroy the device. */
+-      hub_port_logical_disconnect(parent_hub, port1);
+       usb_release_bos_descriptor(udev);
+       udev->bos = bos;
++re_enumerate_no_bos:
++      /* LPM state doesn't matter when we're about to destroy the device. */
++      hub_port_logical_disconnect(parent_hub, port1);
+       return -ENODEV;
+ }
+ 
+diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
+index 8a77a417ccfd..6b53fc3ec636 100644
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -196,6 +196,12 @@ static const struct usb_device_id usb_quirk_list[] = {
+       { USB_DEVICE(0x1a0a, 0x0200), .driver_info =
+                       USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
+ 
++      /* Blackmagic Design Intensity Shuttle */
++      { USB_DEVICE(0x1edb, 0xbd3b), .driver_info = USB_QUIRK_NO_LPM },
++
++      /* Blackmagic Design UltraStudio SDI */
++      { USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
++
+       { }  /* terminating entry must be last */
+ };
+ 
+diff --git a/drivers/usb/gadget/udc/pxa27x_udc.c 
b/drivers/usb/gadget/udc/pxa27x_udc.c
+index 4868369eeec6..69456811ec11 100644
+--- a/drivers/usb/gadget/udc/pxa27x_udc.c
++++ b/drivers/usb/gadget/udc/pxa27x_udc.c
+@@ -2564,6 +2564,9 @@ static int pxa_udc_suspend(struct platform_device *_dev, 
pm_message_t state)
+       udc->pullup_resume = udc->pullup_on;
+       dplus_pullup(udc, 0);
+ 
++      if (udc->driver)
++              udc->driver->disconnect(&udc->gadget);
++
+       return 0;
+ }
+ 
+diff --git a/drivers/usb/host/whci/qset.c b/drivers/usb/host/whci/qset.c
+index dc31c425ce01..9f1c0538b211 100644
+--- a/drivers/usb/host/whci/qset.c
++++ b/drivers/usb/host/whci/qset.c
+@@ -377,6 +377,10 @@ static int qset_fill_page_list(struct whc *whc, struct 
whc_std *std, gfp_t mem_f
+       if (std->pl_virt == NULL)
+               return -ENOMEM;
+       std->dma_addr = dma_map_single(whc->wusbhc.dev, std->pl_virt, pl_len, 
DMA_TO_DEVICE);
++      if (dma_mapping_error(whc->wusbhc.dev, std->dma_addr)) {
++              kfree(std->pl_virt);
++              return -EFAULT;
++      }
+ 
+       for (p = 0; p < std->num_pointers; p++) {
+               std->pl_virt[p].buf_ptr = cpu_to_le64(dma_addr);
+diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig
+index 06cc5d6ea681..dbc56eb5eee4 100644
+--- a/drivers/usb/musb/Kconfig
++++ b/drivers/usb/musb/Kconfig
+@@ -140,7 +140,7 @@ config USB_TI_CPPI_DMA
+ 
+ config USB_TI_CPPI41_DMA
+       bool 'TI CPPI 4.1 (AM335x)'
+-      depends on ARCH_OMAP
++      depends on ARCH_OMAP && DMADEVICES
+       select TI_CPPI41
+ 
+ config USB_TUSB_OMAP_DMA
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index eac7ccaa3c85..7d4f51a32e66 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -132,7 +132,6 @@ static const struct usb_device_id id_table[] = {
+       { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
+       { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
+       { USB_DEVICE(0x10C4, 0xEA70) }, /* Silicon Labs factory default */
+-      { USB_DEVICE(0x10C4, 0xEA80) }, /* Silicon Labs factory default */
+       { USB_DEVICE(0x10C4, 0xEA71) }, /* Infinity GPS-MIC-1 Radio Monophone */
+       { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */
+       { USB_DEVICE(0x10C4, 0xF002) }, /* Elan Digital Systems USBwave12 */
+diff --git a/drivers/usb/serial/usb-serial-simple.c 
b/drivers/usb/serial/usb-serial-simple.c
+index 7064eb8d6142..a1f2e2a05bc5 100644
+--- a/drivers/usb/serial/usb-serial-simple.c
++++ b/drivers/usb/serial/usb-serial-simple.c
+@@ -53,6 +53,7 @@ DEVICE(funsoft, FUNSOFT_IDS);
+ 
+ /* Infineon Flashloader driver */
+ #define FLASHLOADER_IDS()             \
++      { USB_DEVICE_INTERFACE_CLASS(0x058b, 0x0041, USB_CLASS_CDC_DATA) }, \
+       { USB_DEVICE(0x8087, 0x0716) }
+ DEVICE(flashloader, FLASHLOADER_IDS);
+ 
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index 5193c7844315..e557e4ca0392 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -760,8 +760,16 @@ next_slot:
+               }
+ 
+               btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
+-              if (key.objectid > ino ||
+-                  key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end)
++
++              if (key.objectid > ino)
++                      break;
++              if (WARN_ON_ONCE(key.objectid < ino) ||
++                  key.type < BTRFS_EXTENT_DATA_KEY) {
++                      ASSERT(del_nr == 0);
++                      path->slots[0]++;
++                      goto next_slot;
++              }
++              if (key.type > BTRFS_EXTENT_DATA_KEY || key.offset >= end)
+                       break;
+ 
+               fi = btrfs_item_ptr(leaf, path->slots[0],
+@@ -780,8 +788,8 @@ next_slot:
+                               btrfs_file_extent_inline_len(leaf,
+                                                    path->slots[0], fi);
+               } else {
+-                      WARN_ON(1);
+-                      extent_end = search_start;
++                      /* can't happen */
++                      BUG();
+               }
+ 
+               /*
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 0be09bb34b75..5db50e8bf52e 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -1268,8 +1268,14 @@ next_slot:
+               num_bytes = 0;
+               btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
+ 
+-              if (found_key.objectid > ino ||
+-                  found_key.type > BTRFS_EXTENT_DATA_KEY ||
++              if (found_key.objectid > ino)
++                      break;
++              if (WARN_ON_ONCE(found_key.objectid < ino) ||
++                  found_key.type < BTRFS_EXTENT_DATA_KEY) {
++                      path->slots[0]++;
++                      goto next_slot;
++              }
++              if (found_key.type > BTRFS_EXTENT_DATA_KEY ||
+                   found_key.offset > end)
+                       break;
+ 
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index 3d50f1ee51ba..31c9f6471ce7 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3187,6 +3187,150 @@ static void clone_update_extent_map(struct inode 
*inode,
+                       &BTRFS_I(inode)->runtime_flags);
+ }
+ 
++/*
++ * Make sure we do not end up inserting an inline extent into a file that has
++ * already other (non-inline) extents. If a file has an inline extent it can
++ * not have any other extents and the (single) inline extent must start at the
++ * file offset 0. Failing to respect these rules will lead to file corruption,
++ * resulting in EIO errors on read/write operations, hitting BUG_ON's in mm, 
etc
++ *
++ * We can have extents that have been already written to disk or we can have
++ * dirty ranges still in delalloc, in which case the extent maps and items are
++ * created only when we run delalloc, and the delalloc ranges might fall 
outside
++ * the range we are currently locking in the inode's io tree. So we check the
++ * inode's i_size because of that (i_size updates are done while holding the
++ * i_mutex, which we are holding here).
++ * We also check to see if the inode has a size not greater than "datal" but 
has
++ * extents beyond it, due to an fallocate with FALLOC_FL_KEEP_SIZE (and we are
++ * protected against such concurrent fallocate calls by the i_mutex).
++ *
++ * If the file has no extents but a size greater than datal, do not allow the
++ * copy because we would need turn the inline extent into a non-inline one 
(even
++ * with NO_HOLES enabled). If we find our destination inode only has one 
inline
++ * extent, just overwrite it with the source inline extent if its size is less
++ * than the source extent's size, or we could copy the source inline extent's
++ * data into the destination inode's inline extent if the later is greater 
then
++ * the former.
++ */
++static int clone_copy_inline_extent(struct inode *src,
++                                  struct inode *dst,
++                                  struct btrfs_trans_handle *trans,
++                                  struct btrfs_path *path,
++                                  struct btrfs_key *new_key,
++                                  const u64 drop_start,
++                                  const u64 datal,
++                                  const u64 skip,
++                                  const u64 size,
++                                  char *inline_data)
++{
++      struct btrfs_root *root = BTRFS_I(dst)->root;
++      const u64 aligned_end = ALIGN(new_key->offset + datal,
++                                    root->sectorsize);
++      int ret;
++      struct btrfs_key key;
++
++      if (new_key->offset > 0)
++              return -EOPNOTSUPP;
++
++      key.objectid = btrfs_ino(dst);
++      key.type = BTRFS_EXTENT_DATA_KEY;
++      key.offset = 0;
++      ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
++      if (ret < 0) {
++              return ret;
++      } else if (ret > 0) {
++              if (path->slots[0] >= btrfs_header_nritems(path->nodes[0])) {
++                      ret = btrfs_next_leaf(root, path);
++                      if (ret < 0)
++                              return ret;
++                      else if (ret > 0)
++                              goto copy_inline_extent;
++              }
++              btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
++              if (key.objectid == btrfs_ino(dst) &&
++                  key.type == BTRFS_EXTENT_DATA_KEY) {
++                      ASSERT(key.offset > 0);
++                      return -EOPNOTSUPP;
++              }
++      } else if (i_size_read(dst) <= datal) {
++              struct btrfs_file_extent_item *ei;
++              u64 ext_len;
++
++              /*
++               * If the file size is <= datal, make sure there are no other
++               * extents following (can happen do to an fallocate call with
++               * the flag FALLOC_FL_KEEP_SIZE).
++               */
++              ei = btrfs_item_ptr(path->nodes[0], path->slots[0],
++                                  struct btrfs_file_extent_item);
++              /*
++               * If it's an inline extent, it can not have other extents
++               * following it.
++               */
++              if (btrfs_file_extent_type(path->nodes[0], ei) ==
++                  BTRFS_FILE_EXTENT_INLINE)
++                      goto copy_inline_extent;
++
++              ext_len = btrfs_file_extent_num_bytes(path->nodes[0], ei);
++              if (ext_len > aligned_end)
++                      return -EOPNOTSUPP;
++
++              ret = btrfs_next_item(root, path);
++              if (ret < 0) {
++                      return ret;
++              } else if (ret == 0) {
++                      btrfs_item_key_to_cpu(path->nodes[0], &key,
++                                            path->slots[0]);
++                      if (key.objectid == btrfs_ino(dst) &&
++                          key.type == BTRFS_EXTENT_DATA_KEY)
++                              return -EOPNOTSUPP;
++              }
++      }
++
++copy_inline_extent:
++      /*
++       * We have no extent items, or we have an extent at offset 0 which may
++       * or may not be inlined. All these cases are dealt the same way.
++       */
++      if (i_size_read(dst) > datal) {
++              /*
++               * If the destination inode has an inline extent...
++               * This would require copying the data from the source inline
++               * extent into the beginning of the destination's inline extent.
++               * But this is really complex, both extents can be compressed
++               * or just one of them, which would require decompressing and
++               * re-compressing data (which could increase the new compressed
++               * size, not allowing the compressed data to fit anymore in an
++               * inline extent).
++               * So just don't support this case for now (it should be rare,
++               * we are not really saving space when cloning inline extents).
++               */
++              return -EOPNOTSUPP;
++      }
++
++      btrfs_release_path(path);
++      ret = btrfs_drop_extents(trans, root, dst, drop_start, aligned_end, 1);
++      if (ret)
++              return ret;
++      ret = btrfs_insert_empty_item(trans, root, path, new_key, size);
++      if (ret)
++              return ret;
++
++      if (skip) {
++              const u32 start = btrfs_file_extent_calc_inline_size(0);
++
++              memmove(inline_data + start, inline_data + start + skip, datal);
++      }
++
++      write_extent_buffer(path->nodes[0], inline_data,
++                          btrfs_item_ptr_offset(path->nodes[0],
++                                                path->slots[0]),
++                          size);
++      inode_add_bytes(dst, datal);
++
++      return 0;
++}
++
+ /**
+  * btrfs_clone() - clone a range from inode file to another
+  *
+@@ -3451,7 +3595,6 @@ process_slot:
+                       } else if (type == BTRFS_FILE_EXTENT_INLINE) {
+                               u64 skip = 0;
+                               u64 trim = 0;
+-                              u64 aligned_end = 0;
+ 
+                               if (off > key.offset) {
+                                       skip = off - key.offset;
+@@ -3469,42 +3612,22 @@ process_slot:
+                               size -= skip + trim;
+                               datal -= skip + trim;
+ 
+-                              aligned_end = ALIGN(new_key.offset + datal,
+-                                                  root->sectorsize);
+-                              ret = btrfs_drop_extents(trans, root, inode,
+-                                                       drop_start,
+-                                                       aligned_end,
+-                                                       1);
++                              ret = clone_copy_inline_extent(src, inode,
++                                                             trans, path,
++                                                             &new_key,
++                                                             drop_start,
++                                                             datal,
++                                                             skip, size, buf);
+                               if (ret) {
+                                       if (ret != -EOPNOTSUPP)
+                                               btrfs_abort_transaction(trans,
+-                                                      root, ret);
+-                                      btrfs_end_transaction(trans, root);
+-                                      goto out;
+-                              }
+-
+-                              ret = btrfs_insert_empty_item(trans, root, path,
+-                                                            &new_key, size);
+-                              if (ret) {
+-                                      btrfs_abort_transaction(trans, root,
+-                                                              ret);
++                                                                      root,
++                                                                      ret);
+                                       btrfs_end_transaction(trans, root);
+                                       goto out;
+                               }
+-
+-                              if (skip) {
+-                                      u32 start =
+-                                        btrfs_file_extent_calc_inline_size(0);
+-                                      memmove(buf+start, buf+start+skip,
+-                                              datal);
+-                              }
+-
+                               leaf = path->nodes[0];
+                               slot = path->slots[0];
+-                              write_extent_buffer(leaf, buf,
+-                                          btrfs_item_ptr_offset(leaf, slot),
+-                                          size);
+-                              inode_add_bytes(inode, datal);
+                       }
+ 
+                       /* If we have an implicit hole (NO_HOLES feature). */
+diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c
+index 01bad724b5f7..fbb0533e977f 100644
+--- a/fs/btrfs/xattr.c
++++ b/fs/btrfs/xattr.c
+@@ -309,8 +309,10 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char 
*buffer, size_t size)
+               /* check to make sure this item is what we want */
+               if (found_key.objectid != key.objectid)
+                       break;
+-              if (found_key.type != BTRFS_XATTR_ITEM_KEY)
++              if (found_key.type > BTRFS_XATTR_ITEM_KEY)
+                       break;
++              if (found_key.type < BTRFS_XATTR_ITEM_KEY)
++                      goto next;
+ 
+               di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
+               if (verify_dir_item(root, leaf, di))
+diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
+index a92d3f5c6c12..6f29455c03fe 100644
+--- a/fs/ceph/mds_client.c
++++ b/fs/ceph/mds_client.c
+@@ -1857,7 +1857,7 @@ static struct ceph_msg *create_request_message(struct 
ceph_mds_client *mdsc,
+ 
+       len = sizeof(*head) +
+               pathlen1 + pathlen2 + 2*(1 + sizeof(u32) + sizeof(u64)) +
+-              sizeof(struct timespec);
++              sizeof(struct ceph_timespec);
+ 
+       /* calculate (max) length for cap releases */
+       len += sizeof(struct ceph_mds_request_release) *
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index b5a2c29a8db8..b16ba5239dcf 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -404,9 +404,13 @@ static void ext4_handle_error(struct super_block *sb)
+               smp_wmb();
+               sb->s_flags |= MS_RDONLY;
+       }
+-      if (test_opt(sb, ERRORS_PANIC))
++      if (test_opt(sb, ERRORS_PANIC)) {
++              if (EXT4_SB(sb)->s_journal &&
++                !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
++                      return;
+               panic("EXT4-fs (device %s): panic forced after error\n",
+                       sb->s_id);
++      }
+ }
+ 
+ #define ext4_error_ratelimit(sb)                                      \
+@@ -595,8 +599,12 @@ void __ext4_abort(struct super_block *sb, const char 
*function,
+                       jbd2_journal_abort(EXT4_SB(sb)->s_journal, -EIO);
+               save_error_info(sb, function, line);
+       }
+-      if (test_opt(sb, ERRORS_PANIC))
++      if (test_opt(sb, ERRORS_PANIC)) {
++              if (EXT4_SB(sb)->s_journal &&
++                !(EXT4_SB(sb)->s_journal->j_flags & JBD2_REC_ERR))
++                      return;
+               panic("EXT4-fs panic from previous error\n");
++      }
+ }
+ 
+ void __ext4_msg(struct super_block *sb,
+diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
+index 2540324f084b..07e87ec45709 100644
+--- a/fs/jbd2/journal.c
++++ b/fs/jbd2/journal.c
+@@ -2087,8 +2087,12 @@ static void __journal_abort_soft (journal_t *journal, 
int errno)
+ 
+       __jbd2_journal_abort_hard(journal);
+ 
+-      if (errno)
++      if (errno) {
+               jbd2_journal_update_sb_errno(journal);
++              write_lock(&journal->j_state_lock);
++              journal->j_flags |= JBD2_REC_ERR;
++              write_unlock(&journal->j_state_lock);
++      }
+ }
+ 
+ /**
+diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
+index 00689a8a85e4..d7cfc6e42b5e 100644
+--- a/fs/nfs/inode.c
++++ b/fs/nfs/inode.c
+@@ -1717,7 +1717,11 @@ static int nfs_update_inode(struct inode *inode, struct 
nfs_fattr *fattr)
+                       nfsi->attrtimeo_timestamp = now;
+               }
+       }
+-      invalid &= ~NFS_INO_INVALID_ATTR;
++
++      /* Don't declare attrcache up to date if there were no attrs! */
++      if (fattr->valid != 0)
++              invalid &= ~NFS_INO_INVALID_ATTR;
++
+       /* Don't invalidate the data if we were to blame */
+       if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
+                               || S_ISLNK(inode->i_mode)))
+diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
+index 368a6b72290c..0e11fe80e5b9 100644
+--- a/fs/nfs/nfs4client.c
++++ b/fs/nfs/nfs4client.c
+@@ -33,7 +33,7 @@ static int nfs_get_cb_ident_idr(struct nfs_client *clp, int 
minorversion)
+               return ret;
+       idr_preload(GFP_KERNEL);
+       spin_lock(&nn->nfs_client_lock);
+-      ret = idr_alloc(&nn->cb_ident_idr, clp, 0, 0, GFP_NOWAIT);
++      ret = idr_alloc(&nn->cb_ident_idr, clp, 1, 0, GFP_NOWAIT);
+       if (ret >= 0)
+               clp->cl_cb_ident = ret;
+       spin_unlock(&nn->nfs_client_lock);
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index eda99c8ec3ed..b6c3a8792358 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -3241,6 +3241,7 @@ static void init_open_stateid(struct nfs4_ol_stateid 
*stp, struct nfs4_file *fp,
+       stp->st_access_bmap = 0;
+       stp->st_deny_bmap = 0;
+       stp->st_openstp = NULL;
++      init_rwsem(&stp->st_rwsem);
+       spin_lock(&oo->oo_owner.so_client->cl_lock);
+       list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
+       spin_lock(&fp->fi_lock);
+@@ -4057,21 +4058,27 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct 
svc_fh *current_fh, struct nf
+        */
+       if (stp) {
+               /* Stateid was found, this is an OPEN upgrade */
++              down_read(&stp->st_rwsem);
+               status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
+-              if (status)
++              if (status) {
++                      up_read(&stp->st_rwsem);
+                       goto out;
++              }
+       } else {
+               stp = open->op_stp;
+               open->op_stp = NULL;
+               init_open_stateid(stp, fp, open);
++              down_read(&stp->st_rwsem);
+               status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open);
+               if (status) {
++                      up_read(&stp->st_rwsem);
+                       release_open_stateid(stp);
+                       goto out;
+               }
+       }
+       update_stateid(&stp->st_stid.sc_stateid);
+       memcpy(&open->op_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
++      up_read(&stp->st_rwsem);
+ 
+       if (nfsd4_has_session(&resp->cstate)) {
+               if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) {
+@@ -4647,10 +4654,13 @@ static __be32 nfs4_seqid_op_checks(struct 
nfsd4_compound_state *cstate, stateid_
+                * revoked delegations are kept only for free_stateid.
+                */
+               return nfserr_bad_stateid;
++      down_write(&stp->st_rwsem);
+       status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, 
nfsd4_has_session(cstate));
+-      if (status)
+-              return status;
+-      return nfs4_check_fh(current_fh, &stp->st_stid);
++      if (status == nfs_ok)
++              status = nfs4_check_fh(current_fh, &stp->st_stid);
++      if (status != nfs_ok)
++              up_write(&stp->st_rwsem);
++      return status;
+ }
+ 
+ /* 
+@@ -4697,6 +4707,7 @@ static __be32 nfs4_preprocess_confirmed_seqid_op(struct 
nfsd4_compound_state *cs
+               return status;
+       oo = openowner(stp->st_stateowner);
+       if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
++              up_write(&stp->st_rwsem);
+               nfs4_put_stid(&stp->st_stid);
+               return nfserr_bad_stateid;
+       }
+@@ -4727,11 +4738,14 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct 
nfsd4_compound_state *cstate,
+               goto out;
+       oo = openowner(stp->st_stateowner);
+       status = nfserr_bad_stateid;
+-      if (oo->oo_flags & NFS4_OO_CONFIRMED)
++      if (oo->oo_flags & NFS4_OO_CONFIRMED) {
++              up_write(&stp->st_rwsem);
+               goto put_stateid;
++      }
+       oo->oo_flags |= NFS4_OO_CONFIRMED;
+       update_stateid(&stp->st_stid.sc_stateid);
+       memcpy(&oc->oc_resp_stateid, &stp->st_stid.sc_stateid, 
sizeof(stateid_t));
++      up_write(&stp->st_rwsem);
+       dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
+               __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
+ 
+@@ -4810,6 +4824,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
+       memcpy(&od->od_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
+       status = nfs_ok;
+ put_stateid:
++      up_write(&stp->st_rwsem);
+       nfs4_put_stid(&stp->st_stid);
+ out:
+       nfsd4_bump_seqid(cstate, status);
+@@ -4860,6 +4875,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct 
nfsd4_compound_state *cstate,
+               goto out; 
+       update_stateid(&stp->st_stid.sc_stateid);
+       memcpy(&close->cl_stateid, &stp->st_stid.sc_stateid, sizeof(stateid_t));
++      up_write(&stp->st_rwsem);
+ 
+       nfsd4_close_open_stateid(stp);
+ 
+@@ -5088,6 +5104,7 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct 
nfs4_lockowner *lo,
+       stp->st_access_bmap = 0;
+       stp->st_deny_bmap = open_stp->st_deny_bmap;
+       stp->st_openstp = open_stp;
++      init_rwsem(&stp->st_rwsem);
+       list_add(&stp->st_locks, &open_stp->st_locks);
+       list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
+       spin_lock(&fp->fi_lock);
+@@ -5256,6 +5273,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct 
nfsd4_compound_state *cstate,
+                                       &open_stp, nn);
+               if (status)
+                       goto out;
++              up_write(&open_stp->st_rwsem);
+               open_sop = openowner(open_stp->st_stateowner);
+               status = nfserr_bad_stateid;
+               if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid,
+@@ -5263,6 +5281,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct 
nfsd4_compound_state *cstate,
+                       goto out;
+               status = lookup_or_create_lock_state(cstate, open_stp, lock,
+                                                       &lock_stp, &new);
++              if (status == nfs_ok)
++                      down_write(&lock_stp->st_rwsem);
+       } else {
+               status = nfs4_preprocess_seqid_op(cstate,
+                                      lock->lk_old_lock_seqid,
+@@ -5368,6 +5388,8 @@ out:
+                   seqid_mutating_err(ntohl(status)))
+                       lock_sop->lo_owner.so_seqid++;
+ 
++              up_write(&lock_stp->st_rwsem);
++
+               /*
+                * If this is a new, never-before-used stateid, and we are
+                * returning an error, then just go ahead and release it.
+@@ -5538,6 +5560,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct 
nfsd4_compound_state *cstate,
+ fput:
+       fput(filp);
+ put_stateid:
++      up_write(&stp->st_rwsem);
+       nfs4_put_stid(&stp->st_stid);
+ out:
+       nfsd4_bump_seqid(cstate, status);
+diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
+index 2712042a66b1..3ccb1046a2f9 100644
+--- a/fs/nfsd/state.h
++++ b/fs/nfsd/state.h
+@@ -506,14 +506,15 @@ struct nfs4_file {
+  * Better suggestions welcome.
+  */
+ struct nfs4_ol_stateid {
+-      struct nfs4_stid    st_stid; /* must be first field */
+-      struct list_head              st_perfile;
+-      struct list_head              st_perstateowner;
+-      struct list_head              st_locks;
+-      struct nfs4_stateowner      * st_stateowner;
+-      unsigned char                 st_access_bmap;
+-      unsigned char                 st_deny_bmap;
+-      struct nfs4_ol_stateid         * st_openstp;
++      struct nfs4_stid                st_stid;
++      struct list_head                st_perfile;
++      struct list_head                st_perstateowner;
++      struct list_head                st_locks;
++      struct nfs4_stateowner          *st_stateowner;
++      unsigned char                   st_access_bmap;
++      unsigned char                   st_deny_bmap;
++      struct nfs4_ol_stateid          *st_openstp;
++      struct rw_semaphore             st_rwsem;
+ };
+ 
+ static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s)
+diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
+index 914c121ec890..9fc1daecdfb3 100644
+--- a/fs/ocfs2/namei.c
++++ b/fs/ocfs2/namei.c
+@@ -361,6 +361,8 @@ static int ocfs2_mknod(struct inode *dir,
+               mlog_errno(status);
+               goto leave;
+       }
++      /* update inode->i_mode after mask with "umask". */
++      inode->i_mode = mode;
+ 
+       handle = ocfs2_start_trans(osb, ocfs2_mknod_credits(osb->sb,
+                                                           S_ISDIR(mode),
+diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h
+index 4caf8acfef11..c035001df223 100644
+--- a/include/linux/jbd2.h
++++ b/include/linux/jbd2.h
+@@ -1007,6 +1007,7 @@ struct journal_s
+ #define JBD2_ABORT_ON_SYNCDATA_ERR    0x040   /* Abort the journal on file
+                                                * data write error in ordered
+                                                * mode */
++#define JBD2_REC_ERR  0x080   /* The errno in the sb has been recorded */
+ 
+ /*
+  * Function declarations for the journaling transaction and buffer
+diff --git a/include/linux/usb/quirks.h b/include/linux/usb/quirks.h
+index 9948c874e3f1..1d0043dc34e4 100644
+--- a/include/linux/usb/quirks.h
++++ b/include/linux/usb/quirks.h
+@@ -47,4 +47,7 @@
+ /* device generates spurious wakeup, ignore remote wakeup capability */
+ #define USB_QUIRK_IGNORE_REMOTE_WAKEUP                BIT(9)
+ 
++/* device can't handle Link Power Management */
++#define USB_QUIRK_NO_LPM                      BIT(10)
++
+ #endif /* __LINUX_USB_QUIRKS_H */
+diff --git a/include/net/af_unix.h b/include/net/af_unix.h
+index dfe4ddfbb43c..e830c3dff61a 100644
+--- a/include/net/af_unix.h
++++ b/include/net/af_unix.h
+@@ -63,6 +63,7 @@ struct unix_sock {
+ #define UNIX_GC_CANDIDATE     0
+ #define UNIX_GC_MAYBE_CYCLE   1
+       struct socket_wq        peer_wq;
++      wait_queue_t            peer_wake;
+ };
+ 
+ static inline struct unix_sock *unix_sk(struct sock *sk)
+diff --git a/include/net/dst.h b/include/net/dst.h
+index 0fb99a26e973..182b812d45e1 100644
+--- a/include/net/dst.h
++++ b/include/net/dst.h
+@@ -312,6 +312,39 @@ static inline void skb_dst_force(struct sk_buff *skb)
+       }
+ }
+ 
++/**
++ * dst_hold_safe - Take a reference on a dst if possible
++ * @dst: pointer to dst entry
++ *
++ * This helper returns false if it could not safely
++ * take a reference on a dst.
++ */
++static inline bool dst_hold_safe(struct dst_entry *dst)
++{
++      if (dst->flags & DST_NOCACHE)
++              return atomic_inc_not_zero(&dst->__refcnt);
++      dst_hold(dst);
++      return true;
++}
++
++/**
++ * skb_dst_force_safe - makes sure skb dst is refcounted
++ * @skb: buffer
++ *
++ * If dst is not yet refcounted and not destroyed, grab a ref on it.
++ */
++static inline void skb_dst_force_safe(struct sk_buff *skb)
++{
++      if (skb_dst_is_noref(skb)) {
++              struct dst_entry *dst = skb_dst(skb);
++
++              if (!dst_hold_safe(dst))
++                      dst = NULL;
++
++              skb->_skb_refdst = (unsigned long)dst;
++      }
++}
++
+ 
+ /**
+  *    __skb_tunnel_rx - prepare skb for rx reinsert
+diff --git a/include/net/sock.h b/include/net/sock.h
+index a098ce3cd242..a40bc8c0af4b 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -379,6 +379,7 @@ struct sock {
+                               sk_no_check_rx : 1,
+                               sk_userlocks : 4,
+                               sk_protocol  : 8,
++#define SK_PROTOCOL_MAX U8_MAX
+                               sk_type      : 16;
+       kmemcheck_bitfield_end(flags);
+       int                     sk_wmem_queued;
+@@ -715,6 +716,8 @@ enum sock_flags {
+       SOCK_SELECT_ERR_QUEUE, /* Wake select on error queue */
+ };
+ 
++#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << 
SOCK_TIMESTAMPING_RX_SOFTWARE))
++
+ static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
+ {
+       nsk->sk_flags = osk->sk_flags;
+@@ -789,7 +792,7 @@ void sk_stream_write_space(struct sock *sk);
+ static inline void __sk_add_backlog(struct sock *sk, struct sk_buff *skb)
+ {
+       /* dont let skb dst not refcounted, we are going to leave rcu lock */
+-      skb_dst_force(skb);
++      skb_dst_force_safe(skb);
+ 
+       if (!sk->sk_backlog.tail)
+               sk->sk_backlog.head = skb;
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+index bd3c41d4ec07..2273f534b01a 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -1442,13 +1442,13 @@ static void __queue_delayed_work(int cpu, struct 
workqueue_struct *wq,
+       timer_stats_timer_set_start_info(&dwork->timer);
+ 
+       dwork->wq = wq;
+-      /* timer isn't guaranteed to run in this cpu, record earlier */
+-      if (cpu == WORK_CPU_UNBOUND)
+-              cpu = raw_smp_processor_id();
+       dwork->cpu = cpu;
+       timer->expires = jiffies + delay;
+ 
+-      add_timer_on(timer, cpu);
++      if (unlikely(cpu != WORK_CPU_UNBOUND))
++              add_timer_on(timer, cpu);
++      else
++              add_timer(timer);
+ }
+ 
+ /**
+diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
+index c35c3f48fc0f..1428c3ff3341 100644
+--- a/net/ax25/af_ax25.c
++++ b/net/ax25/af_ax25.c
+@@ -806,6 +806,9 @@ static int ax25_create(struct net *net, struct socket 
*sock, int protocol,
+       struct sock *sk;
+       ax25_cb *ax25;
+ 
++      if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
++              return -EINVAL;
++
+       if (!net_eq(net, &init_net))
+               return -EAFNOSUPPORT;
+ 
+diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
+index 7ee9e4ab00f8..b3ef78a644ed 100644
+--- a/net/bluetooth/sco.c
++++ b/net/bluetooth/sco.c
+@@ -520,6 +520,9 @@ static int sco_sock_bind(struct socket *sock, struct 
sockaddr *addr, int addr_le
+       if (!addr || addr->sa_family != AF_BLUETOOTH)
+               return -EINVAL;
+ 
++      if (addr_len < sizeof(struct sockaddr_sco))
++              return -EINVAL;
++
+       lock_sock(sk);
+ 
+       if (sk->sk_state != BT_OPEN) {
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index ea0bcc4a9657..b2921c0d5608 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -3599,7 +3599,8 @@ static void __skb_complete_tx_timestamp(struct sk_buff 
*skb,
+       serr->ee.ee_info = tstype;
+       if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) {
+               serr->ee.ee_data = skb_shinfo(skb)->tskey;
+-              if (sk->sk_protocol == IPPROTO_TCP)
++              if (sk->sk_protocol == IPPROTO_TCP &&
++                  sk->sk_type == SOCK_STREAM)
+                       serr->ee.ee_data -= sk->sk_tskey;
+       }
+ 
+@@ -4108,7 +4109,8 @@ static struct sk_buff *skb_reorder_vlan_header(struct 
sk_buff *skb)
+               return NULL;
+       }
+ 
+-      memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN);
++      memmove(skb->data - ETH_HLEN, skb->data - skb->mac_len - VLAN_HLEN,
++              2 * ETH_ALEN);
+       skb->mac_header += VLAN_HLEN;
+       return skb;
+ }
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 1e5130de31b6..b1a6ff0a9041 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -422,8 +422,6 @@ static void sock_warn_obsolete_bsdism(const char *name)
+       }
+ }
+ 
+-#define SK_FLAGS_TIMESTAMP ((1UL << SOCK_TIMESTAMP) | (1UL << 
SOCK_TIMESTAMPING_RX_SOFTWARE))
+-
+ static void sock_disable_timestamp(struct sock *sk, unsigned long flags)
+ {
+       if (sk->sk_flags & flags) {
+@@ -861,7 +859,8 @@ set_rcvbuf:
+               }
+               if (val & SOF_TIMESTAMPING_OPT_ID &&
+                   !(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID)) {
+-                      if (sk->sk_protocol == IPPROTO_TCP) {
++                      if (sk->sk_protocol == IPPROTO_TCP &&
++                          sk->sk_type == SOCK_STREAM) {
+                               if (sk->sk_state != TCP_ESTABLISHED) {
+                                       ret = -EINVAL;
+                                       break;
+diff --git a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
+index 25733d538147..2aeeb4f22e9d 100644
+--- a/net/decnet/af_decnet.c
++++ b/net/decnet/af_decnet.c
+@@ -678,6 +678,9 @@ static int dn_create(struct net *net, struct socket *sock, 
int protocol,
+ {
+       struct sock *sk;
+ 
++      if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
++              return -EINVAL;
++
+       if (!net_eq(net, &init_net))
+               return -EAFNOSUPPORT;
+ 
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index 9a173577a790..6cf020ea4f46 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -259,6 +259,9 @@ static int inet_create(struct net *net, struct socket 
*sock, int protocol,
+       int try_loading_module = 0;
+       int err;
+ 
++      if (protocol < 0 || protocol >= IPPROTO_MAX)
++              return -EINVAL;
++
+       sock->state = SS_UNCONNECTED;
+ 
+       /* Look for the requested type/protocol pair. */
+diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
+index 606c520ffd5a..8ce8e82d1abb 100644
+--- a/net/ipv4/fou.c
++++ b/net/ipv4/fou.c
+@@ -25,6 +25,7 @@ struct fou {
+       u16 port;
+       struct udp_offload udp_offloads;
+       struct list_head list;
++      struct rcu_head rcu;
+ };
+ 
+ struct fou_cfg {
+@@ -287,7 +288,7 @@ static void fou_release(struct fou *fou)
+ 
+       sock_release(sock);
+ 
+-      kfree(fou);
++      kfree_rcu(fou, rcu);
+ }
+ 
+ static int fou_encap_init(struct sock *sk, struct fou *fou, struct fou_cfg 
*cfg)
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index 6cd9f696d9c6..5d5390299277 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -1553,7 +1553,7 @@ bool tcp_prequeue(struct sock *sk, struct sk_buff *skb)
+       if (likely(sk->sk_rx_dst))
+               skb_dst_drop(skb);
+       else
+-              skb_dst_force(skb);
++              skb_dst_force_safe(skb);
+ 
+       __skb_queue_tail(&tp->ucopy.prequeue, skb);
+       tp->ucopy.memory += skb->truesize;
+@@ -1758,8 +1758,7 @@ void inet_sk_rx_dst_set(struct sock *sk, const struct 
sk_buff *skb)
+ {
+       struct dst_entry *dst = skb_dst(skb);
+ 
+-      if (dst) {
+-              dst_hold(dst);
++      if (dst && dst_hold_safe(dst)) {
+               sk->sk_rx_dst = dst;
+               inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
+       }
+diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
+index 05417c330f4e..ad95905e7a70 100644
+--- a/net/ipv6/af_inet6.c
++++ b/net/ipv6/af_inet6.c
+@@ -109,6 +109,9 @@ static int inet6_create(struct net *net, struct socket 
*sock, int protocol,
+       int try_loading_module = 0;
+       int err;
+ 
++      if (protocol < 0 || protocol >= IPPROTO_MAX)
++              return -EINVAL;
++
+       /* Look for the requested type/protocol pair. */
+ lookup_protocol:
+       err = -ESOCKTNOSUPPORT;
+diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
+index 28d7a245ea34..25cd22c1ddee 100644
+--- a/net/ipv6/ip6_gre.c
++++ b/net/ipv6/ip6_gre.c
+@@ -1563,13 +1563,11 @@ static int ip6gre_changelink(struct net_device *dev, 
struct nlattr *tb[],
+                       return -EEXIST;
+       } else {
+               t = nt;
+-
+-              ip6gre_tunnel_unlink(ign, t);
+-              ip6gre_tnl_change(t, &p, !tb[IFLA_MTU]);
+-              ip6gre_tunnel_link(ign, t);
+-              netdev_state_change(dev);
+       }
+ 
++      ip6gre_tunnel_unlink(ign, t);
++      ip6gre_tnl_change(t, &p, !tb[IFLA_MTU]);
++      ip6gre_tunnel_link(ign, t);
+       return 0;
+ }
+ 
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index 26feadd0b763..b5a4ac8ce4b1 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -93,10 +93,9 @@ static void inet6_sk_rx_dst_set(struct sock *sk, const 
struct sk_buff *skb)
+ {
+       struct dst_entry *dst = skb_dst(skb);
+ 
+-      if (dst) {
++      if (dst && dst_hold_safe(dst)) {
+               const struct rt6_info *rt = (const struct rt6_info *)dst;
+ 
+-              dst_hold(dst);
+               sk->sk_rx_dst = dst;
+               inet_sk(sk)->rx_dst_ifindex = skb->skb_iif;
+               if (rt->rt6i_node)
+diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
+index 3f3a6cbdceb7..b3f6ec0df426 100644
+--- a/net/irda/af_irda.c
++++ b/net/irda/af_irda.c
+@@ -1100,6 +1100,9 @@ static int irda_create(struct net *net, struct socket 
*sock, int protocol,
+ 
+       IRDA_DEBUG(2, "%s()\n", __func__);
+ 
++      if (protocol < 0 || protocol > SK_PROTOCOL_MAX)
++              return -EINVAL;
++
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+ 
+diff --git a/net/rds/send.c b/net/rds/send.c
+index 0a64541020b0..0bae8d43b012 100644
+--- a/net/rds/send.c
++++ b/net/rds/send.c
+@@ -958,11 +958,13 @@ int rds_sendmsg(struct kiocb *iocb, struct socket *sock, 
struct msghdr *msg,
+               release_sock(sk);
+       }
+ 
+-      /* racing with another thread binding seems ok here */
++      lock_sock(sk);
+       if (daddr == 0 || rs->rs_bound_addr == 0) {
++              release_sock(sk);
+               ret = -ENOTCONN; /* XXX not a great errno */
+               goto out;
+       }
++      release_sock(sk);
+ 
+       /* size of rm including all sgs */
+       ret = rds_rm_size(msg, payload_len);
+diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c
+index 0e4198ee2370..3267a5cbb3e8 100644
+--- a/net/sctp/ipv6.c
++++ b/net/sctp/ipv6.c
+@@ -634,6 +634,7 @@ static struct sock *sctp_v6_create_accept_sk(struct sock 
*sk,
+       struct sock *newsk;
+       struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
+       struct sctp6_sock *newsctp6sk;
++      struct ipv6_txoptions *opt;
+ 
+       newsk = sk_alloc(sock_net(sk), PF_INET6, GFP_KERNEL, sk->sk_prot);
+       if (!newsk)
+@@ -653,6 +654,13 @@ static struct sock *sctp_v6_create_accept_sk(struct sock 
*sk,
+ 
+       memcpy(newnp, np, sizeof(struct ipv6_pinfo));
+ 
++      rcu_read_lock();
++      opt = rcu_dereference(np->opt);
++      if (opt)
++              opt = ipv6_dup_options(newsk, opt);
++      RCU_INIT_POINTER(newnp->opt, opt);
++      rcu_read_unlock();
++
+       /* Initialize sk's sport, dport, rcv_saddr and daddr for getsockname()
+        * and getpeername().
+        */
+diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
+index 371a152d9759..642c11570285 100644
+--- a/net/sctp/sm_make_chunk.c
++++ b/net/sctp/sm_make_chunk.c
+@@ -1652,7 +1652,7 @@ static sctp_cookie_param_t *sctp_pack_cookie(const 
struct sctp_endpoint *ep,
+ 
+       /* Set an expiration time for the cookie.  */
+       cookie->c.expiration = ktime_add(asoc->cookie_life,
+-                                       ktime_get());
++                                       ktime_get_real());
+ 
+       /* Copy the peer's init packet.  */
+       memcpy(&cookie->c.peer_init[0], init_chunk->chunk_hdr,
+@@ -1780,7 +1780,7 @@ no_hmac:
+       if (sock_flag(ep->base.sk, SOCK_TIMESTAMP))
+               kt = skb_get_ktime(skb);
+       else
+-              kt = ktime_get();
++              kt = ktime_get_real();
+ 
+       if (!asoc && ktime_before(bear_cookie->expiration, kt)) {
+               /*
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index fb082aa4d656..4130c1b87dd6 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -7181,6 +7181,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
+       newsk->sk_type = sk->sk_type;
+       newsk->sk_bound_dev_if = sk->sk_bound_dev_if;
+       newsk->sk_flags = sk->sk_flags;
++      newsk->sk_tsflags = sk->sk_tsflags;
+       newsk->sk_no_check_tx = sk->sk_no_check_tx;
+       newsk->sk_no_check_rx = sk->sk_no_check_rx;
+       newsk->sk_reuse = sk->sk_reuse;
+@@ -7213,6 +7214,9 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
+       newinet->mc_ttl = 1;
+       newinet->mc_index = 0;
+       newinet->mc_list = NULL;
++
++      if (newsk->sk_flags & SK_FLAGS_TIMESTAMP)
++              net_enable_timestamp();
+ }
+ 
+ static inline void sctp_copy_descendant(struct sock *sk_to,
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index 2ae4a5915aa7..7229794c1419 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -316,6 +316,118 @@ found:
+       return s;
+ }
+ 
++/* Support code for asymmetrically connected dgram sockets
++ *
++ * If a datagram socket is connected to a socket not itself connected
++ * to the first socket (eg, /dev/log), clients may only enqueue more
++ * messages if the present receive queue of the server socket is not
++ * "too large". This means there's a second writeability condition
++ * poll and sendmsg need to test. The dgram recv code will do a wake
++ * up on the peer_wait wait queue of a socket upon reception of a
++ * datagram which needs to be propagated to sleeping would-be writers
++ * since these might not have sent anything so far. This can't be
++ * accomplished via poll_wait because the lifetime of the server
++ * socket might be less than that of its clients if these break their
++ * association with it or if the server socket is closed while clients
++ * are still connected to it and there's no way to inform "a polling
++ * implementation" that it should let go of a certain wait queue
++ *
++ * In order to propagate a wake up, a wait_queue_t of the client
++ * socket is enqueued on the peer_wait queue of the server socket
++ * whose wake function does a wake_up on the ordinary client socket
++ * wait queue. This connection is established whenever a write (or
++ * poll for write) hit the flow control condition and broken when the
++ * association to the server socket is dissolved or after a wake up
++ * was relayed.
++ */
++
++static int unix_dgram_peer_wake_relay(wait_queue_t *q, unsigned mode, int 
flags,
++                                    void *key)
++{
++      struct unix_sock *u;
++      wait_queue_head_t *u_sleep;
++
++      u = container_of(q, struct unix_sock, peer_wake);
++
++      __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait,
++                          q);
++      u->peer_wake.private = NULL;
++
++      /* relaying can only happen while the wq still exists */
++      u_sleep = sk_sleep(&u->sk);
++      if (u_sleep)
++              wake_up_interruptible_poll(u_sleep, key);
++
++      return 0;
++}
++
++static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other)
++{
++      struct unix_sock *u, *u_other;
++      int rc;
++
++      u = unix_sk(sk);
++      u_other = unix_sk(other);
++      rc = 0;
++      spin_lock(&u_other->peer_wait.lock);
++
++      if (!u->peer_wake.private) {
++              u->peer_wake.private = other;
++              __add_wait_queue(&u_other->peer_wait, &u->peer_wake);
++
++              rc = 1;
++      }
++
++      spin_unlock(&u_other->peer_wait.lock);
++      return rc;
++}
++
++static void unix_dgram_peer_wake_disconnect(struct sock *sk,
++                                          struct sock *other)
++{
++      struct unix_sock *u, *u_other;
++
++      u = unix_sk(sk);
++      u_other = unix_sk(other);
++      spin_lock(&u_other->peer_wait.lock);
++
++      if (u->peer_wake.private == other) {
++              __remove_wait_queue(&u_other->peer_wait, &u->peer_wake);
++              u->peer_wake.private = NULL;
++      }
++
++      spin_unlock(&u_other->peer_wait.lock);
++}
++
++static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk,
++                                                 struct sock *other)
++{
++      unix_dgram_peer_wake_disconnect(sk, other);
++      wake_up_interruptible_poll(sk_sleep(sk),
++                                 POLLOUT |
++                                 POLLWRNORM |
++                                 POLLWRBAND);
++}
++
++/* preconditions:
++ *    - unix_peer(sk) == other
++ *    - association is stable
++ */
++static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
++{
++      int connected;
++
++      connected = unix_dgram_peer_wake_connect(sk, other);
++
++      if (unix_recvq_full(other))
++              return 1;
++
++      if (connected)
++              unix_dgram_peer_wake_disconnect(sk, other);
++
++      return 0;
++}
++
+ static inline int unix_writable(struct sock *sk)
+ {
+       return (atomic_read(&sk->sk_wmem_alloc) << 2) <= sk->sk_sndbuf;
+@@ -420,6 +532,8 @@ static void unix_release_sock(struct sock *sk, int embrion)
+                       skpair->sk_state_change(skpair);
+                       sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
+               }
++
++              unix_dgram_peer_wake_disconnect(sk, skpair);
+               sock_put(skpair); /* It may now die */
+               unix_peer(sk) = NULL;
+       }
+@@ -653,6 +767,7 @@ static struct sock *unix_create1(struct net *net, struct 
socket *sock)
+       INIT_LIST_HEAD(&u->link);
+       mutex_init(&u->readlock); /* single task reading lock */
+       init_waitqueue_head(&u->peer_wait);
++      init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
+       unix_insert_socket(unix_sockets_unbound(sk), sk);
+ out:
+       if (sk == NULL)
+@@ -1020,6 +1135,8 @@ restart:
+       if (unix_peer(sk)) {
+               struct sock *old_peer = unix_peer(sk);
+               unix_peer(sk) = other;
++              unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
++
+               unix_state_double_unlock(sk, other);
+ 
+               if (other != old_peer)
+@@ -1459,6 +1576,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, 
struct socket *sock,
+       struct scm_cookie tmp_scm;
+       int max_level;
+       int data_len = 0;
++      int sk_locked;
+ 
+       if (NULL == siocb->scm)
+               siocb->scm = &tmp_scm;
+@@ -1540,12 +1658,14 @@ restart:
+               goto out_free;
+       }
+ 
++      sk_locked = 0;
+       unix_state_lock(other);
++restart_locked:
+       err = -EPERM;
+       if (!unix_may_send(sk, other))
+               goto out_unlock;
+ 
+-      if (sock_flag(other, SOCK_DEAD)) {
++      if (unlikely(sock_flag(other, SOCK_DEAD))) {
+               /*
+                *      Check with 1003.1g - what should
+                *      datagram error
+@@ -1553,10 +1673,14 @@ restart:
+               unix_state_unlock(other);
+               sock_put(other);
+ 
++              if (!sk_locked)
++                      unix_state_lock(sk);
++
+               err = 0;
+-              unix_state_lock(sk);
+               if (unix_peer(sk) == other) {
+                       unix_peer(sk) = NULL;
++                      unix_dgram_peer_wake_disconnect_wakeup(sk, other);
++
+                       unix_state_unlock(sk);
+ 
+                       unix_dgram_disconnected(sk, other);
+@@ -1582,21 +1706,38 @@ restart:
+                       goto out_unlock;
+       }
+ 
+-      if (unix_peer(other) != sk && unix_recvq_full(other)) {
+-              if (!timeo) {
+-                      err = -EAGAIN;
+-                      goto out_unlock;
++      if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
++              if (timeo) {
++                      timeo = unix_wait_for_peer(other, timeo);
++
++                      err = sock_intr_errno(timeo);
++                      if (signal_pending(current))
++                              goto out_free;
++
++                      goto restart;
+               }
+ 
+-              timeo = unix_wait_for_peer(other, timeo);
++              if (!sk_locked) {
++                      unix_state_unlock(other);
++                      unix_state_double_lock(sk, other);
++              }
+ 
+-              err = sock_intr_errno(timeo);
+-              if (signal_pending(current))
+-                      goto out_free;
++              if (unix_peer(sk) != other ||
++                  unix_dgram_peer_wake_me(sk, other)) {
++                      err = -EAGAIN;
++                      sk_locked = 1;
++                      goto out_unlock;
++              }
+ 
+-              goto restart;
++              if (!sk_locked) {
++                      sk_locked = 1;
++                      goto restart_locked;
++              }
+       }
+ 
++      if (unlikely(sk_locked))
++              unix_state_unlock(sk);
++
+       if (sock_flag(other, SOCK_RCVTSTAMP))
+               __net_timestamp(skb);
+       maybe_add_creds(skb, sock, other);
+@@ -1610,6 +1751,8 @@ restart:
+       return len;
+ 
+ out_unlock:
++      if (sk_locked)
++              unix_state_unlock(sk);
+       unix_state_unlock(other);
+ out_free:
+       kfree_skb(skb);
+@@ -1953,14 +2096,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, 
struct socket *sock,
+               memset(&tmp_scm, 0, sizeof(tmp_scm));
+       }
+ 
+-      err = mutex_lock_interruptible(&u->readlock);
+-      if (unlikely(err)) {
+-              /* recvmsg() in non blocking mode is supposed to return -EAGAIN
+-               * sk_rcvtimeo is not honored by mutex_lock_interruptible()
+-               */
+-              err = noblock ? -EAGAIN : -ERESTARTSYS;
+-              goto out;
+-      }
++      mutex_lock(&u->readlock);
+ 
+       if (flags & MSG_PEEK)
+               skip = sk_peek_offset(sk, flags);
+@@ -2001,12 +2137,12 @@ again:
+ 
+                       timeo = unix_stream_data_wait(sk, timeo, last);
+ 
+-                      if (signal_pending(current)
+-                          ||  mutex_lock_interruptible(&u->readlock)) {
++                      if (signal_pending(current)) {
+                               err = sock_intr_errno(timeo);
+                               goto out;
+                       }
+ 
++                      mutex_lock(&u->readlock);
+                       continue;
+  unlock:
+                       unix_state_unlock(sk);
+@@ -2269,14 +2405,16 @@ static unsigned int unix_dgram_poll(struct file *file, 
struct socket *sock,
+               return mask;
+ 
+       writable = unix_writable(sk);
+-      other = unix_peer_get(sk);
+-      if (other) {
+-              if (unix_peer(other) != sk) {
+-                      sock_poll_wait(file, &unix_sk(other)->peer_wait, wait);
+-                      if (unix_recvq_full(other))
+-                              writable = 0;
+-              }
+-              sock_put(other);
++      if (writable) {
++              unix_state_lock(sk);
++
++              other = unix_peer(sk);
++              if (other && unix_peer(other) != sk &&
++                  unix_recvq_full(other) &&
++                  unix_dgram_peer_wake_me(sk, other))
++                      writable = 0;
++
++              unix_state_unlock(sk);
+       }
+ 
+       if (writable)
+diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
+index 4743d71e4aa6..fee27fe2b30f 100644
+--- a/security/keys/keyctl.c
++++ b/security/keys/keyctl.c
+@@ -757,16 +757,16 @@ long keyctl_read_key(key_serial_t keyid, char __user 
*buffer, size_t buflen)
+ 
+       /* the key is probably readable - now try to read it */
+ can_read_key:
+-      ret = key_validate(key);
+-      if (ret == 0) {
+-              ret = -EOPNOTSUPP;
+-              if (key->type->read) {
+-                      /* read the data with the semaphore held (since we
+-                       * might sleep) */
+-                      down_read(&key->sem);
++      ret = -EOPNOTSUPP;
++      if (key->type->read) {
++              /* Read the data with the semaphore held (since we might sleep)
++               * to protect against the key being updated or revoked.
++               */
++              down_read(&key->sem);
++              ret = key_validate(key);
++              if (ret == 0)
+                       ret = key->type->read(key, buffer, buflen);
+-                      up_read(&key->sem);
+-              }
++              up_read(&key->sem);
+       }
+ 
+ error2:
+diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
+index bd536cb221e2..db91639c81e3 100644
+--- a/security/keys/process_keys.c
++++ b/security/keys/process_keys.c
+@@ -794,6 +794,7 @@ long join_session_keyring(const char *name)
+               ret = PTR_ERR(keyring);
+               goto error2;
+       } else if (keyring == new->session_keyring) {
++              key_put(keyring);
+               ret = 0;
+               goto error2;
+       }
+diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
+index b422e406a9cb..99e952293498 100644
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -48,8 +48,9 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM 
parameters per ELD info");
+ #define is_haswell(codec)  ((codec)->vendor_id == 0x80862807)
+ #define is_broadwell(codec)    ((codec)->vendor_id == 0x80862808)
+ #define is_skylake(codec) ((codec)->vendor_id == 0x80862809)
++#define is_broxton(codec) ((codec)->vendor_id == 0x8086280a)
+ #define is_haswell_plus(codec) (is_haswell(codec) || is_broadwell(codec) \
+-                                      || is_skylake(codec))
++                              || is_skylake(codec) || is_broxton(codec))
+ 
+ #define is_valleyview(codec) ((codec)->vendor_id == 0x80862882)
+ #define is_cherryview(codec) ((codec)->vendor_id == 0x80862883)

diff --git a/1520_keyring-refleak-in-join-session-CVE-2016-0728.patch 
b/1520_keyring-refleak-in-join-session-CVE-2016-0728.patch
deleted file mode 100644
index 49020d7..0000000
--- a/1520_keyring-refleak-in-join-session-CVE-2016-0728.patch
+++ /dev/null
@@ -1,81 +0,0 @@
-From 23567fd052a9abb6d67fe8e7a9ccdd9800a540f2 Mon Sep 17 00:00:00 2001
-From: Yevgeny Pats <yevg...@perception-point.io>
-Date: Tue, 19 Jan 2016 22:09:04 +0000
-Subject: KEYS: Fix keyring ref leak in join_session_keyring()
-
-This fixes CVE-2016-0728.
-
-If a thread is asked to join as a session keyring the keyring that's already
-set as its session, we leak a keyring reference.
-
-This can be tested with the following program:
-
-       #include <stddef.h>
-       #include <stdio.h>
-       #include <sys/types.h>
-       #include <keyutils.h>
-
-       int main(int argc, const char *argv[])
-       {
-               int i = 0;
-               key_serial_t serial;
-
-               serial = keyctl(KEYCTL_JOIN_SESSION_KEYRING,
-                               "leaked-keyring");
-               if (serial < 0) {
-                       perror("keyctl");
-                       return -1;
-               }
-
-               if (keyctl(KEYCTL_SETPERM, serial,
-                          KEY_POS_ALL | KEY_USR_ALL) < 0) {
-                       perror("keyctl");
-                       return -1;
-               }
-
-               for (i = 0; i < 100; i++) {
-                       serial = keyctl(KEYCTL_JOIN_SESSION_KEYRING,
-                                       "leaked-keyring");
-                       if (serial < 0) {
-                               perror("keyctl");
-                               return -1;
-                       }
-               }
-
-               return 0;
-       }
-
-If, after the program has run, there something like the following line in
-/proc/keys:
-
-3f3d898f I--Q---   100 perm 3f3f0000     0     0 keyring   leaked-keyring: 
empty
-
-with a usage count of 100 * the number of times the program has been run,
-then the kernel is malfunctioning.  If leaked-keyring has zero usages or
-has been garbage collected, then the problem is fixed.
-
-Reported-by: Yevgeny Pats <yevg...@perception-point.io>
-Signed-off-by: David Howells <dhowe...@redhat.com>
-Acked-by: Don Zickus <dzic...@redhat.com>
-Acked-by: Prarit Bhargava <pra...@redhat.com>
-Acked-by: Jarod Wilson <ja...@redhat.com>
-Signed-off-by: James Morris <james.l.mor...@oracle.com>
----
- security/keys/process_keys.c | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
-index a3f85d2..e6d50172 100644
---- a/security/keys/process_keys.c
-+++ b/security/keys/process_keys.c
-@@ -794,6 +794,7 @@ long join_session_keyring(const char *name)
-               ret = PTR_ERR(keyring);
-               goto error2;
-       } else if (keyring == new->session_keyring) {
-+              key_put(keyring);
-               ret = 0;
-               goto error2;
-       }
--- 
-cgit v0.12
-

Reply via email to