diff options
author | 2016-12-14 07:49:35 -0500 | |
---|---|---|
committer | 2016-12-14 07:49:35 -0500 | |
commit | 294e620804f37e9c6ad5a90ad1c38daac9189256 (patch) | |
tree | a8b4af29748a225d4050e08306b7f8933d9dea3f | |
parent | grsecurity-3.1-4.8.13-201612082118 (diff) | |
download | hardened-patchset-294e620804f37e9c6ad5a90ad1c38daac9189256.tar.gz hardened-patchset-294e620804f37e9c6ad5a90ad1c38daac9189256.tar.bz2 hardened-patchset-294e620804f37e9c6ad5a90ad1c38daac9189256.zip |
grsecurity-3.1-4.8.14-20161211093320161211
-rw-r--r-- | 4.8.14/0000_README (renamed from 4.8.13/0000_README) | 6 | ||||
-rw-r--r-- | 4.8.14/1012_linux-4.8.13.patch (renamed from 4.8.13/1012_linux-4.8.13.patch) | 0 | ||||
-rw-r--r-- | 4.8.14/1013_linux-4.8.14.patch | 1725 | ||||
-rw-r--r-- | 4.8.14/4420_grsecurity-3.1-4.8.14-201612110933.patch (renamed from 4.8.13/4420_grsecurity-3.1-4.8.13-201612082118.patch) | 259 | ||||
-rw-r--r-- | 4.8.14/4425_grsec_remove_EI_PAX.patch (renamed from 4.8.13/4425_grsec_remove_EI_PAX.patch) | 0 | ||||
-rw-r--r-- | 4.8.14/4427_force_XATTR_PAX_tmpfs.patch (renamed from 4.8.13/4427_force_XATTR_PAX_tmpfs.patch) | 6 | ||||
-rw-r--r-- | 4.8.14/4430_grsec-remove-localversion-grsec.patch (renamed from 4.8.13/4430_grsec-remove-localversion-grsec.patch) | 0 | ||||
-rw-r--r-- | 4.8.14/4435_grsec-mute-warnings.patch (renamed from 4.8.13/4435_grsec-mute-warnings.patch) | 0 | ||||
-rw-r--r-- | 4.8.14/4440_grsec-remove-protected-paths.patch (renamed from 4.8.13/4440_grsec-remove-protected-paths.patch) | 0 | ||||
-rw-r--r-- | 4.8.14/4450_grsec-kconfig-default-gids.patch (renamed from 4.8.13/4450_grsec-kconfig-default-gids.patch) | 12 | ||||
-rw-r--r-- | 4.8.14/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 4.8.13/4465_selinux-avc_audit-log-curr_ip.patch) | 2 | ||||
-rw-r--r-- | 4.8.14/4470_disable-compat_vdso.patch (renamed from 4.8.13/4470_disable-compat_vdso.patch) | 0 | ||||
-rw-r--r-- | 4.8.14/4475_emutramp_default_on.patch (renamed from 4.8.13/4475_emutramp_default_on.patch) | 0 |
13 files changed, 1856 insertions, 154 deletions
diff --git a/4.8.13/0000_README b/4.8.14/0000_README index 4bb277a..e2c9a03 100644 --- a/4.8.13/0000_README +++ b/4.8.14/0000_README @@ -6,7 +6,11 @@ Patch: 1012_linux-4.8.13.patch From: http://www.kernel.org Desc: Linux 4.8.13 -Patch: 4420_grsecurity-3.1-4.8.13-201612082118.patch +Patch: 1013_linux-4.8.14.patch +From: http://www.kernel.org +Desc: Linux 4.8.14 + +Patch: 4420_grsecurity-3.1-4.8.14-201612110933.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/4.8.13/1012_linux-4.8.13.patch b/4.8.14/1012_linux-4.8.13.patch index c742393..c742393 100644 --- a/4.8.13/1012_linux-4.8.13.patch +++ b/4.8.14/1012_linux-4.8.13.patch diff --git a/4.8.14/1013_linux-4.8.14.patch b/4.8.14/1013_linux-4.8.14.patch new file mode 100644 index 0000000..63d837b --- /dev/null +++ b/4.8.14/1013_linux-4.8.14.patch @@ -0,0 +1,1725 @@ +diff --git a/Makefile b/Makefile +index b38abe9..6a74924 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 8 +-SUBLEVEL = 13 ++SUBLEVEL = 14 + EXTRAVERSION = + NAME = Psychotic Stoned Sheep + +diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c +index c3c12ef..9c0c8fd 100644 +--- a/arch/sparc/kernel/signal_32.c ++++ b/arch/sparc/kernel/signal_32.c +@@ -89,7 +89,7 @@ asmlinkage void do_sigreturn(struct pt_regs *regs) + sf = (struct signal_frame __user *) regs->u_regs[UREG_FP]; + + /* 1. Make sure we are not getting garbage from the user */ +- if (!invalid_frame_pointer(sf, sizeof(*sf))) ++ if (invalid_frame_pointer(sf, sizeof(*sf))) + goto segv_and_exit; + + if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP])) +@@ -150,7 +150,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) + + synchronize_user_stack(); + sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP]; +- if (!invalid_frame_pointer(sf, sizeof(*sf))) ++ if (invalid_frame_pointer(sf, sizeof(*sf))) + goto segv; + + if (get_user(ufp, &sf->regs.u_regs[UREG_FP])) +diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c +index 7ac6b62..05c7708 100644 +--- a/arch/sparc/mm/init_64.c ++++ b/arch/sparc/mm/init_64.c +@@ -802,8 +802,10 @@ struct mdesc_mblock { + }; + static struct mdesc_mblock *mblocks; + static int num_mblocks; ++static int find_numa_node_for_addr(unsigned long pa, ++ struct node_mem_mask *pnode_mask); + +-static unsigned long ra_to_pa(unsigned long addr) ++static unsigned long __init ra_to_pa(unsigned long addr) + { + int i; + +@@ -819,8 +821,11 @@ static unsigned long ra_to_pa(unsigned long addr) + return addr; + } + +-static int find_node(unsigned long addr) ++static int __init find_node(unsigned long addr) + { ++ static bool search_mdesc = true; ++ static struct node_mem_mask last_mem_mask = { ~0UL, ~0UL }; ++ static int last_index; + int i; + + addr = ra_to_pa(addr); +@@ -830,13 +835,30 @@ static int find_node(unsigned long addr) + if ((addr & p->mask) == p->val) + return i; + } +- /* The following condition has been observed on LDOM guests.*/ +- WARN_ONCE(1, "find_node: A physical address doesn't match a NUMA node" +- " rule. Some physical memory will be owned by node 0."); +- return 0; ++ /* The following condition has been observed on LDOM guests because ++ * node_masks only contains the best latency mask and value. ++ * LDOM guest's mdesc can contain a single latency group to ++ * cover multiple address range. Print warning message only if the ++ * address cannot be found in node_masks nor mdesc. ++ */ ++ if ((search_mdesc) && ++ ((addr & last_mem_mask.mask) != last_mem_mask.val)) { ++ /* find the available node in the mdesc */ ++ last_index = find_numa_node_for_addr(addr, &last_mem_mask); ++ numadbg("find_node: latency group for address 0x%lx is %d\n", ++ addr, last_index); ++ if ((last_index < 0) || (last_index >= num_node_masks)) { ++ /* WARN_ONCE() and use default group 0 */ ++ WARN_ONCE(1, "find_node: A physical address doesn't match a NUMA node rule. Some physical memory will be owned by node 0."); ++ search_mdesc = false; ++ last_index = 0; ++ } ++ } ++ ++ return last_index; + } + +-static u64 memblock_nid_range(u64 start, u64 end, int *nid) ++static u64 __init memblock_nid_range(u64 start, u64 end, int *nid) + { + *nid = find_node(start); + start += PAGE_SIZE; +@@ -1160,6 +1182,41 @@ int __node_distance(int from, int to) + return numa_latency[from][to]; + } + ++static int find_numa_node_for_addr(unsigned long pa, ++ struct node_mem_mask *pnode_mask) ++{ ++ struct mdesc_handle *md = mdesc_grab(); ++ u64 node, arc; ++ int i = 0; ++ ++ node = mdesc_node_by_name(md, MDESC_NODE_NULL, "latency-groups"); ++ if (node == MDESC_NODE_NULL) ++ goto out; ++ ++ mdesc_for_each_node_by_name(md, node, "group") { ++ mdesc_for_each_arc(arc, md, node, MDESC_ARC_TYPE_FWD) { ++ u64 target = mdesc_arc_target(md, arc); ++ struct mdesc_mlgroup *m = find_mlgroup(target); ++ ++ if (!m) ++ continue; ++ if ((pa & m->mask) == m->match) { ++ if (pnode_mask) { ++ pnode_mask->mask = m->mask; ++ pnode_mask->val = m->match; ++ } ++ mdesc_release(md); ++ return i; ++ } ++ } ++ i++; ++ } ++ ++out: ++ mdesc_release(md); ++ return -1; ++} ++ + static int __init find_best_numa_node_for_mlgroup(struct mdesc_mlgroup *grp) + { + int i; +diff --git a/block/blk-map.c b/block/blk-map.c +index b8657fa..27fd8d92 100644 +--- a/block/blk-map.c ++++ b/block/blk-map.c +@@ -118,6 +118,9 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, + struct iov_iter i; + int ret; + ++ if (!iter_is_iovec(iter)) ++ goto fail; ++ + if (map_data) + copy = true; + else if (iov_iter_alignment(iter) & align) +@@ -140,6 +143,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, + + unmap_rq: + __blk_rq_unmap_user(bio); ++fail: + rq->bio = NULL; + return -EINVAL; + } +diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c +index bda37d3..b081929 100644 +--- a/drivers/net/dsa/b53/b53_common.c ++++ b/drivers/net/dsa/b53/b53_common.c +@@ -904,9 +904,10 @@ static void b53_vlan_add(struct dsa_switch *ds, int port, + + vl->members |= BIT(port) | BIT(cpu_port); + if (untagged) +- vl->untag |= BIT(port) | BIT(cpu_port); ++ vl->untag |= BIT(port); + else +- vl->untag &= ~(BIT(port) | BIT(cpu_port)); ++ vl->untag &= ~BIT(port); ++ vl->untag &= ~BIT(cpu_port); + + b53_set_vlan_entry(dev, vid, vl); + b53_fast_age_vlan(dev, vid); +@@ -915,8 +916,6 @@ static void b53_vlan_add(struct dsa_switch *ds, int port, + if (pvid) { + b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), + vlan->vid_end); +- b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(cpu_port), +- vlan->vid_end); + b53_fast_age_vlan(dev, vid); + } + } +@@ -926,7 +925,6 @@ static int b53_vlan_del(struct dsa_switch *ds, int port, + { + struct b53_device *dev = ds_to_priv(ds); + bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; +- unsigned int cpu_port = dev->cpu_port; + struct b53_vlan *vl; + u16 vid; + u16 pvid; +@@ -939,8 +937,6 @@ static int b53_vlan_del(struct dsa_switch *ds, int port, + b53_get_vlan_entry(dev, vid, vl); + + vl->members &= ~BIT(port); +- if ((vl->members & BIT(cpu_port)) == BIT(cpu_port)) +- vl->members = 0; + + if (pvid == vid) { + if (is5325(dev) || is5365(dev)) +@@ -949,18 +945,14 @@ static int b53_vlan_del(struct dsa_switch *ds, int port, + pvid = 0; + } + +- if (untagged) { ++ if (untagged) + vl->untag &= ~(BIT(port)); +- if ((vl->untag & BIT(cpu_port)) == BIT(cpu_port)) +- vl->untag = 0; +- } + + b53_set_vlan_entry(dev, vid, vl); + b53_fast_age_vlan(dev, vid); + } + + b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), pvid); +- b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(cpu_port), pvid); + b53_fast_age_vlan(dev, pvid); + + return 0; +diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c +index b2b8387..4036865 100644 +--- a/drivers/net/dsa/bcm_sf2.c ++++ b/drivers/net/dsa/bcm_sf2.c +@@ -1167,6 +1167,7 @@ static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port, + struct phy_device *phydev) + { + struct bcm_sf2_priv *priv = ds_to_priv(ds); ++ struct ethtool_eee *p = &priv->port_sts[port].eee; + u32 id_mode_dis = 0, port_mode; + const char *str = NULL; + u32 reg; +@@ -1241,6 +1242,9 @@ static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port, + reg |= DUPLX_MODE; + + core_writel(priv, reg, CORE_STS_OVERRIDE_GMIIP_PORT(port)); ++ ++ if (!phydev->is_pseudo_fixed_link) ++ p->eee_enabled = bcm_sf2_eee_init(ds, port, phydev); + } + + static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port, +diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +index 5414563..842d8b9 100644 +--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c ++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c +@@ -1172,6 +1172,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, + struct bcmgenet_tx_ring *ring) + { + struct bcmgenet_priv *priv = netdev_priv(dev); ++ struct device *kdev = &priv->pdev->dev; + struct enet_cb *tx_cb_ptr; + struct netdev_queue *txq; + unsigned int pkts_compl = 0; +@@ -1199,13 +1200,13 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, + if (tx_cb_ptr->skb) { + pkts_compl++; + bytes_compl += GENET_CB(tx_cb_ptr->skb)->bytes_sent; +- dma_unmap_single(&dev->dev, ++ dma_unmap_single(kdev, + dma_unmap_addr(tx_cb_ptr, dma_addr), + dma_unmap_len(tx_cb_ptr, dma_len), + DMA_TO_DEVICE); + bcmgenet_free_cb(tx_cb_ptr); + } else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) { +- dma_unmap_page(&dev->dev, ++ dma_unmap_page(kdev, + dma_unmap_addr(tx_cb_ptr, dma_addr), + dma_unmap_len(tx_cb_ptr, dma_len), + DMA_TO_DEVICE); +@@ -1775,6 +1776,7 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv, + + static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv) + { ++ struct device *kdev = &priv->pdev->dev; + struct enet_cb *cb; + int i; + +@@ -1782,7 +1784,7 @@ static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv) + cb = &priv->rx_cbs[i]; + + if (dma_unmap_addr(cb, dma_addr)) { +- dma_unmap_single(&priv->dev->dev, ++ dma_unmap_single(kdev, + dma_unmap_addr(cb, dma_addr), + priv->rx_buf_len, DMA_FROM_DEVICE); + dma_unmap_addr_set(cb, dma_addr, 0); +diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c +index d954a97..ef0dbcf 100644 +--- a/drivers/net/ethernet/cadence/macb.c ++++ b/drivers/net/ethernet/cadence/macb.c +@@ -959,6 +959,7 @@ static inline void macb_init_rx_ring(struct macb *bp) + addr += bp->rx_buffer_size; + } + bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP); ++ bp->rx_tail = 0; + } + + static int macb_rx(struct macb *bp, int budget) +@@ -1597,8 +1598,6 @@ static void macb_init_rings(struct macb *bp) + bp->queues[0].tx_head = 0; + bp->queues[0].tx_tail = 0; + bp->queues[0].tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP); +- +- bp->rx_tail = 0; + } + + static void macb_reset_hw(struct macb *bp) +diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c +index 467138b..d747e17 100644 +--- a/drivers/net/ethernet/marvell/sky2.c ++++ b/drivers/net/ethernet/marvell/sky2.c +@@ -5220,6 +5220,19 @@ static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sky2_suspend, sky2_resume); + + static void sky2_shutdown(struct pci_dev *pdev) + { ++ struct sky2_hw *hw = pci_get_drvdata(pdev); ++ int port; ++ ++ for (port = 0; port < hw->ports; port++) { ++ struct net_device *ndev = hw->dev[port]; ++ ++ rtnl_lock(); ++ if (netif_running(ndev)) { ++ dev_close(ndev); ++ netif_device_detach(ndev); ++ } ++ rtnl_unlock(); ++ } + sky2_suspend(&pdev->dev); + pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev)); + pci_set_power_state(pdev, PCI_D3hot); +diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c +index 054e795..92c9a95 100644 +--- a/drivers/net/ethernet/renesas/sh_eth.c ++++ b/drivers/net/ethernet/renesas/sh_eth.c +@@ -518,7 +518,7 @@ static struct sh_eth_cpu_data r7s72100_data = { + + .ecsr_value = ECSR_ICD, + .ecsipr_value = ECSIPR_ICDIP, +- .eesipr_value = 0xff7f009f, ++ .eesipr_value = 0xe77f009f, + + .tx_check = EESR_TC1 | EESR_FTC, + .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | +diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c +index 16af1ce..5ad706b 100644 +--- a/drivers/net/geneve.c ++++ b/drivers/net/geneve.c +@@ -844,7 +844,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, + struct geneve_dev *geneve = netdev_priv(dev); + struct geneve_sock *gs4 = geneve->sock4; + struct rtable *rt = NULL; +- const struct iphdr *iip; /* interior IP header */ + int err = -EINVAL; + struct flowi4 fl4; + __u8 tos, ttl; +@@ -871,8 +870,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, + sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); + skb_reset_mac_header(skb); + +- iip = ip_hdr(skb); +- + if (info) { + const struct ip_tunnel_key *key = &info->key; + u8 *opts = NULL; +@@ -892,7 +889,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, + if (unlikely(err)) + goto tx_error; + +- tos = ip_tunnel_ecn_encap(key->tos, iip, skb); ++ tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb); + ttl = key->ttl; + df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; + } else { +@@ -901,7 +898,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, + if (unlikely(err)) + goto tx_error; + +- tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, iip, skb); ++ tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, ip_hdr(skb), skb); + ttl = geneve->ttl; + if (!ttl && IN_MULTICAST(ntohl(fl4.daddr))) + ttl = 1; +@@ -934,7 +931,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, + struct geneve_dev *geneve = netdev_priv(dev); + struct geneve_sock *gs6 = geneve->sock6; + struct dst_entry *dst = NULL; +- const struct iphdr *iip; /* interior IP header */ + int err = -EINVAL; + struct flowi6 fl6; + __u8 prio, ttl; +@@ -959,8 +955,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, + sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); + skb_reset_mac_header(skb); + +- iip = ip_hdr(skb); +- + if (info) { + const struct ip_tunnel_key *key = &info->key; + u8 *opts = NULL; +@@ -981,7 +975,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, + if (unlikely(err)) + goto tx_error; + +- prio = ip_tunnel_ecn_encap(key->tos, iip, skb); ++ prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb); + ttl = key->ttl; + label = info->key.label; + } else { +@@ -991,7 +985,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, + goto tx_error; + + prio = ip_tunnel_ecn_encap(ip6_tclass(fl6.flowlabel), +- iip, skb); ++ ip_hdr(skb), skb); + ttl = geneve->ttl; + if (!ttl && ipv6_addr_is_multicast(&fl6.daddr)) + ttl = 1; +diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c +index c47ec0a..dd623f6 100644 +--- a/drivers/net/usb/cdc_ether.c ++++ b/drivers/net/usb/cdc_ether.c +@@ -388,12 +388,6 @@ void usbnet_cdc_status(struct usbnet *dev, struct urb *urb) + case USB_CDC_NOTIFY_NETWORK_CONNECTION: + netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n", + event->wValue ? "on" : "off"); +- +- /* Work-around for devices with broken off-notifications */ +- if (event->wValue && +- !test_bit(__LINK_STATE_NOCARRIER, &dev->net->state)) +- usbnet_link_change(dev, 0, 0); +- + usbnet_link_change(dev, !!event->wValue, 0); + break; + case USB_CDC_NOTIFY_SPEED_CHANGE: /* tx/rx rates */ +@@ -466,6 +460,36 @@ static int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb) + return 1; + } + ++/* Ensure correct link state ++ * ++ * Some devices (ZTE MF823/831/910) export two carrier on notifications when ++ * connected. This causes the link state to be incorrect. Work around this by ++ * always setting the state to off, then on. ++ */ ++void usbnet_cdc_zte_status(struct usbnet *dev, struct urb *urb) ++{ ++ struct usb_cdc_notification *event; ++ ++ if (urb->actual_length < sizeof(*event)) ++ return; ++ ++ event = urb->transfer_buffer; ++ ++ if (event->bNotificationType != USB_CDC_NOTIFY_NETWORK_CONNECTION) { ++ usbnet_cdc_status(dev, urb); ++ return; ++ } ++ ++ netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n", ++ event->wValue ? "on" : "off"); ++ ++ if (event->wValue && ++ netif_carrier_ok(dev->net)) ++ netif_carrier_off(dev->net); ++ ++ usbnet_link_change(dev, !!event->wValue, 0); ++} ++ + static const struct driver_info cdc_info = { + .description = "CDC Ethernet Device", + .flags = FLAG_ETHER | FLAG_POINTTOPOINT, +@@ -481,7 +505,7 @@ static const struct driver_info zte_cdc_info = { + .flags = FLAG_ETHER | FLAG_POINTTOPOINT, + .bind = usbnet_cdc_zte_bind, + .unbind = usbnet_cdc_unbind, +- .status = usbnet_cdc_status, ++ .status = usbnet_cdc_zte_status, + .set_rx_mode = usbnet_cdc_update_filter, + .manage_power = usbnet_manage_power, + .rx_fixup = usbnet_cdc_zte_rx_fixup, +diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c +index bf3fd34..d807209 100644 +--- a/drivers/net/virtio_net.c ++++ b/drivers/net/virtio_net.c +@@ -1468,6 +1468,11 @@ static void virtnet_free_queues(struct virtnet_info *vi) + netif_napi_del(&vi->rq[i].napi); + } + ++ /* We called napi_hash_del() before netif_napi_del(), ++ * we need to respect an RCU grace period before freeing vi->rq ++ */ ++ synchronize_net(); ++ + kfree(vi->rq); + kfree(vi->sq); + } +diff --git a/include/linux/uio.h b/include/linux/uio.h +index 75b4aaf..944e7ba 100644 +--- a/include/linux/uio.h ++++ b/include/linux/uio.h +@@ -102,12 +102,12 @@ int iov_iter_npages(const struct iov_iter *i, int maxpages); + + const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags); + +-static inline size_t iov_iter_count(struct iov_iter *i) ++static inline size_t iov_iter_count(const struct iov_iter *i) + { + return i->count; + } + +-static inline bool iter_is_iovec(struct iov_iter *i) ++static inline bool iter_is_iovec(const struct iov_iter *i) + { + return !(i->type & (ITER_BVEC | ITER_KVEC)); + } +diff --git a/include/net/gro_cells.h b/include/net/gro_cells.h +index d15214d..2a1abbf 100644 +--- a/include/net/gro_cells.h ++++ b/include/net/gro_cells.h +@@ -68,6 +68,9 @@ static inline int gro_cells_init(struct gro_cells *gcells, struct net_device *de + struct gro_cell *cell = per_cpu_ptr(gcells->cells, i); + + __skb_queue_head_init(&cell->napi_skbs); ++ ++ set_bit(NAPI_STATE_NO_BUSY_POLL, &cell->napi.state); ++ + netif_napi_add(dev, &cell->napi, gro_cell_poll, 64); + napi_enable(&cell->napi); + } +diff --git a/net/core/flow.c b/net/core/flow.c +index 3937b1b..18e8893 100644 +--- a/net/core/flow.c ++++ b/net/core/flow.c +@@ -95,7 +95,6 @@ static void flow_cache_gc_task(struct work_struct *work) + list_for_each_entry_safe(fce, n, &gc_list, u.gc_list) { + flow_entry_kill(fce, xfrm); + atomic_dec(&xfrm->flow_cache_gc_count); +- WARN_ON(atomic_read(&xfrm->flow_cache_gc_count) < 0); + } + } + +@@ -236,9 +235,8 @@ flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir, + if (fcp->hash_count > fc->high_watermark) + flow_cache_shrink(fc, fcp); + +- if (fcp->hash_count > 2 * fc->high_watermark || +- atomic_read(&net->xfrm.flow_cache_gc_count) > fc->high_watermark) { +- atomic_inc(&net->xfrm.flow_cache_genid); ++ if (atomic_read(&net->xfrm.flow_cache_gc_count) > ++ 2 * num_online_cpus() * fc->high_watermark) { + flo = ERR_PTR(-ENOBUFS); + goto ret_object; + } +diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c +index 2c2eb1b..2e9a1c2 100644 +--- a/net/core/net_namespace.c ++++ b/net/core/net_namespace.c +@@ -217,6 +217,8 @@ int peernet2id_alloc(struct net *net, struct net *peer) + bool alloc; + int id; + ++ if (atomic_read(&net->count) == 0) ++ return NETNSA_NSID_NOT_ASSIGNED; + spin_lock_irqsave(&net->nsid_lock, flags); + alloc = atomic_read(&peer->count) == 0 ? false : true; + id = __peernet2id_alloc(net, peer, &alloc); +diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c +index 189cc78..08c3702 100644 +--- a/net/core/rtnetlink.c ++++ b/net/core/rtnetlink.c +@@ -1578,7 +1578,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) + head = &net->dev_index_head[h]; + hlist_for_each_entry(dev, head, index_hlist) { + if (link_dump_filtered(dev, master_idx, kind_ops)) +- continue; ++ goto cont; + if (idx < s_idx) + goto cont; + err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, +@@ -2791,7 +2791,10 @@ static int nlmsg_populate_fdb_fill(struct sk_buff *skb, + + static inline size_t rtnl_fdb_nlmsg_size(void) + { +- return NLMSG_ALIGN(sizeof(struct ndmsg)) + nla_total_size(ETH_ALEN); ++ return NLMSG_ALIGN(sizeof(struct ndmsg)) + ++ nla_total_size(ETH_ALEN) + /* NDA_LLADDR */ ++ nla_total_size(sizeof(u16)) + /* NDA_VLAN */ ++ 0; + } + + static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type, +diff --git a/net/core/sock.c b/net/core/sock.c +index 10acacc..ba27920 100644 +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -715,7 +715,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, + val = min_t(u32, val, sysctl_wmem_max); + set_sndbuf: + sk->sk_userlocks |= SOCK_SNDBUF_LOCK; +- sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF); ++ sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF); + /* Wake up sending tasks if we upped the value. */ + sk->sk_write_space(sk); + break; +@@ -751,7 +751,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, + * returning the value we actually used in getsockopt + * is the most desirable behavior. + */ +- sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF); ++ sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF); + break; + + case SO_RCVBUFFORCE: +diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c +index b567c87..edbe59d 100644 +--- a/net/dccp/ipv4.c ++++ b/net/dccp/ipv4.c +@@ -700,6 +700,7 @@ int dccp_invalid_packet(struct sk_buff *skb) + { + const struct dccp_hdr *dh; + unsigned int cscov; ++ u8 dccph_doff; + + if (skb->pkt_type != PACKET_HOST) + return 1; +@@ -721,18 +722,19 @@ int dccp_invalid_packet(struct sk_buff *skb) + /* + * If P.Data Offset is too small for packet type, drop packet and return + */ +- if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) { +- DCCP_WARN("P.Data Offset(%u) too small\n", dh->dccph_doff); ++ dccph_doff = dh->dccph_doff; ++ if (dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) { ++ DCCP_WARN("P.Data Offset(%u) too small\n", dccph_doff); + return 1; + } + /* + * If P.Data Offset is too too large for packet, drop packet and return + */ +- if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) { +- DCCP_WARN("P.Data Offset(%u) too large\n", dh->dccph_doff); ++ if (!pskb_may_pull(skb, dccph_doff * sizeof(u32))) { ++ DCCP_WARN("P.Data Offset(%u) too large\n", dccph_doff); + return 1; + } +- ++ dh = dccp_hdr(skb); + /* + * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet + * has short sequence numbers), drop packet and return +diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c +index f30bad9..3bdecd2 100644 +--- a/net/dsa/dsa2.c ++++ b/net/dsa/dsa2.c +@@ -28,8 +28,10 @@ static struct dsa_switch_tree *dsa_get_dst(u32 tree) + struct dsa_switch_tree *dst; + + list_for_each_entry(dst, &dsa_switch_trees, list) +- if (dst->tree == tree) ++ if (dst->tree == tree) { ++ kref_get(&dst->refcount); + return dst; ++ } + return NULL; + } + +diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c +index eebbc0f..ed22af6 100644 +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -1237,7 +1237,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb, + fixedid = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID); + + /* fixed ID is invalid if DF bit is not set */ +- if (fixedid && !(iph->frag_off & htons(IP_DF))) ++ if (fixedid && !(ip_hdr(skb)->frag_off & htons(IP_DF))) + goto out; + } + +diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c +index d95631d..20fb25e 100644 +--- a/net/ipv4/esp4.c ++++ b/net/ipv4/esp4.c +@@ -476,7 +476,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) + esph = (void *)skb_push(skb, 4); + *seqhi = esph->spi; + esph->spi = esph->seq_no; +- esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.input.hi); ++ esph->seq_no = XFRM_SKB_CB(skb)->seq.input.hi; + aead_request_set_callback(req, 0, esp_input_done_esn, skb); + } + +diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c +index 1b25daf..9301308 100644 +--- a/net/ipv4/fib_frontend.c ++++ b/net/ipv4/fib_frontend.c +@@ -157,7 +157,7 @@ static void fib_replace_table(struct net *net, struct fib_table *old, + + int fib_unmerge(struct net *net) + { +- struct fib_table *old, *new; ++ struct fib_table *old, *new, *main_table; + + /* attempt to fetch local table if it has been allocated */ + old = fib_get_table(net, RT_TABLE_LOCAL); +@@ -168,11 +168,21 @@ int fib_unmerge(struct net *net) + if (!new) + return -ENOMEM; + ++ /* table is already unmerged */ ++ if (new == old) ++ return 0; ++ + /* replace merged table with clean table */ +- if (new != old) { +- fib_replace_table(net, old, new); +- fib_free_table(old); +- } ++ fib_replace_table(net, old, new); ++ fib_free_table(old); ++ ++ /* attempt to fetch main table if it has been allocated */ ++ main_table = fib_get_table(net, RT_TABLE_MAIN); ++ if (!main_table) ++ return 0; ++ ++ /* flush local entries from main table */ ++ fib_table_flush_external(main_table); + + return 0; + } +diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c +index 7ef7031..84fd7272 100644 +--- a/net/ipv4/fib_trie.c ++++ b/net/ipv4/fib_trie.c +@@ -681,6 +681,13 @@ static unsigned char update_suffix(struct key_vector *tn) + { + unsigned char slen = tn->pos; + unsigned long stride, i; ++ unsigned char slen_max; ++ ++ /* only vector 0 can have a suffix length greater than or equal to ++ * tn->pos + tn->bits, the second highest node will have a suffix ++ * length at most of tn->pos + tn->bits - 1 ++ */ ++ slen_max = min_t(unsigned char, tn->pos + tn->bits - 1, tn->slen); + + /* search though the list of children looking for nodes that might + * have a suffix greater than the one we currently have. This is +@@ -698,12 +705,8 @@ static unsigned char update_suffix(struct key_vector *tn) + slen = n->slen; + i &= ~(stride - 1); + +- /* if slen covers all but the last bit we can stop here +- * there will be nothing longer than that since only node +- * 0 and 1 << (bits - 1) could have that as their suffix +- * length. +- */ +- if ((slen + 1) >= (tn->pos + tn->bits)) ++ /* stop searching if we have hit the maximum possible value */ ++ if (slen >= slen_max) + break; + } + +@@ -875,39 +878,27 @@ static struct key_vector *resize(struct trie *t, struct key_vector *tn) + return collapse(t, tn); + + /* update parent in case halve failed */ +- tp = node_parent(tn); +- +- /* Return if at least one deflate was run */ +- if (max_work != MAX_WORK) +- return tp; +- +- /* push the suffix length to the parent node */ +- if (tn->slen > tn->pos) { +- unsigned char slen = update_suffix(tn); +- +- if (slen > tp->slen) +- tp->slen = slen; +- } +- +- return tp; ++ return node_parent(tn); + } + +-static void leaf_pull_suffix(struct key_vector *tp, struct key_vector *l) ++static void node_pull_suffix(struct key_vector *tn, unsigned char slen) + { +- while ((tp->slen > tp->pos) && (tp->slen > l->slen)) { +- if (update_suffix(tp) > l->slen) ++ unsigned char node_slen = tn->slen; ++ ++ while ((node_slen > tn->pos) && (node_slen > slen)) { ++ slen = update_suffix(tn); ++ if (node_slen == slen) + break; +- tp = node_parent(tp); ++ ++ tn = node_parent(tn); ++ node_slen = tn->slen; + } + } + +-static void leaf_push_suffix(struct key_vector *tn, struct key_vector *l) ++static void node_push_suffix(struct key_vector *tn, unsigned char slen) + { +- /* if this is a new leaf then tn will be NULL and we can sort +- * out parent suffix lengths as a part of trie_rebalance +- */ +- while (tn->slen < l->slen) { +- tn->slen = l->slen; ++ while (tn->slen < slen) { ++ tn->slen = slen; + tn = node_parent(tn); + } + } +@@ -1028,6 +1019,7 @@ static int fib_insert_node(struct trie *t, struct key_vector *tp, + } + + /* Case 3: n is NULL, and will just insert a new leaf */ ++ node_push_suffix(tp, new->fa_slen); + NODE_INIT_PARENT(l, tp); + put_child_root(tp, key, l); + trie_rebalance(t, tp); +@@ -1069,7 +1061,7 @@ static int fib_insert_alias(struct trie *t, struct key_vector *tp, + /* if we added to the tail node then we need to update slen */ + if (l->slen < new->fa_slen) { + l->slen = new->fa_slen; +- leaf_push_suffix(tp, l); ++ node_push_suffix(tp, new->fa_slen); + } + + return 0; +@@ -1470,6 +1462,8 @@ static void fib_remove_alias(struct trie *t, struct key_vector *tp, + * out parent suffix lengths as a part of trie_rebalance + */ + if (hlist_empty(&l->leaf)) { ++ if (tp->slen == l->slen) ++ node_pull_suffix(tp, tp->pos); + put_child_root(tp, l->key, NULL); + node_free(l); + trie_rebalance(t, tp); +@@ -1482,7 +1476,7 @@ static void fib_remove_alias(struct trie *t, struct key_vector *tp, + + /* update the trie with the latest suffix length */ + l->slen = fa->fa_slen; +- leaf_pull_suffix(tp, l); ++ node_pull_suffix(tp, fa->fa_slen); + } + + /* Caller must hold RTNL. */ +@@ -1713,8 +1707,10 @@ struct fib_table *fib_trie_unmerge(struct fib_table *oldtb) + local_l = fib_find_node(lt, &local_tp, l->key); + + if (fib_insert_alias(lt, local_tp, local_l, new_fa, +- NULL, l->key)) ++ NULL, l->key)) { ++ kmem_cache_free(fn_alias_kmem, new_fa); + goto out; ++ } + } + + /* stop loop if key wrapped back to 0 */ +@@ -1751,6 +1747,10 @@ void fib_table_flush_external(struct fib_table *tb) + if (IS_TRIE(pn)) + break; + ++ /* update the suffix to address pulled leaves */ ++ if (pn->slen > pn->pos) ++ update_suffix(pn); ++ + /* resize completed node */ + pn = resize(t, pn); + cindex = get_index(pkey, pn); +@@ -1826,6 +1826,10 @@ int fib_table_flush(struct fib_table *tb) + if (IS_TRIE(pn)) + break; + ++ /* update the suffix to address pulled leaves */ ++ if (pn->slen > pn->pos) ++ update_suffix(pn); ++ + /* resize completed node */ + pn = resize(t, pn); + cindex = get_index(pkey, pn); +diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c +index 307daed..f4790c3 100644 +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -98,6 +98,9 @@ int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb) + + iph->tot_len = htons(skb->len); + ip_send_check(iph); ++ ++ skb->protocol = htons(ETH_P_IP); ++ + return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, + net, sk, skb, NULL, skb_dst(skb)->dev, + dst_output); +diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c +index 66ddcb6..dcdd5ae 100644 +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -662,6 +662,10 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len, + if (len > 0xFFFF) + return -EMSGSIZE; + ++ /* Must have at least a full ICMP header. */ ++ if (len < icmph_len) ++ return -EINVAL; ++ + /* + * Check the flags. + */ +diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c +index c0d71e7..a2d54f5 100644 +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -1451,7 +1451,7 @@ static void udp_v4_rehash(struct sock *sk) + udp_lib_rehash(sk, new_hash); + } + +-static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) ++int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) + { + int rc; + +diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h +index 7e0fe4b..feb50a1 100644 +--- a/net/ipv4/udp_impl.h ++++ b/net/ipv4/udp_impl.h +@@ -25,7 +25,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock, + int flags, int *addr_len); + int udp_sendpage(struct sock *sk, struct page *page, int offset, size_t size, + int flags); +-int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); ++int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); + void udp_destroy_sock(struct sock *sk); + + #ifdef CONFIG_PROC_FS +diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c +index 2eea073..705d9fb 100644 +--- a/net/ipv4/udplite.c ++++ b/net/ipv4/udplite.c +@@ -50,7 +50,7 @@ struct proto udplite_prot = { + .sendmsg = udp_sendmsg, + .recvmsg = udp_recvmsg, + .sendpage = udp_sendpage, +- .backlog_rcv = udp_queue_rcv_skb, ++ .backlog_rcv = __udp_queue_rcv_skb, + .hash = udp_lib_hash, + .unhash = udp_lib_unhash, + .get_port = udp_v4_get_port, +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index f5432d6..8f2e36f 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -163,7 +163,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx, + + static void addrconf_dad_start(struct inet6_ifaddr *ifp); + static void addrconf_dad_work(struct work_struct *w); +-static void addrconf_dad_completed(struct inet6_ifaddr *ifp); ++static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id); + static void addrconf_dad_run(struct inet6_dev *idev); + static void addrconf_rs_timer(unsigned long data); + static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa); +@@ -2893,6 +2893,7 @@ static void add_addr(struct inet6_dev *idev, const struct in6_addr *addr, + spin_lock_bh(&ifp->lock); + ifp->flags &= ~IFA_F_TENTATIVE; + spin_unlock_bh(&ifp->lock); ++ rt_genid_bump_ipv6(dev_net(idev->dev)); + ipv6_ifa_notify(RTM_NEWADDR, ifp); + in6_ifa_put(ifp); + } +@@ -3736,7 +3737,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp) + { + struct inet6_dev *idev = ifp->idev; + struct net_device *dev = idev->dev; +- bool notify = false; ++ bool bump_id, notify = false; + + addrconf_join_solict(dev, &ifp->addr); + +@@ -3751,11 +3752,12 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp) + idev->cnf.accept_dad < 1 || + !(ifp->flags&IFA_F_TENTATIVE) || + ifp->flags & IFA_F_NODAD) { ++ bump_id = ifp->flags & IFA_F_TENTATIVE; + ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); + spin_unlock(&ifp->lock); + read_unlock_bh(&idev->lock); + +- addrconf_dad_completed(ifp); ++ addrconf_dad_completed(ifp, bump_id); + return; + } + +@@ -3815,8 +3817,8 @@ static void addrconf_dad_work(struct work_struct *w) + struct inet6_ifaddr, + dad_work); + struct inet6_dev *idev = ifp->idev; ++ bool bump_id, disable_ipv6 = false; + struct in6_addr mcaddr; +- bool disable_ipv6 = false; + + enum { + DAD_PROCESS, +@@ -3886,11 +3888,12 @@ static void addrconf_dad_work(struct work_struct *w) + * DAD was successful + */ + ++ bump_id = ifp->flags & IFA_F_TENTATIVE; + ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED); + spin_unlock(&ifp->lock); + write_unlock_bh(&idev->lock); + +- addrconf_dad_completed(ifp); ++ addrconf_dad_completed(ifp, bump_id); + + goto out; + } +@@ -3927,7 +3930,7 @@ static bool ipv6_lonely_lladdr(struct inet6_ifaddr *ifp) + return true; + } + +-static void addrconf_dad_completed(struct inet6_ifaddr *ifp) ++static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id) + { + struct net_device *dev = ifp->idev->dev; + struct in6_addr lladdr; +@@ -3978,6 +3981,9 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp) + spin_unlock(&ifp->lock); + write_unlock_bh(&ifp->idev->lock); + } ++ ++ if (bump_id) ++ rt_genid_bump_ipv6(dev_net(dev)); + } + + static void addrconf_dad_run(struct inet6_dev *idev) +diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c +index 060a60b..111ba55 100644 +--- a/net/ipv6/esp6.c ++++ b/net/ipv6/esp6.c +@@ -418,7 +418,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) + esph = (void *)skb_push(skb, 4); + *seqhi = esph->spi; + esph->spi = esph->seq_no; +- esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.input.hi); ++ esph->seq_no = XFRM_SKB_CB(skb)->seq.input.hi; + aead_request_set_callback(req, 0, esp_input_done_esn, skb); + } + +diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c +index a09418b..93294cf 100644 +--- a/net/ipv6/ip6_offload.c ++++ b/net/ipv6/ip6_offload.c +@@ -98,7 +98,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, + segs = ops->callbacks.gso_segment(skb, features); + } + +- if (IS_ERR(segs)) ++ if (IS_ERR_OR_NULL(segs)) + goto out; + + for (skb = segs; skb; skb = skb->next) { +diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c +index 41489f3..da4e7b3 100644 +--- a/net/ipv6/ip6_tunnel.c ++++ b/net/ipv6/ip6_tunnel.c +@@ -1014,6 +1014,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, + int mtu; + unsigned int psh_hlen = sizeof(struct ipv6hdr) + t->encap_hlen; + unsigned int max_headroom = psh_hlen; ++ bool use_cache = false; + int err = -1; + + /* NBMA tunnel */ +@@ -1038,7 +1039,15 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, + + memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); + neigh_release(neigh); +- } else if (!fl6->flowi6_mark) ++ } else if (!(t->parms.flags & ++ (IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) { ++ /* enable the cache only only if the routing decision does ++ * not depend on the current inner header value ++ */ ++ use_cache = true; ++ } ++ ++ if (use_cache) + dst = dst_cache_get(&t->dst_cache); + + if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr)) +@@ -1113,7 +1122,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, + skb = new_skb; + } + +- if (!fl6->flowi6_mark && ndst) ++ if (use_cache && ndst) + dst_cache_set_ip6(&t->dst_cache, ndst, &fl6->saddr); + skb_dst_set(skb, dst); + +@@ -1134,7 +1143,6 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, + if (err) + return err; + +- skb->protocol = htons(ETH_P_IPV6); + skb_push(skb, sizeof(struct ipv6hdr)); + skb_reset_network_header(skb); + ipv6h = ipv6_hdr(skb); +diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c +index 462f2a76b..1d18432 100644 +--- a/net/ipv6/output_core.c ++++ b/net/ipv6/output_core.c +@@ -148,6 +148,8 @@ int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb) + ipv6_hdr(skb)->payload_len = htons(len); + IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); + ++ skb->protocol = htons(ETH_P_IPV6); ++ + return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, + net, sk, skb, NULL, skb_dst(skb)->dev, + dst_output); +diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c +index c2a8656..fa39ab8 100644 +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -514,7 +514,7 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, + return; + } + +-static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) ++int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) + { + int rc; + +diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h +index 0682c03..3c1dbc9 100644 +--- a/net/ipv6/udp_impl.h ++++ b/net/ipv6/udp_impl.h +@@ -26,7 +26,7 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname, + int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len); + int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock, + int flags, int *addr_len); +-int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); ++int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb); + void udpv6_destroy_sock(struct sock *sk); + + void udp_v6_clear_sk(struct sock *sk, int size); +diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c +index fd6ef41..af2895c 100644 +--- a/net/ipv6/udplite.c ++++ b/net/ipv6/udplite.c +@@ -45,7 +45,7 @@ struct proto udplitev6_prot = { + .getsockopt = udpv6_getsockopt, + .sendmsg = udpv6_sendmsg, + .recvmsg = udpv6_recvmsg, +- .backlog_rcv = udpv6_queue_rcv_skb, ++ .backlog_rcv = __udpv6_queue_rcv_skb, + .hash = udp_lib_hash, + .unhash = udp_lib_unhash, + .get_port = udp_v6_get_port, +diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c +index 42de4cc..d0e906d 100644 +--- a/net/l2tp/l2tp_ip.c ++++ b/net/l2tp/l2tp_ip.c +@@ -251,8 +251,6 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) + int ret; + int chk_addr_ret; + +- if (!sock_flag(sk, SOCK_ZAPPED)) +- return -EINVAL; + if (addr_len < sizeof(struct sockaddr_l2tpip)) + return -EINVAL; + if (addr->l2tp_family != AF_INET) +@@ -267,6 +265,9 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) + read_unlock_bh(&l2tp_ip_lock); + + lock_sock(sk); ++ if (!sock_flag(sk, SOCK_ZAPPED)) ++ goto out; ++ + if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_l2tpip)) + goto out; + +diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c +index ea2ae66..b9c6a41 100644 +--- a/net/l2tp/l2tp_ip6.c ++++ b/net/l2tp/l2tp_ip6.c +@@ -269,8 +269,6 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) + int addr_type; + int err; + +- if (!sock_flag(sk, SOCK_ZAPPED)) +- return -EINVAL; + if (addr->l2tp_family != AF_INET6) + return -EINVAL; + if (addr_len < sizeof(*addr)) +@@ -296,6 +294,9 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) + lock_sock(sk); + + err = -EINVAL; ++ if (!sock_flag(sk, SOCK_ZAPPED)) ++ goto out_unlock; ++ + if (sk->sk_state != TCP_CLOSE) + goto out_unlock; + +diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c +index 62bea45..246f29d 100644 +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -329,7 +329,6 @@ static void netlink_sock_destruct(struct sock *sk) + if (nlk->cb_running) { + if (nlk->cb.done) + nlk->cb.done(&nlk->cb); +- + module_put(nlk->cb.module); + kfree_skb(nlk->cb.skb); + } +@@ -346,6 +345,14 @@ static void netlink_sock_destruct(struct sock *sk) + WARN_ON(nlk_sk(sk)->groups); + } + ++static void netlink_sock_destruct_work(struct work_struct *work) ++{ ++ struct netlink_sock *nlk = container_of(work, struct netlink_sock, ++ work); ++ ++ sk_free(&nlk->sk); ++} ++ + /* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on + * SMP. Look, when several writers sleep and reader wakes them up, all but one + * immediately hit write lock and grab all the cpus. Exclusive sleep solves +@@ -648,8 +655,18 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol, + static void deferred_put_nlk_sk(struct rcu_head *head) + { + struct netlink_sock *nlk = container_of(head, struct netlink_sock, rcu); ++ struct sock *sk = &nlk->sk; ++ ++ if (!atomic_dec_and_test(&sk->sk_refcnt)) ++ return; ++ ++ if (nlk->cb_running && nlk->cb.done) { ++ INIT_WORK(&nlk->work, netlink_sock_destruct_work); ++ schedule_work(&nlk->work); ++ return; ++ } + +- sock_put(&nlk->sk); ++ sk_free(sk); + } + + static int netlink_release(struct socket *sock) +diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h +index 3cfd6cc..4fdb383 100644 +--- a/net/netlink/af_netlink.h ++++ b/net/netlink/af_netlink.h +@@ -3,6 +3,7 @@ + + #include <linux/rhashtable.h> + #include <linux/atomic.h> ++#include <linux/workqueue.h> + #include <net/sock.h> + + #define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8) +@@ -33,6 +34,7 @@ struct netlink_sock { + + struct rhash_head node; + struct rcu_head rcu; ++ struct work_struct work; + }; + + static inline struct netlink_sock *nlk_sk(struct sock *sk) +diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c +index d2238b2..dd23323 100644 +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -3648,19 +3648,25 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv + + if (optlen != sizeof(val)) + return -EINVAL; +- if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) +- return -EBUSY; + if (copy_from_user(&val, optval, sizeof(val))) + return -EFAULT; + switch (val) { + case TPACKET_V1: + case TPACKET_V2: + case TPACKET_V3: +- po->tp_version = val; +- return 0; ++ break; + default: + return -EINVAL; + } ++ lock_sock(sk); ++ if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { ++ ret = -EBUSY; ++ } else { ++ po->tp_version = val; ++ ret = 0; ++ } ++ release_sock(sk); ++ return ret; + } + case PACKET_RESERVE: + { +@@ -4164,6 +4170,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + /* Added to avoid minimal code churn */ + struct tpacket_req *req = &req_u->req; + ++ lock_sock(sk); + /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ + if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { + net_warn_ratelimited("Tx-ring is not supported.\n"); +@@ -4245,7 +4252,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + goto out; + } + +- lock_sock(sk); + + /* Detach socket from network */ + spin_lock(&po->bind_lock); +@@ -4294,11 +4300,11 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + if (!tx_ring) + prb_shutdown_retire_blk_timer(po, rb_queue); + } +- release_sock(sk); + + if (pg_vec) + free_pg_vec(pg_vec, order, req->tp_block_nr); + out: ++ release_sock(sk); + return err; + } + +diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c +index b54d56d..cf9b2fe 100644 +--- a/net/sched/act_pedit.c ++++ b/net/sched/act_pedit.c +@@ -108,6 +108,17 @@ static void tcf_pedit_cleanup(struct tc_action *a, int bind) + kfree(keys); + } + ++static bool offset_valid(struct sk_buff *skb, int offset) ++{ ++ if (offset > 0 && offset > skb->len) ++ return false; ++ ++ if (offset < 0 && -offset > skb_headroom(skb)) ++ return false; ++ ++ return true; ++} ++ + static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a, + struct tcf_result *res) + { +@@ -134,6 +145,11 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a, + if (tkey->offmask) { + char *d, _d; + ++ if (!offset_valid(skb, off + tkey->at)) { ++ pr_info("tc filter pedit 'at' offset %d out of bounds\n", ++ off + tkey->at); ++ goto bad; ++ } + d = skb_header_pointer(skb, off + tkey->at, 1, + &_d); + if (!d) +@@ -146,10 +162,10 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a, + " offset must be on 32 bit boundaries\n"); + goto bad; + } +- if (offset > 0 && offset > skb->len) { +- pr_info("tc filter pedit" +- " offset %d can't exceed pkt length %d\n", +- offset, skb->len); ++ ++ if (!offset_valid(skb, off + offset)) { ++ pr_info("tc filter pedit offset %d out of bounds\n", ++ offset); + goto bad; + } + +diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c +index 0b8c3ac..1bf1f451 100644 +--- a/net/sched/cls_basic.c ++++ b/net/sched/cls_basic.c +@@ -62,9 +62,6 @@ static unsigned long basic_get(struct tcf_proto *tp, u32 handle) + struct basic_head *head = rtnl_dereference(tp->root); + struct basic_filter *f; + +- if (head == NULL) +- return 0UL; +- + list_for_each_entry(f, &head->flist, link) { + if (f->handle == handle) { + l = (unsigned long) f; +@@ -109,7 +106,6 @@ static bool basic_destroy(struct tcf_proto *tp, bool force) + tcf_unbind_filter(tp, &f->res); + call_rcu(&f->rcu, basic_delete_filter); + } +- RCU_INIT_POINTER(tp->root, NULL); + kfree_rcu(head, rcu); + return true; + } +diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c +index c3002c2..dbec458 100644 +--- a/net/sched/cls_bpf.c ++++ b/net/sched/cls_bpf.c +@@ -200,7 +200,6 @@ static bool cls_bpf_destroy(struct tcf_proto *tp, bool force) + call_rcu(&prog->rcu, __cls_bpf_delete_prog); + } + +- RCU_INIT_POINTER(tp->root, NULL); + kfree_rcu(head, rcu); + return true; + } +@@ -211,9 +210,6 @@ static unsigned long cls_bpf_get(struct tcf_proto *tp, u32 handle) + struct cls_bpf_prog *prog; + unsigned long ret = 0UL; + +- if (head == NULL) +- return 0UL; +- + list_for_each_entry(prog, &head->plist, link) { + if (prog->handle == handle) { + ret = (unsigned long) prog; +diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c +index 4c85bd3..c104c20 100644 +--- a/net/sched/cls_cgroup.c ++++ b/net/sched/cls_cgroup.c +@@ -130,11 +130,10 @@ static bool cls_cgroup_destroy(struct tcf_proto *tp, bool force) + + if (!force) + return false; +- +- if (head) { +- RCU_INIT_POINTER(tp->root, NULL); ++ /* Head can still be NULL due to cls_cgroup_init(). */ ++ if (head) + call_rcu(&head->rcu, cls_cgroup_destroy_rcu); +- } ++ + return true; + } + +diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c +index fbfec6a..d7ba2b4 100644 +--- a/net/sched/cls_flow.c ++++ b/net/sched/cls_flow.c +@@ -583,7 +583,6 @@ static bool flow_destroy(struct tcf_proto *tp, bool force) + list_del_rcu(&f->list); + call_rcu(&f->rcu, flow_destroy_filter); + } +- RCU_INIT_POINTER(tp->root, NULL); + kfree_rcu(head, rcu); + return true; + } +diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c +index 5060801..a411571 100644 +--- a/net/sched/cls_flower.c ++++ b/net/sched/cls_flower.c +@@ -13,6 +13,7 @@ + #include <linux/init.h> + #include <linux/module.h> + #include <linux/rhashtable.h> ++#include <linux/workqueue.h> + + #include <linux/if_ether.h> + #include <linux/in6.h> +@@ -55,7 +56,10 @@ struct cls_fl_head { + bool mask_assigned; + struct list_head filters; + struct rhashtable_params ht_params; +- struct rcu_head rcu; ++ union { ++ struct work_struct work; ++ struct rcu_head rcu; ++ }; + }; + + struct cls_fl_filter { +@@ -239,6 +243,24 @@ static void fl_hw_update_stats(struct tcf_proto *tp, struct cls_fl_filter *f) + dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol, &tc); + } + ++static void fl_destroy_sleepable(struct work_struct *work) ++{ ++ struct cls_fl_head *head = container_of(work, struct cls_fl_head, ++ work); ++ if (head->mask_assigned) ++ rhashtable_destroy(&head->ht); ++ kfree(head); ++ module_put(THIS_MODULE); ++} ++ ++static void fl_destroy_rcu(struct rcu_head *rcu) ++{ ++ struct cls_fl_head *head = container_of(rcu, struct cls_fl_head, rcu); ++ ++ INIT_WORK(&head->work, fl_destroy_sleepable); ++ schedule_work(&head->work); ++} ++ + static bool fl_destroy(struct tcf_proto *tp, bool force) + { + struct cls_fl_head *head = rtnl_dereference(tp->root); +@@ -252,10 +274,9 @@ static bool fl_destroy(struct tcf_proto *tp, bool force) + list_del_rcu(&f->list); + call_rcu(&f->rcu, fl_destroy_filter); + } +- RCU_INIT_POINTER(tp->root, NULL); +- if (head->mask_assigned) +- rhashtable_destroy(&head->ht); +- kfree_rcu(head, rcu); ++ ++ __module_get(THIS_MODULE); ++ call_rcu(&head->rcu, fl_destroy_rcu); + return true; + } + +diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c +index 25927b6..f935429 100644 +--- a/net/sched/cls_matchall.c ++++ b/net/sched/cls_matchall.c +@@ -114,7 +114,6 @@ static bool mall_destroy(struct tcf_proto *tp, bool force) + + call_rcu(&f->rcu, mall_destroy_filter); + } +- RCU_INIT_POINTER(tp->root, NULL); + kfree_rcu(head, rcu); + return true; + } +diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h +index f9c9fc0..9992dfa 100644 +--- a/net/sched/cls_rsvp.h ++++ b/net/sched/cls_rsvp.h +@@ -152,7 +152,8 @@ static int rsvp_classify(struct sk_buff *skb, const struct tcf_proto *tp, + return -1; + nhptr = ip_hdr(skb); + #endif +- ++ if (unlikely(!head)) ++ return -1; + restart: + + #if RSVP_DST_LEN == 4 +diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c +index 944c8ff..403746b 100644 +--- a/net/sched/cls_tcindex.c ++++ b/net/sched/cls_tcindex.c +@@ -503,7 +503,6 @@ static bool tcindex_destroy(struct tcf_proto *tp, bool force) + walker.fn = tcindex_destroy_element; + tcindex_walk(tp, &walker); + +- RCU_INIT_POINTER(tp->root, NULL); + call_rcu(&p->rcu, __tcindex_destroy); + return true; + } +diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c +index 65b1bbf..6167699 100644 +--- a/net/tipc/bearer.c ++++ b/net/tipc/bearer.c +@@ -402,6 +402,10 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b, + dev = dev_get_by_name(net, driver_name); + if (!dev) + return -ENODEV; ++ if (tipc_mtu_bad(dev, 0)) { ++ dev_put(dev); ++ return -EINVAL; ++ } + + /* Associate TIPC bearer with L2 bearer */ + rcu_assign_pointer(b->media_ptr, dev); +@@ -606,8 +610,6 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt, + if (!b) + return NOTIFY_DONE; + +- b->mtu = dev->mtu; +- + switch (evt) { + case NETDEV_CHANGE: + if (netif_carrier_ok(dev)) +@@ -621,6 +623,11 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt, + tipc_reset_bearer(net, b); + break; + case NETDEV_CHANGEMTU: ++ if (tipc_mtu_bad(dev, 0)) { ++ bearer_disable(net, b); ++ break; ++ } ++ b->mtu = dev->mtu; + tipc_reset_bearer(net, b); + break; + case NETDEV_CHANGEADDR: +diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h +index 43757f1..d93f1f1 100644 +--- a/net/tipc/bearer.h ++++ b/net/tipc/bearer.h +@@ -39,6 +39,7 @@ + + #include "netlink.h" + #include "core.h" ++#include "msg.h" + #include <net/genetlink.h> + + #define MAX_MEDIA 3 +@@ -59,6 +60,9 @@ + #define TIPC_MEDIA_TYPE_IB 2 + #define TIPC_MEDIA_TYPE_UDP 3 + ++/* minimum bearer MTU */ ++#define TIPC_MIN_BEARER_MTU (MAX_H_SIZE + INT_H_SIZE) ++ + /** + * struct tipc_media_addr - destination address used by TIPC bearers + * @value: address info (format defined by media) +@@ -213,4 +217,13 @@ void tipc_bearer_xmit(struct net *net, u32 bearer_id, + void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id, + struct sk_buff_head *xmitq); + ++/* check if device MTU is too low for tipc headers */ ++static inline bool tipc_mtu_bad(struct net_device *dev, unsigned int reserve) ++{ ++ if (dev->mtu >= TIPC_MIN_BEARER_MTU + reserve) ++ return false; ++ netdev_warn(dev, "MTU too low for tipc bearer\n"); ++ return true; ++} ++ + #endif /* _TIPC_BEARER_H */ +diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c +index ae7e14c..f60f346 100644 +--- a/net/tipc/udp_media.c ++++ b/net/tipc/udp_media.c +@@ -372,6 +372,11 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b, + udp_conf.local_ip.s_addr = htonl(INADDR_ANY); + udp_conf.use_udp_checksums = false; + ub->ifindex = dev->ifindex; ++ if (tipc_mtu_bad(dev, sizeof(struct iphdr) + ++ sizeof(struct udphdr))) { ++ err = -EINVAL; ++ goto err; ++ } + b->mtu = dev->mtu - sizeof(struct iphdr) + - sizeof(struct udphdr); + #if IS_ENABLED(CONFIG_IPV6) +diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c +index 8309687..568f307 100644 +--- a/net/unix/af_unix.c ++++ b/net/unix/af_unix.c +@@ -2199,7 +2199,8 @@ static int unix_dgram_recvmsg(struct socket *sock, struct msghdr *msg, + * Sleep until more data has arrived. But check for races.. + */ + static long unix_stream_data_wait(struct sock *sk, long timeo, +- struct sk_buff *last, unsigned int last_len) ++ struct sk_buff *last, unsigned int last_len, ++ bool freezable) + { + struct sk_buff *tail; + DEFINE_WAIT(wait); +@@ -2220,7 +2221,10 @@ static long unix_stream_data_wait(struct sock *sk, long timeo, + + sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); + unix_state_unlock(sk); +- timeo = freezable_schedule_timeout(timeo); ++ if (freezable) ++ timeo = freezable_schedule_timeout(timeo); ++ else ++ timeo = schedule_timeout(timeo); + unix_state_lock(sk); + + if (sock_flag(sk, SOCK_DEAD)) +@@ -2250,7 +2254,8 @@ struct unix_stream_read_state { + unsigned int splice_flags; + }; + +-static int unix_stream_read_generic(struct unix_stream_read_state *state) ++static int unix_stream_read_generic(struct unix_stream_read_state *state, ++ bool freezable) + { + struct scm_cookie scm; + struct socket *sock = state->socket; +@@ -2330,7 +2335,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state) + mutex_unlock(&u->iolock); + + timeo = unix_stream_data_wait(sk, timeo, last, +- last_len); ++ last_len, freezable); + + if (signal_pending(current)) { + err = sock_intr_errno(timeo); +@@ -2472,7 +2477,7 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg, + .flags = flags + }; + +- return unix_stream_read_generic(&state); ++ return unix_stream_read_generic(&state, true); + } + + static ssize_t skb_unix_socket_splice(struct sock *sk, +@@ -2518,7 +2523,7 @@ static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos, + flags & SPLICE_F_NONBLOCK) + state.flags = MSG_DONTWAIT; + +- return unix_stream_read_generic(&state); ++ return unix_stream_read_generic(&state, false); + } + + static int unix_shutdown(struct socket *sock, int mode) diff --git a/4.8.13/4420_grsecurity-3.1-4.8.13-201612082118.patch b/4.8.14/4420_grsecurity-3.1-4.8.14-201612110933.patch index a2b5f41..c16e8f5 100644 --- a/4.8.13/4420_grsecurity-3.1-4.8.13-201612082118.patch +++ b/4.8.14/4420_grsecurity-3.1-4.8.14-201612110933.patch @@ -407,7 +407,7 @@ index ffab8b5..b8fcd61 100644 A toggle value indicating if modules are allowed to be loaded diff --git a/Makefile b/Makefile -index b38abe9..edadcba 100644 +index 6a74924..c5a7b40 100644 --- a/Makefile +++ b/Makefile @@ -302,7 +302,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -12837,7 +12837,7 @@ index 988acc8b..f26345c 100644 pte_t *huge_pte_alloc(struct mm_struct *mm, diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c -index 7ac6b62..58e934c 100644 +index 05c7708..222a546 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -189,9 +189,9 @@ unsigned long sparc64_kern_sec_context __read_mostly; @@ -40819,10 +40819,10 @@ index 36c7ac3..ba1f2fd 100644 blk_requestq_cachep = kmem_cache_create("request_queue", sizeof(struct request_queue), 0, SLAB_PANIC, NULL); diff --git a/block/blk-map.c b/block/blk-map.c -index b8657fa..dad7c1e 100644 +index 27fd8d92..c03179e 100644 --- a/block/blk-map.c +++ b/block/blk-map.c -@@ -219,7 +219,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, +@@ -223,7 +223,7 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, if (!len || !kbuf) return -EINVAL; @@ -63902,10 +63902,10 @@ index 771cc26..c681a90 100644 /* * Init NAPI, so that state is set to NAPI_STATE_SCHED, diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c -index d954a97..2a1c33a 100644 +index ef0dbcf..8d94c43 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c -@@ -1341,7 +1341,7 @@ static inline int macb_clear_csum(struct sk_buff *skb) +@@ -1342,7 +1342,7 @@ static inline int macb_clear_csum(struct sk_buff *skb) return 0; } @@ -63914,7 +63914,7 @@ index d954a97..2a1c33a 100644 { u16 queue_index = skb_get_queue_mapping(skb); struct macb *bp = netdev_priv(dev); -@@ -2612,7 +2612,7 @@ static int at91ether_close(struct net_device *dev) +@@ -2611,7 +2611,7 @@ static int at91ether_close(struct net_device *dev) } /* Transmit packet */ @@ -64986,7 +64986,7 @@ index e55638c..5fe3a62 100644 int (*set_speed)(struct net_device *, u8 aneg, u16 sp, u8 dpx, u32 adv); int (*get_settings)(struct net_device *, struct ethtool_cmd *); diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c -index 054e795..5180c73 100644 +index 92c9a95..1c8f44b 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -2300,7 +2300,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev) @@ -65408,10 +65408,10 @@ index 93dc10b..6598671 100644 struct net_local *lp = netdev_priv(dev); struct sk_buff *new_skb; diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c -index 16af1ce..deabcc5 100644 +index 5ad706b..6a5d38a 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c -@@ -1450,7 +1450,7 @@ nla_put_failure: +@@ -1444,7 +1444,7 @@ nla_put_failure: return -EMSGSIZE; } @@ -65420,7 +65420,7 @@ index 16af1ce..deabcc5 100644 .kind = "geneve", .maxtype = IFLA_GENEVE_MAX, .policy = geneve_policy, -@@ -1516,7 +1516,7 @@ static int geneve_netdevice_event(struct notifier_block *unused, +@@ -1510,7 +1510,7 @@ static int geneve_netdevice_event(struct notifier_block *unused, return NOTIFY_DONE; } @@ -66151,7 +66151,7 @@ index a2515887..6d13233 100644 /* we will have to manufacture ethernet headers, prepare template */ diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c -index bf3fd34..43d918f 100644 +index d807209..90cc005 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c @@ -48,7 +48,7 @@ module_param(gso, bool, 0444); @@ -140959,7 +140959,7 @@ index 8d4608c..460372d 100644 int __genl_register_family(struct genl_family *family); diff --git a/include/net/gro_cells.h b/include/net/gro_cells.h -index d15214d..f6de1b4 100644 +index 2a1abbf..93305b8 100644 --- a/include/net/gro_cells.h +++ b/include/net/gro_cells.h @@ -25,7 +25,7 @@ static inline int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *sk @@ -159318,7 +159318,7 @@ index cb06ace..3cab3fc 100644 fp->len = fprog->len; /* Since unattached filters are not copied back to user diff --git a/net/core/flow.c b/net/core/flow.c -index 3937b1b..b18d1cb 100644 +index 18e8893..82936b2 100644 --- a/net/core/flow.c +++ b/net/core/flow.c @@ -65,7 +65,7 @@ static void flow_cache_new_hashrnd(unsigned long arg) @@ -159330,16 +159330,7 @@ index 3937b1b..b18d1cb 100644 return 0; if (fle->object && !fle->object->ops->check(fle->object)) return 0; -@@ -238,7 +238,7 @@ flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir, - - if (fcp->hash_count > 2 * fc->high_watermark || - atomic_read(&net->xfrm.flow_cache_gc_count) > fc->high_watermark) { -- atomic_inc(&net->xfrm.flow_cache_genid); -+ atomic_inc_unchecked(&net->xfrm.flow_cache_genid); - flo = ERR_PTR(-ENOBUFS); - goto ret_object; - } -@@ -253,7 +253,7 @@ flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir, +@@ -251,7 +251,7 @@ flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir, hlist_add_head(&fle->u.hlist, &fcp->hash_table[hash]); fcp->hash_count++; } @@ -159348,7 +159339,7 @@ index 3937b1b..b18d1cb 100644 flo = fle->object; if (!flo) goto ret_object; -@@ -274,7 +274,7 @@ nocache: +@@ -272,7 +272,7 @@ nocache: } flo = resolver(net, key, family, dir, flo, ctx); if (fle) { @@ -159525,10 +159516,10 @@ index 6e4f347..8eff663 100644 static DEVICE_ATTR_RO(carrier_changes); diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c -index 2c2eb1b..2f3b518 100644 +index 2e9a1c2..95e9455 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c -@@ -526,7 +526,7 @@ static __net_exit void net_ns_net_exit(struct net *net) +@@ -528,7 +528,7 @@ static __net_exit void net_ns_net_exit(struct net *net) ns_free_inum(&net->ns); } @@ -159537,7 +159528,7 @@ index 2c2eb1b..2f3b518 100644 .init = net_ns_net_init, .exit = net_ns_net_exit, }; -@@ -775,7 +775,7 @@ static int __register_pernet_operations(struct list_head *list, +@@ -777,7 +777,7 @@ static int __register_pernet_operations(struct list_head *list, int error; LIST_HEAD(net_exit_list); @@ -159546,7 +159537,7 @@ index 2c2eb1b..2f3b518 100644 if (ops->init || (ops->id && ops->size)) { for_each_net(net) { error = ops_init(ops, net); -@@ -788,7 +788,7 @@ static int __register_pernet_operations(struct list_head *list, +@@ -790,7 +790,7 @@ static int __register_pernet_operations(struct list_head *list, out_undo: /* If I have an error cleanup all namespaces I initialized */ @@ -159555,7 +159546,7 @@ index 2c2eb1b..2f3b518 100644 ops_exit_list(ops, &net_exit_list); ops_free_list(ops, &net_exit_list); return error; -@@ -799,7 +799,7 @@ static void __unregister_pernet_operations(struct pernet_operations *ops) +@@ -801,7 +801,7 @@ static void __unregister_pernet_operations(struct pernet_operations *ops) struct net *net; LIST_HEAD(net_exit_list); @@ -159564,7 +159555,7 @@ index 2c2eb1b..2f3b518 100644 for_each_net(net) list_add_tail(&net->exit_list, &net_exit_list); ops_exit_list(ops, &net_exit_list); -@@ -933,7 +933,7 @@ int register_pernet_device(struct pernet_operations *ops) +@@ -935,7 +935,7 @@ int register_pernet_device(struct pernet_operations *ops) mutex_lock(&net_mutex); error = register_pernet_operations(&pernet_list, ops); if (!error && (first_device == &pernet_list)) @@ -159609,7 +159600,7 @@ index 306b8f0..0214187 100644 pr_warn("cannot create /proc/net/%s\n", PG_PROC_DIR); return -ENODEV; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 189cc78..d76c934 100644 +index 08c3702..d50e672 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -61,7 +61,7 @@ struct rtnl_link { @@ -159656,7 +159647,7 @@ index 189cc78..d76c934 100644 nla_put_u8(skb, IFLA_PROTO_DOWN, dev->proto_down)) goto nla_put_failure; -@@ -3829,7 +3832,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) +@@ -3832,7 +3835,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) __rtnl_unlock(); rtnl = net->rtnl; { @@ -159758,7 +159749,7 @@ index 3864b4b6..d2cbe83 100644 } diff --git a/net/core/sock.c b/net/core/sock.c -index 10acacc..8b564eb 100644 +index ba27920..3f998d0 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -411,13 +411,13 @@ int __sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) @@ -160360,7 +160351,7 @@ index cb7176c..afd2c62 100644 return NULL; } diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c -index eebbc0f..59069ff 100644 +index ed22af6..0e88bcd 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -1445,7 +1445,7 @@ int inet_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) @@ -160504,10 +160495,10 @@ index 062a67c..cb05c97 100644 .exit = devinet_exit_net, }; diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c -index 1b25daf..9ef9ef2 100644 +index 9301308..e164d8d 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c -@@ -1141,12 +1141,12 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, +@@ -1151,12 +1151,12 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event, #ifdef CONFIG_IP_ROUTE_MULTIPATH fib_sync_up(dev, RTNH_F_DEAD); #endif @@ -160522,7 +160513,7 @@ index 1b25daf..9ef9ef2 100644 if (!ifa->ifa_dev->ifa_list) { /* Last address was deleted from this interface. * Disable IP. -@@ -1186,7 +1186,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo +@@ -1196,7 +1196,7 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo #ifdef CONFIG_IP_ROUTE_MULTIPATH fib_sync_up(dev, RTNH_F_DEAD); #endif @@ -160974,7 +160965,7 @@ index 4a9e6db..06174e1 100644 pr_err("Unable to proc dir entry\n"); return -ENOMEM; diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c -index 66ddcb6..0de0097 100644 +index dcdd5ae..2b7b5a2 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -59,7 +59,7 @@ struct ping_table { @@ -161013,7 +161004,7 @@ index 66ddcb6..0de0097 100644 info, (u8 *)icmph); #endif } -@@ -924,10 +924,10 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock, +@@ -928,10 +928,10 @@ int ping_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock, } if (inet6_sk(sk)->rxopt.all) @@ -161026,7 +161017,7 @@ index 66ddcb6..0de0097 100644 else if (skb->protocol == htons(ETH_P_IP) && isk->cmsg_flags) ip_cmsg_recv(msg, skb); #endif -@@ -1124,7 +1124,7 @@ static void ping_v4_format_sock(struct sock *sp, struct seq_file *f, +@@ -1128,7 +1128,7 @@ static void ping_v4_format_sock(struct sock *sp, struct seq_file *f, from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)), 0, sock_i_ino(sp), atomic_read(&sp->sk_refcnt), sp, @@ -161603,7 +161594,7 @@ index f712b41..b651403 100644 syn_set ? 0 : icsk->icsk_user_timeout, syn_set)) { /* Has it gone just too far? */ diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c -index c0d71e7..f4b404a3 100644 +index a2d54f5..f94953a 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -87,6 +87,7 @@ @@ -161826,7 +161817,7 @@ index 542074c..648df74 100644 sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl)); diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c -index f5432d6..42b4ef0 100644 +index 8f2e36f..720a68f 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -179,7 +179,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = { @@ -161865,7 +161856,7 @@ index f5432d6..42b4ef0 100644 if (ops->ndo_do_ioctl) { mm_segment_t oldfs = get_fs(); -@@ -4119,16 +4119,23 @@ static const struct file_operations if6_fops = { +@@ -4125,16 +4125,23 @@ static const struct file_operations if6_fops = { .release = seq_release_net, }; @@ -161890,7 +161881,7 @@ index f5432d6..42b4ef0 100644 } static struct pernet_operations if6_proc_net_ops = { -@@ -4747,7 +4754,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, +@@ -4753,7 +4760,7 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, s_ip_idx = ip_idx = cb->args[2]; rcu_read_lock(); @@ -161899,7 +161890,7 @@ index f5432d6..42b4ef0 100644 for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { idx = 0; head = &net->dev_index_head[h]; -@@ -4960,7 +4967,7 @@ static inline size_t inet6_if_nlmsg_size(void) +@@ -4966,7 +4973,7 @@ static inline size_t inet6_if_nlmsg_size(void) + nla_total_size(inet6_ifla6_size()); /* IFLA_PROTINFO */ } @@ -161908,7 +161899,7 @@ index f5432d6..42b4ef0 100644 int items, int bytes) { int i; -@@ -4970,7 +4977,7 @@ static inline void __snmp6_fill_statsdev(u64 *stats, atomic_long_t *mib, +@@ -4976,7 +4983,7 @@ static inline void __snmp6_fill_statsdev(u64 *stats, atomic_long_t *mib, /* Use put_unaligned() because stats may not be aligned for u64. */ put_unaligned(items, &stats[0]); for (i = 1; i < items; i++) @@ -161917,7 +161908,7 @@ index f5432d6..42b4ef0 100644 memset(&stats[items], 0, pad); } -@@ -5427,7 +5434,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) +@@ -5433,7 +5440,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) rt_genid_bump_ipv6(net); break; } @@ -161926,7 +161917,7 @@ index f5432d6..42b4ef0 100644 } static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) -@@ -5447,7 +5454,7 @@ int addrconf_sysctl_forward(struct ctl_table *ctl, int write, +@@ -5453,7 +5460,7 @@ int addrconf_sysctl_forward(struct ctl_table *ctl, int write, int *valp = ctl->data; int val = *valp; loff_t pos = *ppos; @@ -161935,7 +161926,7 @@ index f5432d6..42b4ef0 100644 int ret; /* -@@ -5470,7 +5477,7 @@ static +@@ -5476,7 +5483,7 @@ static int addrconf_sysctl_hop_limit(struct ctl_table *ctl, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { @@ -161944,7 +161935,7 @@ index f5432d6..42b4ef0 100644 int min_hl = 1, max_hl = 255; lctl = *ctl; -@@ -5486,7 +5493,7 @@ int addrconf_sysctl_mtu(struct ctl_table *ctl, int write, +@@ -5492,7 +5499,7 @@ int addrconf_sysctl_mtu(struct ctl_table *ctl, int write, { struct inet6_dev *idev = ctl->extra1; int min_mtu = IPV6_MIN_MTU; @@ -161953,7 +161944,7 @@ index f5432d6..42b4ef0 100644 lctl = *ctl; lctl.extra1 = &min_mtu; -@@ -5561,7 +5568,7 @@ int addrconf_sysctl_disable(struct ctl_table *ctl, int write, +@@ -5567,7 +5574,7 @@ int addrconf_sysctl_disable(struct ctl_table *ctl, int write, int *valp = ctl->data; int val = *valp; loff_t pos = *ppos; @@ -161962,7 +161953,7 @@ index f5432d6..42b4ef0 100644 int ret; /* -@@ -5626,7 +5633,7 @@ static int addrconf_sysctl_stable_secret(struct ctl_table *ctl, int write, +@@ -5632,7 +5639,7 @@ static int addrconf_sysctl_stable_secret(struct ctl_table *ctl, int write, int err; struct in6_addr addr; char str[IPV6_MAX_STRLEN]; @@ -161971,7 +161962,7 @@ index f5432d6..42b4ef0 100644 struct net *net = ctl->extra2; struct ipv6_stable_secret *secret = ctl->data; -@@ -5695,7 +5702,7 @@ int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl, +@@ -5701,7 +5708,7 @@ int addrconf_sysctl_ignore_routes_with_linkdown(struct ctl_table *ctl, int *valp = ctl->data; int val = *valp; loff_t pos = *ppos; @@ -161980,7 +161971,7 @@ index f5432d6..42b4ef0 100644 int ret; /* ctl->data points to idev->cnf.ignore_routes_when_linkdown -@@ -6035,7 +6042,7 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name, +@@ -6041,7 +6048,7 @@ static int __addrconf_sysctl_register(struct net *net, char *dev_name, struct inet6_dev *idev, struct ipv6_devconf *p) { int i, ifindex; @@ -162111,7 +162102,7 @@ index edc3daa..c951634 100644 .maxtype = IFLA_GRE_MAX, .policy = ip6gre_policy, diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c -index 41489f3..62a4ed4 100644 +index da4e7b3..fd21a2d 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c @@ -80,7 +80,7 @@ static u32 HASH(const struct in6_addr *addr1, const struct in6_addr *addr2) @@ -162123,7 +162114,7 @@ index 41489f3..62a4ed4 100644 static int ip6_tnl_net_id __read_mostly; struct ip6_tnl_net { -@@ -1997,7 +1997,7 @@ static const struct nla_policy ip6_tnl_policy[IFLA_IPTUN_MAX + 1] = { +@@ -2005,7 +2005,7 @@ static const struct nla_policy ip6_tnl_policy[IFLA_IPTUN_MAX + 1] = { [IFLA_IPTUN_ENCAP_DPORT] = { .type = NLA_U16 }, }; @@ -162611,7 +162602,7 @@ index af6a09e..3dafd52 100644 } diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c -index c2a8656..cef76e9 100644 +index fa39ab8..580da9b 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c @@ -78,6 +78,10 @@ static u32 udp6_ehashfn(const struct net *net, @@ -163562,10 +163553,10 @@ index 57fc5a4..310e75b 100644 } diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c -index 42de4cc..f00aa3e 100644 +index d0e906d..a6abcf4 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c -@@ -610,7 +610,7 @@ static struct inet_protosw l2tp_ip_protosw = { +@@ -611,7 +611,7 @@ static struct inet_protosw l2tp_ip_protosw = { .ops = &l2tp_ip_ops, }; @@ -163575,10 +163566,10 @@ index 42de4cc..f00aa3e 100644 .netns_ok = 1, }; diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c -index ea2ae66..0ef42f0 100644 +index b9c6a41..95592d6 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c -@@ -771,7 +771,7 @@ static struct inet_protosw l2tp_ip6_protosw = { +@@ -772,7 +772,7 @@ static struct inet_protosw l2tp_ip6_protosw = { .ops = &l2tp_ip6_ops, }; @@ -165372,7 +165363,7 @@ index 11de55e..f25e448 100644 return 0; } diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c -index 62bea45..94c8501 100644 +index 246f29d..1b68023 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -287,7 +287,7 @@ static void netlink_overrun(struct sock *sk) @@ -165384,7 +165375,7 @@ index 62bea45..94c8501 100644 } static void netlink_rcv_wake(struct sock *sk) -@@ -1703,11 +1703,12 @@ static void netlink_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb) +@@ -1720,11 +1720,12 @@ static void netlink_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb) static void netlink_cmsg_listen_all_nsid(struct sock *sk, struct msghdr *msg, struct sk_buff *skb) { @@ -165399,7 +165390,7 @@ index 62bea45..94c8501 100644 } static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) -@@ -2151,7 +2152,9 @@ errout_skb: +@@ -2168,7 +2169,9 @@ errout_skb: int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, const struct nlmsghdr *nlh, @@ -165410,7 +165401,7 @@ index 62bea45..94c8501 100644 { struct netlink_callback *cb; struct sock *sk; -@@ -2174,7 +2177,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, +@@ -2191,7 +2194,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, goto error_unlock; } /* add reference of module which cb->dump belongs to */ @@ -165419,7 +165410,7 @@ index 62bea45..94c8501 100644 ret = -EPROTONOSUPPORT; goto error_unlock; } -@@ -2185,8 +2188,8 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, +@@ -2202,8 +2205,8 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb, cb->dump = control->dump; cb->done = control->done; cb->nlh = nlh; @@ -165430,7 +165421,7 @@ index 62bea45..94c8501 100644 cb->min_dump_alloc = control->min_dump_alloc; cb->skb = skb; -@@ -2453,7 +2456,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v) +@@ -2470,7 +2473,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v) sk_wmem_alloc_get(s), nlk->cb_running, atomic_read(&s->sk_refcnt), @@ -165439,7 +165430,7 @@ index 62bea45..94c8501 100644 sock_i_ino(s) ); -@@ -2560,7 +2563,7 @@ static void __init netlink_add_usersock_entry(void) +@@ -2577,7 +2580,7 @@ static void __init netlink_add_usersock_entry(void) netlink_table_ungrab(); } @@ -165612,7 +165603,7 @@ index 7eb955e..479c9a6 100644 static int __init ovs_vxlan_tnl_init(void) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index d2238b2..746fec2 100644 +index dd23323..746fec2 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -278,7 +278,7 @@ static int packet_direct_xmit(struct sk_buff *skb) @@ -165667,38 +165658,7 @@ index d2238b2..746fec2 100644 spin_unlock(&sk->sk_receive_queue.lock); drop_n_restore: -@@ -3648,19 +3648,25 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv - - if (optlen != sizeof(val)) - return -EINVAL; -- if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) -- return -EBUSY; - if (copy_from_user(&val, optval, sizeof(val))) - return -EFAULT; - switch (val) { - case TPACKET_V1: - case TPACKET_V2: - case TPACKET_V3: -+ break; -+ default: -+ return -EINVAL; -+ } -+ lock_sock(sk); -+ if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { -+ ret = -EBUSY; -+ } else { - po->tp_version = val; -- return 0; -- default: -- return -EINVAL; -+ ret = 0; - } -+ release_sock(sk); -+ return ret; - } - case PACKET_RESERVE: - { -@@ -3841,7 +3847,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, +@@ -3847,7 +3847,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, case PACKET_HDRLEN: if (len > sizeof(int)) len = sizeof(int); @@ -165707,7 +165667,7 @@ index d2238b2..746fec2 100644 return -EFAULT; switch (val) { case TPACKET_V1: -@@ -3876,9 +3882,9 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, +@@ -3882,9 +3882,9 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, case PACKET_ROLLOVER_STATS: if (!po->rollover) return -EINVAL; @@ -165720,7 +165680,7 @@ index d2238b2..746fec2 100644 data = &rstats; lv = sizeof(rstats); break; -@@ -3896,7 +3902,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, +@@ -3902,7 +3902,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, len = lv; if (put_user(len, optlen)) return -EFAULT; @@ -165729,35 +165689,6 @@ index d2238b2..746fec2 100644 return -EFAULT; return 0; } -@@ -4164,6 +4170,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, - /* Added to avoid minimal code churn */ - struct tpacket_req *req = &req_u->req; - -+ lock_sock(sk); - /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ - if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { - net_warn_ratelimited("Tx-ring is not supported.\n"); -@@ -4245,7 +4252,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, - goto out; - } - -- lock_sock(sk); - - /* Detach socket from network */ - spin_lock(&po->bind_lock); -@@ -4294,11 +4300,11 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, - if (!tx_ring) - prb_shutdown_retire_blk_timer(po, rb_queue); - } -- release_sock(sk); - - if (pg_vec) - free_pg_vec(pg_vec, order, req->tp_block_nr); - out: -+ release_sock(sk); - return err; - } - diff --git a/net/packet/diag.c b/net/packet/diag.c index 0ed68f0..54c1dbe 100644 --- a/net/packet/diag.c @@ -167438,7 +167369,7 @@ index 0dd0224..36a22a0 100644 sub->evt.event = htohl(event, sub->swap); sub->evt.found_lower = htohl(found_lower, sub->swap); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c -index 8309687..50b3b18 100644 +index 568f307..e5ca018 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -921,6 +921,12 @@ static struct sock *unix_find_other(struct net *net, @@ -167488,7 +167419,7 @@ index 8309687..50b3b18 100644 done_path_create(&path, dentry); return err; } -@@ -2799,9 +2819,13 @@ static int unix_seq_show(struct seq_file *seq, void *v) +@@ -2804,9 +2824,13 @@ static int unix_seq_show(struct seq_file *seq, void *v) seq_puts(seq, "Num RefCount Protocol Flags Type St " "Inode Path\n"); else { @@ -167503,7 +167434,7 @@ index 8309687..50b3b18 100644 seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu", s, -@@ -2826,10 +2850,29 @@ static int unix_seq_show(struct seq_file *seq, void *v) +@@ -2831,10 +2855,29 @@ static int unix_seq_show(struct seq_file *seq, void *v) seq_putc(seq, '@'); i++; } @@ -170220,7 +170151,7 @@ index 172850b..a4e216d 100644 { return symtab->add_cgraph_insertion_hook(hook, data); diff --git a/scripts/gcc-plugins/gcc-generate-gimple-pass.h b/scripts/gcc-plugins/gcc-generate-gimple-pass.h -index 526c3c7..0b081fe 100644 +index 526c3c7..831300b 100644 --- a/scripts/gcc-plugins/gcc-generate-gimple-pass.h +++ b/scripts/gcc-plugins/gcc-generate-gimple-pass.h @@ -119,7 +119,7 @@ public: @@ -170232,6 +170163,50 @@ index 526c3c7..0b081fe 100644 #ifndef NO_EXECUTE #if BUILDING_GCC_VERSION >= 5000 +@@ -136,6 +136,7 @@ opt_pass *_MAKE_PASS_NAME_PASS(void) + return new _PASS_NAME_PASS(); + } + #else ++struct opt_pass *_MAKE_PASS_NAME_PASS(void); + struct opt_pass *_MAKE_PASS_NAME_PASS(void) + { + return &_PASS_NAME_PASS.pass; +diff --git a/scripts/gcc-plugins/gcc-generate-ipa-pass.h b/scripts/gcc-plugins/gcc-generate-ipa-pass.h +index 9bd926e..93d8743 100644 +--- a/scripts/gcc-plugins/gcc-generate-ipa-pass.h ++++ b/scripts/gcc-plugins/gcc-generate-ipa-pass.h +@@ -225,6 +225,7 @@ opt_pass *_MAKE_PASS_NAME_PASS(void) + return new _PASS_NAME_PASS(); + } + #else ++struct opt_pass *_MAKE_PASS_NAME_PASS(void); + struct opt_pass *_MAKE_PASS_NAME_PASS(void) + { + return &_PASS_NAME_PASS.pass; +diff --git a/scripts/gcc-plugins/gcc-generate-rtl-pass.h b/scripts/gcc-plugins/gcc-generate-rtl-pass.h +index 1dc67a5..e858d67 100644 +--- a/scripts/gcc-plugins/gcc-generate-rtl-pass.h ++++ b/scripts/gcc-plugins/gcc-generate-rtl-pass.h +@@ -136,6 +136,7 @@ opt_pass *_MAKE_PASS_NAME_PASS(void) + return new _PASS_NAME_PASS(); + } + #else ++struct opt_pass *_MAKE_PASS_NAME_PASS(void); + struct opt_pass *_MAKE_PASS_NAME_PASS(void) + { + return &_PASS_NAME_PASS.pass; +diff --git a/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h b/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h +index a27e2b3..d5ed4e2 100644 +--- a/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h ++++ b/scripts/gcc-plugins/gcc-generate-simple_ipa-pass.h +@@ -136,6 +136,7 @@ opt_pass *_MAKE_PASS_NAME_PASS(void) + return new _PASS_NAME_PASS(); + } + #else ++struct opt_pass *_MAKE_PASS_NAME_PASS(void); + struct opt_pass *_MAKE_PASS_NAME_PASS(void) + { + return &_PASS_NAME_PASS.pass; diff --git a/scripts/gcc-plugins/gen-random-seed.sh b/scripts/gcc-plugins/gen-random-seed.sh new file mode 100644 index 0000000..7514850 @@ -172617,7 +172592,7 @@ index 0000000..a213367 +} diff --git a/scripts/gcc-plugins/latent_entropy_plugin.c b/scripts/gcc-plugins/latent_entropy_plugin.c new file mode 100644 -index 0000000..4ff5389 +index 0000000..fc16dd7 --- /dev/null +++ b/scripts/gcc-plugins/latent_entropy_plugin.c @@ -0,0 +1,613 @@ @@ -172704,7 +172679,7 @@ index 0000000..4ff5389 +static GTY(()) tree latent_entropy_decl; + +static struct plugin_info latent_entropy_plugin_info = { -+ .version = "201610182310", ++ .version = "20161210", + .help = "disable\tturn off latent entropy instrumentation\n", +}; + @@ -174462,10 +174437,10 @@ index 0000000..2f53f14 +#include "gcc-generate-gimple-pass.h" diff --git a/scripts/gcc-plugins/rap_plugin/rap_hash.c b/scripts/gcc-plugins/rap_plugin/rap_hash.c new file mode 100644 -index 0000000..7c59f38 +index 0000000..161102f --- /dev/null +++ b/scripts/gcc-plugins/rap_plugin/rap_hash.c -@@ -0,0 +1,382 @@ +@@ -0,0 +1,380 @@ +/* + * Copyright 2012-2016 by PaX Team <pageexec@freemail.hu> + * Licensed under the GPL v2 @@ -174585,8 +174560,6 @@ index 0000000..7c59f38 + } +} + -+__attribute__((weak)) tree c_global_trees[CTI_MAX]; -+ +// the core computation of the rap hash +// the first piece is a (hopefully) compiler independent encondig of the type, derived from the gcc tree code +// the second piece is type specific information, such as the size, qualifiers, (recursively) referenced types, etc diff --git a/4.8.13/4425_grsec_remove_EI_PAX.patch b/4.8.14/4425_grsec_remove_EI_PAX.patch index 594598a..594598a 100644 --- a/4.8.13/4425_grsec_remove_EI_PAX.patch +++ b/4.8.14/4425_grsec_remove_EI_PAX.patch diff --git a/4.8.13/4427_force_XATTR_PAX_tmpfs.patch b/4.8.14/4427_force_XATTR_PAX_tmpfs.patch index 2562d2f..caecb91 100644 --- a/4.8.13/4427_force_XATTR_PAX_tmpfs.patch +++ b/4.8.14/4427_force_XATTR_PAX_tmpfs.patch @@ -14,7 +14,7 @@ diff -Naur a/mm/shmem.c b/mm/shmem.c static int shmem_user_xattr_handler_set(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *name, const void *value, -@@ -3271,7 +3270,6 @@ +@@ -3273,7 +3272,6 @@ name = xattr_full_name(handler, name); return simple_xattr_set(&info->xattrs, name, value, size, flags); } @@ -22,7 +22,7 @@ diff -Naur a/mm/shmem.c b/mm/shmem.c static const struct xattr_handler shmem_security_xattr_handler = { .prefix = XATTR_SECURITY_PREFIX, -@@ -3285,13 +3283,11 @@ +@@ -3287,13 +3285,11 @@ .set = shmem_xattr_handler_set, }; @@ -36,7 +36,7 @@ diff -Naur a/mm/shmem.c b/mm/shmem.c static const struct xattr_handler *shmem_xattr_handlers[] = { #ifdef CONFIG_TMPFS_POSIX_ACL -@@ -3301,9 +3297,7 @@ +@@ -3303,9 +3299,7 @@ &shmem_security_xattr_handler, &shmem_trusted_xattr_handler, diff --git a/4.8.13/4430_grsec-remove-localversion-grsec.patch b/4.8.14/4430_grsec-remove-localversion-grsec.patch index 31cf878..31cf878 100644 --- a/4.8.13/4430_grsec-remove-localversion-grsec.patch +++ b/4.8.14/4430_grsec-remove-localversion-grsec.patch diff --git a/4.8.13/4435_grsec-mute-warnings.patch b/4.8.14/4435_grsec-mute-warnings.patch index 8929222..8929222 100644 --- a/4.8.13/4435_grsec-mute-warnings.patch +++ b/4.8.14/4435_grsec-mute-warnings.patch diff --git a/4.8.13/4440_grsec-remove-protected-paths.patch b/4.8.14/4440_grsec-remove-protected-paths.patch index 741546d..741546d 100644 --- a/4.8.13/4440_grsec-remove-protected-paths.patch +++ b/4.8.14/4440_grsec-remove-protected-paths.patch diff --git a/4.8.13/4450_grsec-kconfig-default-gids.patch b/4.8.14/4450_grsec-kconfig-default-gids.patch index 6fd0511..cee6e27 100644 --- a/4.8.13/4450_grsec-kconfig-default-gids.patch +++ b/4.8.14/4450_grsec-kconfig-default-gids.patch @@ -16,7 +16,7 @@ from shooting themselves in the foot. diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig --- a/grsecurity/Kconfig 2012-10-13 09:51:35.000000000 -0400 +++ b/grsecurity/Kconfig 2012-10-13 09:52:32.000000000 -0400 -@@ -699,7 +699,7 @@ +@@ -700,7 +700,7 @@ config GRKERNSEC_AUDIT_GID int "GID for auditing" depends on GRKERNSEC_AUDIT_GROUP @@ -25,7 +25,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig config GRKERNSEC_EXECLOG bool "Exec logging" -@@ -948,7 +948,7 @@ +@@ -949,7 +949,7 @@ config GRKERNSEC_TPE_UNTRUSTED_GID int "GID for TPE-untrusted users" depends on GRKERNSEC_TPE && !GRKERNSEC_TPE_INVERT @@ -34,7 +34,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig help Setting this GID determines what group TPE restrictions will be *enabled* for. If the sysctl option is enabled, a sysctl option -@@ -957,7 +957,7 @@ +@@ -958,7 +958,7 @@ config GRKERNSEC_TPE_TRUSTED_GID int "GID for TPE-trusted users" depends on GRKERNSEC_TPE && GRKERNSEC_TPE_INVERT @@ -43,7 +43,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig help Setting this GID determines what group TPE restrictions will be *disabled* for. If the sysctl option is enabled, a sysctl option -@@ -1042,7 +1042,7 @@ +@@ -1043,7 +1043,7 @@ config GRKERNSEC_SOCKET_ALL_GID int "GID to deny all sockets for" depends on GRKERNSEC_SOCKET_ALL @@ -52,7 +52,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig help Here you can choose the GID to disable socket access for. Remember to add the users you want socket access disabled for to the GID -@@ -1063,7 +1063,7 @@ +@@ -1064,7 +1064,7 @@ config GRKERNSEC_SOCKET_CLIENT_GID int "GID to deny client sockets for" depends on GRKERNSEC_SOCKET_CLIENT @@ -61,7 +61,7 @@ diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig help Here you can choose the GID to disable client socket access for. Remember to add the users you want client socket access disabled for to -@@ -1081,7 +1081,7 @@ +@@ -1082,7 +1082,7 @@ config GRKERNSEC_SOCKET_SERVER_GID int "GID to deny server sockets for" depends on GRKERNSEC_SOCKET_SERVER diff --git a/4.8.13/4465_selinux-avc_audit-log-curr_ip.patch b/4.8.14/4465_selinux-avc_audit-log-curr_ip.patch index 7248385..06a5294 100644 --- a/4.8.13/4465_selinux-avc_audit-log-curr_ip.patch +++ b/4.8.14/4465_selinux-avc_audit-log-curr_ip.patch @@ -28,7 +28,7 @@ Signed-off-by: Lorenzo Hernandez Garcia-Hierro <lorenzo@gnu.org> diff -Naur a/grsecurity/Kconfig b/grsecurity/Kconfig --- a/grsecurity/Kconfig 2011-04-17 19:25:54.000000000 -0400 +++ b/grsecurity/Kconfig 2011-04-17 19:32:53.000000000 -0400 -@@ -1176,6 +1176,27 @@ +@@ -1177,6 +1177,27 @@ menu "Logging Options" depends on GRKERNSEC diff --git a/4.8.13/4470_disable-compat_vdso.patch b/4.8.14/4470_disable-compat_vdso.patch index 1e4b84a..1e4b84a 100644 --- a/4.8.13/4470_disable-compat_vdso.patch +++ b/4.8.14/4470_disable-compat_vdso.patch diff --git a/4.8.13/4475_emutramp_default_on.patch b/4.8.14/4475_emutramp_default_on.patch index 7b468ee..7b468ee 100644 --- a/4.8.13/4475_emutramp_default_on.patch +++ b/4.8.14/4475_emutramp_default_on.patch |