diff options
author | 2016-12-07 05:27:47 -0500 | |
---|---|---|
committer | 2016-12-07 05:27:47 -0500 | |
commit | 3da94a803e5dfdf6dc39bd7f4c4d860bc8cf5b49 (patch) | |
tree | 03b27129f28c6d952fea3f62c4e8cdce80d13b24 | |
parent | grsecurity-3.1-4.8.12-201612031658 (diff) | |
download | hardened-patchset-3da94a803e5dfdf6dc39bd7f4c4d860bc8cf5b49.tar.gz hardened-patchset-3da94a803e5dfdf6dc39bd7f4c4d860bc8cf5b49.tar.bz2 hardened-patchset-3da94a803e5dfdf6dc39bd7f4c4d860bc8cf5b49.zip |
grsecurity-3.1-4.8.12-20161206230620161206
-rw-r--r-- | 4.8.12/0000_README | 2 | ||||
-rw-r--r-- | 4.8.12/4420_grsecurity-3.1-4.8.12-201612062306.patch (renamed from 4.8.12/4420_grsecurity-3.1-4.8.12-201612031658.patch) | 253 |
2 files changed, 195 insertions, 60 deletions
diff --git a/4.8.12/0000_README b/4.8.12/0000_README index e80d57a..99a02b8 100644 --- a/4.8.12/0000_README +++ b/4.8.12/0000_README @@ -10,7 +10,7 @@ Patch: 1011_linux-4.8.12.patch From: http://www.kernel.org Desc: Linux 4.8.12 -Patch: 4420_grsecurity-3.1-4.8.12-201612031658.patch +Patch: 4420_grsecurity-3.1-4.8.12-201612062306.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/4.8.12/4420_grsecurity-3.1-4.8.12-201612031658.patch b/4.8.12/4420_grsecurity-3.1-4.8.12-201612062306.patch index 4ae7f33..5929283 100644 --- a/4.8.12/4420_grsecurity-3.1-4.8.12-201612031658.patch +++ b/4.8.12/4420_grsecurity-3.1-4.8.12-201612062306.patch @@ -5123,22 +5123,6 @@ index e20bd43..7e476da 100644 #endif /* !__ASSEMBLY__ */ #endif /* __ASM_PGTABLE_H */ -diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h -index ace0a96..c7c4d3c 100644 ---- a/arch/arm64/include/asm/processor.h -+++ b/arch/arm64/include/asm/processor.h -@@ -194,4 +194,11 @@ void cpu_enable_pan(void *__unused); - void cpu_enable_uao(void *__unused); - void cpu_enable_cache_maint_trap(void *__unused); - -+#ifdef CONFIG_PAX_RAP -+static inline void pax_reload_rap_cookie(unsigned long *rap_cookie) -+{ -+ asm volatile("mov\tx19, %0\n\t" : : "r"(*rap_cookie) : "r19"); -+} -+#endif -+ - #endif /* __ASM_PROCESSOR_H */ diff --git a/arch/arm64/include/asm/string.h b/arch/arm64/include/asm/string.h index 2eb714c..3a10471 100644 --- a/arch/arm64/include/asm/string.h @@ -11736,7 +11720,7 @@ index 4f2384a..4e88949 100644 lib-$(CONFIG_SPARC32) += ashrdi3.o lib-$(CONFIG_SPARC32) += memcpy.o memset.o diff --git a/arch/sparc/lib/atomic_64.S b/arch/sparc/lib/atomic_64.S -index a5c5a02..b62dbfec 100644 +index a5c5a02..47db32c 100644 --- a/arch/sparc/lib/atomic_64.S +++ b/arch/sparc/lib/atomic_64.S @@ -16,11 +16,22 @@ @@ -11765,9 +11749,12 @@ index a5c5a02..b62dbfec 100644 cas [%o1], %g1, %g7; \ cmp %g1, %g7; \ bne,pn %icc, BACKOFF_LABEL(2f, 1b); \ -@@ -30,11 +41,15 @@ ENTRY(atomic_##op) /* %o0 = increment, %o1 = atomic_ptr */ \ +@@ -28,13 +39,17 @@ ENTRY(atomic_##op) /* %o0 = increment, %o1 = atomic_ptr */ \ + retl; \ + nop; \ 2: BACKOFF_SPIN(%o2, %o3, 1b); \ - ENDPROC(atomic_##op); \ +-ENDPROC(atomic_##op); \ ++ENDPROC(atomic_##op##suffix); -#define ATOMIC_OP_RETURN(op) \ -ENTRY(atomic_##op##_return) /* %o0 = increment, %o1 = atomic_ptr */ \ @@ -11784,16 +11771,18 @@ index a5c5a02..b62dbfec 100644 cas [%o1], %g1, %g7; \ cmp %g1, %g7; \ bne,pn %icc, BACKOFF_LABEL(2f, 1b); \ -@@ -44,6 +59,9 @@ ENTRY(atomic_##op##_return) /* %o0 = increment, %o1 = atomic_ptr */ \ +@@ -42,7 +57,10 @@ ENTRY(atomic_##op##_return) /* %o0 = increment, %o1 = atomic_ptr */ \ + retl; \ + sra %g1, 0, %o0; \ 2: BACKOFF_SPIN(%o2, %o3, 1b); \ - ENDPROC(atomic_##op##_return); - +-ENDPROC(atomic_##op##_return); ++ENDPROC(atomic_##op##_return##suffix); ++ +#define ATOMIC_OP_RETURN(op) __ATOMIC_OP_RETURN(op, , op, ) \ + __ATOMIC_OP_RETURN(op, _unchecked, __REFCOUNT_OP(op), __OVERFLOW_IOP) -+ + #define ATOMIC_FETCH_OP(op) \ ENTRY(atomic_fetch_##op) /* %o0 = increment, %o1 = atomic_ptr */ \ - BACKOFF_SETUP(%o2); \ @@ -73,13 +91,16 @@ ATOMIC_OPS(xor) #undef ATOMIC_OPS #undef ATOMIC_FETCH_OP @@ -11814,9 +11803,12 @@ index a5c5a02..b62dbfec 100644 casx [%o1], %g1, %g7; \ cmp %g1, %g7; \ bne,pn %xcc, BACKOFF_LABEL(2f, 1b); \ -@@ -89,11 +110,15 @@ ENTRY(atomic64_##op) /* %o0 = increment, %o1 = atomic_ptr */ \ +@@ -87,13 +108,17 @@ ENTRY(atomic64_##op) /* %o0 = increment, %o1 = atomic_ptr */ \ + retl; \ + nop; \ 2: BACKOFF_SPIN(%o2, %o3, 1b); \ - ENDPROC(atomic64_##op); \ +-ENDPROC(atomic64_##op); \ ++ENDPROC(atomic64_##op##suffix); -#define ATOMIC64_OP_RETURN(op) \ -ENTRY(atomic64_##op##_return) /* %o0 = increment, %o1 = atomic_ptr */ \ @@ -11833,16 +11825,18 @@ index a5c5a02..b62dbfec 100644 casx [%o1], %g1, %g7; \ cmp %g1, %g7; \ bne,pn %xcc, BACKOFF_LABEL(2f, 1b); \ -@@ -103,6 +128,9 @@ ENTRY(atomic64_##op##_return) /* %o0 = increment, %o1 = atomic_ptr */ \ +@@ -101,7 +126,10 @@ ENTRY(atomic64_##op##_return) /* %o0 = increment, %o1 = atomic_ptr */ \ + retl; \ + op %g1, %o0, %o0; \ 2: BACKOFF_SPIN(%o2, %o3, 1b); \ - ENDPROC(atomic64_##op##_return); - +-ENDPROC(atomic64_##op##_return); ++ENDPROC(atomic64_##op##_return##suffix); ++ +#define ATOMIC64_OP_RETURN(op) __ATOMIC64_OP_RETURN(op, , op, ) \ + __ATOMIC64_OP_RETURN(op, _unchecked, __REFCOUNT_OP(op), __OVERFLOW_XOP) -+ + #define ATOMIC64_FETCH_OP(op) \ ENTRY(atomic64_fetch_##op) /* %o0 = increment, %o1 = atomic_ptr */ \ - BACKOFF_SETUP(%o2); \ @@ -132,7 +160,12 @@ ATOMIC64_OPS(xor) #undef ATOMIC64_OPS #undef ATOMIC64_FETCH_OP @@ -31555,7 +31549,7 @@ index 9e152cd..60ef544 100644 * We have to walk the irq descriptors to setup the vector * space for the cpu which comes online. Prevent irq diff --git a/arch/x86/kernel/step.c b/arch/x86/kernel/step.c -index c9a0738..f0ab628 100644 +index c9a0738..3d1b164 100644 --- a/arch/x86/kernel/step.c +++ b/arch/x86/kernel/step.c @@ -45,7 +45,8 @@ unsigned long convert_ip_to_linear(struct task_struct *child, struct pt_regs *re @@ -31572,7 +31566,7 @@ index c9a0738..f0ab628 100644 unsigned char opcode[15]; unsigned long addr = convert_ip_to_linear(child, regs); -+ if (addr == -EINVAL) ++ if (addr == -1L) + return 0; + copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0); @@ -36157,7 +36151,7 @@ index a3a983f..69f6099 100644 extern u32 pnp_bios_is_utter_crap; pnp_bios_is_utter_crap = 1; diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c -index dc80230..d0ef276 100644 +index dc80230..b245d86 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -14,6 +14,8 @@ @@ -36193,7 +36187,19 @@ index dc80230..d0ef276 100644 return 0; *prefetch = (instr_lo == 0xF) && -@@ -160,7 +170,10 @@ is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr) +@@ -151,7 +161,10 @@ is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr) + if (error_code & PF_INSTR) + return 0; + +- instr = (void *)convert_ip_to_linear(current, regs); ++ addr = convert_ip_to_linear(current, regs); ++ if (addr == -1L) ++ return 0; ++ instr = (void *)addr; + max_instr = instr + 15; + + if (user_mode(regs) && instr >= (unsigned char *)TASK_SIZE_MAX) +@@ -160,7 +173,10 @@ is_prefetch(struct pt_regs *regs, unsigned long error_code, unsigned long addr) while (instr < max_instr) { unsigned char opcode; @@ -36205,7 +36211,7 @@ index dc80230..d0ef276 100644 break; instr++; -@@ -244,6 +257,34 @@ force_sig_info_fault(int si_signo, int si_code, unsigned long address, +@@ -244,6 +260,34 @@ force_sig_info_fault(int si_signo, int si_code, unsigned long address, force_sig_info(si_signo, &info, tsk); } @@ -36240,7 +36246,7 @@ index dc80230..d0ef276 100644 DEFINE_SPINLOCK(pgd_lock); LIST_HEAD(pgd_list); -@@ -294,10 +335,27 @@ void vmalloc_sync_all(void) +@@ -294,10 +338,27 @@ void vmalloc_sync_all(void) for (address = VMALLOC_START & PMD_MASK; address >= TASK_SIZE_MAX && address < FIXADDR_TOP; address += PMD_SIZE) { @@ -36268,7 +36274,7 @@ index dc80230..d0ef276 100644 spinlock_t *pgt_lock; pmd_t *ret; -@@ -305,8 +363,14 @@ void vmalloc_sync_all(void) +@@ -305,8 +366,14 @@ void vmalloc_sync_all(void) pgt_lock = &pgd_page_get_mm(page)->page_table_lock; spin_lock(pgt_lock); @@ -36284,7 +36290,7 @@ index dc80230..d0ef276 100644 if (!ret) break; -@@ -340,6 +404,12 @@ static noinline int vmalloc_fault(unsigned long address) +@@ -340,6 +407,12 @@ static noinline int vmalloc_fault(unsigned long address) * an interrupt in the middle of a task switch.. */ pgd_paddr = read_cr3(); @@ -36297,7 +36303,7 @@ index dc80230..d0ef276 100644 pmd_k = vmalloc_sync_one(__va(pgd_paddr), address); if (!pmd_k) return -1; -@@ -439,11 +509,24 @@ static noinline int vmalloc_fault(unsigned long address) +@@ -439,11 +512,24 @@ static noinline int vmalloc_fault(unsigned long address) * happen within a race in page table update. In the later * case just flush: */ @@ -36323,7 +36329,7 @@ index dc80230..d0ef276 100644 if (pgd_none(*pgd)) { set_pgd(pgd, *pgd_ref); arch_flush_lazy_mmu_mode(); -@@ -616,7 +699,7 @@ static int is_errata93(struct pt_regs *regs, unsigned long address) +@@ -616,7 +702,7 @@ static int is_errata93(struct pt_regs *regs, unsigned long address) static int is_errata100(struct pt_regs *regs, unsigned long address) { #ifdef CONFIG_X86_64 @@ -36332,7 +36338,7 @@ index dc80230..d0ef276 100644 return 1; #endif return 0; -@@ -643,9 +726,9 @@ static int is_f00f_bug(struct pt_regs *regs, unsigned long address) +@@ -643,9 +729,9 @@ static int is_f00f_bug(struct pt_regs *regs, unsigned long address) } static const char nx_warning[] = KERN_CRIT @@ -36344,7 +36350,7 @@ index dc80230..d0ef276 100644 static void show_fault_oops(struct pt_regs *regs, unsigned long error_code, -@@ -654,7 +737,7 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code, +@@ -654,7 +740,7 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code, if (!oops_may_print()) return; @@ -36353,7 +36359,7 @@ index dc80230..d0ef276 100644 unsigned int level; pgd_t *pgd; pte_t *pte; -@@ -665,13 +748,25 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code, +@@ -665,13 +751,25 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code, pte = lookup_address_in_pgd(pgd, address, &level); if (pte && pte_present(*pte) && !pte_exec(*pte)) @@ -36381,7 +36387,7 @@ index dc80230..d0ef276 100644 printk(KERN_ALERT "BUG: unable to handle kernel "); if (address < PAGE_SIZE) printk(KERN_CONT "NULL pointer dereference"); -@@ -855,6 +950,21 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, +@@ -855,6 +953,21 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code, } #endif @@ -36403,7 +36409,7 @@ index dc80230..d0ef276 100644 /* * To avoid leaking information about the kernel page table * layout, pretend that user-mode accesses to kernel addresses -@@ -966,7 +1076,7 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, +@@ -966,7 +1079,7 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address, if (fault & (VM_FAULT_HWPOISON|VM_FAULT_HWPOISON_LARGE)) { printk(KERN_ERR "MCE: Killing %s:%d due to hardware memory corruption fault at %lx\n", @@ -36412,7 +36418,7 @@ index dc80230..d0ef276 100644 code = BUS_MCEERR_AR; } #endif -@@ -1025,6 +1135,109 @@ static int spurious_fault_check(unsigned long error_code, pte_t *pte) +@@ -1025,6 +1138,109 @@ static int spurious_fault_check(unsigned long error_code, pte_t *pte) return 1; } @@ -36522,7 +36528,7 @@ index dc80230..d0ef276 100644 /* * Handle a spurious fault caused by a stale TLB entry. * -@@ -1112,6 +1325,10 @@ access_error(unsigned long error_code, struct vm_area_struct *vma) +@@ -1112,6 +1328,10 @@ access_error(unsigned long error_code, struct vm_area_struct *vma) { /* This is only called for the current mm, so: */ bool foreign = false; @@ -36533,7 +36539,7 @@ index dc80230..d0ef276 100644 /* * Make sure to check the VMA so that we do not perform * faults just to hit a PF_PK as soon as we fill in a -@@ -1183,6 +1400,22 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, +@@ -1183,6 +1403,22 @@ __do_page_fault(struct pt_regs *regs, unsigned long error_code, tsk = current; mm = tsk->mm; @@ -36556,7 +36562,7 @@ index dc80230..d0ef276 100644 /* * Detect and handle instructions that would cause a page fault for * both a tracked kernel page and a userspace page. -@@ -1309,6 +1542,11 @@ retry: +@@ -1309,6 +1545,11 @@ retry: might_sleep(); } @@ -36568,7 +36574,7 @@ index dc80230..d0ef276 100644 vma = find_vma(mm, address); if (unlikely(!vma)) { bad_area(regs, error_code, address); -@@ -1320,18 +1558,24 @@ retry: +@@ -1320,18 +1561,24 @@ retry: bad_area(regs, error_code, address); return; } @@ -36604,7 +36610,7 @@ index dc80230..d0ef276 100644 if (unlikely(expand_stack(vma, address))) { bad_area(regs, error_code, address); return; -@@ -1451,3 +1695,292 @@ trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) +@@ -1451,3 +1698,292 @@ trace_do_page_fault(struct pt_regs *regs, unsigned long error_code) } NOKPROBE_SYMBOL(trace_do_page_fault); #endif /* CONFIG_TRACING */ @@ -39793,7 +39799,7 @@ index d6ee929..0454327 100644 .getproplen = olpc_dt_getproplen, .getproperty = olpc_dt_getproperty, diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c -index b12c26e..089a429 100644 +index b12c26e..eacc01f 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -160,11 +160,8 @@ static void do_fpu_end(void) @@ -39821,6 +39827,45 @@ index b12c26e..089a429 100644 syscall_init(); /* This sets MSR_*STAR and related */ #endif load_TR_desc(); /* This does ltr */ +@@ -289,9 +282,13 @@ int hibernate_resume_nonboot_cpu_disable(void) + * any more at that point (the page tables used by it previously may + * have been overwritten by hibernate image data). + */ ++ pax_open_kernel(); + smp_ops.play_dead = resume_play_dead; ++ pax_close_kernel(); + ret = disable_nonboot_cpus(); ++ pax_open_kernel(); + smp_ops.play_dead = play_dead; ++ pax_close_kernel(); + return ret; + } + #endif +diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c +index 9634557..47043c7 100644 +--- a/arch/x86/power/hibernate_64.c ++++ b/arch/x86/power/hibernate_64.c +@@ -130,15 +130,14 @@ static int relocate_restore_code(void) + + /* Make the page containing the relocated code executable */ + pgd = (pgd_t *)__va(read_cr3()) + pgd_index(relocated_restore_code); ++ set_pgd(pgd, __pgd(pgd_val(*pgd) & ~_PAGE_NX)); + pud = pud_offset(pgd, relocated_restore_code); +- if (pud_large(*pud)) { +- set_pud(pud, __pud(pud_val(*pud) & ~_PAGE_NX)); +- } else { ++ set_pud(pud, __pud(pud_val(*pud) & ~_PAGE_NX)); ++ if (!pud_large(*pud)) { + pmd_t *pmd = pmd_offset(pud, relocated_restore_code); + +- if (pmd_large(*pmd)) { +- set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_NX)); +- } else { ++ set_pmd(pmd, __pmd(pmd_val(*pmd) & ~_PAGE_NX)); ++ if (!pmd_large(*pmd)) { + pte_t *pte = pte_offset_kernel(pmd, relocated_restore_code); + + set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_NX)); diff --git a/arch/x86/power/hibernate_asm_32.S b/arch/x86/power/hibernate_asm_32.S index 1d0fa0e..5003de0 100644 --- a/arch/x86/power/hibernate_asm_32.S @@ -60519,6 +60564,19 @@ index c439c82..1f20f57 100644 union axis_conversion ac; /* hw -> logical axis */ int mapped_btns[3]; +diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c +index f9154b8..bb13e3e 100644 +--- a/drivers/misc/lkdtm_core.c ++++ b/drivers/misc/lkdtm_core.c +@@ -78,7 +78,7 @@ static irqreturn_t jp_handle_irq_event(unsigned int irq, + return 0; + } + +-static void jp_tasklet_action(struct softirq_action *a) ++static void jp_tasklet_action(void) + { + lkdtm_handler(); + jprobe_return(); diff --git a/drivers/misc/mic/scif/scif_api.c b/drivers/misc/mic/scif/scif_api.c index ddc9e4b..9e27f41 100644 --- a/drivers/misc/mic/scif/scif_api.c @@ -80212,9 +80270,18 @@ index 30e5312..1493a73 100644 int wilc_mac_open(struct net_device *ndev); int wilc_mac_close(struct net_device *ndev); diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c -index 90cc8cd..b98abd7 100644 +index 90cc8cd..5617025 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c +@@ -94,7 +94,7 @@ + static int p80211knetdev_init(netdevice_t *netdev); + static int p80211knetdev_open(netdevice_t *netdev); + static int p80211knetdev_stop(netdevice_t *netdev); +-static int p80211knetdev_hard_start_xmit(struct sk_buff *skb, ++static netdev_tx_t p80211knetdev_hard_start_xmit(struct sk_buff *skb, + netdevice_t *netdev); + static void p80211knetdev_set_multicast_list(netdevice_t *dev); + static int p80211knetdev_do_ioctl(netdevice_t *dev, struct ifreq *ifr, @@ -317,7 +317,7 @@ static void p80211netdev_rx_bh(unsigned long arg) * Returns: * zero on success, non-zero on failure. @@ -135861,7 +135928,7 @@ index 6935d02..5e3f46e 100644 /* * Used for initialization calls.. diff --git a/include/linux/init_task.h b/include/linux/init_task.h -index f8834f8..eb807a2 100644 +index f8834f8..9884265 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -159,6 +159,12 @@ extern struct task_group root_task_group; @@ -135885,6 +135952,14 @@ index f8834f8..eb807a2 100644 .fs = &init_fs, \ .files = &init_files, \ .signal = &init_signals, \ +@@ -233,7 +240,6 @@ extern struct task_group root_task_group; + .pending = { \ + .list = LIST_HEAD_INIT(tsk.pending.list), \ + .signal = {{0}}}, \ +- .blocked = {{0}}, \ + .alloc_lock = __SPIN_LOCK_UNLOCKED(tsk.alloc_lock), \ + .journal_info = NULL, \ + .cpu_timers = INIT_CPU_TIMERS(tsk.cpu_timers), \ diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index b6683f0..9c8f391 100644 --- a/include/linux/interrupt.h @@ -165524,7 +165599,7 @@ index 7eb955e..479c9a6 100644 static int __init ovs_vxlan_tnl_init(void) diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index d2238b2..7123b3f 100644 +index d2238b2..746fec2 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c @@ -278,7 +278,7 @@ static int packet_direct_xmit(struct sk_buff *skb) @@ -165579,7 +165654,38 @@ index d2238b2..7123b3f 100644 spin_unlock(&sk->sk_receive_queue.lock); drop_n_restore: -@@ -3841,7 +3841,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, +@@ -3648,19 +3648,25 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv + + if (optlen != sizeof(val)) + return -EINVAL; +- if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) +- return -EBUSY; + if (copy_from_user(&val, optval, sizeof(val))) + return -EFAULT; + switch (val) { + case TPACKET_V1: + case TPACKET_V2: + case TPACKET_V3: ++ break; ++ default: ++ return -EINVAL; ++ } ++ lock_sock(sk); ++ if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) { ++ ret = -EBUSY; ++ } else { + po->tp_version = val; +- return 0; +- default: +- return -EINVAL; ++ ret = 0; + } ++ release_sock(sk); ++ return ret; + } + case PACKET_RESERVE: + { +@@ -3841,7 +3847,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, case PACKET_HDRLEN: if (len > sizeof(int)) len = sizeof(int); @@ -165588,7 +165694,7 @@ index d2238b2..7123b3f 100644 return -EFAULT; switch (val) { case TPACKET_V1: -@@ -3876,9 +3876,9 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, +@@ -3876,9 +3882,9 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, case PACKET_ROLLOVER_STATS: if (!po->rollover) return -EINVAL; @@ -165601,7 +165707,7 @@ index d2238b2..7123b3f 100644 data = &rstats; lv = sizeof(rstats); break; -@@ -3896,7 +3896,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, +@@ -3896,7 +3902,7 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, len = lv; if (put_user(len, optlen)) return -EFAULT; @@ -165610,6 +165716,35 @@ index d2238b2..7123b3f 100644 return -EFAULT; return 0; } +@@ -4164,6 +4170,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + /* Added to avoid minimal code churn */ + struct tpacket_req *req = &req_u->req; + ++ lock_sock(sk); + /* Opening a Tx-ring is NOT supported in TPACKET_V3 */ + if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) { + net_warn_ratelimited("Tx-ring is not supported.\n"); +@@ -4245,7 +4252,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + goto out; + } + +- lock_sock(sk); + + /* Detach socket from network */ + spin_lock(&po->bind_lock); +@@ -4294,11 +4300,11 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u, + if (!tx_ring) + prb_shutdown_retire_blk_timer(po, rb_queue); + } +- release_sock(sk); + + if (pg_vec) + free_pg_vec(pg_vec, order, req->tp_block_nr); + out: ++ release_sock(sk); + return err; + } + diff --git a/net/packet/diag.c b/net/packet/diag.c index 0ed68f0..54c1dbe 100644 --- a/net/packet/diag.c |