summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pagano <mpagano@gentoo.org>2016-01-31 10:36:20 -0500
committerMike Pagano <mpagano@gentoo.org>2016-01-31 10:36:20 -0500
commit41033c2db3e1f066508325a49e17c53e24013843 (patch)
tree18eff7e92d7ab46a79fe6bc517f02f6c382a71a0
parentEnsure that thread joining a session keyring does not leak the keyring refere... (diff)
downloadlinux-patches-41033c2db3e1f066508325a49e17c53e24013843.tar.gz
linux-patches-41033c2db3e1f066508325a49e17c53e24013843.tar.bz2
linux-patches-41033c2db3e1f066508325a49e17c53e24013843.zip
Linux patch 3.18.26. Removal of redundant patchset.3.18-27
-rw-r--r--0000_README8
-rw-r--r--1025_linux-3.18.26.patch1763
-rw-r--r--1520_keyring-refleak-in-join-session-CVE-2016-0728.patch81
3 files changed, 1767 insertions, 85 deletions
diff --git a/0000_README b/0000_README
index 3fe5eecd..728c863c 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 00000000..5ad05b03
--- /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 49020d7d..00000000
--- 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 <yevgeny@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 <yevgeny@perception-point.io>
-Signed-off-by: David Howells <dhowells@redhat.com>
-Acked-by: Don Zickus <dzickus@redhat.com>
-Acked-by: Prarit Bhargava <prarit@redhat.com>
-Acked-by: Jarod Wilson <jarod@redhat.com>
-Signed-off-by: James Morris <james.l.morris@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
-