Contents of /trunk/kernel-alx/patches-4.9/0254-4.9.155-all-fixes.patch
Parent Directory | Revision Log
Revision 3307 -
(show annotations)
(download)
Tue Mar 12 10:43:13 2019 UTC (5 years, 6 months ago) by niro
File size: 34902 byte(s)
Tue Mar 12 10:43:13 2019 UTC (5 years, 6 months ago) by niro
File size: 34902 byte(s)
-linux-4.9.155
1 | diff --git a/Makefile b/Makefile |
2 | index 9964792e200f..1933ac9c3406 100644 |
3 | --- a/Makefile |
4 | +++ b/Makefile |
5 | @@ -1,6 +1,6 @@ |
6 | VERSION = 4 |
7 | PATCHLEVEL = 9 |
8 | -SUBLEVEL = 154 |
9 | +SUBLEVEL = 155 |
10 | EXTRAVERSION = |
11 | NAME = Roaring Lionus |
12 | |
13 | diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c |
14 | index 318394ed5c7a..5e11ad3164e0 100644 |
15 | --- a/arch/arm/mach-cns3xxx/pcie.c |
16 | +++ b/arch/arm/mach-cns3xxx/pcie.c |
17 | @@ -83,7 +83,7 @@ static void __iomem *cns3xxx_pci_map_bus(struct pci_bus *bus, |
18 | } else /* remote PCI bus */ |
19 | base = cnspci->cfg1_regs + ((busno & 0xf) << 20); |
20 | |
21 | - return base + (where & 0xffc) + (devfn << 12); |
22 | + return base + where + (devfn << 12); |
23 | } |
24 | |
25 | static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn, |
26 | diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c |
27 | index f6e71c73cceb..76c9b51fa7f1 100644 |
28 | --- a/arch/arm64/kernel/hibernate.c |
29 | +++ b/arch/arm64/kernel/hibernate.c |
30 | @@ -297,8 +297,10 @@ int swsusp_arch_suspend(void) |
31 | dcache_clean_range(__idmap_text_start, __idmap_text_end); |
32 | |
33 | /* Clean kvm setup code to PoC? */ |
34 | - if (el2_reset_needed()) |
35 | + if (el2_reset_needed()) { |
36 | dcache_clean_range(__hyp_idmap_text_start, __hyp_idmap_text_end); |
37 | + dcache_clean_range(__hyp_text_start, __hyp_text_end); |
38 | + } |
39 | |
40 | /* |
41 | * Tell the hibernation core that we've just restored |
42 | diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S |
43 | index d3b5f75e652e..fcb486d09555 100644 |
44 | --- a/arch/arm64/kernel/hyp-stub.S |
45 | +++ b/arch/arm64/kernel/hyp-stub.S |
46 | @@ -28,6 +28,8 @@ |
47 | #include <asm/virt.h> |
48 | |
49 | .text |
50 | + .pushsection .hyp.text, "ax" |
51 | + |
52 | .align 11 |
53 | |
54 | ENTRY(__hyp_stub_vectors) |
55 | diff --git a/arch/arm64/kernel/kaslr.c b/arch/arm64/kernel/kaslr.c |
56 | index 2a21318fed1d..c9ca903462a6 100644 |
57 | --- a/arch/arm64/kernel/kaslr.c |
58 | +++ b/arch/arm64/kernel/kaslr.c |
59 | @@ -88,6 +88,7 @@ u64 __init kaslr_early_init(u64 dt_phys, u64 modulo_offset) |
60 | * we end up running with module randomization disabled. |
61 | */ |
62 | module_alloc_base = (u64)_etext - MODULES_VSIZE; |
63 | + __flush_dcache_area(&module_alloc_base, sizeof(module_alloc_base)); |
64 | |
65 | /* |
66 | * Try to map the FDT early. If this fails, we simply bail, |
67 | diff --git a/drivers/base/core.c b/drivers/base/core.c |
68 | index f43caad30e1e..901aec4bb01d 100644 |
69 | --- a/drivers/base/core.c |
70 | +++ b/drivers/base/core.c |
71 | @@ -862,6 +862,8 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) |
72 | return; |
73 | |
74 | mutex_lock(&gdp_mutex); |
75 | + if (!kobject_has_children(glue_dir)) |
76 | + kobject_del(glue_dir); |
77 | kobject_put(glue_dir); |
78 | mutex_unlock(&gdp_mutex); |
79 | } |
80 | diff --git a/drivers/mmc/host/sdhci-iproc.c b/drivers/mmc/host/sdhci-iproc.c |
81 | index 524c8e0b72fd..40bdeca6d692 100644 |
82 | --- a/drivers/mmc/host/sdhci-iproc.c |
83 | +++ b/drivers/mmc/host/sdhci-iproc.c |
84 | @@ -242,7 +242,10 @@ static int sdhci_iproc_probe(struct platform_device *pdev) |
85 | |
86 | iproc_host->data = iproc_data; |
87 | |
88 | - mmc_of_parse(host->mmc); |
89 | + ret = mmc_of_parse(host->mmc); |
90 | + if (ret) |
91 | + goto err; |
92 | + |
93 | sdhci_get_of_property(pdev); |
94 | |
95 | host->mmc->caps |= iproc_host->data->mmc_caps; |
96 | diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c |
97 | index ef9bc26ebc1a..714593023bbc 100644 |
98 | --- a/drivers/net/ethernet/freescale/ucc_geth.c |
99 | +++ b/drivers/net/ethernet/freescale/ucc_geth.c |
100 | @@ -1888,6 +1888,8 @@ static void ucc_geth_free_tx(struct ucc_geth_private *ugeth) |
101 | u16 i, j; |
102 | u8 __iomem *bd; |
103 | |
104 | + netdev_reset_queue(ugeth->ndev); |
105 | + |
106 | ug_info = ugeth->ug_info; |
107 | uf_info = &ug_info->uf_info; |
108 | |
109 | diff --git a/drivers/net/ethernet/mellanox/mlx4/fw.c b/drivers/net/ethernet/mellanox/mlx4/fw.c |
110 | index 84bab9f0732e..9af0887c8a29 100644 |
111 | --- a/drivers/net/ethernet/mellanox/mlx4/fw.c |
112 | +++ b/drivers/net/ethernet/mellanox/mlx4/fw.c |
113 | @@ -2037,9 +2037,11 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, |
114 | { |
115 | struct mlx4_cmd_mailbox *mailbox; |
116 | __be32 *outbox; |
117 | + u64 qword_field; |
118 | u32 dword_field; |
119 | - int err; |
120 | + u16 word_field; |
121 | u8 byte_field; |
122 | + int err; |
123 | static const u8 a0_dmfs_query_hw_steering[] = { |
124 | [0] = MLX4_STEERING_DMFS_A0_DEFAULT, |
125 | [1] = MLX4_STEERING_DMFS_A0_DYNAMIC, |
126 | @@ -2067,19 +2069,32 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, |
127 | |
128 | /* QPC/EEC/CQC/EQC/RDMARC attributes */ |
129 | |
130 | - MLX4_GET(param->qpc_base, outbox, INIT_HCA_QPC_BASE_OFFSET); |
131 | - MLX4_GET(param->log_num_qps, outbox, INIT_HCA_LOG_QP_OFFSET); |
132 | - MLX4_GET(param->srqc_base, outbox, INIT_HCA_SRQC_BASE_OFFSET); |
133 | - MLX4_GET(param->log_num_srqs, outbox, INIT_HCA_LOG_SRQ_OFFSET); |
134 | - MLX4_GET(param->cqc_base, outbox, INIT_HCA_CQC_BASE_OFFSET); |
135 | - MLX4_GET(param->log_num_cqs, outbox, INIT_HCA_LOG_CQ_OFFSET); |
136 | - MLX4_GET(param->altc_base, outbox, INIT_HCA_ALTC_BASE_OFFSET); |
137 | - MLX4_GET(param->auxc_base, outbox, INIT_HCA_AUXC_BASE_OFFSET); |
138 | - MLX4_GET(param->eqc_base, outbox, INIT_HCA_EQC_BASE_OFFSET); |
139 | - MLX4_GET(param->log_num_eqs, outbox, INIT_HCA_LOG_EQ_OFFSET); |
140 | - MLX4_GET(param->num_sys_eqs, outbox, INIT_HCA_NUM_SYS_EQS_OFFSET); |
141 | - MLX4_GET(param->rdmarc_base, outbox, INIT_HCA_RDMARC_BASE_OFFSET); |
142 | - MLX4_GET(param->log_rd_per_qp, outbox, INIT_HCA_LOG_RD_OFFSET); |
143 | + MLX4_GET(qword_field, outbox, INIT_HCA_QPC_BASE_OFFSET); |
144 | + param->qpc_base = qword_field & ~((u64)0x1f); |
145 | + MLX4_GET(byte_field, outbox, INIT_HCA_LOG_QP_OFFSET); |
146 | + param->log_num_qps = byte_field & 0x1f; |
147 | + MLX4_GET(qword_field, outbox, INIT_HCA_SRQC_BASE_OFFSET); |
148 | + param->srqc_base = qword_field & ~((u64)0x1f); |
149 | + MLX4_GET(byte_field, outbox, INIT_HCA_LOG_SRQ_OFFSET); |
150 | + param->log_num_srqs = byte_field & 0x1f; |
151 | + MLX4_GET(qword_field, outbox, INIT_HCA_CQC_BASE_OFFSET); |
152 | + param->cqc_base = qword_field & ~((u64)0x1f); |
153 | + MLX4_GET(byte_field, outbox, INIT_HCA_LOG_CQ_OFFSET); |
154 | + param->log_num_cqs = byte_field & 0x1f; |
155 | + MLX4_GET(qword_field, outbox, INIT_HCA_ALTC_BASE_OFFSET); |
156 | + param->altc_base = qword_field; |
157 | + MLX4_GET(qword_field, outbox, INIT_HCA_AUXC_BASE_OFFSET); |
158 | + param->auxc_base = qword_field; |
159 | + MLX4_GET(qword_field, outbox, INIT_HCA_EQC_BASE_OFFSET); |
160 | + param->eqc_base = qword_field & ~((u64)0x1f); |
161 | + MLX4_GET(byte_field, outbox, INIT_HCA_LOG_EQ_OFFSET); |
162 | + param->log_num_eqs = byte_field & 0x1f; |
163 | + MLX4_GET(word_field, outbox, INIT_HCA_NUM_SYS_EQS_OFFSET); |
164 | + param->num_sys_eqs = word_field & 0xfff; |
165 | + MLX4_GET(qword_field, outbox, INIT_HCA_RDMARC_BASE_OFFSET); |
166 | + param->rdmarc_base = qword_field & ~((u64)0x1f); |
167 | + MLX4_GET(byte_field, outbox, INIT_HCA_LOG_RD_OFFSET); |
168 | + param->log_rd_per_qp = byte_field & 0x7; |
169 | |
170 | MLX4_GET(dword_field, outbox, INIT_HCA_FLAGS_OFFSET); |
171 | if (dword_field & (1 << INIT_HCA_DEVICE_MANAGED_FLOW_STEERING_EN)) { |
172 | @@ -2098,22 +2113,21 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, |
173 | /* steering attributes */ |
174 | if (param->steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) { |
175 | MLX4_GET(param->mc_base, outbox, INIT_HCA_FS_BASE_OFFSET); |
176 | - MLX4_GET(param->log_mc_entry_sz, outbox, |
177 | - INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); |
178 | - MLX4_GET(param->log_mc_table_sz, outbox, |
179 | - INIT_HCA_FS_LOG_TABLE_SZ_OFFSET); |
180 | - MLX4_GET(byte_field, outbox, |
181 | - INIT_HCA_FS_A0_OFFSET); |
182 | + MLX4_GET(byte_field, outbox, INIT_HCA_FS_LOG_ENTRY_SZ_OFFSET); |
183 | + param->log_mc_entry_sz = byte_field & 0x1f; |
184 | + MLX4_GET(byte_field, outbox, INIT_HCA_FS_LOG_TABLE_SZ_OFFSET); |
185 | + param->log_mc_table_sz = byte_field & 0x1f; |
186 | + MLX4_GET(byte_field, outbox, INIT_HCA_FS_A0_OFFSET); |
187 | param->dmfs_high_steer_mode = |
188 | a0_dmfs_query_hw_steering[(byte_field >> 6) & 3]; |
189 | } else { |
190 | MLX4_GET(param->mc_base, outbox, INIT_HCA_MC_BASE_OFFSET); |
191 | - MLX4_GET(param->log_mc_entry_sz, outbox, |
192 | - INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); |
193 | - MLX4_GET(param->log_mc_hash_sz, outbox, |
194 | - INIT_HCA_LOG_MC_HASH_SZ_OFFSET); |
195 | - MLX4_GET(param->log_mc_table_sz, outbox, |
196 | - INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); |
197 | + MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MC_ENTRY_SZ_OFFSET); |
198 | + param->log_mc_entry_sz = byte_field & 0x1f; |
199 | + MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MC_HASH_SZ_OFFSET); |
200 | + param->log_mc_hash_sz = byte_field & 0x1f; |
201 | + MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MC_TABLE_SZ_OFFSET); |
202 | + param->log_mc_table_sz = byte_field & 0x1f; |
203 | } |
204 | |
205 | /* CX3 is capable of extending CQEs/EQEs from 32 to 64 bytes */ |
206 | @@ -2137,15 +2151,18 @@ int mlx4_QUERY_HCA(struct mlx4_dev *dev, |
207 | /* TPT attributes */ |
208 | |
209 | MLX4_GET(param->dmpt_base, outbox, INIT_HCA_DMPT_BASE_OFFSET); |
210 | - MLX4_GET(param->mw_enabled, outbox, INIT_HCA_TPT_MW_OFFSET); |
211 | - MLX4_GET(param->log_mpt_sz, outbox, INIT_HCA_LOG_MPT_SZ_OFFSET); |
212 | + MLX4_GET(byte_field, outbox, INIT_HCA_TPT_MW_OFFSET); |
213 | + param->mw_enabled = byte_field >> 7; |
214 | + MLX4_GET(byte_field, outbox, INIT_HCA_LOG_MPT_SZ_OFFSET); |
215 | + param->log_mpt_sz = byte_field & 0x3f; |
216 | MLX4_GET(param->mtt_base, outbox, INIT_HCA_MTT_BASE_OFFSET); |
217 | MLX4_GET(param->cmpt_base, outbox, INIT_HCA_CMPT_BASE_OFFSET); |
218 | |
219 | /* UAR attributes */ |
220 | |
221 | MLX4_GET(param->uar_page_sz, outbox, INIT_HCA_UAR_PAGE_SZ_OFFSET); |
222 | - MLX4_GET(param->log_uar_sz, outbox, INIT_HCA_LOG_UAR_SZ_OFFSET); |
223 | + MLX4_GET(byte_field, outbox, INIT_HCA_LOG_UAR_SZ_OFFSET); |
224 | + param->log_uar_sz = byte_field & 0xf; |
225 | |
226 | /* phv_check enable */ |
227 | MLX4_GET(byte_field, outbox, INIT_HCA_CACHELINE_SZ_OFFSET); |
228 | diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c |
229 | index 5d6eab19a9d8..da9246f6c31e 100644 |
230 | --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c |
231 | +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c |
232 | @@ -1216,14 +1216,6 @@ static int esw_vport_ingress_config(struct mlx5_eswitch *esw, |
233 | int err = 0; |
234 | u8 *smac_v; |
235 | |
236 | - if (vport->info.spoofchk && !is_valid_ether_addr(vport->info.mac)) { |
237 | - mlx5_core_warn(esw->dev, |
238 | - "vport[%d] configure ingress rules failed, illegal mac with spoofchk\n", |
239 | - vport->vport); |
240 | - return -EPERM; |
241 | - |
242 | - } |
243 | - |
244 | esw_vport_cleanup_ingress_rules(esw, vport); |
245 | |
246 | if (!vport->info.vlan && !vport->info.qos && !vport->info.spoofchk) { |
247 | @@ -1709,13 +1701,10 @@ int mlx5_eswitch_set_vport_mac(struct mlx5_eswitch *esw, |
248 | mutex_lock(&esw->state_lock); |
249 | evport = &esw->vports[vport]; |
250 | |
251 | - if (evport->info.spoofchk && !is_valid_ether_addr(mac)) { |
252 | + if (evport->info.spoofchk && !is_valid_ether_addr(mac)) |
253 | mlx5_core_warn(esw->dev, |
254 | - "MAC invalidation is not allowed when spoofchk is on, vport(%d)\n", |
255 | + "Set invalid MAC while spoofchk is on, vport(%d)\n", |
256 | vport); |
257 | - err = -EPERM; |
258 | - goto unlock; |
259 | - } |
260 | |
261 | err = mlx5_modify_nic_vport_mac_address(esw->dev, vport, mac); |
262 | if (err) { |
263 | @@ -1859,6 +1848,10 @@ int mlx5_eswitch_set_vport_spoofchk(struct mlx5_eswitch *esw, |
264 | evport = &esw->vports[vport]; |
265 | pschk = evport->info.spoofchk; |
266 | evport->info.spoofchk = spoofchk; |
267 | + if (pschk && !is_valid_ether_addr(evport->info.mac)) |
268 | + mlx5_core_warn(esw->dev, |
269 | + "Spoofchk in set while MAC is invalid, vport(%d)\n", |
270 | + evport->vport); |
271 | if (evport->enabled && esw->mode == SRIOV_LEGACY) |
272 | err = esw_vport_ingress_config(esw, evport); |
273 | if (err) |
274 | diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c |
275 | index b299277361b7..4a2609c4dd6e 100644 |
276 | --- a/drivers/net/ipvlan/ipvlan_main.c |
277 | +++ b/drivers/net/ipvlan/ipvlan_main.c |
278 | @@ -85,12 +85,12 @@ static int ipvlan_set_port_mode(struct ipvl_port *port, u16 nval) |
279 | err = ipvlan_register_nf_hook(); |
280 | if (!err) { |
281 | mdev->l3mdev_ops = &ipvl_l3mdev_ops; |
282 | - mdev->priv_flags |= IFF_L3MDEV_MASTER; |
283 | + mdev->priv_flags |= IFF_L3MDEV_RX_HANDLER; |
284 | } else |
285 | goto fail; |
286 | } else if (port->mode == IPVLAN_MODE_L3S) { |
287 | /* Old mode was L3S */ |
288 | - mdev->priv_flags &= ~IFF_L3MDEV_MASTER; |
289 | + mdev->priv_flags &= ~IFF_L3MDEV_RX_HANDLER; |
290 | ipvlan_unregister_nf_hook(); |
291 | mdev->l3mdev_ops = NULL; |
292 | } |
293 | @@ -158,7 +158,7 @@ static void ipvlan_port_destroy(struct net_device *dev) |
294 | |
295 | dev->priv_flags &= ~IFF_IPVLAN_MASTER; |
296 | if (port->mode == IPVLAN_MODE_L3S) { |
297 | - dev->priv_flags &= ~IFF_L3MDEV_MASTER; |
298 | + dev->priv_flags &= ~IFF_L3MDEV_RX_HANDLER; |
299 | ipvlan_unregister_nf_hook(); |
300 | dev->l3mdev_ops = NULL; |
301 | } |
302 | diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c |
303 | index c857d2d7bbec..69ffbd7b76f7 100644 |
304 | --- a/drivers/platform/x86/asus-nb-wmi.c |
305 | +++ b/drivers/platform/x86/asus-nb-wmi.c |
306 | @@ -477,8 +477,7 @@ static const struct key_entry asus_nb_wmi_keymap[] = { |
307 | { KE_KEY, 0x30, { KEY_VOLUMEUP } }, |
308 | { KE_KEY, 0x31, { KEY_VOLUMEDOWN } }, |
309 | { KE_KEY, 0x32, { KEY_MUTE } }, |
310 | - { KE_KEY, 0x33, { KEY_DISPLAYTOGGLE } }, /* LCD on */ |
311 | - { KE_KEY, 0x34, { KEY_DISPLAY_OFF } }, /* LCD off */ |
312 | + { KE_KEY, 0x35, { KEY_SCREENLOCK } }, |
313 | { KE_KEY, 0x40, { KEY_PREVIOUSSONG } }, |
314 | { KE_KEY, 0x41, { KEY_NEXTSONG } }, |
315 | { KE_KEY, 0x43, { KEY_STOPCD } }, /* Stop/Eject */ |
316 | diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c |
317 | index 441d434a48c1..33e65b71c49a 100644 |
318 | --- a/fs/cifs/connect.c |
319 | +++ b/fs/cifs/connect.c |
320 | @@ -48,6 +48,7 @@ |
321 | #include "cifs_unicode.h" |
322 | #include "cifs_debug.h" |
323 | #include "cifs_fs_sb.h" |
324 | +#include "dns_resolve.h" |
325 | #include "ntlmssp.h" |
326 | #include "nterr.h" |
327 | #include "rfc1002pdu.h" |
328 | @@ -306,6 +307,53 @@ static void cifs_prune_tlinks(struct work_struct *work); |
329 | static int cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, |
330 | const char *devname); |
331 | |
332 | +/* |
333 | + * Resolve hostname and set ip addr in tcp ses. Useful for hostnames that may |
334 | + * get their ip addresses changed at some point. |
335 | + * |
336 | + * This should be called with server->srv_mutex held. |
337 | + */ |
338 | +#ifdef CONFIG_CIFS_DFS_UPCALL |
339 | +static int reconn_set_ipaddr(struct TCP_Server_Info *server) |
340 | +{ |
341 | + int rc; |
342 | + int len; |
343 | + char *unc, *ipaddr = NULL; |
344 | + |
345 | + if (!server->hostname) |
346 | + return -EINVAL; |
347 | + |
348 | + len = strlen(server->hostname) + 3; |
349 | + |
350 | + unc = kmalloc(len, GFP_KERNEL); |
351 | + if (!unc) { |
352 | + cifs_dbg(FYI, "%s: failed to create UNC path\n", __func__); |
353 | + return -ENOMEM; |
354 | + } |
355 | + snprintf(unc, len, "\\\\%s", server->hostname); |
356 | + |
357 | + rc = dns_resolve_server_name_to_ip(unc, &ipaddr); |
358 | + kfree(unc); |
359 | + |
360 | + if (rc < 0) { |
361 | + cifs_dbg(FYI, "%s: failed to resolve server part of %s to IP: %d\n", |
362 | + __func__, server->hostname, rc); |
363 | + return rc; |
364 | + } |
365 | + |
366 | + rc = cifs_convert_address((struct sockaddr *)&server->dstaddr, ipaddr, |
367 | + strlen(ipaddr)); |
368 | + kfree(ipaddr); |
369 | + |
370 | + return !rc ? -1 : 0; |
371 | +} |
372 | +#else |
373 | +static inline int reconn_set_ipaddr(struct TCP_Server_Info *server) |
374 | +{ |
375 | + return 0; |
376 | +} |
377 | +#endif |
378 | + |
379 | /* |
380 | * cifs tcp session reconnection |
381 | * |
382 | @@ -403,6 +451,11 @@ cifs_reconnect(struct TCP_Server_Info *server) |
383 | rc = generic_ip_connect(server); |
384 | if (rc) { |
385 | cifs_dbg(FYI, "reconnect error %d\n", rc); |
386 | + rc = reconn_set_ipaddr(server); |
387 | + if (rc) { |
388 | + cifs_dbg(FYI, "%s: failed to resolve hostname: %d\n", |
389 | + __func__, rc); |
390 | + } |
391 | mutex_unlock(&server->srv_mutex); |
392 | msleep(3000); |
393 | } else { |
394 | diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c |
395 | index 50251a8af0ce..52b6e4a40748 100644 |
396 | --- a/fs/cifs/smb2pdu.c |
397 | +++ b/fs/cifs/smb2pdu.c |
398 | @@ -2686,8 +2686,8 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, |
399 | if (rc == -ENODATA && rsp->hdr.Status == STATUS_NO_MORE_FILES) { |
400 | srch_inf->endOfSearch = true; |
401 | rc = 0; |
402 | - } |
403 | - cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE); |
404 | + } else |
405 | + cifs_stats_fail_inc(tcon, SMB2_QUERY_DIRECTORY_HE); |
406 | goto qdir_exit; |
407 | } |
408 | |
409 | diff --git a/fs/dcache.c b/fs/dcache.c |
410 | index f903b86b06e5..29c0286bd638 100644 |
411 | --- a/fs/dcache.c |
412 | +++ b/fs/dcache.c |
413 | @@ -1164,15 +1164,11 @@ static enum lru_status dentry_lru_isolate_shrink(struct list_head *item, |
414 | */ |
415 | void shrink_dcache_sb(struct super_block *sb) |
416 | { |
417 | - long freed; |
418 | - |
419 | do { |
420 | LIST_HEAD(dispose); |
421 | |
422 | - freed = list_lru_walk(&sb->s_dentry_lru, |
423 | + list_lru_walk(&sb->s_dentry_lru, |
424 | dentry_lru_isolate_shrink, &dispose, 1024); |
425 | - |
426 | - this_cpu_sub(nr_dentry_unused, freed); |
427 | shrink_dentry_list(&dispose); |
428 | cond_resched(); |
429 | } while (list_lru_count(&sb->s_dentry_lru) > 0); |
430 | diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c |
431 | index 05f1ec728840..073126707270 100644 |
432 | --- a/fs/gfs2/rgrp.c |
433 | +++ b/fs/gfs2/rgrp.c |
434 | @@ -1705,9 +1705,9 @@ static int gfs2_rbm_find(struct gfs2_rbm *rbm, u8 state, u32 *minext, |
435 | goto next_iter; |
436 | } |
437 | if (ret == -E2BIG) { |
438 | - n += rbm->bii - initial_bii; |
439 | rbm->bii = 0; |
440 | rbm->offset = 0; |
441 | + n += (rbm->bii - initial_bii); |
442 | goto res_covered_end_of_rgrp; |
443 | } |
444 | return ret; |
445 | diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c |
446 | index a64adc2fced9..56b4f855fa9b 100644 |
447 | --- a/fs/notify/fsnotify.c |
448 | +++ b/fs/notify/fsnotify.c |
449 | @@ -101,9 +101,9 @@ int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) |
450 | parent = dget_parent(dentry); |
451 | p_inode = parent->d_inode; |
452 | |
453 | - if (unlikely(!fsnotify_inode_watches_children(p_inode))) |
454 | + if (unlikely(!fsnotify_inode_watches_children(p_inode))) { |
455 | __fsnotify_update_child_dentry_flags(p_inode); |
456 | - else if (p_inode->i_fsnotify_mask & mask) { |
457 | + } else if (p_inode->i_fsnotify_mask & mask & ~FS_EVENT_ON_CHILD) { |
458 | struct name_snapshot name; |
459 | |
460 | /* we are notifying a parent so come up with the new mask which |
461 | @@ -207,6 +207,10 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, |
462 | else |
463 | mnt = NULL; |
464 | |
465 | + /* An event "on child" is not intended for a mount mark */ |
466 | + if (mask & FS_EVENT_ON_CHILD) |
467 | + mnt = NULL; |
468 | + |
469 | /* |
470 | * Optimization: srcu_read_lock() has a memory barrier which can |
471 | * be expensive. It protects walking the *_fsnotify_marks lists. |
472 | diff --git a/fs/read_write.c b/fs/read_write.c |
473 | index ba280596ec78..9819f7c6c8c5 100644 |
474 | --- a/fs/read_write.c |
475 | +++ b/fs/read_write.c |
476 | @@ -392,8 +392,10 @@ ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos) |
477 | iter->type |= WRITE; |
478 | ret = file->f_op->write_iter(&kiocb, iter); |
479 | BUG_ON(ret == -EIOCBQUEUED); |
480 | - if (ret > 0) |
481 | + if (ret > 0) { |
482 | *ppos = kiocb.ki_pos; |
483 | + fsnotify_modify(file); |
484 | + } |
485 | return ret; |
486 | } |
487 | EXPORT_SYMBOL(vfs_iter_write); |
488 | diff --git a/fs/super.c b/fs/super.c |
489 | index 7e9beab77259..abe2541fb28c 100644 |
490 | --- a/fs/super.c |
491 | +++ b/fs/super.c |
492 | @@ -119,13 +119,23 @@ static unsigned long super_cache_count(struct shrinker *shrink, |
493 | sb = container_of(shrink, struct super_block, s_shrink); |
494 | |
495 | /* |
496 | - * Don't call trylock_super as it is a potential |
497 | - * scalability bottleneck. The counts could get updated |
498 | - * between super_cache_count and super_cache_scan anyway. |
499 | - * Call to super_cache_count with shrinker_rwsem held |
500 | - * ensures the safety of call to list_lru_shrink_count() and |
501 | - * s_op->nr_cached_objects(). |
502 | + * We don't call trylock_super() here as it is a scalability bottleneck, |
503 | + * so we're exposed to partial setup state. The shrinker rwsem does not |
504 | + * protect filesystem operations backing list_lru_shrink_count() or |
505 | + * s_op->nr_cached_objects(). Counts can change between |
506 | + * super_cache_count and super_cache_scan, so we really don't need locks |
507 | + * here. |
508 | + * |
509 | + * However, if we are currently mounting the superblock, the underlying |
510 | + * filesystem might be in a state of partial construction and hence it |
511 | + * is dangerous to access it. trylock_super() uses a MS_BORN check to |
512 | + * avoid this situation, so do the same here. The memory barrier is |
513 | + * matched with the one in mount_fs() as we don't hold locks here. |
514 | */ |
515 | + if (!(sb->s_flags & MS_BORN)) |
516 | + return 0; |
517 | + smp_rmb(); |
518 | + |
519 | if (sb->s_op && sb->s_op->nr_cached_objects) |
520 | total_objects = sb->s_op->nr_cached_objects(sb, sc); |
521 | |
522 | @@ -1193,6 +1203,14 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data) |
523 | sb = root->d_sb; |
524 | BUG_ON(!sb); |
525 | WARN_ON(!sb->s_bdi); |
526 | + |
527 | + /* |
528 | + * Write barrier is for super_cache_count(). We place it before setting |
529 | + * MS_BORN as the data dependency between the two functions is the |
530 | + * superblock structure contents that we just set up, not the MS_BORN |
531 | + * flag. |
532 | + */ |
533 | + smp_wmb(); |
534 | sb->s_flags |= MS_BORN; |
535 | |
536 | error = security_sb_kern_mount(sb, flags, secdata); |
537 | diff --git a/include/linux/kobject.h b/include/linux/kobject.h |
538 | index e6284591599e..5957c6a3fd7f 100644 |
539 | --- a/include/linux/kobject.h |
540 | +++ b/include/linux/kobject.h |
541 | @@ -113,6 +113,23 @@ extern void kobject_put(struct kobject *kobj); |
542 | extern const void *kobject_namespace(struct kobject *kobj); |
543 | extern char *kobject_get_path(struct kobject *kobj, gfp_t flag); |
544 | |
545 | +/** |
546 | + * kobject_has_children - Returns whether a kobject has children. |
547 | + * @kobj: the object to test |
548 | + * |
549 | + * This will return whether a kobject has other kobjects as children. |
550 | + * |
551 | + * It does NOT account for the presence of attribute files, only sub |
552 | + * directories. It also assumes there is no concurrent addition or |
553 | + * removal of such children, and thus relies on external locking. |
554 | + */ |
555 | +static inline bool kobject_has_children(struct kobject *kobj) |
556 | +{ |
557 | + WARN_ON_ONCE(atomic_read(&kobj->kref.refcount) == 0); |
558 | + |
559 | + return kobj->sd && kobj->sd->dir.subdirs; |
560 | +} |
561 | + |
562 | struct kobj_type { |
563 | void (*release)(struct kobject *kobj); |
564 | const struct sysfs_ops *sysfs_ops; |
565 | diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h |
566 | index f254982e1a8f..2ecf0f32444e 100644 |
567 | --- a/include/linux/netdevice.h |
568 | +++ b/include/linux/netdevice.h |
569 | @@ -1368,6 +1368,7 @@ struct net_device_ops { |
570 | * @IFF_PHONY_HEADROOM: the headroom value is controlled by an external |
571 | * entity (i.e. the master device for bridged veth) |
572 | * @IFF_MACSEC: device is a MACsec device |
573 | + * @IFF_L3MDEV_RX_HANDLER: only invoke the rx handler of L3 master device |
574 | */ |
575 | enum netdev_priv_flags { |
576 | IFF_802_1Q_VLAN = 1<<0, |
577 | @@ -1398,6 +1399,7 @@ enum netdev_priv_flags { |
578 | IFF_RXFH_CONFIGURED = 1<<25, |
579 | IFF_PHONY_HEADROOM = 1<<26, |
580 | IFF_MACSEC = 1<<27, |
581 | + IFF_L3MDEV_RX_HANDLER = 1<<28, |
582 | }; |
583 | |
584 | #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN |
585 | @@ -1427,6 +1429,7 @@ enum netdev_priv_flags { |
586 | #define IFF_TEAM IFF_TEAM |
587 | #define IFF_RXFH_CONFIGURED IFF_RXFH_CONFIGURED |
588 | #define IFF_MACSEC IFF_MACSEC |
589 | +#define IFF_L3MDEV_RX_HANDLER IFF_L3MDEV_RX_HANDLER |
590 | |
591 | /** |
592 | * struct net_device - The DEVICE structure. |
593 | @@ -4244,6 +4247,11 @@ static inline bool netif_supports_nofcs(struct net_device *dev) |
594 | return dev->priv_flags & IFF_SUPP_NOFCS; |
595 | } |
596 | |
597 | +static inline bool netif_has_l3_rx_handler(const struct net_device *dev) |
598 | +{ |
599 | + return dev->priv_flags & IFF_L3MDEV_RX_HANDLER; |
600 | +} |
601 | + |
602 | static inline bool netif_is_l3_master(const struct net_device *dev) |
603 | { |
604 | return dev->priv_flags & IFF_L3MDEV_MASTER; |
605 | diff --git a/include/net/l3mdev.h b/include/net/l3mdev.h |
606 | index 3832099289c5..128487658ff7 100644 |
607 | --- a/include/net/l3mdev.h |
608 | +++ b/include/net/l3mdev.h |
609 | @@ -142,7 +142,8 @@ struct sk_buff *l3mdev_l3_rcv(struct sk_buff *skb, u16 proto) |
610 | |
611 | if (netif_is_l3_slave(skb->dev)) |
612 | master = netdev_master_upper_dev_get_rcu(skb->dev); |
613 | - else if (netif_is_l3_master(skb->dev)) |
614 | + else if (netif_is_l3_master(skb->dev) || |
615 | + netif_has_l3_rx_handler(skb->dev)) |
616 | master = skb->dev; |
617 | |
618 | if (master && master->l3mdev_ops->l3mdev_l3_rcv) |
619 | diff --git a/kernel/exit.c b/kernel/exit.c |
620 | index 6dd7ff4b337a..d9394fcd0e2c 100644 |
621 | --- a/kernel/exit.c |
622 | +++ b/kernel/exit.c |
623 | @@ -525,12 +525,14 @@ static struct task_struct *find_alive_thread(struct task_struct *p) |
624 | return NULL; |
625 | } |
626 | |
627 | -static struct task_struct *find_child_reaper(struct task_struct *father) |
628 | +static struct task_struct *find_child_reaper(struct task_struct *father, |
629 | + struct list_head *dead) |
630 | __releases(&tasklist_lock) |
631 | __acquires(&tasklist_lock) |
632 | { |
633 | struct pid_namespace *pid_ns = task_active_pid_ns(father); |
634 | struct task_struct *reaper = pid_ns->child_reaper; |
635 | + struct task_struct *p, *n; |
636 | |
637 | if (likely(reaper != father)) |
638 | return reaper; |
639 | @@ -546,6 +548,12 @@ static struct task_struct *find_child_reaper(struct task_struct *father) |
640 | panic("Attempted to kill init! exitcode=0x%08x\n", |
641 | father->signal->group_exit_code ?: father->exit_code); |
642 | } |
643 | + |
644 | + list_for_each_entry_safe(p, n, dead, ptrace_entry) { |
645 | + list_del_init(&p->ptrace_entry); |
646 | + release_task(p); |
647 | + } |
648 | + |
649 | zap_pid_ns_processes(pid_ns); |
650 | write_lock_irq(&tasklist_lock); |
651 | |
652 | @@ -632,7 +640,7 @@ static void forget_original_parent(struct task_struct *father, |
653 | exit_ptrace(father, dead); |
654 | |
655 | /* Can drop and reacquire tasklist_lock */ |
656 | - reaper = find_child_reaper(father); |
657 | + reaper = find_child_reaper(father, dead); |
658 | if (list_empty(&father->children)) |
659 | return; |
660 | |
661 | diff --git a/mm/memory-failure.c b/mm/memory-failure.c |
662 | index 851efb004857..4f1f5fd12042 100644 |
663 | --- a/mm/memory-failure.c |
664 | +++ b/mm/memory-failure.c |
665 | @@ -336,7 +336,8 @@ static void kill_procs(struct list_head *to_kill, int forcekill, int trapno, |
666 | if (fail || tk->addr_valid == 0) { |
667 | pr_err("Memory failure: %#lx: forcibly killing %s:%d because of failure to unmap corrupted page\n", |
668 | pfn, tk->tsk->comm, tk->tsk->pid); |
669 | - force_sig(SIGKILL, tk->tsk); |
670 | + do_send_sig_info(SIGKILL, SEND_SIG_PRIV, |
671 | + tk->tsk, PIDTYPE_PID); |
672 | } |
673 | |
674 | /* |
675 | diff --git a/mm/migrate.c b/mm/migrate.c |
676 | index 821623fc7091..b08c1a4a1c22 100644 |
677 | --- a/mm/migrate.c |
678 | +++ b/mm/migrate.c |
679 | @@ -1044,10 +1044,13 @@ out: |
680 | * If migration is successful, decrease refcount of the newpage |
681 | * which will not free the page because new page owner increased |
682 | * refcounter. As well, if it is LRU page, add the page to LRU |
683 | - * list in here. |
684 | + * list in here. Use the old state of the isolated source page to |
685 | + * determine if we migrated a LRU page. newpage was already unlocked |
686 | + * and possibly modified by its owner - don't rely on the page |
687 | + * state. |
688 | */ |
689 | if (rc == MIGRATEPAGE_SUCCESS) { |
690 | - if (unlikely(__PageMovable(newpage))) |
691 | + if (unlikely(!is_lru)) |
692 | put_page(newpage); |
693 | else |
694 | putback_lru_page(newpage); |
695 | diff --git a/mm/oom_kill.c b/mm/oom_kill.c |
696 | index 4a184157cc3d..1de3695cb419 100644 |
697 | --- a/mm/oom_kill.c |
698 | +++ b/mm/oom_kill.c |
699 | @@ -861,6 +861,13 @@ static void oom_kill_process(struct oom_control *oc, const char *message) |
700 | * still freeing memory. |
701 | */ |
702 | read_lock(&tasklist_lock); |
703 | + |
704 | + /* |
705 | + * The task 'p' might have already exited before reaching here. The |
706 | + * put_task_struct() will free task_struct 'p' while the loop still try |
707 | + * to access the field of 'p', so, get an extra reference. |
708 | + */ |
709 | + get_task_struct(p); |
710 | for_each_thread(p, t) { |
711 | list_for_each_entry(child, &t->children, sibling) { |
712 | unsigned int child_points; |
713 | @@ -880,6 +887,7 @@ static void oom_kill_process(struct oom_control *oc, const char *message) |
714 | } |
715 | } |
716 | } |
717 | + put_task_struct(p); |
718 | read_unlock(&tasklist_lock); |
719 | |
720 | p = find_lock_task_mm(victim); |
721 | diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c |
722 | index 496f8d86b503..c7334d1e392a 100644 |
723 | --- a/net/ipv4/ip_fragment.c |
724 | +++ b/net/ipv4/ip_fragment.c |
725 | @@ -423,6 +423,7 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) |
726 | * fragment. |
727 | */ |
728 | |
729 | + err = -EINVAL; |
730 | /* Find out where to put this fragment. */ |
731 | prev_tail = qp->q.fragments_tail; |
732 | if (!prev_tail) |
733 | @@ -499,7 +500,6 @@ static int ip_frag_queue(struct ipq *qp, struct sk_buff *skb) |
734 | |
735 | discard_qp: |
736 | inet_frag_kill(&qp->q); |
737 | - err = -EINVAL; |
738 | __IP_INC_STATS(net, IPSTATS_MIB_REASM_OVERLAPS); |
739 | err: |
740 | kfree_skb(skb); |
741 | diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c |
742 | index c81b2c5caf26..8885dbad217b 100644 |
743 | --- a/net/ipv6/af_inet6.c |
744 | +++ b/net/ipv6/af_inet6.c |
745 | @@ -359,6 +359,9 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) |
746 | err = -EINVAL; |
747 | goto out_unlock; |
748 | } |
749 | + } |
750 | + |
751 | + if (sk->sk_bound_dev_if) { |
752 | dev = dev_get_by_index_rcu(net, sk->sk_bound_dev_if); |
753 | if (!dev) { |
754 | err = -ENODEV; |
755 | diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c |
756 | index b96dbe38ecad..4ae758bcb2cf 100644 |
757 | --- a/net/l2tp/l2tp_core.c |
758 | +++ b/net/l2tp/l2tp_core.c |
759 | @@ -83,8 +83,7 @@ |
760 | #define L2TP_SLFLAG_S 0x40000000 |
761 | #define L2TP_SL_SEQ_MASK 0x00ffffff |
762 | |
763 | -#define L2TP_HDR_SIZE_SEQ 10 |
764 | -#define L2TP_HDR_SIZE_NOSEQ 6 |
765 | +#define L2TP_HDR_SIZE_MAX 14 |
766 | |
767 | /* Default trace flags */ |
768 | #define L2TP_DEFAULT_DEBUG_FLAGS 0 |
769 | @@ -796,11 +795,9 @@ void l2tp_recv_common(struct l2tp_session *session, struct sk_buff *skb, |
770 | "%s: recv data ns=%u, session nr=%u\n", |
771 | session->name, ns, session->nr); |
772 | } |
773 | + ptr += 4; |
774 | } |
775 | |
776 | - /* Advance past L2-specific header, if present */ |
777 | - ptr += session->l2specific_len; |
778 | - |
779 | if (L2TP_SKB_CB(skb)->has_seq) { |
780 | /* Received a packet with sequence numbers. If we're the LNS, |
781 | * check if we sre sending sequence numbers and if not, |
782 | @@ -944,7 +941,7 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb, |
783 | __skb_pull(skb, sizeof(struct udphdr)); |
784 | |
785 | /* Short packet? */ |
786 | - if (!pskb_may_pull(skb, L2TP_HDR_SIZE_SEQ)) { |
787 | + if (!pskb_may_pull(skb, L2TP_HDR_SIZE_MAX)) { |
788 | l2tp_info(tunnel, L2TP_MSG_DATA, |
789 | "%s: recv short packet (len=%d)\n", |
790 | tunnel->name, skb->len); |
791 | @@ -1023,6 +1020,10 @@ static int l2tp_udp_recv_core(struct l2tp_tunnel *tunnel, struct sk_buff *skb, |
792 | goto error; |
793 | } |
794 | |
795 | + if (tunnel->version == L2TP_HDR_VER_3 && |
796 | + l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) |
797 | + goto error; |
798 | + |
799 | l2tp_recv_common(session, skb, ptr, optr, hdrflags, length, payload_hook); |
800 | l2tp_session_dec_refcount(session); |
801 | |
802 | @@ -1122,21 +1123,20 @@ static int l2tp_build_l2tpv3_header(struct l2tp_session *session, void *buf) |
803 | memcpy(bufp, &session->cookie[0], session->cookie_len); |
804 | bufp += session->cookie_len; |
805 | } |
806 | - if (session->l2specific_len) { |
807 | - if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) { |
808 | - u32 l2h = 0; |
809 | - if (session->send_seq) { |
810 | - l2h = 0x40000000 | session->ns; |
811 | - session->ns++; |
812 | - session->ns &= 0xffffff; |
813 | - l2tp_dbg(session, L2TP_MSG_SEQ, |
814 | - "%s: updated ns to %u\n", |
815 | - session->name, session->ns); |
816 | - } |
817 | + if (session->l2specific_type == L2TP_L2SPECTYPE_DEFAULT) { |
818 | + u32 l2h = 0; |
819 | |
820 | - *((__be32 *) bufp) = htonl(l2h); |
821 | + if (session->send_seq) { |
822 | + l2h = 0x40000000 | session->ns; |
823 | + session->ns++; |
824 | + session->ns &= 0xffffff; |
825 | + l2tp_dbg(session, L2TP_MSG_SEQ, |
826 | + "%s: updated ns to %u\n", |
827 | + session->name, session->ns); |
828 | } |
829 | - bufp += session->l2specific_len; |
830 | + |
831 | + *((__be32 *)bufp) = htonl(l2h); |
832 | + bufp += 4; |
833 | } |
834 | |
835 | return bufp - optr; |
836 | @@ -1813,7 +1813,7 @@ int l2tp_session_delete(struct l2tp_session *session) |
837 | EXPORT_SYMBOL_GPL(l2tp_session_delete); |
838 | |
839 | /* We come here whenever a session's send_seq, cookie_len or |
840 | - * l2specific_len parameters are set. |
841 | + * l2specific_type parameters are set. |
842 | */ |
843 | void l2tp_session_set_header_len(struct l2tp_session *session, int version) |
844 | { |
845 | @@ -1822,7 +1822,8 @@ void l2tp_session_set_header_len(struct l2tp_session *session, int version) |
846 | if (session->send_seq) |
847 | session->hdr_len += 4; |
848 | } else { |
849 | - session->hdr_len = 4 + session->cookie_len + session->l2specific_len; |
850 | + session->hdr_len = 4 + session->cookie_len; |
851 | + session->hdr_len += l2tp_get_l2specific_len(session); |
852 | if (session->tunnel->encap == L2TP_ENCAPTYPE_UDP) |
853 | session->hdr_len += 4; |
854 | } |
855 | diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h |
856 | index 86356a23a0a7..7cc49715606e 100644 |
857 | --- a/net/l2tp/l2tp_core.h |
858 | +++ b/net/l2tp/l2tp_core.h |
859 | @@ -314,6 +314,37 @@ do { \ |
860 | #define l2tp_session_dec_refcount(s) l2tp_session_dec_refcount_1(s) |
861 | #endif |
862 | |
863 | +static inline int l2tp_get_l2specific_len(struct l2tp_session *session) |
864 | +{ |
865 | + switch (session->l2specific_type) { |
866 | + case L2TP_L2SPECTYPE_DEFAULT: |
867 | + return 4; |
868 | + case L2TP_L2SPECTYPE_NONE: |
869 | + default: |
870 | + return 0; |
871 | + } |
872 | +} |
873 | + |
874 | +static inline int l2tp_v3_ensure_opt_in_linear(struct l2tp_session *session, struct sk_buff *skb, |
875 | + unsigned char **ptr, unsigned char **optr) |
876 | +{ |
877 | + int opt_len = session->peer_cookie_len + l2tp_get_l2specific_len(session); |
878 | + |
879 | + if (opt_len > 0) { |
880 | + int off = *ptr - *optr; |
881 | + |
882 | + if (!pskb_may_pull(skb, off + opt_len)) |
883 | + return -1; |
884 | + |
885 | + if (skb->data != *optr) { |
886 | + *optr = skb->data; |
887 | + *ptr = skb->data + off; |
888 | + } |
889 | + } |
890 | + |
891 | + return 0; |
892 | +} |
893 | + |
894 | #define l2tp_printk(ptr, type, func, fmt, ...) \ |
895 | do { \ |
896 | if (((ptr)->debug) & (type)) \ |
897 | diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c |
898 | index 9d77a54e8854..03a696d3bcd9 100644 |
899 | --- a/net/l2tp/l2tp_ip.c |
900 | +++ b/net/l2tp/l2tp_ip.c |
901 | @@ -157,6 +157,9 @@ static int l2tp_ip_recv(struct sk_buff *skb) |
902 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); |
903 | } |
904 | |
905 | + if (l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) |
906 | + goto discard_sess; |
907 | + |
908 | l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, tunnel->recv_payload_hook); |
909 | l2tp_session_dec_refcount(session); |
910 | |
911 | diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c |
912 | index 247097289fd0..5e6d09863480 100644 |
913 | --- a/net/l2tp/l2tp_ip6.c |
914 | +++ b/net/l2tp/l2tp_ip6.c |
915 | @@ -169,6 +169,9 @@ static int l2tp_ip6_recv(struct sk_buff *skb) |
916 | print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, ptr, length); |
917 | } |
918 | |
919 | + if (l2tp_v3_ensure_opt_in_linear(session, skb, &ptr, &optr)) |
920 | + goto discard_sess; |
921 | + |
922 | l2tp_recv_common(session, skb, ptr, optr, 0, skb->len, |
923 | tunnel->recv_payload_hook); |
924 | l2tp_session_dec_refcount(session); |
925 | diff --git a/net/netrom/nr_timer.c b/net/netrom/nr_timer.c |
926 | index 94d05806a9a2..f0ecaec1ff3d 100644 |
927 | --- a/net/netrom/nr_timer.c |
928 | +++ b/net/netrom/nr_timer.c |
929 | @@ -53,21 +53,21 @@ void nr_start_t1timer(struct sock *sk) |
930 | { |
931 | struct nr_sock *nr = nr_sk(sk); |
932 | |
933 | - mod_timer(&nr->t1timer, jiffies + nr->t1); |
934 | + sk_reset_timer(sk, &nr->t1timer, jiffies + nr->t1); |
935 | } |
936 | |
937 | void nr_start_t2timer(struct sock *sk) |
938 | { |
939 | struct nr_sock *nr = nr_sk(sk); |
940 | |
941 | - mod_timer(&nr->t2timer, jiffies + nr->t2); |
942 | + sk_reset_timer(sk, &nr->t2timer, jiffies + nr->t2); |
943 | } |
944 | |
945 | void nr_start_t4timer(struct sock *sk) |
946 | { |
947 | struct nr_sock *nr = nr_sk(sk); |
948 | |
949 | - mod_timer(&nr->t4timer, jiffies + nr->t4); |
950 | + sk_reset_timer(sk, &nr->t4timer, jiffies + nr->t4); |
951 | } |
952 | |
953 | void nr_start_idletimer(struct sock *sk) |
954 | @@ -75,37 +75,37 @@ void nr_start_idletimer(struct sock *sk) |
955 | struct nr_sock *nr = nr_sk(sk); |
956 | |
957 | if (nr->idle > 0) |
958 | - mod_timer(&nr->idletimer, jiffies + nr->idle); |
959 | + sk_reset_timer(sk, &nr->idletimer, jiffies + nr->idle); |
960 | } |
961 | |
962 | void nr_start_heartbeat(struct sock *sk) |
963 | { |
964 | - mod_timer(&sk->sk_timer, jiffies + 5 * HZ); |
965 | + sk_reset_timer(sk, &sk->sk_timer, jiffies + 5 * HZ); |
966 | } |
967 | |
968 | void nr_stop_t1timer(struct sock *sk) |
969 | { |
970 | - del_timer(&nr_sk(sk)->t1timer); |
971 | + sk_stop_timer(sk, &nr_sk(sk)->t1timer); |
972 | } |
973 | |
974 | void nr_stop_t2timer(struct sock *sk) |
975 | { |
976 | - del_timer(&nr_sk(sk)->t2timer); |
977 | + sk_stop_timer(sk, &nr_sk(sk)->t2timer); |
978 | } |
979 | |
980 | void nr_stop_t4timer(struct sock *sk) |
981 | { |
982 | - del_timer(&nr_sk(sk)->t4timer); |
983 | + sk_stop_timer(sk, &nr_sk(sk)->t4timer); |
984 | } |
985 | |
986 | void nr_stop_idletimer(struct sock *sk) |
987 | { |
988 | - del_timer(&nr_sk(sk)->idletimer); |
989 | + sk_stop_timer(sk, &nr_sk(sk)->idletimer); |
990 | } |
991 | |
992 | void nr_stop_heartbeat(struct sock *sk) |
993 | { |
994 | - del_timer(&sk->sk_timer); |
995 | + sk_stop_timer(sk, &sk->sk_timer); |
996 | } |
997 | |
998 | int nr_t1timer_running(struct sock *sk) |
999 | diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c |
1000 | index 0fc76d845103..9f704a7f2a28 100644 |
1001 | --- a/net/rose/rose_route.c |
1002 | +++ b/net/rose/rose_route.c |
1003 | @@ -848,6 +848,7 @@ void rose_link_device_down(struct net_device *dev) |
1004 | |
1005 | /* |
1006 | * Route a frame to an appropriate AX.25 connection. |
1007 | + * A NULL ax25_cb indicates an internally generated frame. |
1008 | */ |
1009 | int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) |
1010 | { |
1011 | @@ -865,6 +866,10 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) |
1012 | |
1013 | if (skb->len < ROSE_MIN_LEN) |
1014 | return res; |
1015 | + |
1016 | + if (!ax25) |
1017 | + return rose_loopback_queue(skb, NULL); |
1018 | + |
1019 | frametype = skb->data[2]; |
1020 | lci = ((skb->data[0] << 8) & 0xF00) + ((skb->data[1] << 0) & 0x0FF); |
1021 | if (frametype == ROSE_CALL_REQUEST && |