Contents of /trunk/kernel-alx/patches-4.4/0137-4.4.38-all-fixes.patch
Parent Directory | Revision Log
Revision 2873 -
(show annotations)
(download)
Mon Mar 27 13:49:15 2017 UTC (7 years, 6 months ago) by niro
File size: 32131 byte(s)
Mon Mar 27 13:49:15 2017 UTC (7 years, 6 months ago) by niro
File size: 32131 byte(s)
linux-4.4.38
1 | diff --git a/Makefile b/Makefile |
2 | index b57ec79b4941..6876efe0d735 100644 |
3 | --- a/Makefile |
4 | +++ b/Makefile |
5 | @@ -1,6 +1,6 @@ |
6 | VERSION = 4 |
7 | PATCHLEVEL = 4 |
8 | -SUBLEVEL = 37 |
9 | +SUBLEVEL = 38 |
10 | EXTRAVERSION = |
11 | NAME = Blurry Fish Butt |
12 | |
13 | diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c |
14 | index c3c12efe0bc0..9c0c8fd0b292 100644 |
15 | --- a/arch/sparc/kernel/signal_32.c |
16 | +++ b/arch/sparc/kernel/signal_32.c |
17 | @@ -89,7 +89,7 @@ asmlinkage void do_sigreturn(struct pt_regs *regs) |
18 | sf = (struct signal_frame __user *) regs->u_regs[UREG_FP]; |
19 | |
20 | /* 1. Make sure we are not getting garbage from the user */ |
21 | - if (!invalid_frame_pointer(sf, sizeof(*sf))) |
22 | + if (invalid_frame_pointer(sf, sizeof(*sf))) |
23 | goto segv_and_exit; |
24 | |
25 | if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP])) |
26 | @@ -150,7 +150,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs) |
27 | |
28 | synchronize_user_stack(); |
29 | sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP]; |
30 | - if (!invalid_frame_pointer(sf, sizeof(*sf))) |
31 | + if (invalid_frame_pointer(sf, sizeof(*sf))) |
32 | goto segv; |
33 | |
34 | if (get_user(ufp, &sf->regs.u_regs[UREG_FP])) |
35 | diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c |
36 | index a5331c336b2a..3d3414c14792 100644 |
37 | --- a/arch/sparc/mm/init_64.c |
38 | +++ b/arch/sparc/mm/init_64.c |
39 | @@ -800,8 +800,10 @@ struct mdesc_mblock { |
40 | }; |
41 | static struct mdesc_mblock *mblocks; |
42 | static int num_mblocks; |
43 | +static int find_numa_node_for_addr(unsigned long pa, |
44 | + struct node_mem_mask *pnode_mask); |
45 | |
46 | -static unsigned long ra_to_pa(unsigned long addr) |
47 | +static unsigned long __init ra_to_pa(unsigned long addr) |
48 | { |
49 | int i; |
50 | |
51 | @@ -817,8 +819,11 @@ static unsigned long ra_to_pa(unsigned long addr) |
52 | return addr; |
53 | } |
54 | |
55 | -static int find_node(unsigned long addr) |
56 | +static int __init find_node(unsigned long addr) |
57 | { |
58 | + static bool search_mdesc = true; |
59 | + static struct node_mem_mask last_mem_mask = { ~0UL, ~0UL }; |
60 | + static int last_index; |
61 | int i; |
62 | |
63 | addr = ra_to_pa(addr); |
64 | @@ -828,13 +833,30 @@ static int find_node(unsigned long addr) |
65 | if ((addr & p->mask) == p->val) |
66 | return i; |
67 | } |
68 | - /* The following condition has been observed on LDOM guests.*/ |
69 | - WARN_ONCE(1, "find_node: A physical address doesn't match a NUMA node" |
70 | - " rule. Some physical memory will be owned by node 0."); |
71 | - return 0; |
72 | + /* The following condition has been observed on LDOM guests because |
73 | + * node_masks only contains the best latency mask and value. |
74 | + * LDOM guest's mdesc can contain a single latency group to |
75 | + * cover multiple address range. Print warning message only if the |
76 | + * address cannot be found in node_masks nor mdesc. |
77 | + */ |
78 | + if ((search_mdesc) && |
79 | + ((addr & last_mem_mask.mask) != last_mem_mask.val)) { |
80 | + /* find the available node in the mdesc */ |
81 | + last_index = find_numa_node_for_addr(addr, &last_mem_mask); |
82 | + numadbg("find_node: latency group for address 0x%lx is %d\n", |
83 | + addr, last_index); |
84 | + if ((last_index < 0) || (last_index >= num_node_masks)) { |
85 | + /* WARN_ONCE() and use default group 0 */ |
86 | + WARN_ONCE(1, "find_node: A physical address doesn't match a NUMA node rule. Some physical memory will be owned by node 0."); |
87 | + search_mdesc = false; |
88 | + last_index = 0; |
89 | + } |
90 | + } |
91 | + |
92 | + return last_index; |
93 | } |
94 | |
95 | -static u64 memblock_nid_range(u64 start, u64 end, int *nid) |
96 | +static u64 __init memblock_nid_range(u64 start, u64 end, int *nid) |
97 | { |
98 | *nid = find_node(start); |
99 | start += PAGE_SIZE; |
100 | @@ -1158,6 +1180,41 @@ int __node_distance(int from, int to) |
101 | return numa_latency[from][to]; |
102 | } |
103 | |
104 | +static int find_numa_node_for_addr(unsigned long pa, |
105 | + struct node_mem_mask *pnode_mask) |
106 | +{ |
107 | + struct mdesc_handle *md = mdesc_grab(); |
108 | + u64 node, arc; |
109 | + int i = 0; |
110 | + |
111 | + node = mdesc_node_by_name(md, MDESC_NODE_NULL, "latency-groups"); |
112 | + if (node == MDESC_NODE_NULL) |
113 | + goto out; |
114 | + |
115 | + mdesc_for_each_node_by_name(md, node, "group") { |
116 | + mdesc_for_each_arc(arc, md, node, MDESC_ARC_TYPE_FWD) { |
117 | + u64 target = mdesc_arc_target(md, arc); |
118 | + struct mdesc_mlgroup *m = find_mlgroup(target); |
119 | + |
120 | + if (!m) |
121 | + continue; |
122 | + if ((pa & m->mask) == m->match) { |
123 | + if (pnode_mask) { |
124 | + pnode_mask->mask = m->mask; |
125 | + pnode_mask->val = m->match; |
126 | + } |
127 | + mdesc_release(md); |
128 | + return i; |
129 | + } |
130 | + } |
131 | + i++; |
132 | + } |
133 | + |
134 | +out: |
135 | + mdesc_release(md); |
136 | + return -1; |
137 | +} |
138 | + |
139 | static int find_best_numa_node_for_mlgroup(struct mdesc_mlgroup *grp) |
140 | { |
141 | int i; |
142 | diff --git a/block/blk-map.c b/block/blk-map.c |
143 | index f565e11f465a..69953bd97e65 100644 |
144 | --- a/block/blk-map.c |
145 | +++ b/block/blk-map.c |
146 | @@ -90,6 +90,9 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, |
147 | if (!iter || !iter->count) |
148 | return -EINVAL; |
149 | |
150 | + if (!iter_is_iovec(iter)) |
151 | + return -EINVAL; |
152 | + |
153 | iov_for_each(iov, i, *iter) { |
154 | unsigned long uaddr = (unsigned long) iov.iov_base; |
155 | |
156 | diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c |
157 | index 6f946fedbb77..0864f05633a2 100644 |
158 | --- a/drivers/net/dsa/bcm_sf2.c |
159 | +++ b/drivers/net/dsa/bcm_sf2.c |
160 | @@ -1137,6 +1137,7 @@ static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port, |
161 | struct phy_device *phydev) |
162 | { |
163 | struct bcm_sf2_priv *priv = ds_to_priv(ds); |
164 | + struct ethtool_eee *p = &priv->port_sts[port].eee; |
165 | u32 id_mode_dis = 0, port_mode; |
166 | const char *str = NULL; |
167 | u32 reg; |
168 | @@ -1211,6 +1212,9 @@ force_link: |
169 | reg |= DUPLX_MODE; |
170 | |
171 | core_writel(priv, reg, CORE_STS_OVERRIDE_GMIIP_PORT(port)); |
172 | + |
173 | + if (!phydev->is_pseudo_fixed_link) |
174 | + p->eee_enabled = bcm_sf2_eee_init(ds, port, phydev); |
175 | } |
176 | |
177 | static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port, |
178 | diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c |
179 | index 0fb3f8de88e9..91627561c58d 100644 |
180 | --- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c |
181 | +++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c |
182 | @@ -1168,6 +1168,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, |
183 | struct bcmgenet_tx_ring *ring) |
184 | { |
185 | struct bcmgenet_priv *priv = netdev_priv(dev); |
186 | + struct device *kdev = &priv->pdev->dev; |
187 | struct enet_cb *tx_cb_ptr; |
188 | struct netdev_queue *txq; |
189 | unsigned int pkts_compl = 0; |
190 | @@ -1195,7 +1196,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, |
191 | pkts_compl++; |
192 | dev->stats.tx_packets++; |
193 | dev->stats.tx_bytes += tx_cb_ptr->skb->len; |
194 | - dma_unmap_single(&dev->dev, |
195 | + dma_unmap_single(kdev, |
196 | dma_unmap_addr(tx_cb_ptr, dma_addr), |
197 | dma_unmap_len(tx_cb_ptr, dma_len), |
198 | DMA_TO_DEVICE); |
199 | @@ -1203,7 +1204,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev, |
200 | } else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) { |
201 | dev->stats.tx_bytes += |
202 | dma_unmap_len(tx_cb_ptr, dma_len); |
203 | - dma_unmap_page(&dev->dev, |
204 | + dma_unmap_page(kdev, |
205 | dma_unmap_addr(tx_cb_ptr, dma_addr), |
206 | dma_unmap_len(tx_cb_ptr, dma_len), |
207 | DMA_TO_DEVICE); |
208 | @@ -1754,6 +1755,7 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv, |
209 | |
210 | static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv) |
211 | { |
212 | + struct device *kdev = &priv->pdev->dev; |
213 | struct enet_cb *cb; |
214 | int i; |
215 | |
216 | @@ -1761,7 +1763,7 @@ static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv) |
217 | cb = &priv->rx_cbs[i]; |
218 | |
219 | if (dma_unmap_addr(cb, dma_addr)) { |
220 | - dma_unmap_single(&priv->dev->dev, |
221 | + dma_unmap_single(kdev, |
222 | dma_unmap_addr(cb, dma_addr), |
223 | priv->rx_buf_len, DMA_FROM_DEVICE); |
224 | dma_unmap_addr_set(cb, dma_addr, 0); |
225 | diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c |
226 | index 5606a043063e..4b62aa1f9ff8 100644 |
227 | --- a/drivers/net/ethernet/marvell/sky2.c |
228 | +++ b/drivers/net/ethernet/marvell/sky2.c |
229 | @@ -5220,6 +5220,19 @@ static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sky2_suspend, sky2_resume); |
230 | |
231 | static void sky2_shutdown(struct pci_dev *pdev) |
232 | { |
233 | + struct sky2_hw *hw = pci_get_drvdata(pdev); |
234 | + int port; |
235 | + |
236 | + for (port = 0; port < hw->ports; port++) { |
237 | + struct net_device *ndev = hw->dev[port]; |
238 | + |
239 | + rtnl_lock(); |
240 | + if (netif_running(ndev)) { |
241 | + dev_close(ndev); |
242 | + netif_device_detach(ndev); |
243 | + } |
244 | + rtnl_unlock(); |
245 | + } |
246 | sky2_suspend(&pdev->dev); |
247 | pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev)); |
248 | pci_set_power_state(pdev, PCI_D3hot); |
249 | diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c |
250 | index 36fc9427418f..480f3dae0780 100644 |
251 | --- a/drivers/net/ethernet/renesas/sh_eth.c |
252 | +++ b/drivers/net/ethernet/renesas/sh_eth.c |
253 | @@ -832,7 +832,7 @@ static struct sh_eth_cpu_data r7s72100_data = { |
254 | |
255 | .ecsr_value = ECSR_ICD, |
256 | .ecsipr_value = ECSIPR_ICDIP, |
257 | - .eesipr_value = 0xff7f009f, |
258 | + .eesipr_value = 0xe77f009f, |
259 | |
260 | .tx_check = EESR_TC1 | EESR_FTC, |
261 | .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | |
262 | diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c |
263 | index 4827c6987ac3..f0961cbaf87e 100644 |
264 | --- a/drivers/net/geneve.c |
265 | +++ b/drivers/net/geneve.c |
266 | @@ -815,7 +815,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, |
267 | struct geneve_dev *geneve = netdev_priv(dev); |
268 | struct geneve_sock *gs4 = geneve->sock4; |
269 | struct rtable *rt = NULL; |
270 | - const struct iphdr *iip; /* interior IP header */ |
271 | int err = -EINVAL; |
272 | struct flowi4 fl4; |
273 | __u8 tos, ttl; |
274 | @@ -842,8 +841,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, |
275 | sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); |
276 | skb_reset_mac_header(skb); |
277 | |
278 | - iip = ip_hdr(skb); |
279 | - |
280 | if (info) { |
281 | const struct ip_tunnel_key *key = &info->key; |
282 | u8 *opts = NULL; |
283 | @@ -859,7 +856,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, |
284 | if (unlikely(err)) |
285 | goto err; |
286 | |
287 | - tos = ip_tunnel_ecn_encap(key->tos, iip, skb); |
288 | + tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb); |
289 | ttl = key->ttl; |
290 | df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0; |
291 | } else { |
292 | @@ -869,7 +866,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, |
293 | if (unlikely(err)) |
294 | goto err; |
295 | |
296 | - tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, iip, skb); |
297 | + tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, ip_hdr(skb), skb); |
298 | ttl = geneve->ttl; |
299 | if (!ttl && IN_MULTICAST(ntohl(fl4.daddr))) |
300 | ttl = 1; |
301 | @@ -903,7 +900,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, |
302 | struct geneve_dev *geneve = netdev_priv(dev); |
303 | struct geneve_sock *gs6 = geneve->sock6; |
304 | struct dst_entry *dst = NULL; |
305 | - const struct iphdr *iip; /* interior IP header */ |
306 | int err = -EINVAL; |
307 | struct flowi6 fl6; |
308 | __u8 prio, ttl; |
309 | @@ -927,8 +923,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, |
310 | sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true); |
311 | skb_reset_mac_header(skb); |
312 | |
313 | - iip = ip_hdr(skb); |
314 | - |
315 | if (info) { |
316 | const struct ip_tunnel_key *key = &info->key; |
317 | u8 *opts = NULL; |
318 | @@ -945,7 +939,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, |
319 | if (unlikely(err)) |
320 | goto err; |
321 | |
322 | - prio = ip_tunnel_ecn_encap(key->tos, iip, skb); |
323 | + prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb); |
324 | ttl = key->ttl; |
325 | } else { |
326 | udp_csum = false; |
327 | @@ -954,7 +948,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, |
328 | if (unlikely(err)) |
329 | goto err; |
330 | |
331 | - prio = ip_tunnel_ecn_encap(fl6.flowi6_tos, iip, skb); |
332 | + prio = ip_tunnel_ecn_encap(fl6.flowi6_tos, ip_hdr(skb), skb); |
333 | ttl = geneve->ttl; |
334 | if (!ttl && ipv6_addr_is_multicast(&fl6.daddr)) |
335 | ttl = 1; |
336 | diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c |
337 | index f94ab786088f..0e2a19e58923 100644 |
338 | --- a/drivers/net/virtio_net.c |
339 | +++ b/drivers/net/virtio_net.c |
340 | @@ -1465,6 +1465,11 @@ static void virtnet_free_queues(struct virtnet_info *vi) |
341 | netif_napi_del(&vi->rq[i].napi); |
342 | } |
343 | |
344 | + /* We called napi_hash_del() before netif_napi_del(), |
345 | + * we need to respect an RCU grace period before freeing vi->rq |
346 | + */ |
347 | + synchronize_net(); |
348 | + |
349 | kfree(vi->rq); |
350 | kfree(vi->sq); |
351 | } |
352 | diff --git a/include/linux/uio.h b/include/linux/uio.h |
353 | index 5f9c59da978b..e2225109b816 100644 |
354 | --- a/include/linux/uio.h |
355 | +++ b/include/linux/uio.h |
356 | @@ -101,12 +101,12 @@ int iov_iter_npages(const struct iov_iter *i, int maxpages); |
357 | |
358 | const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags); |
359 | |
360 | -static inline size_t iov_iter_count(struct iov_iter *i) |
361 | +static inline size_t iov_iter_count(const struct iov_iter *i) |
362 | { |
363 | return i->count; |
364 | } |
365 | |
366 | -static inline bool iter_is_iovec(struct iov_iter *i) |
367 | +static inline bool iter_is_iovec(const struct iov_iter *i) |
368 | { |
369 | return !(i->type & (ITER_BVEC | ITER_KVEC)); |
370 | } |
371 | diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c |
372 | index 2c2eb1b629b1..2e9a1c2818c7 100644 |
373 | --- a/net/core/net_namespace.c |
374 | +++ b/net/core/net_namespace.c |
375 | @@ -217,6 +217,8 @@ int peernet2id_alloc(struct net *net, struct net *peer) |
376 | bool alloc; |
377 | int id; |
378 | |
379 | + if (atomic_read(&net->count) == 0) |
380 | + return NETNSA_NSID_NOT_ASSIGNED; |
381 | spin_lock_irqsave(&net->nsid_lock, flags); |
382 | alloc = atomic_read(&peer->count) == 0 ? false : true; |
383 | id = __peernet2id_alloc(net, peer, &alloc); |
384 | diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c |
385 | index 87b91ffbdec3..b94e165a4f79 100644 |
386 | --- a/net/core/rtnetlink.c |
387 | +++ b/net/core/rtnetlink.c |
388 | @@ -2600,7 +2600,10 @@ nla_put_failure: |
389 | |
390 | static inline size_t rtnl_fdb_nlmsg_size(void) |
391 | { |
392 | - return NLMSG_ALIGN(sizeof(struct ndmsg)) + nla_total_size(ETH_ALEN); |
393 | + return NLMSG_ALIGN(sizeof(struct ndmsg)) + |
394 | + nla_total_size(ETH_ALEN) + /* NDA_LLADDR */ |
395 | + nla_total_size(sizeof(u16)) + /* NDA_VLAN */ |
396 | + 0; |
397 | } |
398 | |
399 | static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type) |
400 | diff --git a/net/core/sock.c b/net/core/sock.c |
401 | index 88f017854509..f4c0917e66b5 100644 |
402 | --- a/net/core/sock.c |
403 | +++ b/net/core/sock.c |
404 | @@ -745,7 +745,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname, |
405 | val = min_t(u32, val, sysctl_wmem_max); |
406 | set_sndbuf: |
407 | sk->sk_userlocks |= SOCK_SNDBUF_LOCK; |
408 | - sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF); |
409 | + sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF); |
410 | /* Wake up sending tasks if we upped the value. */ |
411 | sk->sk_write_space(sk); |
412 | break; |
413 | @@ -781,7 +781,7 @@ set_rcvbuf: |
414 | * returning the value we actually used in getsockopt |
415 | * is the most desirable behavior. |
416 | */ |
417 | - sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF); |
418 | + sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF); |
419 | break; |
420 | |
421 | case SO_RCVBUFFORCE: |
422 | diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c |
423 | index 861e1fa25d5e..0759f5b9180e 100644 |
424 | --- a/net/dccp/ipv4.c |
425 | +++ b/net/dccp/ipv4.c |
426 | @@ -698,6 +698,7 @@ int dccp_invalid_packet(struct sk_buff *skb) |
427 | { |
428 | const struct dccp_hdr *dh; |
429 | unsigned int cscov; |
430 | + u8 dccph_doff; |
431 | |
432 | if (skb->pkt_type != PACKET_HOST) |
433 | return 1; |
434 | @@ -719,18 +720,19 @@ int dccp_invalid_packet(struct sk_buff *skb) |
435 | /* |
436 | * If P.Data Offset is too small for packet type, drop packet and return |
437 | */ |
438 | - if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) { |
439 | - DCCP_WARN("P.Data Offset(%u) too small\n", dh->dccph_doff); |
440 | + dccph_doff = dh->dccph_doff; |
441 | + if (dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) { |
442 | + DCCP_WARN("P.Data Offset(%u) too small\n", dccph_doff); |
443 | return 1; |
444 | } |
445 | /* |
446 | * If P.Data Offset is too too large for packet, drop packet and return |
447 | */ |
448 | - if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) { |
449 | - DCCP_WARN("P.Data Offset(%u) too large\n", dh->dccph_doff); |
450 | + if (!pskb_may_pull(skb, dccph_doff * sizeof(u32))) { |
451 | + DCCP_WARN("P.Data Offset(%u) too large\n", dccph_doff); |
452 | return 1; |
453 | } |
454 | - |
455 | + dh = dccp_hdr(skb); |
456 | /* |
457 | * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet |
458 | * has short sequence numbers), drop packet and return |
459 | diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c |
460 | index d95631d09248..20fb25e3027b 100644 |
461 | --- a/net/ipv4/esp4.c |
462 | +++ b/net/ipv4/esp4.c |
463 | @@ -476,7 +476,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb) |
464 | esph = (void *)skb_push(skb, 4); |
465 | *seqhi = esph->spi; |
466 | esph->spi = esph->seq_no; |
467 | - esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.input.hi); |
468 | + esph->seq_no = XFRM_SKB_CB(skb)->seq.input.hi; |
469 | aead_request_set_callback(req, 0, esp_input_done_esn, skb); |
470 | } |
471 | |
472 | diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c |
473 | index f2ad5216c438..2b7283303650 100644 |
474 | --- a/net/ipv4/ip_output.c |
475 | +++ b/net/ipv4/ip_output.c |
476 | @@ -102,6 +102,9 @@ int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb) |
477 | |
478 | iph->tot_len = htons(skb->len); |
479 | ip_send_check(iph); |
480 | + |
481 | + skb->protocol = htons(ETH_P_IP); |
482 | + |
483 | return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT, |
484 | net, sk, skb, NULL, skb_dst(skb)->dev, |
485 | dst_output); |
486 | diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c |
487 | index aa67e0e64b69..23160d2b3f71 100644 |
488 | --- a/net/ipv4/ping.c |
489 | +++ b/net/ipv4/ping.c |
490 | @@ -660,6 +660,10 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len, |
491 | if (len > 0xFFFF) |
492 | return -EMSGSIZE; |
493 | |
494 | + /* Must have at least a full ICMP header. */ |
495 | + if (len < icmph_len) |
496 | + return -EINVAL; |
497 | + |
498 | /* |
499 | * Check the flags. |
500 | */ |
501 | diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c |
502 | index 060a60b2f8a6..111ba55fd512 100644 |
503 | --- a/net/ipv6/esp6.c |
504 | +++ b/net/ipv6/esp6.c |
505 | @@ -418,7 +418,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb) |
506 | esph = (void *)skb_push(skb, 4); |
507 | *seqhi = esph->spi; |
508 | esph->spi = esph->seq_no; |
509 | - esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.input.hi); |
510 | + esph->seq_no = XFRM_SKB_CB(skb)->seq.input.hi; |
511 | aead_request_set_callback(req, 0, esp_input_done_esn, skb); |
512 | } |
513 | |
514 | diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c |
515 | index e8878886eba4..2994d1f1a661 100644 |
516 | --- a/net/ipv6/ip6_tunnel.c |
517 | +++ b/net/ipv6/ip6_tunnel.c |
518 | @@ -1043,6 +1043,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, |
519 | struct ipv6_tel_txoption opt; |
520 | struct dst_entry *dst = NULL, *ndst = NULL; |
521 | struct net_device *tdev; |
522 | + bool use_cache = false; |
523 | int mtu; |
524 | unsigned int max_headroom = sizeof(struct ipv6hdr); |
525 | u8 proto; |
526 | @@ -1070,7 +1071,15 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, |
527 | |
528 | memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); |
529 | neigh_release(neigh); |
530 | - } else if (!fl6->flowi6_mark) |
531 | + } else if (!(t->parms.flags & |
532 | + (IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) { |
533 | + /* enable the cache only only if the routing decision does |
534 | + * not depend on the current inner header value |
535 | + */ |
536 | + use_cache = true; |
537 | + } |
538 | + |
539 | + if (use_cache) |
540 | dst = ip6_tnl_dst_get(t); |
541 | |
542 | if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr)) |
543 | @@ -1134,7 +1143,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb, |
544 | skb = new_skb; |
545 | } |
546 | |
547 | - if (!fl6->flowi6_mark && ndst) |
548 | + if (use_cache && ndst) |
549 | ip6_tnl_dst_set(t, ndst); |
550 | skb_dst_set(skb, dst); |
551 | |
552 | diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c |
553 | index 462f2a76b5c2..1d184322a7b1 100644 |
554 | --- a/net/ipv6/output_core.c |
555 | +++ b/net/ipv6/output_core.c |
556 | @@ -148,6 +148,8 @@ int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb) |
557 | ipv6_hdr(skb)->payload_len = htons(len); |
558 | IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr); |
559 | |
560 | + skb->protocol = htons(ETH_P_IPV6); |
561 | + |
562 | return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT, |
563 | net, sk, skb, NULL, skb_dst(skb)->dev, |
564 | dst_output); |
565 | diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c |
566 | index 42de4ccd159f..d0e906d39642 100644 |
567 | --- a/net/l2tp/l2tp_ip.c |
568 | +++ b/net/l2tp/l2tp_ip.c |
569 | @@ -251,8 +251,6 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
570 | int ret; |
571 | int chk_addr_ret; |
572 | |
573 | - if (!sock_flag(sk, SOCK_ZAPPED)) |
574 | - return -EINVAL; |
575 | if (addr_len < sizeof(struct sockaddr_l2tpip)) |
576 | return -EINVAL; |
577 | if (addr->l2tp_family != AF_INET) |
578 | @@ -267,6 +265,9 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
579 | read_unlock_bh(&l2tp_ip_lock); |
580 | |
581 | lock_sock(sk); |
582 | + if (!sock_flag(sk, SOCK_ZAPPED)) |
583 | + goto out; |
584 | + |
585 | if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_l2tpip)) |
586 | goto out; |
587 | |
588 | diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c |
589 | index 9ee4ddb6b397..3c4f867d3633 100644 |
590 | --- a/net/l2tp/l2tp_ip6.c |
591 | +++ b/net/l2tp/l2tp_ip6.c |
592 | @@ -266,8 +266,6 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
593 | int addr_type; |
594 | int err; |
595 | |
596 | - if (!sock_flag(sk, SOCK_ZAPPED)) |
597 | - return -EINVAL; |
598 | if (addr->l2tp_family != AF_INET6) |
599 | return -EINVAL; |
600 | if (addr_len < sizeof(*addr)) |
601 | @@ -293,6 +291,9 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) |
602 | lock_sock(sk); |
603 | |
604 | err = -EINVAL; |
605 | + if (!sock_flag(sk, SOCK_ZAPPED)) |
606 | + goto out_unlock; |
607 | + |
608 | if (sk->sk_state != TCP_CLOSE) |
609 | goto out_unlock; |
610 | |
611 | diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c |
612 | index 28fc283c1ec1..360700a2f46c 100644 |
613 | --- a/net/netlink/af_netlink.c |
614 | +++ b/net/netlink/af_netlink.c |
615 | @@ -931,7 +931,6 @@ static void netlink_sock_destruct(struct sock *sk) |
616 | if (nlk->cb_running) { |
617 | if (nlk->cb.done) |
618 | nlk->cb.done(&nlk->cb); |
619 | - |
620 | module_put(nlk->cb.module); |
621 | kfree_skb(nlk->cb.skb); |
622 | } |
623 | @@ -960,6 +959,14 @@ static void netlink_sock_destruct(struct sock *sk) |
624 | WARN_ON(nlk_sk(sk)->groups); |
625 | } |
626 | |
627 | +static void netlink_sock_destruct_work(struct work_struct *work) |
628 | +{ |
629 | + struct netlink_sock *nlk = container_of(work, struct netlink_sock, |
630 | + work); |
631 | + |
632 | + sk_free(&nlk->sk); |
633 | +} |
634 | + |
635 | /* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on |
636 | * SMP. Look, when several writers sleep and reader wakes them up, all but one |
637 | * immediately hit write lock and grab all the cpus. Exclusive sleep solves |
638 | @@ -1265,8 +1272,18 @@ out_module: |
639 | static void deferred_put_nlk_sk(struct rcu_head *head) |
640 | { |
641 | struct netlink_sock *nlk = container_of(head, struct netlink_sock, rcu); |
642 | + struct sock *sk = &nlk->sk; |
643 | + |
644 | + if (!atomic_dec_and_test(&sk->sk_refcnt)) |
645 | + return; |
646 | + |
647 | + if (nlk->cb_running && nlk->cb.done) { |
648 | + INIT_WORK(&nlk->work, netlink_sock_destruct_work); |
649 | + schedule_work(&nlk->work); |
650 | + return; |
651 | + } |
652 | |
653 | - sock_put(&nlk->sk); |
654 | + sk_free(sk); |
655 | } |
656 | |
657 | static int netlink_release(struct socket *sock) |
658 | diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h |
659 | index 14437d9b1965..df32cb92d9fc 100644 |
660 | --- a/net/netlink/af_netlink.h |
661 | +++ b/net/netlink/af_netlink.h |
662 | @@ -3,6 +3,7 @@ |
663 | |
664 | #include <linux/rhashtable.h> |
665 | #include <linux/atomic.h> |
666 | +#include <linux/workqueue.h> |
667 | #include <net/sock.h> |
668 | |
669 | #define NLGRPSZ(x) (ALIGN(x, sizeof(unsigned long) * 8) / 8) |
670 | @@ -53,6 +54,7 @@ struct netlink_sock { |
671 | |
672 | struct rhash_head node; |
673 | struct rcu_head rcu; |
674 | + struct work_struct work; |
675 | }; |
676 | |
677 | static inline struct netlink_sock *nlk_sk(struct sock *sk) |
678 | diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c |
679 | index 34e4fcfd240b..f223d1c80ccf 100644 |
680 | --- a/net/packet/af_packet.c |
681 | +++ b/net/packet/af_packet.c |
682 | @@ -3572,19 +3572,25 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv |
683 | |
684 | if (optlen != sizeof(val)) |
685 | return -EINVAL; |
686 | - if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) |
687 | - return -EBUSY; |
688 | if (copy_from_user(&val, optval, sizeof(val))) |
689 | return -EFAULT; |
690 | switch (val) { |
691 | case TPACKET_V1: |
692 | case TPACKET_V2: |
693 | case TPACKET_V3: |
694 | - po->tp_version = val; |
695 | - return 0; |
696 | + break; |
697 | default: |
698 | return -EINVAL; |
699 | } |
700 | + lock_sock(sk); |
701 | + if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { |
702 | + ret = -EBUSY; |
703 | + } else { |
704 | + po->tp_version = val; |
705 | + ret = 0; |
706 | + } |
707 | + release_sock(sk); |
708 | + return ret; |
709 | } |
710 | case PACKET_RESERVE: |
711 | { |
712 | @@ -4067,6 +4073,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, |
713 | /* Added to avoid minimal code churn */ |
714 | struct tpacket_req *req = &req_u->req; |
715 | |
716 | + lock_sock(sk); |
717 | /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ |
718 | if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { |
719 | WARN(1, "Tx-ring is not supported.\n"); |
720 | @@ -4148,7 +4155,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, |
721 | goto out; |
722 | } |
723 | |
724 | - lock_sock(sk); |
725 | |
726 | /* Detach socket from network */ |
727 | spin_lock(&po->bind_lock); |
728 | @@ -4197,11 +4203,11 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, |
729 | if (!tx_ring) |
730 | prb_shutdown_retire_blk_timer(po, rb_queue); |
731 | } |
732 | - release_sock(sk); |
733 | |
734 | if (pg_vec) |
735 | free_pg_vec(pg_vec, order, req->tp_block_nr); |
736 | out: |
737 | + release_sock(sk); |
738 | return err; |
739 | } |
740 | |
741 | diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c |
742 | index e38a7701f154..c3434e902445 100644 |
743 | --- a/net/sched/act_pedit.c |
744 | +++ b/net/sched/act_pedit.c |
745 | @@ -104,6 +104,17 @@ static void tcf_pedit_cleanup(struct tc_action *a, int bind) |
746 | kfree(keys); |
747 | } |
748 | |
749 | +static bool offset_valid(struct sk_buff *skb, int offset) |
750 | +{ |
751 | + if (offset > 0 && offset > skb->len) |
752 | + return false; |
753 | + |
754 | + if (offset < 0 && -offset > skb_headroom(skb)) |
755 | + return false; |
756 | + |
757 | + return true; |
758 | +} |
759 | + |
760 | static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a, |
761 | struct tcf_result *res) |
762 | { |
763 | @@ -130,6 +141,11 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a, |
764 | if (tkey->offmask) { |
765 | char *d, _d; |
766 | |
767 | + if (!offset_valid(skb, off + tkey->at)) { |
768 | + pr_info("tc filter pedit 'at' offset %d out of bounds\n", |
769 | + off + tkey->at); |
770 | + goto bad; |
771 | + } |
772 | d = skb_header_pointer(skb, off + tkey->at, 1, |
773 | &_d); |
774 | if (!d) |
775 | @@ -142,10 +158,10 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a, |
776 | " offset must be on 32 bit boundaries\n"); |
777 | goto bad; |
778 | } |
779 | - if (offset > 0 && offset > skb->len) { |
780 | - pr_info("tc filter pedit" |
781 | - " offset %d can't exceed pkt length %d\n", |
782 | - offset, skb->len); |
783 | + |
784 | + if (!offset_valid(skb, off + offset)) { |
785 | + pr_info("tc filter pedit offset %d out of bounds\n", |
786 | + offset); |
787 | goto bad; |
788 | } |
789 | |
790 | diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c |
791 | index 0b8c3ace671f..1bf1f4517db6 100644 |
792 | --- a/net/sched/cls_basic.c |
793 | +++ b/net/sched/cls_basic.c |
794 | @@ -62,9 +62,6 @@ static unsigned long basic_get(struct tcf_proto *tp, u32 handle) |
795 | struct basic_head *head = rtnl_dereference(tp->root); |
796 | struct basic_filter *f; |
797 | |
798 | - if (head == NULL) |
799 | - return 0UL; |
800 | - |
801 | list_for_each_entry(f, &head->flist, link) { |
802 | if (f->handle == handle) { |
803 | l = (unsigned long) f; |
804 | @@ -109,7 +106,6 @@ static bool basic_destroy(struct tcf_proto *tp, bool force) |
805 | tcf_unbind_filter(tp, &f->res); |
806 | call_rcu(&f->rcu, basic_delete_filter); |
807 | } |
808 | - RCU_INIT_POINTER(tp->root, NULL); |
809 | kfree_rcu(head, rcu); |
810 | return true; |
811 | } |
812 | diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c |
813 | index 5faaa5425f7b..3eef0215e53f 100644 |
814 | --- a/net/sched/cls_bpf.c |
815 | +++ b/net/sched/cls_bpf.c |
816 | @@ -199,7 +199,6 @@ static bool cls_bpf_destroy(struct tcf_proto *tp, bool force) |
817 | call_rcu(&prog->rcu, __cls_bpf_delete_prog); |
818 | } |
819 | |
820 | - RCU_INIT_POINTER(tp->root, NULL); |
821 | kfree_rcu(head, rcu); |
822 | return true; |
823 | } |
824 | @@ -210,9 +209,6 @@ static unsigned long cls_bpf_get(struct tcf_proto *tp, u32 handle) |
825 | struct cls_bpf_prog *prog; |
826 | unsigned long ret = 0UL; |
827 | |
828 | - if (head == NULL) |
829 | - return 0UL; |
830 | - |
831 | list_for_each_entry(prog, &head->plist, link) { |
832 | if (prog->handle == handle) { |
833 | ret = (unsigned long) prog; |
834 | diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c |
835 | index 4c85bd3a750c..c104c2019feb 100644 |
836 | --- a/net/sched/cls_cgroup.c |
837 | +++ b/net/sched/cls_cgroup.c |
838 | @@ -130,11 +130,10 @@ static bool cls_cgroup_destroy(struct tcf_proto *tp, bool force) |
839 | |
840 | if (!force) |
841 | return false; |
842 | - |
843 | - if (head) { |
844 | - RCU_INIT_POINTER(tp->root, NULL); |
845 | + /* Head can still be NULL due to cls_cgroup_init(). */ |
846 | + if (head) |
847 | call_rcu(&head->rcu, cls_cgroup_destroy_rcu); |
848 | - } |
849 | + |
850 | return true; |
851 | } |
852 | |
853 | diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c |
854 | index fbfec6a18839..d7ba2b4ff0f3 100644 |
855 | --- a/net/sched/cls_flow.c |
856 | +++ b/net/sched/cls_flow.c |
857 | @@ -583,7 +583,6 @@ static bool flow_destroy(struct tcf_proto *tp, bool force) |
858 | list_del_rcu(&f->list); |
859 | call_rcu(&f->rcu, flow_destroy_filter); |
860 | } |
861 | - RCU_INIT_POINTER(tp->root, NULL); |
862 | kfree_rcu(head, rcu); |
863 | return true; |
864 | } |
865 | diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c |
866 | index 95b021243233..e5a58c82728a 100644 |
867 | --- a/net/sched/cls_flower.c |
868 | +++ b/net/sched/cls_flower.c |
869 | @@ -13,6 +13,7 @@ |
870 | #include <linux/init.h> |
871 | #include <linux/module.h> |
872 | #include <linux/rhashtable.h> |
873 | +#include <linux/workqueue.h> |
874 | |
875 | #include <linux/if_ether.h> |
876 | #include <linux/in6.h> |
877 | @@ -55,7 +56,10 @@ struct cls_fl_head { |
878 | bool mask_assigned; |
879 | struct list_head filters; |
880 | struct rhashtable_params ht_params; |
881 | - struct rcu_head rcu; |
882 | + union { |
883 | + struct work_struct work; |
884 | + struct rcu_head rcu; |
885 | + }; |
886 | }; |
887 | |
888 | struct cls_fl_filter { |
889 | @@ -165,6 +169,24 @@ static void fl_destroy_filter(struct rcu_head *head) |
890 | kfree(f); |
891 | } |
892 | |
893 | +static void fl_destroy_sleepable(struct work_struct *work) |
894 | +{ |
895 | + struct cls_fl_head *head = container_of(work, struct cls_fl_head, |
896 | + work); |
897 | + if (head->mask_assigned) |
898 | + rhashtable_destroy(&head->ht); |
899 | + kfree(head); |
900 | + module_put(THIS_MODULE); |
901 | +} |
902 | + |
903 | +static void fl_destroy_rcu(struct rcu_head *rcu) |
904 | +{ |
905 | + struct cls_fl_head *head = container_of(rcu, struct cls_fl_head, rcu); |
906 | + |
907 | + INIT_WORK(&head->work, fl_destroy_sleepable); |
908 | + schedule_work(&head->work); |
909 | +} |
910 | + |
911 | static bool fl_destroy(struct tcf_proto *tp, bool force) |
912 | { |
913 | struct cls_fl_head *head = rtnl_dereference(tp->root); |
914 | @@ -177,10 +199,9 @@ static bool fl_destroy(struct tcf_proto *tp, bool force) |
915 | list_del_rcu(&f->list); |
916 | call_rcu(&f->rcu, fl_destroy_filter); |
917 | } |
918 | - RCU_INIT_POINTER(tp->root, NULL); |
919 | - if (head->mask_assigned) |
920 | - rhashtable_destroy(&head->ht); |
921 | - kfree_rcu(head, rcu); |
922 | + |
923 | + __module_get(THIS_MODULE); |
924 | + call_rcu(&head->rcu, fl_destroy_rcu); |
925 | return true; |
926 | } |
927 | |
928 | diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h |
929 | index f9c9fc075fe6..9992dfac6938 100644 |
930 | --- a/net/sched/cls_rsvp.h |
931 | +++ b/net/sched/cls_rsvp.h |
932 | @@ -152,7 +152,8 @@ static int rsvp_classify(struct sk_buff *skb, const struct tcf_proto *tp, |
933 | return -1; |
934 | nhptr = ip_hdr(skb); |
935 | #endif |
936 | - |
937 | + if (unlikely(!head)) |
938 | + return -1; |
939 | restart: |
940 | |
941 | #if RSVP_DST_LEN == 4 |
942 | diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c |
943 | index 944c8ff45055..403746b20263 100644 |
944 | --- a/net/sched/cls_tcindex.c |
945 | +++ b/net/sched/cls_tcindex.c |
946 | @@ -503,7 +503,6 @@ static bool tcindex_destroy(struct tcf_proto *tp, bool force) |
947 | walker.fn = tcindex_destroy_element; |
948 | tcindex_walk(tp, &walker); |
949 | |
950 | - RCU_INIT_POINTER(tp->root, NULL); |
951 | call_rcu(&p->rcu, __tcindex_destroy); |
952 | return true; |
953 | } |
954 | diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c |
955 | index 824cc1e160bc..73f75258ce46 100644 |
956 | --- a/net/unix/af_unix.c |
957 | +++ b/net/unix/af_unix.c |
958 | @@ -2194,7 +2194,8 @@ out: |
959 | * Sleep until more data has arrived. But check for races.. |
960 | */ |
961 | static long unix_stream_data_wait(struct sock *sk, long timeo, |
962 | - struct sk_buff *last, unsigned int last_len) |
963 | + struct sk_buff *last, unsigned int last_len, |
964 | + bool freezable) |
965 | { |
966 | struct sk_buff *tail; |
967 | DEFINE_WAIT(wait); |
968 | @@ -2215,7 +2216,10 @@ static long unix_stream_data_wait(struct sock *sk, long timeo, |
969 | |
970 | sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk); |
971 | unix_state_unlock(sk); |
972 | - timeo = freezable_schedule_timeout(timeo); |
973 | + if (freezable) |
974 | + timeo = freezable_schedule_timeout(timeo); |
975 | + else |
976 | + timeo = schedule_timeout(timeo); |
977 | unix_state_lock(sk); |
978 | |
979 | if (sock_flag(sk, SOCK_DEAD)) |
980 | @@ -2245,7 +2249,8 @@ struct unix_stream_read_state { |
981 | unsigned int splice_flags; |
982 | }; |
983 | |
984 | -static int unix_stream_read_generic(struct unix_stream_read_state *state) |
985 | +static int unix_stream_read_generic(struct unix_stream_read_state *state, |
986 | + bool freezable) |
987 | { |
988 | struct scm_cookie scm; |
989 | struct socket *sock = state->socket; |
990 | @@ -2324,7 +2329,7 @@ again: |
991 | mutex_unlock(&u->iolock); |
992 | |
993 | timeo = unix_stream_data_wait(sk, timeo, last, |
994 | - last_len); |
995 | + last_len, freezable); |
996 | |
997 | if (signal_pending(current)) { |
998 | err = sock_intr_errno(timeo); |
999 | @@ -2466,7 +2471,7 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg, |
1000 | .flags = flags |
1001 | }; |
1002 | |
1003 | - return unix_stream_read_generic(&state); |
1004 | + return unix_stream_read_generic(&state, true); |
1005 | } |
1006 | |
1007 | static ssize_t skb_unix_socket_splice(struct sock *sk, |
1008 | @@ -2512,7 +2517,7 @@ static ssize_t unix_stream_splice_read(struct socket *sock, loff_t *ppos, |
1009 | flags & SPLICE_F_NONBLOCK) |
1010 | state.flags = MSG_DONTWAIT; |
1011 | |
1012 | - return unix_stream_read_generic(&state); |
1013 | + return unix_stream_read_generic(&state, false); |
1014 | } |
1015 | |
1016 | static int unix_shutdown(struct socket *sock, int mode) |