summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--4.8.12/0000_README2
-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