Gentoo Archives: gentoo-commits

From: Mike Pagano <mpagano@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/linux-patches:4.4 commit in: /
Date: Sun, 11 Aug 2019 10:58:07
Message-Id: 1565521057.dfbe70571efea1bce9d1d371801d4c350cb4d589.mpagano@gentoo
1 commit: dfbe70571efea1bce9d1d371801d4c350cb4d589
2 Author: Mike Pagano <mpagano <AT> gentoo <DOT> org>
3 AuthorDate: Sun Aug 11 10:57:37 2019 +0000
4 Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org>
5 CommitDate: Sun Aug 11 10:57:37 2019 +0000
6 URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=dfbe7057
7
8 Linux patch 4.4.189
9
10 Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>
11
12 0000_README | 4 +
13 1188_linux-4.4.189.patch | 840 +++++++++++++++++++++++++++++++++++++++++++++++
14 2 files changed, 844 insertions(+)
15
16 diff --git a/0000_README b/0000_README
17 index a8c41eb..91e5cbd 100644
18 --- a/0000_README
19 +++ b/0000_README
20 @@ -795,6 +795,10 @@ Patch: 1187_linux-4.4.188.patch
21 From: http://www.kernel.org
22 Desc: Linux 4.4.188
23
24 +Patch: 1188_linux-4.4.189.patch
25 +From: http://www.kernel.org
26 +Desc: Linux 4.4.189
27 +
28 Patch: 1500_XATTR_USER_PREFIX.patch
29 From: https://bugs.gentoo.org/show_bug.cgi?id=470644
30 Desc: Support for namespace user.pax.* on tmpfs.
31
32 diff --git a/1188_linux-4.4.189.patch b/1188_linux-4.4.189.patch
33 new file mode 100644
34 index 0000000..1c12460
35 --- /dev/null
36 +++ b/1188_linux-4.4.189.patch
37 @@ -0,0 +1,840 @@
38 +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
39 +index 175d57049168..7a9fd54a0186 100644
40 +--- a/Documentation/kernel-parameters.txt
41 ++++ b/Documentation/kernel-parameters.txt
42 +@@ -2184,6 +2184,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
43 + improves system performance, but it may also
44 + expose users to several CPU vulnerabilities.
45 + Equivalent to: nopti [X86]
46 ++ nospectre_v1 [X86]
47 + nospectre_v2 [X86]
48 + spectre_v2_user=off [X86]
49 + spec_store_bypass_disable=off [X86]
50 +@@ -2498,9 +2499,9 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
51 +
52 + nohugeiomap [KNL,x86] Disable kernel huge I/O mappings.
53 +
54 +- nospectre_v1 [PPC] Disable mitigations for Spectre Variant 1 (bounds
55 +- check bypass). With this option data leaks are possible
56 +- in the system.
57 ++ nospectre_v1 [X86,PPC] Disable mitigations for Spectre Variant 1
58 ++ (bounds check bypass). With this option data leaks are
59 ++ possible in the system.
60 +
61 + nospectre_v2 [X86,PPC_FSL_BOOK3E] Disable all mitigations for the Spectre variant 2
62 + (indirect branch prediction) vulnerability. System may
63 +diff --git a/Makefile b/Makefile
64 +index 87d663191986..81a0ada6536f 100644
65 +--- a/Makefile
66 ++++ b/Makefile
67 +@@ -1,6 +1,6 @@
68 + VERSION = 4
69 + PATCHLEVEL = 4
70 +-SUBLEVEL = 188
71 ++SUBLEVEL = 189
72 + EXTRAVERSION =
73 + NAME = Blurry Fish Butt
74 +
75 +diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
76 +index ad83c245781c..0a66f8241f18 100644
77 +--- a/arch/arm64/include/asm/cpufeature.h
78 ++++ b/arch/arm64/include/asm/cpufeature.h
79 +@@ -41,9 +41,10 @@
80 +
81 + /* CPU feature register tracking */
82 + enum ftr_type {
83 +- FTR_EXACT, /* Use a predefined safe value */
84 +- FTR_LOWER_SAFE, /* Smaller value is safe */
85 +- FTR_HIGHER_SAFE,/* Bigger value is safe */
86 ++ FTR_EXACT, /* Use a predefined safe value */
87 ++ FTR_LOWER_SAFE, /* Smaller value is safe */
88 ++ FTR_HIGHER_SAFE, /* Bigger value is safe */
89 ++ FTR_HIGHER_OR_ZERO_SAFE, /* Bigger value is safe, but 0 is biggest */
90 + };
91 +
92 + #define FTR_STRICT true /* SANITY check strict matching required */
93 +diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
94 +index c1eddc07d996..062484d34450 100644
95 +--- a/arch/arm64/kernel/cpufeature.c
96 ++++ b/arch/arm64/kernel/cpufeature.c
97 +@@ -126,10 +126,12 @@ static struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
98 + };
99 +
100 + static struct arm64_ftr_bits ftr_ctr[] = {
101 +- U_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RAO */
102 +- ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 28, 3, 0),
103 +- U_ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_SAFE, 24, 4, 0), /* CWG */
104 +- U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0), /* ERG */
105 ++ U_ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 31, 1, 1), /* RES1 */
106 ++ ARM64_FTR_BITS(FTR_STRICT, FTR_EXACT, 30, 1, 0),
107 ++ U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 29, 1, 1), /* DIC */
108 ++ U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 28, 1, 1), /* IDC */
109 ++ U_ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_OR_ZERO_SAFE, 24, 4, 0), /* CWG */
110 ++ U_ARM64_FTR_BITS(FTR_STRICT, FTR_HIGHER_OR_ZERO_SAFE, 20, 4, 0), /* ERG */
111 + U_ARM64_FTR_BITS(FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 1), /* DminLine */
112 + /*
113 + * Linux can handle differing I-cache policies. Userspace JITs will
114 +@@ -339,6 +341,10 @@ static s64 arm64_ftr_safe_value(struct arm64_ftr_bits *ftrp, s64 new, s64 cur)
115 + case FTR_LOWER_SAFE:
116 + ret = new < cur ? new : cur;
117 + break;
118 ++ case FTR_HIGHER_OR_ZERO_SAFE:
119 ++ if (!cur || !new)
120 ++ break;
121 ++ /* Fallthrough */
122 + case FTR_HIGHER_SAFE:
123 + ret = new > cur ? new : cur;
124 + break;
125 +diff --git a/arch/x86/entry/calling.h b/arch/x86/entry/calling.h
126 +index 3c71dd947c7b..5e24cd248728 100644
127 +--- a/arch/x86/entry/calling.h
128 ++++ b/arch/x86/entry/calling.h
129 +@@ -1,3 +1,5 @@
130 ++#include <asm/cpufeatures.h>
131 ++
132 + /*
133 +
134 + x86 function call convention, 64-bit:
135 +@@ -199,6 +201,23 @@ For 32-bit we have the following conventions - kernel is built with
136 + .byte 0xf1
137 + .endm
138 +
139 ++/*
140 ++ * Mitigate Spectre v1 for conditional swapgs code paths.
141 ++ *
142 ++ * FENCE_SWAPGS_USER_ENTRY is used in the user entry swapgs code path, to
143 ++ * prevent a speculative swapgs when coming from kernel space.
144 ++ *
145 ++ * FENCE_SWAPGS_KERNEL_ENTRY is used in the kernel entry non-swapgs code path,
146 ++ * to prevent the swapgs from getting speculatively skipped when coming from
147 ++ * user space.
148 ++ */
149 ++.macro FENCE_SWAPGS_USER_ENTRY
150 ++ ALTERNATIVE "", "lfence", X86_FEATURE_FENCE_SWAPGS_USER
151 ++.endm
152 ++.macro FENCE_SWAPGS_KERNEL_ENTRY
153 ++ ALTERNATIVE "", "lfence", X86_FEATURE_FENCE_SWAPGS_KERNEL
154 ++.endm
155 ++
156 + #else /* CONFIG_X86_64 */
157 +
158 + /*
159 +diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S
160 +index 375ed605c83d..afb805b0148b 100644
161 +--- a/arch/x86/entry/entry_64.S
162 ++++ b/arch/x86/entry/entry_64.S
163 +@@ -551,6 +551,7 @@ END(irq_entries_start)
164 + * tracking that we're in kernel mode.
165 + */
166 + SWAPGS
167 ++ FENCE_SWAPGS_USER_ENTRY
168 + SWITCH_KERNEL_CR3
169 +
170 + /*
171 +@@ -566,8 +567,10 @@ END(irq_entries_start)
172 + #ifdef CONFIG_CONTEXT_TRACKING
173 + call enter_from_user_mode
174 + #endif
175 +-
176 ++ jmp 2f
177 + 1:
178 ++ FENCE_SWAPGS_KERNEL_ENTRY
179 ++2:
180 + /*
181 + * Save previous stack pointer, optionally switch to interrupt stack.
182 + * irq_count is used to check if a CPU is already on an interrupt stack
183 +@@ -1077,6 +1080,13 @@ ENTRY(paranoid_entry)
184 + movq %rax, %cr3
185 + 2:
186 + #endif
187 ++ /*
188 ++ * The above doesn't do an unconditional CR3 write, even in the PTI
189 ++ * case. So do an lfence to prevent GS speculation, regardless of
190 ++ * whether PTI is enabled.
191 ++ */
192 ++ FENCE_SWAPGS_KERNEL_ENTRY
193 ++
194 + ret
195 + END(paranoid_entry)
196 +
197 +@@ -1133,12 +1143,12 @@ ENTRY(error_entry)
198 + testb $3, CS+8(%rsp)
199 + jz .Lerror_kernelspace
200 +
201 +-.Lerror_entry_from_usermode_swapgs:
202 + /*
203 + * We entered from user mode or we're pretending to have entered
204 + * from user mode due to an IRET fault.
205 + */
206 + SWAPGS
207 ++ FENCE_SWAPGS_USER_ENTRY
208 +
209 + .Lerror_entry_from_usermode_after_swapgs:
210 + /*
211 +@@ -1152,6 +1162,8 @@ ENTRY(error_entry)
212 + #endif
213 + ret
214 +
215 ++.Lerror_entry_done_lfence:
216 ++ FENCE_SWAPGS_KERNEL_ENTRY
217 + .Lerror_entry_done:
218 + TRACE_IRQS_OFF
219 + ret
220 +@@ -1170,14 +1182,16 @@ ENTRY(error_entry)
221 + cmpq %rax, RIP+8(%rsp)
222 + je .Lbstep_iret
223 + cmpq $gs_change, RIP+8(%rsp)
224 +- jne .Lerror_entry_done
225 ++ jne .Lerror_entry_done_lfence
226 +
227 + /*
228 + * hack: gs_change can fail with user gsbase. If this happens, fix up
229 + * gsbase and proceed. We'll fix up the exception and land in
230 + * gs_change's error handler with kernel gsbase.
231 + */
232 +- jmp .Lerror_entry_from_usermode_swapgs
233 ++ SWAPGS
234 ++ FENCE_SWAPGS_USER_ENTRY
235 ++ jmp .Lerror_entry_done
236 +
237 + .Lbstep_iret:
238 + /* Fix truncated RIP */
239 +@@ -1190,6 +1204,7 @@ ENTRY(error_entry)
240 + * Switch to kernel gsbase:
241 + */
242 + SWAPGS
243 ++ FENCE_SWAPGS_USER_ENTRY
244 +
245 + /*
246 + * Pretend that the exception came from user mode: set up pt_regs
247 +@@ -1286,6 +1301,7 @@ ENTRY(nmi)
248 + * to switch CR3 here.
249 + */
250 + cld
251 ++ FENCE_SWAPGS_USER_ENTRY
252 + movq %rsp, %rdx
253 + movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
254 + pushq 5*8(%rdx) /* pt_regs->ss */
255 +@@ -1574,6 +1590,7 @@ end_repeat_nmi:
256 + movq %rax, %cr3
257 + 2:
258 + #endif
259 ++ FENCE_SWAPGS_KERNEL_ENTRY
260 +
261 + /* paranoidentry do_nmi, 0; without TRACE_IRQS_OFF */
262 + call do_nmi
263 +diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
264 +index d9f7d1770e98..113cb01ebaac 100644
265 +--- a/arch/x86/include/asm/cpufeatures.h
266 ++++ b/arch/x86/include/asm/cpufeatures.h
267 +@@ -192,17 +192,17 @@
268 + #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */
269 + #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */
270 +
271 ++#define X86_FEATURE_FENCE_SWAPGS_USER ( 7*32+10) /* "" LFENCE in user entry SWAPGS path */
272 ++#define X86_FEATURE_FENCE_SWAPGS_KERNEL ( 7*32+11) /* "" LFENCE in kernel entry SWAPGS path */
273 ++
274 + #define X86_FEATURE_RETPOLINE ( 7*32+12) /* "" Generic Retpoline mitigation for Spectre variant 2 */
275 + #define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */
276 +
277 + #define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */
278 +-#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */
279 +-
280 + #define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */
281 + #define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */
282 +
283 +-/* Because the ALTERNATIVE scheme is for members of the X86_FEATURE club... */
284 +-#define X86_FEATURE_KAISER ( 7*32+31) /* CONFIG_PAGE_TABLE_ISOLATION w/o nokaiser */
285 ++#define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */
286 +
287 + #define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled*/
288 + #define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */
289 +@@ -215,6 +215,7 @@
290 + #define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */
291 + #define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* "" L1TF workaround PTE inversion */
292 + #define X86_FEATURE_IBRS_ENHANCED ( 7*32+30) /* Enhanced IBRS */
293 ++#define X86_FEATURE_KAISER ( 7*32+31) /* CONFIG_PAGE_TABLE_ISOLATION w/o nokaiser */
294 +
295 + /* Virtualization flags: Linux defined, word 8 */
296 + #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */
297 +@@ -338,5 +339,6 @@
298 + #define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */
299 + #define X86_BUG_MDS X86_BUG(19) /* CPU is affected by Microarchitectural data sampling */
300 + #define X86_BUG_MSBDS_ONLY X86_BUG(20) /* CPU is only affected by the MSDBS variant of BUG_MDS */
301 ++#define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */
302 +
303 + #endif /* _ASM_X86_CPUFEATURES_H */
304 +diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c
305 +index ab2df0f9ac45..917c63aa1599 100644
306 +--- a/arch/x86/kernel/cpu/bugs.c
307 ++++ b/arch/x86/kernel/cpu/bugs.c
308 +@@ -30,6 +30,7 @@
309 + #include <asm/intel-family.h>
310 + #include <asm/e820.h>
311 +
312 ++static void __init spectre_v1_select_mitigation(void);
313 + static void __init spectre_v2_select_mitigation(void);
314 + static void __init ssb_select_mitigation(void);
315 + static void __init l1tf_select_mitigation(void);
316 +@@ -87,17 +88,11 @@ void __init check_bugs(void)
317 + if (boot_cpu_has(X86_FEATURE_STIBP))
318 + x86_spec_ctrl_mask |= SPEC_CTRL_STIBP;
319 +
320 +- /* Select the proper spectre mitigation before patching alternatives */
321 ++ /* Select the proper CPU mitigations before patching alternatives: */
322 ++ spectre_v1_select_mitigation();
323 + spectre_v2_select_mitigation();
324 +-
325 +- /*
326 +- * Select proper mitigation for any exposure to the Speculative Store
327 +- * Bypass vulnerability.
328 +- */
329 + ssb_select_mitigation();
330 +-
331 + l1tf_select_mitigation();
332 +-
333 + mds_select_mitigation();
334 +
335 + arch_smt_update();
336 +@@ -251,6 +246,98 @@ static int __init mds_cmdline(char *str)
337 + }
338 + early_param("mds", mds_cmdline);
339 +
340 ++#undef pr_fmt
341 ++#define pr_fmt(fmt) "Spectre V1 : " fmt
342 ++
343 ++enum spectre_v1_mitigation {
344 ++ SPECTRE_V1_MITIGATION_NONE,
345 ++ SPECTRE_V1_MITIGATION_AUTO,
346 ++};
347 ++
348 ++static enum spectre_v1_mitigation spectre_v1_mitigation =
349 ++ SPECTRE_V1_MITIGATION_AUTO;
350 ++
351 ++static const char * const spectre_v1_strings[] = {
352 ++ [SPECTRE_V1_MITIGATION_NONE] = "Vulnerable: __user pointer sanitization and usercopy barriers only; no swapgs barriers",
353 ++ [SPECTRE_V1_MITIGATION_AUTO] = "Mitigation: usercopy/swapgs barriers and __user pointer sanitization",
354 ++};
355 ++
356 ++/*
357 ++ * Does SMAP provide full mitigation against speculative kernel access to
358 ++ * userspace?
359 ++ */
360 ++static bool smap_works_speculatively(void)
361 ++{
362 ++ if (!boot_cpu_has(X86_FEATURE_SMAP))
363 ++ return false;
364 ++
365 ++ /*
366 ++ * On CPUs which are vulnerable to Meltdown, SMAP does not
367 ++ * prevent speculative access to user data in the L1 cache.
368 ++ * Consider SMAP to be non-functional as a mitigation on these
369 ++ * CPUs.
370 ++ */
371 ++ if (boot_cpu_has(X86_BUG_CPU_MELTDOWN))
372 ++ return false;
373 ++
374 ++ return true;
375 ++}
376 ++
377 ++static void __init spectre_v1_select_mitigation(void)
378 ++{
379 ++ if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1) || cpu_mitigations_off()) {
380 ++ spectre_v1_mitigation = SPECTRE_V1_MITIGATION_NONE;
381 ++ return;
382 ++ }
383 ++
384 ++ if (spectre_v1_mitigation == SPECTRE_V1_MITIGATION_AUTO) {
385 ++ /*
386 ++ * With Spectre v1, a user can speculatively control either
387 ++ * path of a conditional swapgs with a user-controlled GS
388 ++ * value. The mitigation is to add lfences to both code paths.
389 ++ *
390 ++ * If FSGSBASE is enabled, the user can put a kernel address in
391 ++ * GS, in which case SMAP provides no protection.
392 ++ *
393 ++ * [ NOTE: Don't check for X86_FEATURE_FSGSBASE until the
394 ++ * FSGSBASE enablement patches have been merged. ]
395 ++ *
396 ++ * If FSGSBASE is disabled, the user can only put a user space
397 ++ * address in GS. That makes an attack harder, but still
398 ++ * possible if there's no SMAP protection.
399 ++ */
400 ++ if (!smap_works_speculatively()) {
401 ++ /*
402 ++ * Mitigation can be provided from SWAPGS itself or
403 ++ * PTI as the CR3 write in the Meltdown mitigation
404 ++ * is serializing.
405 ++ *
406 ++ * If neither is there, mitigate with an LFENCE to
407 ++ * stop speculation through swapgs.
408 ++ */
409 ++ if (boot_cpu_has_bug(X86_BUG_SWAPGS) &&
410 ++ !boot_cpu_has(X86_FEATURE_KAISER))
411 ++ setup_force_cpu_cap(X86_FEATURE_FENCE_SWAPGS_USER);
412 ++
413 ++ /*
414 ++ * Enable lfences in the kernel entry (non-swapgs)
415 ++ * paths, to prevent user entry from speculatively
416 ++ * skipping swapgs.
417 ++ */
418 ++ setup_force_cpu_cap(X86_FEATURE_FENCE_SWAPGS_KERNEL);
419 ++ }
420 ++ }
421 ++
422 ++ pr_info("%s\n", spectre_v1_strings[spectre_v1_mitigation]);
423 ++}
424 ++
425 ++static int __init nospectre_v1_cmdline(char *str)
426 ++{
427 ++ spectre_v1_mitigation = SPECTRE_V1_MITIGATION_NONE;
428 ++ return 0;
429 ++}
430 ++early_param("nospectre_v1", nospectre_v1_cmdline);
431 ++
432 + #undef pr_fmt
433 + #define pr_fmt(fmt) "Spectre V2 : " fmt
434 +
435 +@@ -1154,7 +1241,7 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr
436 + break;
437 +
438 + case X86_BUG_SPECTRE_V1:
439 +- return sprintf(buf, "Mitigation: __user pointer sanitization\n");
440 ++ return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]);
441 +
442 + case X86_BUG_SPECTRE_V2:
443 + return sprintf(buf, "%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled],
444 +diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
445 +index 4bce77bc7e61..3965235973c8 100644
446 +--- a/arch/x86/kernel/cpu/common.c
447 ++++ b/arch/x86/kernel/cpu/common.c
448 +@@ -853,6 +853,7 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c)
449 + #define NO_L1TF BIT(3)
450 + #define NO_MDS BIT(4)
451 + #define MSBDS_ONLY BIT(5)
452 ++#define NO_SWAPGS BIT(6)
453 +
454 + #define VULNWL(_vendor, _family, _model, _whitelist) \
455 + { X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist }
456 +@@ -876,29 +877,37 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
457 + VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION),
458 + VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION),
459 +
460 +- VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY),
461 +- VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF | MSBDS_ONLY),
462 +- VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY),
463 +- VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY),
464 +- VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY),
465 +- VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY),
466 ++ VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
467 ++ VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
468 ++ VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
469 ++ VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
470 ++ VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
471 ++ VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
472 +
473 + VULNWL_INTEL(CORE_YONAH, NO_SSB),
474 +
475 +- VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY),
476 ++ VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS),
477 +
478 +- VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF),
479 +- VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF),
480 +- VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF),
481 ++ VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS),
482 ++ VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF | NO_SWAPGS),
483 ++ VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS),
484 ++
485 ++ /*
486 ++ * Technically, swapgs isn't serializing on AMD (despite it previously
487 ++ * being documented as such in the APM). But according to AMD, %gs is
488 ++ * updated non-speculatively, and the issuing of %gs-relative memory
489 ++ * operands will be blocked until the %gs update completes, which is
490 ++ * good enough for our purposes.
491 ++ */
492 +
493 + /* AMD Family 0xf - 0x12 */
494 +- VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
495 +- VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
496 +- VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
497 +- VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS),
498 ++ VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
499 ++ VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
500 ++ VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
501 ++ VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS),
502 +
503 + /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */
504 +- VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS),
505 ++ VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS),
506 + {}
507 + };
508 +
509 +@@ -935,6 +944,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c)
510 + setup_force_cpu_bug(X86_BUG_MSBDS_ONLY);
511 + }
512 +
513 ++ if (!cpu_matches(NO_SWAPGS))
514 ++ setup_force_cpu_bug(X86_BUG_SWAPGS);
515 ++
516 + if (cpu_matches(NO_MELTDOWN))
517 + return;
518 +
519 +diff --git a/block/blk-core.c b/block/blk-core.c
520 +index 50d77c90070d..7662f97dded6 100644
521 +--- a/block/blk-core.c
522 ++++ b/block/blk-core.c
523 +@@ -870,6 +870,7 @@ blk_init_allocated_queue(struct request_queue *q, request_fn_proc *rfn,
524 +
525 + fail:
526 + blk_free_flush_queue(q->fq);
527 ++ q->fq = NULL;
528 + return NULL;
529 + }
530 + EXPORT_SYMBOL(blk_init_allocated_queue);
531 +diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c
532 +index 7d00f2994738..860a33a90ebf 100644
533 +--- a/drivers/atm/iphase.c
534 ++++ b/drivers/atm/iphase.c
535 +@@ -63,6 +63,7 @@
536 + #include <asm/byteorder.h>
537 + #include <linux/vmalloc.h>
538 + #include <linux/jiffies.h>
539 ++#include <linux/nospec.h>
540 + #include "iphase.h"
541 + #include "suni.h"
542 + #define swap_byte_order(x) (((x & 0xff) << 8) | ((x & 0xff00) >> 8))
543 +@@ -2755,8 +2756,11 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
544 + }
545 + if (copy_from_user(&ia_cmds, arg, sizeof ia_cmds)) return -EFAULT;
546 + board = ia_cmds.status;
547 +- if ((board < 0) || (board > iadev_count))
548 +- board = 0;
549 ++
550 ++ if ((board < 0) || (board > iadev_count))
551 ++ board = 0;
552 ++ board = array_index_nospec(board, iadev_count + 1);
553 ++
554 + iadev = ia_dev[board];
555 + switch (ia_cmds.cmd) {
556 + case MEMDUMP:
557 +diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
558 +index 00d8366a614e..e1807296a1a0 100644
559 +--- a/drivers/hid/hid-ids.h
560 ++++ b/drivers/hid/hid-ids.h
561 +@@ -470,6 +470,7 @@
562 + #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A 0x0a4a
563 + #define USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A 0x0b4a
564 + #define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE 0x134a
565 ++#define USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641 0x0641
566 +
567 + #define USB_VENDOR_ID_HUION 0x256c
568 + #define USB_DEVICE_ID_HUION_TABLET 0x006e
569 +diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
570 +index c9a11315493b..5dcdfdca4fd7 100644
571 +--- a/drivers/hid/usbhid/hid-quirks.c
572 ++++ b/drivers/hid/usbhid/hid-quirks.c
573 +@@ -82,6 +82,7 @@ static const struct hid_blacklist {
574 + { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A, HID_QUIRK_ALWAYS_POLL },
575 + { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0B4A, HID_QUIRK_ALWAYS_POLL },
576 + { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE, HID_QUIRK_ALWAYS_POLL },
577 ++ { USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_PIXART_OEM_USB_OPTICAL_MOUSE_0641, HID_QUIRK_ALWAYS_POLL },
578 + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077, HID_QUIRK_ALWAYS_POLL },
579 + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS, HID_QUIRK_NOGET },
580 + { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_MOUSE_C01A, HID_QUIRK_ALWAYS_POLL },
581 +diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
582 +index 4dc5e12dbfce..13de5ce3facf 100644
583 +--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
584 ++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
585 +@@ -1957,7 +1957,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
586 + }
587 +
588 + /* select a non-FCoE queue */
589 +- return fallback(dev, skb) % (BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos);
590 ++ return fallback(dev, skb) % (BNX2X_NUM_ETH_QUEUES(bp));
591 + }
592 +
593 + void bnx2x_set_num_queues(struct bnx2x *bp)
594 +diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c
595 +index 7c42be586be8..35bcc6dbada9 100644
596 +--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
597 ++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
598 +@@ -778,7 +778,7 @@ static void mlx5_unregister_device(struct mlx5_core_dev *dev)
599 + struct mlx5_interface *intf;
600 +
601 + mutex_lock(&intf_mutex);
602 +- list_for_each_entry(intf, &intf_list, list)
603 ++ list_for_each_entry_reverse(intf, &intf_list, list)
604 + mlx5_remove_device(intf, priv);
605 + list_del(&priv->dev_list);
606 + mutex_unlock(&intf_mutex);
607 +diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
608 +index 02327e6c4819..39976892b312 100644
609 +--- a/drivers/net/ppp/pppoe.c
610 ++++ b/drivers/net/ppp/pppoe.c
611 +@@ -1152,6 +1152,9 @@ static const struct proto_ops pppoe_ops = {
612 + .recvmsg = pppoe_recvmsg,
613 + .mmap = sock_no_mmap,
614 + .ioctl = pppox_ioctl,
615 ++#ifdef CONFIG_COMPAT
616 ++ .compat_ioctl = pppox_compat_ioctl,
617 ++#endif
618 + };
619 +
620 + static const struct pppox_proto pppoe_proto = {
621 +diff --git a/drivers/net/ppp/pppox.c b/drivers/net/ppp/pppox.c
622 +index 0e1b30622477..011fbd10cb73 100644
623 +--- a/drivers/net/ppp/pppox.c
624 ++++ b/drivers/net/ppp/pppox.c
625 +@@ -22,6 +22,7 @@
626 + #include <linux/string.h>
627 + #include <linux/module.h>
628 + #include <linux/kernel.h>
629 ++#include <linux/compat.h>
630 + #include <linux/errno.h>
631 + #include <linux/netdevice.h>
632 + #include <linux/net.h>
633 +@@ -103,6 +104,18 @@ int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
634 +
635 + EXPORT_SYMBOL(pppox_ioctl);
636 +
637 ++#ifdef CONFIG_COMPAT
638 ++int pppox_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
639 ++{
640 ++ if (cmd == PPPOEIOCSFWD32)
641 ++ cmd = PPPOEIOCSFWD;
642 ++
643 ++ return pppox_ioctl(sock, cmd, (unsigned long)compat_ptr(arg));
644 ++}
645 ++
646 ++EXPORT_SYMBOL(pppox_compat_ioctl);
647 ++#endif
648 ++
649 + static int pppox_create(struct net *net, struct socket *sock, int protocol,
650 + int kern)
651 + {
652 +diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
653 +index 53c1f2bd0f24..19d0692a2d2f 100644
654 +--- a/drivers/net/ppp/pptp.c
655 ++++ b/drivers/net/ppp/pptp.c
656 +@@ -674,6 +674,9 @@ static const struct proto_ops pptp_ops = {
657 + .recvmsg = sock_no_recvmsg,
658 + .mmap = sock_no_mmap,
659 + .ioctl = pppox_ioctl,
660 ++#ifdef CONFIG_COMPAT
661 ++ .compat_ioctl = pppox_compat_ioctl,
662 ++#endif
663 + };
664 +
665 + static const struct pppox_proto pppox_pptp_proto = {
666 +diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
667 +index 1a1368f5863c..25daebd6f410 100644
668 +--- a/drivers/spi/spi-bcm2835.c
669 ++++ b/drivers/spi/spi-bcm2835.c
670 +@@ -554,7 +554,8 @@ static int bcm2835_spi_transfer_one(struct spi_master *master,
671 + bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv);
672 +
673 + /* handle all the 3-wire mode */
674 +- if ((spi->mode & SPI_3WIRE) && (tfr->rx_buf))
675 ++ if (spi->mode & SPI_3WIRE && tfr->rx_buf &&
676 ++ tfr->rx_buf != master->dummy_rx)
677 + cs |= BCM2835_SPI_CS_REN;
678 + else
679 + cs &= ~BCM2835_SPI_CS_REN;
680 +diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
681 +index a52ca5cba015..5af973621c73 100644
682 +--- a/fs/compat_ioctl.c
683 ++++ b/fs/compat_ioctl.c
684 +@@ -1016,9 +1016,6 @@ COMPATIBLE_IOCTL(PPPIOCDISCONN)
685 + COMPATIBLE_IOCTL(PPPIOCATTCHAN)
686 + COMPATIBLE_IOCTL(PPPIOCGCHAN)
687 + COMPATIBLE_IOCTL(PPPIOCGL2TPSTATS)
688 +-/* PPPOX */
689 +-COMPATIBLE_IOCTL(PPPOEIOCSFWD)
690 +-COMPATIBLE_IOCTL(PPPOEIOCDFWD)
691 + /* ppdev */
692 + COMPATIBLE_IOCTL(PPSETMODE)
693 + COMPATIBLE_IOCTL(PPRSTATUS)
694 +diff --git a/include/linux/if_pppox.h b/include/linux/if_pppox.h
695 +index b49cf923becc..93ef387eadb1 100644
696 +--- a/include/linux/if_pppox.h
697 ++++ b/include/linux/if_pppox.h
698 +@@ -84,6 +84,9 @@ extern int register_pppox_proto(int proto_num, const struct pppox_proto *pp);
699 + extern void unregister_pppox_proto(int proto_num);
700 + extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */
701 + extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
702 ++extern int pppox_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
703 ++
704 ++#define PPPOEIOCSFWD32 _IOW(0xB1 ,0, compat_size_t)
705 +
706 + /* PPPoX socket states */
707 + enum {
708 +diff --git a/include/net/tcp.h b/include/net/tcp.h
709 +index 77438a8406ec..0410fd29d569 100644
710 +--- a/include/net/tcp.h
711 ++++ b/include/net/tcp.h
712 +@@ -1526,6 +1526,23 @@ static inline void tcp_check_send_head(struct sock *sk, struct sk_buff *skb_unli
713 + tcp_sk(sk)->highest_sack = NULL;
714 + }
715 +
716 ++static inline struct sk_buff *tcp_rtx_queue_head(const struct sock *sk)
717 ++{
718 ++ struct sk_buff *skb = tcp_write_queue_head(sk);
719 ++
720 ++ if (skb == tcp_send_head(sk))
721 ++ skb = NULL;
722 ++
723 ++ return skb;
724 ++}
725 ++
726 ++static inline struct sk_buff *tcp_rtx_queue_tail(const struct sock *sk)
727 ++{
728 ++ struct sk_buff *skb = tcp_send_head(sk);
729 ++
730 ++ return skb ? tcp_write_queue_prev(sk, skb) : tcp_write_queue_tail(sk);
731 ++}
732 ++
733 + static inline void __tcp_add_write_queue_tail(struct sock *sk, struct sk_buff *skb)
734 + {
735 + __skb_queue_tail(&sk->sk_write_queue, skb);
736 +diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c
737 +index 1394da63614a..a7953962112a 100644
738 +--- a/net/bridge/br_vlan.c
739 ++++ b/net/bridge/br_vlan.c
740 +@@ -580,6 +580,11 @@ void br_vlan_flush(struct net_bridge *br)
741 +
742 + ASSERT_RTNL();
743 +
744 ++ /* delete auto-added default pvid local fdb before flushing vlans
745 ++ * otherwise it will be leaked on bridge device init failure
746 ++ */
747 ++ br_fdb_delete_by_port(br, NULL, 0, 1);
748 ++
749 + vg = br_vlan_group(br);
750 + __vlan_flush(vg);
751 + RCU_INIT_POINTER(br->vlgrp, NULL);
752 +diff --git a/net/core/dev.c b/net/core/dev.c
753 +index db5345f5f7b0..152e1e6316e6 100644
754 +--- a/net/core/dev.c
755 ++++ b/net/core/dev.c
756 +@@ -7768,6 +7768,8 @@ static void __net_exit default_device_exit(struct net *net)
757 +
758 + /* Push remaining network devices to init_net */
759 + snprintf(fb_name, IFNAMSIZ, "dev%d", dev->ifindex);
760 ++ if (__dev_get_by_name(&init_net, fb_name))
761 ++ snprintf(fb_name, IFNAMSIZ, "dev%%d");
762 + err = dev_change_net_namespace(dev, &init_net, fb_name);
763 + if (err) {
764 + pr_emerg("%s: failed to move %s to init_net: %d\n",
765 +diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
766 +index 53edd60fd381..76ffce0c18ae 100644
767 +--- a/net/ipv4/tcp_output.c
768 ++++ b/net/ipv4/tcp_output.c
769 +@@ -1151,6 +1151,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
770 + struct tcp_sock *tp = tcp_sk(sk);
771 + struct sk_buff *buff;
772 + int nsize, old_factor;
773 ++ long limit;
774 + int nlen;
775 + u8 flags;
776 +
777 +@@ -1161,7 +1162,15 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len,
778 + if (nsize < 0)
779 + nsize = 0;
780 +
781 +- if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf + 0x20000)) {
782 ++ /* tcp_sendmsg() can overshoot sk_wmem_queued by one full size skb.
783 ++ * We need some allowance to not penalize applications setting small
784 ++ * SO_SNDBUF values.
785 ++ * Also allow first and last skb in retransmit queue to be split.
786 ++ */
787 ++ limit = sk->sk_sndbuf + 2 * SKB_TRUESIZE(GSO_MAX_SIZE);
788 ++ if (unlikely((sk->sk_wmem_queued >> 1) > limit &&
789 ++ skb != tcp_rtx_queue_head(sk) &&
790 ++ skb != tcp_rtx_queue_tail(sk))) {
791 + NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG);
792 + return -ENOMEM;
793 + }
794 +diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
795 +index 2764c4bd072c..d3f1222c1a8c 100644
796 +--- a/net/l2tp/l2tp_ppp.c
797 ++++ b/net/l2tp/l2tp_ppp.c
798 +@@ -1805,6 +1805,9 @@ static const struct proto_ops pppol2tp_ops = {
799 + .recvmsg = pppol2tp_recvmsg,
800 + .mmap = sock_no_mmap,
801 + .ioctl = pppox_ioctl,
802 ++#ifdef CONFIG_COMPAT
803 ++ .compat_ioctl = pppox_compat_ioctl,
804 ++#endif
805 + };
806 +
807 + static const struct pppox_proto pppol2tp_proto = {
808 +diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c
809 +index 088e8da06b00..0f3cb410e42e 100644
810 +--- a/net/netfilter/nfnetlink_acct.c
811 ++++ b/net/netfilter/nfnetlink_acct.c
812 +@@ -97,6 +97,8 @@ nfnl_acct_new(struct sock *nfnl, struct sk_buff *skb,
813 + return -EINVAL;
814 + if (flags & NFACCT_F_OVERQUOTA)
815 + return -EINVAL;
816 ++ if ((flags & NFACCT_F_QUOTA) && !tb[NFACCT_QUOTA])
817 ++ return -EINVAL;
818 +
819 + size += sizeof(u64);
820 + }
821 +diff --git a/net/sched/sch_codel.c b/net/sched/sch_codel.c
822 +index 9b7e2980ee5c..3bc5dec3b17b 100644
823 +--- a/net/sched/sch_codel.c
824 ++++ b/net/sched/sch_codel.c
825 +@@ -68,7 +68,8 @@ static struct sk_buff *dequeue(struct codel_vars *vars, struct Qdisc *sch)
826 + {
827 + struct sk_buff *skb = __skb_dequeue(&sch->q);
828 +
829 +- prefetch(&skb->end); /* we'll need skb_shinfo() */
830 ++ if (skb)
831 ++ prefetch(&skb->end); /* we'll need skb_shinfo() */
832 + return skb;
833 + }
834 +
835 +diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
836 +index 9a65664f749c..d2bf92e71150 100644
837 +--- a/net/tipc/netlink_compat.c
838 ++++ b/net/tipc/netlink_compat.c
839 +@@ -55,6 +55,7 @@ struct tipc_nl_compat_msg {
840 + int rep_type;
841 + int rep_size;
842 + int req_type;
843 ++ int req_size;
844 + struct net *net;
845 + struct sk_buff *rep;
846 + struct tlv_desc *req;
847 +@@ -252,7 +253,8 @@ static int tipc_nl_compat_dumpit(struct tipc_nl_compat_cmd_dump *cmd,
848 + int err;
849 + struct sk_buff *arg;
850 +
851 +- if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type))
852 ++ if (msg->req_type && (!msg->req_size ||
853 ++ !TLV_CHECK_TYPE(msg->req, msg->req_type)))
854 + return -EINVAL;
855 +
856 + msg->rep = tipc_tlv_alloc(msg->rep_size);
857 +@@ -345,7 +347,8 @@ static int tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd,
858 + {
859 + int err;
860 +
861 +- if (msg->req_type && !TLV_CHECK_TYPE(msg->req, msg->req_type))
862 ++ if (msg->req_type && (!msg->req_size ||
863 ++ !TLV_CHECK_TYPE(msg->req, msg->req_type)))
864 + return -EINVAL;
865 +
866 + err = __tipc_nl_compat_doit(cmd, msg);
867 +@@ -1192,8 +1195,8 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info)
868 + goto send;
869 + }
870 +
871 +- len = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN);
872 +- if (!len || !TLV_OK(msg.req, len)) {
873 ++ msg.req_size = nlmsg_attrlen(req_nlh, GENL_HDRLEN + TIPC_GENL_HDRLEN);
874 ++ if (msg.req_size && !TLV_OK(msg.req, msg.req_size)) {
875 + msg.rep = tipc_get_err_tlv(TIPC_CFG_NOT_SUPPORTED);
876 + err = -EOPNOTSUPP;
877 + goto send;