diff options
author | Anthony G. Basile <blueness@gentoo.org> | 2016-01-17 14:20:18 -0500 |
---|---|---|
committer | Anthony G. Basile <blueness@gentoo.org> | 2016-01-17 14:20:18 -0500 |
commit | 12f1edb59638e9b2f260174cfb297927edab395f (patch) | |
tree | df2d3273ca6cce26d0d0d63755e6cc37e762b2fd | |
parent | grsecurity-3.1-4.3.3-201601051958 (diff) | |
download | hardened-patchset-12f1edb59638e9b2f260174cfb297927edab395f.tar.gz hardened-patchset-12f1edb59638e9b2f260174cfb297927edab395f.tar.bz2 hardened-patchset-12f1edb59638e9b2f260174cfb297927edab395f.zip |
grsecurity-3.1-4.3.3-20160116175720160116
-rw-r--r-- | 4.3.3/0000_README | 2 | ||||
-rw-r--r-- | 4.3.3/4420_grsecurity-3.1-4.3.3-201601161757.patch (renamed from 4.3.3/4420_grsecurity-3.1-4.3.3-201601051958.patch) | 1567 |
2 files changed, 1466 insertions, 103 deletions
diff --git a/4.3.3/0000_README b/4.3.3/0000_README index ac59d19..8ff755f 100644 --- a/4.3.3/0000_README +++ b/4.3.3/0000_README @@ -2,7 +2,7 @@ README ----------------------------------------------------------------------------- Individual Patch Descriptions: ----------------------------------------------------------------------------- -Patch: 4420_grsecurity-3.1-4.3.3-201601051958.patch +Patch: 4420_grsecurity-3.1-4.3.3-201601161757.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/4.3.3/4420_grsecurity-3.1-4.3.3-201601051958.patch b/4.3.3/4420_grsecurity-3.1-4.3.3-201601161757.patch index 0bcf4a7..15482a1 100644 --- a/4.3.3/4420_grsecurity-3.1-4.3.3-201601051958.patch +++ b/4.3.3/4420_grsecurity-3.1-4.3.3-201601161757.patch @@ -4702,7 +4702,7 @@ index 7cd1514..0307305 100644 } diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c -index b8efb8c..88fa837 100644 +index b8efb8c..0b8f924 100644 --- a/arch/arm/net/bpf_jit_32.c +++ b/arch/arm/net/bpf_jit_32.c @@ -20,6 +20,7 @@ @@ -4778,7 +4778,24 @@ index b8efb8c..88fa837 100644 return (u64)err << 32 | ntohl(ret); } -@@ -199,8 +184,10 @@ static void jit_fill_hole(void *area, unsigned int size) +@@ -182,31 +167,19 @@ static inline int mem_words_used(struct jit_ctx *ctx) + return fls(ctx->seen & SEEN_MEM); + } + +-static inline bool is_load_to_a(u16 inst) +-{ +- switch (inst) { +- case BPF_LD | BPF_W | BPF_LEN: +- case BPF_LD | BPF_W | BPF_ABS: +- case BPF_LD | BPF_H | BPF_ABS: +- case BPF_LD | BPF_B | BPF_ABS: +- return true; +- default: +- return false; +- } +-} +- + static void jit_fill_hole(void *area, unsigned int size) { u32 *ptr; /* We are guaranteed to have aligned memory. */ @@ -4789,7 +4806,22 @@ index b8efb8c..88fa837 100644 } static void build_prologue(struct jit_ctx *ctx) -@@ -556,6 +543,9 @@ static int build_body(struct jit_ctx *ctx) + { + u16 reg_set = saved_regs(ctx); +- u16 first_inst = ctx->skf->insns[0].code; + u16 off; + + #ifdef CONFIG_FRAME_POINTER +@@ -236,7 +209,7 @@ static void build_prologue(struct jit_ctx *ctx) + emit(ARM_MOV_I(r_X, 0), ctx); + + /* do not leak kernel data to userspace */ +- if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst))) ++ if (bpf_needs_clear_a(&ctx->skf->insns[0])) + emit(ARM_MOV_I(r_A, 0), ctx); + + /* stack space for the BPF_MEM words */ +@@ -556,6 +529,9 @@ static int build_body(struct jit_ctx *ctx) case BPF_LD | BPF_B | BPF_ABS: load_order = 0; load: @@ -4799,7 +4831,7 @@ index b8efb8c..88fa837 100644 emit_mov_i(r_off, k, ctx); load_common: ctx->seen |= SEEN_DATA | SEEN_CALL; -@@ -570,18 +560,6 @@ load_common: +@@ -570,18 +546,6 @@ load_common: condt = ARM_COND_HI; } @@ -4818,6 +4850,16 @@ index b8efb8c..88fa837 100644 _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data), ctx); +@@ -744,7 +708,8 @@ load_ind: + case BPF_ALU | BPF_RSH | BPF_K: + if (unlikely(k > 31)) + return -1; +- emit(ARM_LSR_I(r_A, r_A, k), ctx); ++ if (k) ++ emit(ARM_LSR_I(r_A, r_A, k), ctx); + break; + case BPF_ALU | BPF_RSH | BPF_X: + update_on_xread(ctx); diff --git a/arch/arm/plat-iop/setup.c b/arch/arm/plat-iop/setup.c index 5b217f4..c23f40e 100644 --- a/arch/arm/plat-iop/setup.c @@ -7046,6 +7088,47 @@ index 5c81fdd..db158d3 100644 int __virt_addr_valid(const volatile void *kaddr) { return pfn_valid(PFN_DOWN(virt_to_phys(kaddr))); +diff --git a/arch/mips/net/bpf_jit.c b/arch/mips/net/bpf_jit.c +index 0c4a133..26e947d 100644 +--- a/arch/mips/net/bpf_jit.c ++++ b/arch/mips/net/bpf_jit.c +@@ -521,19 +521,6 @@ static inline u16 align_sp(unsigned int num) + return num; + } + +-static bool is_load_to_a(u16 inst) +-{ +- switch (inst) { +- case BPF_LD | BPF_W | BPF_LEN: +- case BPF_LD | BPF_W | BPF_ABS: +- case BPF_LD | BPF_H | BPF_ABS: +- case BPF_LD | BPF_B | BPF_ABS: +- return true; +- default: +- return false; +- } +-} +- + static void save_bpf_jit_regs(struct jit_ctx *ctx, unsigned offset) + { + int i = 0, real_off = 0; +@@ -614,7 +601,6 @@ static unsigned int get_stack_depth(struct jit_ctx *ctx) + + static void build_prologue(struct jit_ctx *ctx) + { +- u16 first_inst = ctx->skf->insns[0].code; + int sp_off; + + /* Calculate the total offset for the stack pointer */ +@@ -641,7 +627,7 @@ static void build_prologue(struct jit_ctx *ctx) + emit_jit_reg_move(r_X, r_zero, ctx); + + /* Do not leak kernel data to userspace */ +- if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst))) ++ if (bpf_needs_clear_a(&ctx->skf->insns[0])) + emit_jit_reg_move(r_A, r_zero, ctx); + } + diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c index a2358b4..7cead4f 100644 --- a/arch/mips/sgi-ip27/ip27-nmi.c @@ -9339,6 +9422,31 @@ index 0f432a7..abfe841 100644 /* If hint, make sure it matches our alignment restrictions */ if (!fixed && addr) { addr = _ALIGN_UP(addr, 1ul << pshift); +diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c +index 17cea18..264c473 100644 +--- a/arch/powerpc/net/bpf_jit_comp.c ++++ b/arch/powerpc/net/bpf_jit_comp.c +@@ -78,18 +78,9 @@ static void bpf_jit_build_prologue(struct bpf_prog *fp, u32 *image, + PPC_LI(r_X, 0); + } + +- switch (filter[0].code) { +- case BPF_RET | BPF_K: +- case BPF_LD | BPF_W | BPF_LEN: +- case BPF_LD | BPF_W | BPF_ABS: +- case BPF_LD | BPF_H | BPF_ABS: +- case BPF_LD | BPF_B | BPF_ABS: +- /* first instruction sets A register (or is RET 'constant') */ +- break; +- default: +- /* make sure we dont leak kernel information to user */ ++ /* make sure we dont leak kernel information to user */ ++ if (bpf_needs_clear_a(&filter[0])) + PPC_LI(r_A, 0); +- } + } + + static void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 5038fd5..87a2033 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c @@ -12192,6 +12300,35 @@ index 4ac88b7..bac6cb2 100644 #endif /* CONFIG_SMP */ #endif /* CONFIG_DEBUG_DCFLUSH */ } +diff --git a/arch/sparc/net/bpf_jit_comp.c b/arch/sparc/net/bpf_jit_comp.c +index f8b9f71..17e71d2 100644 +--- a/arch/sparc/net/bpf_jit_comp.c ++++ b/arch/sparc/net/bpf_jit_comp.c +@@ -420,22 +420,9 @@ void bpf_jit_compile(struct bpf_prog *fp) + } + emit_reg_move(O7, r_saved_O7); + +- switch (filter[0].code) { +- case BPF_RET | BPF_K: +- case BPF_LD | BPF_W | BPF_LEN: +- case BPF_LD | BPF_W | BPF_ABS: +- case BPF_LD | BPF_H | BPF_ABS: +- case BPF_LD | BPF_B | BPF_ABS: +- /* The first instruction sets the A register (or is +- * a "RET 'constant'") +- */ +- break; +- default: +- /* Make sure we dont leak kernel information to the +- * user. +- */ ++ /* Make sure we dont leak kernel information to the user. */ ++ if (bpf_needs_clear_a(&filter[0])) + emit_clear(r_A); /* A = 0 */ +- } + + for (i = 0; i < flen; i++) { + unsigned int K = filter[i].k; diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig index 106c21b..185bf0f 100644 --- a/arch/tile/Kconfig @@ -24159,6 +24296,19 @@ index 66dd3fe9..c9bfa35 100644 } } +diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h +index 165be83..031e5d22 100644 +--- a/arch/x86/kernel/cpu/perf_event.h ++++ b/arch/x86/kernel/cpu/perf_event.h +@@ -790,7 +790,7 @@ static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip) + regs->cs = kernel_ip(ip) ? __KERNEL_CS : __USER_CS; + if (regs->flags & X86_VM_MASK) + regs->flags ^= (PERF_EFLAGS_VM | X86_VM_MASK); +- regs->ip = ip; ++ regs->ip = kernel_ip(ip) ? ktva_ktla(ip) : ip; + } + + ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event); diff --git a/arch/x86/kernel/cpu/perf_event_amd_iommu.c b/arch/x86/kernel/cpu/perf_event_amd_iommu.c index 97242a9..cf9c30e 100644 --- a/arch/x86/kernel/cpu/perf_event_amd_iommu.c @@ -24321,6 +24471,67 @@ index 377e8f8..2982f48 100644 ret = intel_cqm_setup_rmid_cache(); if (ret) +diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c +index 84f236a..6251ea8 100644 +--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c ++++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c +@@ -561,7 +561,7 @@ int intel_pmu_drain_bts_buffer(void) + + static inline void intel_pmu_drain_pebs_buffer(void) + { +- struct pt_regs regs; ++ struct pt_regs regs = {}; + + x86_pmu.drain_pebs(®s); + } +@@ -832,7 +832,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) + struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); + unsigned long from = cpuc->lbr_entries[0].from; + unsigned long old_to, to = cpuc->lbr_entries[0].to; +- unsigned long ip = regs->ip; ++ unsigned long ip = ktva_ktla(regs->ip); + int is_64bit = 0; + void *kaddr; + int size; +@@ -884,6 +884,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) + } else { + kaddr = (void *)to; + } ++ kaddr = (void *)ktva_ktla((unsigned long)kaddr); + + do { + struct insn insn; +@@ -1032,7 +1033,7 @@ static void setup_pebs_sample_data(struct perf_event *event, + } + + if (event->attr.precise_ip > 1 && x86_pmu.intel_cap.pebs_format >= 2) { +- regs->ip = pebs->real_ip; ++ set_linear_ip(regs, pebs->real_ip); + regs->flags |= PERF_EFLAGS_EXACT; + } else if (event->attr.precise_ip > 1 && intel_pmu_pebs_fixup_ip(regs)) + regs->flags |= PERF_EFLAGS_EXACT; +diff --git a/arch/x86/kernel/cpu/perf_event_intel_lbr.c b/arch/x86/kernel/cpu/perf_event_intel_lbr.c +index b2c9475..7288a46 100644 +--- a/arch/x86/kernel/cpu/perf_event_intel_lbr.c ++++ b/arch/x86/kernel/cpu/perf_event_intel_lbr.c +@@ -682,7 +682,7 @@ static int branch_type(unsigned long from, unsigned long to, int abort) + * Ensure we don't blindy read any address by validating it is + * a known text address. + */ +- if (kernel_text_address(from)) { ++ if (kernel_text_address(ktva_ktla(from))) { + addr = (void *)from; + /* + * Assume we can get the maximum possible size +@@ -704,7 +704,7 @@ static int branch_type(unsigned long from, unsigned long to, int abort) + #ifdef CONFIG_X86_64 + is64 = kernel_ip((unsigned long)addr) || !test_thread_flag(TIF_IA32); + #endif +- insn_init(&insn, addr, bytes_read, is64); ++ insn_init(&insn, (void *)ktva_ktla((unsigned long)addr), bytes_read, is64); + insn_get_opcode(&insn); + if (!insn.opcode.got) + return X86_BR_ABORT; diff --git a/arch/x86/kernel/cpu/perf_event_intel_pt.c b/arch/x86/kernel/cpu/perf_event_intel_pt.c index 4216928..cdae603 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_pt.c @@ -29230,9 +29441,18 @@ index c3f7602..f6033e1 100644 /* diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c -index bf4db6e..d491400 100644 +index bf4db6e..624137c 100644 --- a/arch/x86/kernel/uprobes.c +++ b/arch/x86/kernel/uprobes.c +@@ -287,7 +287,7 @@ static int uprobe_init_insn(struct arch_uprobe *auprobe, struct insn *insn, bool + { + u32 volatile *good_insns; + +- insn_init(insn, auprobe->insn, sizeof(auprobe->insn), x86_64); ++ insn_init(insn, (void *)ktva_ktla((unsigned long)auprobe->insn), sizeof(auprobe->insn), x86_64); + /* has the side-effect of processing the entire instruction */ + insn_get_length(insn); + if (WARN_ON_ONCE(!insn_complete(insn))) @@ -978,7 +978,7 @@ arch_uretprobe_hijack_return_addr(unsigned long trampoline_vaddr, struct pt_regs if (nleft != rasize) { @@ -34681,9 +34901,18 @@ index 0057a7acc..95c7edd 100644 might_sleep(); if (is_enabled()) /* recheck and proper locking in *_core() */ diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c -index 71fc79a..7388ad7 100644 +index 71fc79a..3dd1f49 100644 --- a/arch/x86/mm/mpx.c +++ b/arch/x86/mm/mpx.c +@@ -193,7 +193,7 @@ static int mpx_insn_decode(struct insn *insn, + */ + if (!nr_copied) + return -EFAULT; +- insn_init(insn, buf, nr_copied, x86_64); ++ insn_init(insn, (void *)ktva_ktla((unsigned long)buf), nr_copied, x86_64); + insn_get_length(insn); + /* + * copy_from_user() tries to get as many bytes as we could see in @@ -292,11 +292,11 @@ siginfo_t *mpx_generate_siginfo(struct pt_regs *regs) * We were not able to extract an address from the instruction, * probably because there was something invalid in it. @@ -42077,6 +42306,19 @@ index 5db3445..21414d5 100644 } /* +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +index 0d13e63..3f67919 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h +@@ -2338,7 +2338,7 @@ static inline void amdgpu_unregister_atpx_handler(void) {} + * KMS + */ + extern const struct drm_ioctl_desc amdgpu_ioctls_kms[]; +-extern int amdgpu_max_kms_ioctl; ++extern const int amdgpu_max_kms_ioctl; + + int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags); + int amdgpu_driver_unload_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 8e99514..3d68786 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c @@ -42174,6 +42416,35 @@ index 6068d82..7ecd87c 100644 } static const struct vga_switcheroo_client_ops amdgpu_switcheroo_ops = { +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +index b190c2a..d1b18c2 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -544,8 +544,12 @@ static int __init amdgpu_init(void) + DRM_INFO("amdgpu kernel modesetting enabled.\n"); + driver = &kms_driver; + pdriver = &amdgpu_kms_pci_driver; +- driver->driver_features |= DRIVER_MODESET; +- driver->num_ioctls = amdgpu_max_kms_ioctl; ++ ++ pax_open_kernel(); ++ *(u32 *)&driver->driver_features |= DRIVER_MODESET; ++ *(int *)&driver->num_ioctls = amdgpu_max_kms_ioctl; ++ pax_close_kernel(); ++ + amdgpu_register_atpx_handler(); + + amdgpu_amdkfd_init(); +diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +index 5d11e79..04cc53e 100644 +--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c ++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c +@@ -703,4 +703,4 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = { + DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(AMDGPU_GEM_USERPTR, amdgpu_gem_userptr_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + }; +-int amdgpu_max_kms_ioctl = ARRAY_SIZE(amdgpu_ioctls_kms); ++const int amdgpu_max_kms_ioctl = ARRAY_SIZE(amdgpu_ioctls_kms); diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index c6a1b4c..32873f8 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c @@ -42631,6 +42902,27 @@ index 7b69070..d7bd78b 100644 pqn->q); if (retval != 0) return retval; +diff --git a/drivers/gpu/drm/armada/armada_drv.c b/drivers/gpu/drm/armada/armada_drv.c +index 225034b..4bb9696 100644 +--- a/drivers/gpu/drm/armada/armada_drv.c ++++ b/drivers/gpu/drm/armada/armada_drv.c +@@ -324,6 +324,7 @@ static struct drm_driver armada_drm_driver = { + .driver_features = DRIVER_GEM | DRIVER_MODESET | + DRIVER_HAVE_IRQ | DRIVER_PRIME, + .ioctls = armada_ioctls, ++ .num_ioctls = ARRAY_SIZE(armada_ioctls), + .fops = &armada_drm_fops, + }; + +@@ -484,8 +485,6 @@ static int __init armada_drm_init(void) + { + int ret; + +- armada_drm_driver.num_ioctls = ARRAY_SIZE(armada_ioctls); +- + ret = platform_driver_register(&armada_lcd_platform_driver); + if (ret) + return ret; diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 8328e70..fbd9db2 100644 --- a/drivers/gpu/drm/drm_crtc.c @@ -42867,6 +43159,49 @@ index d93e737..edb8a4a 100644 unsigned int nr = DRM_IOCTL_NR(cmd); int retcode = -EINVAL; char stack_kdata[128]; +diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c +index 1b1bd42..0e49027 100644 +--- a/drivers/gpu/drm/drm_pci.c ++++ b/drivers/gpu/drm/drm_pci.c +@@ -305,7 +305,7 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, + /* No locking needed since shadow-attach is single-threaded since it may + * only be called from the per-driver module init hook. */ + if (!drm_core_check_feature(dev, DRIVER_MODESET)) +- list_add_tail(&dev->legacy_dev_list, &driver->legacy_dev_list); ++ pax_list_add_tail(&dev->legacy_dev_list, (struct list_head *)&driver->legacy_dev_list); + + return 0; + +@@ -340,7 +340,7 @@ int drm_pci_init(struct drm_driver *driver, struct pci_driver *pdriver) + return pci_register_driver(pdriver); + + /* If not using KMS, fall back to stealth mode manual scanning. */ +- INIT_LIST_HEAD(&driver->legacy_dev_list); ++ INIT_LIST_HEAD((struct list_head *)&driver->legacy_dev_list); + for (i = 0; pdriver->id_table[i].vendor != 0; i++) { + pid = &pdriver->id_table[i]; + +@@ -446,7 +446,7 @@ void drm_pci_exit(struct drm_driver *driver, struct pci_driver *pdriver) + } else { + list_for_each_entry_safe(dev, tmp, &driver->legacy_dev_list, + legacy_dev_list) { +- list_del(&dev->legacy_dev_list); ++ pax_list_del(&dev->legacy_dev_list); + drm_put_dev(dev); + } + } +diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c +index ae9e6b2..80b2703 100644 +--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c ++++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c +@@ -614,7 +614,6 @@ static int exynos_drm_platform_probe(struct platform_device *pdev) + struct component_match *match; + + pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32); +- exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls); + + match = exynos_drm_match_add(&pdev->dev); + if (IS_ERR(match)) diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c b/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c index d4813e0..6c1ab4d 100644 --- a/drivers/gpu/drm/gma500/mdfld_dsi_dpi.c @@ -42890,8 +43225,54 @@ index d4813e0..6c1ab4d 100644 if (pipe) { pipeconf_reg = PIPECCONF; dspcntr_reg = DSPCCNTR; +diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c +index 92e7e57..f59f5d3 100644 +--- a/drivers/gpu/drm/gma500/psb_drv.c ++++ b/drivers/gpu/drm/gma500/psb_drv.c +@@ -376,7 +376,10 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags) + + dev->vblank_disable_allowed = true; + dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ +- dev->driver->get_vblank_counter = psb_get_vblank_counter; ++ ++ pax_open_kernel(); ++ *(void **)&dev->driver->get_vblank_counter = psb_get_vblank_counter; ++ pax_close_kernel(); + + psb_modeset_init(dev); + psb_fbdev_init(dev); +diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c +index d918567..6cfd904 100644 +--- a/drivers/gpu/drm/i810/i810_dma.c ++++ b/drivers/gpu/drm/i810/i810_dma.c +@@ -1250,7 +1250,7 @@ const struct drm_ioctl_desc i810_ioctls[] = { + DRM_IOCTL_DEF_DRV(I810_FLIP, i810_flip_bufs, DRM_AUTH|DRM_UNLOCKED), + }; + +-int i810_max_ioctl = ARRAY_SIZE(i810_ioctls); ++const int i810_max_ioctl = ARRAY_SIZE(i810_ioctls); + + /** + * Determine if the device really is AGP or not. +diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c +index 44f4a13..0063c1b 100644 +--- a/drivers/gpu/drm/i810/i810_drv.c ++++ b/drivers/gpu/drm/i810/i810_drv.c +@@ -87,7 +87,11 @@ static int __init i810_init(void) + pr_err("drm/i810 does not support SMP\n"); + return -EINVAL; + } +- driver.num_ioctls = i810_max_ioctl; ++ ++ pax_open_kernel(); ++ *(int *)&driver.num_ioctls = i810_max_ioctl; ++ pax_close_kernel(); ++ + return drm_pci_init(&driver, &i810_pci_driver); + } + diff --git a/drivers/gpu/drm/i810/i810_drv.h b/drivers/gpu/drm/i810/i810_drv.h -index 93ec5dc..82acbaf 100644 +index 93ec5dc..204ec92 100644 --- a/drivers/gpu/drm/i810/i810_drv.h +++ b/drivers/gpu/drm/i810/i810_drv.h @@ -110,8 +110,8 @@ typedef struct drm_i810_private { @@ -42905,8 +43286,17 @@ index 93ec5dc..82acbaf 100644 int front_offset; } drm_i810_private_t; +@@ -128,7 +128,7 @@ extern int i810_driver_device_is_agp(struct drm_device *dev); + + extern long i810_ioctl(struct file *file, unsigned int cmd, unsigned long arg); + extern const struct drm_ioctl_desc i810_ioctls[]; +-extern int i810_max_ioctl; ++extern const int i810_max_ioctl; + + #define I810_BASE(reg) ((unsigned long) \ + dev_priv->mmio_map->handle) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c -index ab37d11..df030da 100644 +index ab37d11..5cbacc7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -383,7 +383,7 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) @@ -42918,6 +43308,72 @@ index ab37d11..df030da 100644 } static const struct vga_switcheroo_client_ops i915_switcheroo_ops = { +@@ -1273,4 +1273,4 @@ const struct drm_ioctl_desc i915_ioctls[] = { + DRM_IOCTL_DEF_DRV(I915_GEM_CONTEXT_SETPARAM, i915_gem_context_setparam_ioctl, DRM_UNLOCKED|DRM_RENDER_ALLOW), + }; + +-int i915_max_ioctl = ARRAY_SIZE(i915_ioctls); ++const int i915_max_ioctl = ARRAY_SIZE(i915_ioctls); +diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c +index ab64d68..e6be8e5 100644 +--- a/drivers/gpu/drm/i915/i915_drv.c ++++ b/drivers/gpu/drm/i915/i915_drv.c +@@ -1697,25 +1697,27 @@ static struct pci_driver i915_pci_driver = { + + static int __init i915_init(void) + { +- driver.num_ioctls = i915_max_ioctl; ++ pax_open_kernel(); ++ *(int *)&driver.num_ioctls = i915_max_ioctl; + + /* + * Enable KMS by default, unless explicitly overriden by + * either the i915.modeset prarameter or by the + * vga_text_mode_force boot option. + */ +- driver.driver_features |= DRIVER_MODESET; ++ *(u32 *)&driver.driver_features |= DRIVER_MODESET; + + if (i915.modeset == 0) +- driver.driver_features &= ~DRIVER_MODESET; ++ *(u32 *)&driver.driver_features &= ~DRIVER_MODESET; + + #ifdef CONFIG_VGA_CONSOLE + if (vgacon_text_force() && i915.modeset == -1) +- driver.driver_features &= ~DRIVER_MODESET; ++ *(u32 *)&driver.driver_features &= ~DRIVER_MODESET; + #endif + + if (!(driver.driver_features & DRIVER_MODESET)) { +- driver.get_vblank_timestamp = NULL; ++ *(void **)&driver.get_vblank_timestamp = NULL; ++ pax_close_kernel(); + /* Silently fail loading to not upset userspace. */ + DRM_DEBUG_DRIVER("KMS and UMS disabled.\n"); + return 0; +@@ -1727,7 +1729,8 @@ static int __init i915_init(void) + * a single CRTC will actually work. + */ + if (driver.driver_features & DRIVER_MODESET) +- driver.driver_features |= DRIVER_ATOMIC; ++ *(u32 *)&driver.driver_features |= DRIVER_ATOMIC; ++ pax_close_kernel(); + + return drm_pci_init(&driver, &i915_pci_driver); + } +diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h +index e1db8de..3abe8a4 100644 +--- a/drivers/gpu/drm/i915/i915_drv.h ++++ b/drivers/gpu/drm/i915/i915_drv.h +@@ -2601,7 +2601,7 @@ struct drm_i915_cmd_table { + #include "i915_trace.h" + + extern const struct drm_ioctl_desc i915_ioctls[]; +-extern int i915_max_ioctl; ++extern const int i915_max_ioctl; + + extern int i915_suspend_legacy(struct drm_device *dev, pm_message_t state); + extern int i915_resume_legacy(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index a953d49..bf179e7 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -43044,6 +43500,137 @@ index 97f3a56..32c712e 100644 else ret = drm_ioctl(filp, cmd, arg); +diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c +index 39d73db..b5187a1 100644 +--- a/drivers/gpu/drm/i915/i915_irq.c ++++ b/drivers/gpu/drm/i915/i915_irq.c +@@ -4143,14 +4143,15 @@ void intel_irq_init(struct drm_i915_private *dev_priv) + + pm_qos_add_request(&dev_priv->pm_qos, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); + ++ pax_open_kernel(); + if (IS_GEN2(dev_priv)) { + dev->max_vblank_count = 0; +- dev->driver->get_vblank_counter = i8xx_get_vblank_counter; ++ *(void **)&dev->driver->get_vblank_counter = i8xx_get_vblank_counter; + } else if (IS_G4X(dev_priv) || INTEL_INFO(dev_priv)->gen >= 5) { + dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ +- dev->driver->get_vblank_counter = gm45_get_vblank_counter; ++ *(void **)&dev->driver->get_vblank_counter = gm45_get_vblank_counter; + } else { +- dev->driver->get_vblank_counter = i915_get_vblank_counter; ++ *(void **)&dev->driver->get_vblank_counter = i915_get_vblank_counter; + dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ + } + +@@ -4162,66 +4163,67 @@ void intel_irq_init(struct drm_i915_private *dev_priv) + if (!IS_GEN2(dev_priv)) + dev->vblank_disable_immediate = true; + +- dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; +- dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; ++ *(void **)&dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; ++ *(void **)&dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; + + if (IS_CHERRYVIEW(dev_priv)) { +- dev->driver->irq_handler = cherryview_irq_handler; +- dev->driver->irq_preinstall = cherryview_irq_preinstall; +- dev->driver->irq_postinstall = cherryview_irq_postinstall; +- dev->driver->irq_uninstall = cherryview_irq_uninstall; +- dev->driver->enable_vblank = valleyview_enable_vblank; +- dev->driver->disable_vblank = valleyview_disable_vblank; ++ *(void **)&dev->driver->irq_handler = cherryview_irq_handler; ++ *(void **)&dev->driver->irq_preinstall = cherryview_irq_preinstall; ++ *(void **)&dev->driver->irq_postinstall = cherryview_irq_postinstall; ++ *(void **)&dev->driver->irq_uninstall = cherryview_irq_uninstall; ++ *(void **)&dev->driver->enable_vblank = valleyview_enable_vblank; ++ *(void **)&dev->driver->disable_vblank = valleyview_disable_vblank; + dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; + } else if (IS_VALLEYVIEW(dev_priv)) { +- dev->driver->irq_handler = valleyview_irq_handler; +- dev->driver->irq_preinstall = valleyview_irq_preinstall; +- dev->driver->irq_postinstall = valleyview_irq_postinstall; +- dev->driver->irq_uninstall = valleyview_irq_uninstall; +- dev->driver->enable_vblank = valleyview_enable_vblank; +- dev->driver->disable_vblank = valleyview_disable_vblank; ++ *(void **)&dev->driver->irq_handler = valleyview_irq_handler; ++ *(void **)&dev->driver->irq_preinstall = valleyview_irq_preinstall; ++ *(void **)&dev->driver->irq_postinstall = valleyview_irq_postinstall; ++ *(void **)&dev->driver->irq_uninstall = valleyview_irq_uninstall; ++ *(void **)&dev->driver->enable_vblank = valleyview_enable_vblank; ++ *(void **)&dev->driver->disable_vblank = valleyview_disable_vblank; + dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; + } else if (INTEL_INFO(dev_priv)->gen >= 8) { +- dev->driver->irq_handler = gen8_irq_handler; +- dev->driver->irq_preinstall = gen8_irq_reset; +- dev->driver->irq_postinstall = gen8_irq_postinstall; +- dev->driver->irq_uninstall = gen8_irq_uninstall; +- dev->driver->enable_vblank = gen8_enable_vblank; +- dev->driver->disable_vblank = gen8_disable_vblank; ++ *(void **)&dev->driver->irq_handler = gen8_irq_handler; ++ *(void **)&dev->driver->irq_preinstall = gen8_irq_reset; ++ *(void **)&dev->driver->irq_postinstall = gen8_irq_postinstall; ++ *(void **)&dev->driver->irq_uninstall = gen8_irq_uninstall; ++ *(void **)&dev->driver->enable_vblank = gen8_enable_vblank; ++ *(void **)&dev->driver->disable_vblank = gen8_disable_vblank; + if (HAS_PCH_SPLIT(dev)) + dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup; + else + dev_priv->display.hpd_irq_setup = bxt_hpd_irq_setup; + } else if (HAS_PCH_SPLIT(dev)) { +- dev->driver->irq_handler = ironlake_irq_handler; +- dev->driver->irq_preinstall = ironlake_irq_reset; +- dev->driver->irq_postinstall = ironlake_irq_postinstall; +- dev->driver->irq_uninstall = ironlake_irq_uninstall; +- dev->driver->enable_vblank = ironlake_enable_vblank; +- dev->driver->disable_vblank = ironlake_disable_vblank; ++ *(void **)&dev->driver->irq_handler = ironlake_irq_handler; ++ *(void **)&dev->driver->irq_preinstall = ironlake_irq_reset; ++ *(void **)&dev->driver->irq_postinstall = ironlake_irq_postinstall; ++ *(void **)&dev->driver->irq_uninstall = ironlake_irq_uninstall; ++ *(void **)&dev->driver->enable_vblank = ironlake_enable_vblank; ++ *(void **)&dev->driver->disable_vblank = ironlake_disable_vblank; + dev_priv->display.hpd_irq_setup = ibx_hpd_irq_setup; + } else { + if (INTEL_INFO(dev_priv)->gen == 2) { +- dev->driver->irq_preinstall = i8xx_irq_preinstall; +- dev->driver->irq_postinstall = i8xx_irq_postinstall; +- dev->driver->irq_handler = i8xx_irq_handler; +- dev->driver->irq_uninstall = i8xx_irq_uninstall; ++ *(void **)&dev->driver->irq_preinstall = i8xx_irq_preinstall; ++ *(void **)&dev->driver->irq_postinstall = i8xx_irq_postinstall; ++ *(void **)&dev->driver->irq_handler = i8xx_irq_handler; ++ *(void **)&dev->driver->irq_uninstall = i8xx_irq_uninstall; + } else if (INTEL_INFO(dev_priv)->gen == 3) { +- dev->driver->irq_preinstall = i915_irq_preinstall; +- dev->driver->irq_postinstall = i915_irq_postinstall; +- dev->driver->irq_uninstall = i915_irq_uninstall; +- dev->driver->irq_handler = i915_irq_handler; ++ *(void **)&dev->driver->irq_preinstall = i915_irq_preinstall; ++ *(void **)&dev->driver->irq_postinstall = i915_irq_postinstall; ++ *(void **)&dev->driver->irq_uninstall = i915_irq_uninstall; ++ *(void **)&dev->driver->irq_handler = i915_irq_handler; + } else { +- dev->driver->irq_preinstall = i965_irq_preinstall; +- dev->driver->irq_postinstall = i965_irq_postinstall; +- dev->driver->irq_uninstall = i965_irq_uninstall; +- dev->driver->irq_handler = i965_irq_handler; ++ *(void **)&dev->driver->irq_preinstall = i965_irq_preinstall; ++ *(void **)&dev->driver->irq_postinstall = i965_irq_postinstall; ++ *(void **)&dev->driver->irq_uninstall = i965_irq_uninstall; ++ *(void **)&dev->driver->irq_handler = i965_irq_handler; + } + if (I915_HAS_HOTPLUG(dev_priv)) + dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; +- dev->driver->enable_vblank = i915_enable_vblank; +- dev->driver->disable_vblank = i915_disable_vblank; ++ *(void **)&dev->driver->enable_vblank = i915_enable_vblank; ++ *(void **)&dev->driver->disable_vblank = i915_disable_vblank; + } ++ pax_close_kernel(); + } + + /** diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b2270d5..e5c48fe 100644 --- a/drivers/gpu/drm/i915/intel_display.c @@ -43108,8 +43695,24 @@ index 74f505b..21f6914 100644 return -EBUSY; imx_drm_crtc = kzalloc(sizeof(*imx_drm_crtc), GFP_KERNEL); +diff --git a/drivers/gpu/drm/mga/mga_drv.c b/drivers/gpu/drm/mga/mga_drv.c +index 5e2f131..d227dbc 100644 +--- a/drivers/gpu/drm/mga/mga_drv.c ++++ b/drivers/gpu/drm/mga/mga_drv.c +@@ -92,7 +92,10 @@ static struct pci_driver mga_pci_driver = { + + static int __init mga_init(void) + { +- driver.num_ioctls = mga_max_ioctl; ++ pax_open_kernel(); ++ *(int *)&driver.num_ioctls = mga_max_ioctl; ++ pax_close_kernel(); ++ + return drm_pci_init(&driver, &mga_pci_driver); + } + diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h -index b4a20149..219ab78 100644 +index b4a20149..caa87d9 100644 --- a/drivers/gpu/drm/mga/mga_drv.h +++ b/drivers/gpu/drm/mga/mga_drv.h @@ -122,9 +122,9 @@ typedef struct drm_mga_private { @@ -43124,6 +43727,15 @@ index b4a20149..219ab78 100644 u32 next_fence_to_post; unsigned int fb_cpp; +@@ -152,7 +152,7 @@ typedef struct drm_mga_private { + } drm_mga_private_t; + + extern const struct drm_ioctl_desc mga_ioctls[]; +-extern int mga_max_ioctl; ++extern const int mga_max_ioctl; + + /* mga_dma.c */ + extern int mga_dma_bootstrap(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/mga/mga_ioc32.c b/drivers/gpu/drm/mga/mga_ioc32.c index 729bfd5..14bae78 100644 --- a/drivers/gpu/drm/mga/mga_ioc32.c @@ -43197,6 +43809,16 @@ index 1b071b8..de8601a 100644 - *sequence) <= (1 << 23))); *sequence = cur_fence; +diff --git a/drivers/gpu/drm/mga/mga_state.c b/drivers/gpu/drm/mga/mga_state.c +index 792f924..aeb1334 100644 +--- a/drivers/gpu/drm/mga/mga_state.c ++++ b/drivers/gpu/drm/mga/mga_state.c +@@ -1099,4 +1099,4 @@ const struct drm_ioctl_desc mga_ioctls[] = { + DRM_IOCTL_DEF_DRV(MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + }; + +-int mga_max_ioctl = ARRAY_SIZE(mga_ioctls); ++const int mga_max_ioctl = ARRAY_SIZE(mga_ioctls); diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 4dca65a..3486961 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -43210,6 +43832,51 @@ index 4dca65a..3486961 100644 #define BIT_TABLE(id, funcid) ((struct bit_table){ id, parse_bit_##funcid##_tbl_entry }) +diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c +index ccefb64..a19593d 100644 +--- a/drivers/gpu/drm/nouveau/nouveau_drm.c ++++ b/drivers/gpu/drm/nouveau/nouveau_drm.c +@@ -76,7 +76,6 @@ MODULE_PARM_DESC(runpm, "disable (0), force enable (1), optimus only default (-1 + int nouveau_runtime_pm = -1; + module_param_named(runpm, nouveau_runtime_pm, int, 0400); + +-static struct drm_driver driver_stub; + static struct drm_driver driver_pci; + static struct drm_driver driver_platform; + +@@ -917,7 +916,7 @@ nouveau_driver_fops = { + }; + + static struct drm_driver +-driver_stub = { ++driver_pci = { + .driver_features = + DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME | DRIVER_RENDER | + DRIVER_KMS_LEGACY_CONTEXT, +@@ -929,6 +928,8 @@ driver_stub = { + .postclose = nouveau_drm_postclose, + .lastclose = nouveau_vga_lastclose, + ++ .set_busid = drm_pci_set_busid, ++ + #if defined(CONFIG_DEBUG_FS) + .debugfs_init = nouveau_debugfs_init, + .debugfs_cleanup = nouveau_debugfs_takedown, +@@ -1065,10 +1066,10 @@ err_free: + static int __init + nouveau_drm_init(void) + { +- driver_pci = driver_stub; +- driver_pci.set_busid = drm_pci_set_busid; +- driver_platform = driver_stub; +- driver_platform.set_busid = drm_platform_set_busid; ++ pax_open_kernel(); ++ memcpy((void *)&driver_platform, &driver_pci, sizeof driver_pci); ++ *(void **)&driver_platform.set_busid = drm_platform_set_busid; ++ pax_close_kernel(); + + nouveau_display_options(); + diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h index 3c902c2..1b2d658 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -43371,6 +44038,32 @@ index 6911b8c..89d6867 100644 seq_printf(m, "%d\n", qdev->irq_received_error); return 0; } +diff --git a/drivers/gpu/drm/qxl/qxl_drv.c b/drivers/gpu/drm/qxl/qxl_drv.c +index 83f6f0b..0d36693 100644 +--- a/drivers/gpu/drm/qxl/qxl_drv.c ++++ b/drivers/gpu/drm/qxl/qxl_drv.c +@@ -37,7 +37,7 @@ + #include "qxl_drv.h" + #include "qxl_object.h" + +-extern int qxl_max_ioctls; ++extern const int qxl_max_ioctls; + static const struct pci_device_id pciidlist[] = { + { 0x1b36, 0x100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA << 8, + 0xffff00, 0 }, +@@ -278,7 +278,11 @@ static int __init qxl_init(void) + + if (qxl_modeset == 0) + return -EINVAL; +- qxl_driver.num_ioctls = qxl_max_ioctls; ++ ++ pax_open_kernel(); ++ *(int *)&qxl_driver.num_ioctls = qxl_max_ioctls; ++ pax_close_kernel(); ++ + return drm_pci_init(&qxl_driver, &qxl_pci_driver); + } + diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 01a8694..584fb48 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h @@ -43391,7 +44084,7 @@ index 01a8694..584fb48 100644 wait_queue_head_t display_event; wait_queue_head_t cursor_event; diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c -index bda5c5f..140ac46 100644 +index bda5c5f..aa09e3e 100644 --- a/drivers/gpu/drm/qxl/qxl_ioctl.c +++ b/drivers/gpu/drm/qxl/qxl_ioctl.c @@ -183,7 +183,7 @@ static int qxl_process_single_command(struct qxl_device *qdev, @@ -43426,6 +44119,12 @@ index bda5c5f..140ac46 100644 sizeof(user_cmd))) return -EFAULT; +@@ -439,4 +439,4 @@ const struct drm_ioctl_desc qxl_ioctls[] = { + DRM_AUTH|DRM_UNLOCKED), + }; + +-int qxl_max_ioctls = ARRAY_SIZE(qxl_ioctls); ++const int qxl_max_ioctls = ARRAY_SIZE(qxl_ioctls); diff --git a/drivers/gpu/drm/qxl/qxl_irq.c b/drivers/gpu/drm/qxl/qxl_irq.c index 0bf1e20..42a7310 100644 --- a/drivers/gpu/drm/qxl/qxl_irq.c @@ -43547,8 +44246,23 @@ index 2c45ac9..5d740f8 100644 /* We don't support anything other than bus-mastering ring mode, * but the ring can be in either AGP or PCI space for the ring +diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c +index c57b4de..2614d79 100644 +--- a/drivers/gpu/drm/r128/r128_drv.c ++++ b/drivers/gpu/drm/r128/r128_drv.c +@@ -94,7 +94,9 @@ static struct pci_driver r128_pci_driver = { + + static int __init r128_init(void) + { +- driver.num_ioctls = r128_max_ioctl; ++ pax_open_kernel(); ++ *(int *)&driver.num_ioctls = r128_max_ioctl; ++ pax_close_kernel(); + + return drm_pci_init(&driver, &r128_pci_driver); + } diff --git a/drivers/gpu/drm/r128/r128_drv.h b/drivers/gpu/drm/r128/r128_drv.h -index 723e5d6..102dbaf 100644 +index 723e5d6..6efb284 100644 --- a/drivers/gpu/drm/r128/r128_drv.h +++ b/drivers/gpu/drm/r128/r128_drv.h @@ -93,14 +93,14 @@ typedef struct drm_r128_private { @@ -43568,6 +44282,15 @@ index 723e5d6..102dbaf 100644 u32 color_fmt; unsigned int front_offset; +@@ -135,7 +135,7 @@ typedef struct drm_r128_buf_priv { + } drm_r128_buf_priv_t; + + extern const struct drm_ioctl_desc r128_ioctls[]; +-extern int r128_max_ioctl; ++extern const int r128_max_ioctl; + + /* r128_cce.c */ + extern int r128_cce_init(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/gpu/drm/r128/r128_ioc32.c b/drivers/gpu/drm/r128/r128_ioc32.c index 663f38c..ec159a1 100644 --- a/drivers/gpu/drm/r128/r128_ioc32.c @@ -43624,7 +44347,7 @@ index c2ae496..30b5993 100644 return IRQ_HANDLED; } diff --git a/drivers/gpu/drm/r128/r128_state.c b/drivers/gpu/drm/r128/r128_state.c -index 8fd2d9f..18c9660 100644 +index 8fd2d9f..4e99166 100644 --- a/drivers/gpu/drm/r128/r128_state.c +++ b/drivers/gpu/drm/r128/r128_state.c @@ -320,10 +320,10 @@ static void r128_clear_box(drm_r128_private_t *dev_priv, @@ -43640,6 +44363,12 @@ index 8fd2d9f..18c9660 100644 } #endif +@@ -1641,4 +1641,4 @@ const struct drm_ioctl_desc r128_ioctls[] = { + DRM_IOCTL_DEF_DRV(R128_GETPARAM, r128_getparam, DRM_AUTH), + }; + +-int r128_max_ioctl = ARRAY_SIZE(r128_ioctls); ++const int r128_max_ioctl = ARRAY_SIZE(r128_ioctls); diff --git a/drivers/gpu/drm/radeon/mkregtable.c b/drivers/gpu/drm/radeon/mkregtable.c index b928c17..e5d9400 100644 --- a/drivers/gpu/drm/radeon/mkregtable.c @@ -43674,8 +44403,50 @@ index f3f562f..0c099bb 100644 } static const struct vga_switcheroo_client_ops radeon_switcheroo_ops = { +diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c +index 5751446..f39a861 100644 +--- a/drivers/gpu/drm/radeon/radeon_drv.c ++++ b/drivers/gpu/drm/radeon/radeon_drv.c +@@ -130,7 +130,7 @@ extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, + ktime_t *etime); + extern bool radeon_is_px(struct drm_device *dev); + extern const struct drm_ioctl_desc radeon_ioctls_kms[]; +-extern int radeon_max_kms_ioctl; ++extern const int radeon_max_kms_ioctl; + int radeon_mmap(struct file *filp, struct vm_area_struct *vma); + int radeon_mode_dumb_mmap(struct drm_file *filp, + struct drm_device *dev, +@@ -650,8 +650,12 @@ static int __init radeon_init(void) + DRM_INFO("radeon kernel modesetting enabled.\n"); + driver = &kms_driver; + pdriver = &radeon_kms_pci_driver; +- driver->driver_features |= DRIVER_MODESET; +- driver->num_ioctls = radeon_max_kms_ioctl; ++ ++ pax_open_kernel(); ++ *(u32 *)&driver->driver_features |= DRIVER_MODESET; ++ *(int *)&driver->num_ioctls = radeon_max_kms_ioctl; ++ pax_close_kernel(); ++ + radeon_register_atpx_handler(); + + } else { +@@ -659,8 +663,11 @@ static int __init radeon_init(void) + DRM_INFO("radeon userspace modesetting enabled.\n"); + driver = &driver_old; + pdriver = &radeon_pci_driver; +- driver->driver_features &= ~DRIVER_MODESET; +- driver->num_ioctls = radeon_max_ioctl; ++ ++ pax_open_kernel(); ++ *(u32 *)&driver->driver_features &= ~DRIVER_MODESET; ++ *(int *)&driver->num_ioctls = radeon_max_ioctl; ++ pax_close_kernel(); + #else + DRM_ERROR("No UMS support in radeon module!\n"); + return -EINVAL; diff --git a/drivers/gpu/drm/radeon/radeon_drv.h b/drivers/gpu/drm/radeon/radeon_drv.h -index 46bd393..6ae4719 100644 +index 46bd393..8f077b5 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.h +++ b/drivers/gpu/drm/radeon/radeon_drv.h @@ -264,7 +264,7 @@ typedef struct drm_radeon_private { @@ -43687,6 +44458,15 @@ index 46bd393..6ae4719 100644 int vblank_crtc; uint32_t irq_enable_reg; uint32_t r500_disp_irq_reg; +@@ -336,7 +336,7 @@ typedef struct drm_radeon_kcmd_buffer { + + extern int radeon_no_wb; + extern struct drm_ioctl_desc radeon_ioctls[]; +-extern int radeon_max_ioctl; ++extern const int radeon_max_ioctl; + + extern u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv); + extern void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val); diff --git a/drivers/gpu/drm/radeon/radeon_ioc32.c b/drivers/gpu/drm/radeon/radeon_ioc32.c index 0b98ea1..a3c770f 100644 --- a/drivers/gpu/drm/radeon/radeon_ioc32.c @@ -43753,8 +44533,18 @@ index 244b19b..c19226d 100644 init_waitqueue_head(&dev_priv->swi_queue); dev->max_vblank_count = 0x001fffff; +diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c +index 0e932bf..3de01a7 100644 +--- a/drivers/gpu/drm/radeon/radeon_kms.c ++++ b/drivers/gpu/drm/radeon/radeon_kms.c +@@ -932,4 +932,4 @@ const struct drm_ioctl_desc radeon_ioctls_kms[] = { + DRM_IOCTL_DEF_DRV(RADEON_GEM_OP, radeon_gem_op_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + DRM_IOCTL_DEF_DRV(RADEON_GEM_USERPTR, radeon_gem_userptr_ioctl, DRM_AUTH|DRM_UNLOCKED|DRM_RENDER_ALLOW), + }; +-int radeon_max_kms_ioctl = ARRAY_SIZE(radeon_ioctls_kms); ++const int radeon_max_kms_ioctl = ARRAY_SIZE(radeon_ioctls_kms); diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c -index 15aee72..cda326e 100644 +index 15aee72..c6df119 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c @@ -2168,7 +2168,7 @@ static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file * @@ -43775,6 +44565,12 @@ index 15aee72..cda326e 100644 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID); +@@ -3258,4 +3258,4 @@ struct drm_ioctl_desc radeon_ioctls[] = { + DRM_IOCTL_DEF_DRV(RADEON_CS, r600_cs_legacy_ioctl, DRM_AUTH) + }; + +-int radeon_max_ioctl = ARRAY_SIZE(radeon_ioctls); ++const int radeon_max_ioctl = ARRAY_SIZE(radeon_ioctls); diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index 06ac59fe..57e0681 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c @@ -43799,6 +44595,83 @@ index 06ac59fe..57e0681 100644 } vma->vm_ops = &radeon_ttm_vm_ops; return 0; +diff --git a/drivers/gpu/drm/savage/savage_bci.c b/drivers/gpu/drm/savage/savage_bci.c +index d47dff9..0752202 100644 +--- a/drivers/gpu/drm/savage/savage_bci.c ++++ b/drivers/gpu/drm/savage/savage_bci.c +@@ -1080,4 +1080,4 @@ const struct drm_ioctl_desc savage_ioctls[] = { + DRM_IOCTL_DEF_DRV(SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH), + }; + +-int savage_max_ioctl = ARRAY_SIZE(savage_ioctls); ++const int savage_max_ioctl = ARRAY_SIZE(savage_ioctls); +diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c +index 21aed1f..5db7419 100644 +--- a/drivers/gpu/drm/savage/savage_drv.c ++++ b/drivers/gpu/drm/savage/savage_drv.c +@@ -76,7 +76,10 @@ static struct pci_driver savage_pci_driver = { + + static int __init savage_init(void) + { +- driver.num_ioctls = savage_max_ioctl; ++ pax_open_kernel(); ++ *(int *)&driver.num_ioctls = savage_max_ioctl; ++ pax_close_kernel(); ++ + return drm_pci_init(&driver, &savage_pci_driver); + } + +diff --git a/drivers/gpu/drm/savage/savage_drv.h b/drivers/gpu/drm/savage/savage_drv.h +index 37b6995..9b31aaf 100644 +--- a/drivers/gpu/drm/savage/savage_drv.h ++++ b/drivers/gpu/drm/savage/savage_drv.h +@@ -107,7 +107,7 @@ enum savage_family { + }; + + extern const struct drm_ioctl_desc savage_ioctls[]; +-extern int savage_max_ioctl; ++extern const int savage_max_ioctl; + + #define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX)) + +diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c +index 79bce76..4fd9a20 100644 +--- a/drivers/gpu/drm/sis/sis_drv.c ++++ b/drivers/gpu/drm/sis/sis_drv.c +@@ -128,7 +128,10 @@ static struct pci_driver sis_pci_driver = { + + static int __init sis_init(void) + { +- driver.num_ioctls = sis_max_ioctl; ++ pax_open_kernel(); ++ *(int *)&driver.num_ioctls = sis_max_ioctl; ++ pax_close_kernel(); ++ + return drm_pci_init(&driver, &sis_pci_driver); + } + +diff --git a/drivers/gpu/drm/sis/sis_drv.h b/drivers/gpu/drm/sis/sis_drv.h +index 16f972b..4f46125 100644 +--- a/drivers/gpu/drm/sis/sis_drv.h ++++ b/drivers/gpu/drm/sis/sis_drv.h +@@ -73,6 +73,6 @@ extern void sis_reclaim_buffers_locked(struct drm_device *dev, + extern void sis_lastclose(struct drm_device *dev); + + extern const struct drm_ioctl_desc sis_ioctls[]; +-extern int sis_max_ioctl; ++extern const int sis_max_ioctl; + + #endif +diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c +index 93ad8a5..48f0a57 100644 +--- a/drivers/gpu/drm/sis/sis_mm.c ++++ b/drivers/gpu/drm/sis/sis_mm.c +@@ -359,4 +359,4 @@ const struct drm_ioctl_desc sis_ioctls[] = { + DRM_IOCTL_DEF_DRV(SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY), + }; + +-int sis_max_ioctl = ARRAY_SIZE(sis_ioctls); ++const int sis_max_ioctl = ARRAY_SIZE(sis_ioctls); diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index ddefb85..9011500 100644 --- a/drivers/gpu/drm/tegra/dc.c @@ -44080,8 +44953,34 @@ index 62c7b1d..2018818 100644 } pr_warn("released /dev/fb%d user=%d count=%d\n", +diff --git a/drivers/gpu/drm/via/via_dma.c b/drivers/gpu/drm/via/via_dma.c +index d17d8f2..67e8e48b 100644 +--- a/drivers/gpu/drm/via/via_dma.c ++++ b/drivers/gpu/drm/via/via_dma.c +@@ -737,4 +737,4 @@ const struct drm_ioctl_desc via_ioctls[] = { + DRM_IOCTL_DEF_DRV(VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH) + }; + +-int via_max_ioctl = ARRAY_SIZE(via_ioctls); ++const int via_max_ioctl = ARRAY_SIZE(via_ioctls); +diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c +index ed8aa8f..16c84fc 100644 +--- a/drivers/gpu/drm/via/via_drv.c ++++ b/drivers/gpu/drm/via/via_drv.c +@@ -107,7 +107,10 @@ static struct pci_driver via_pci_driver = { + + static int __init via_init(void) + { +- driver.num_ioctls = via_max_ioctl; ++ pax_open_kernel(); ++ *(int *)&driver.num_ioctls = via_max_ioctl; ++ pax_close_kernel(); ++ + via_init_command_verifier(); + return drm_pci_init(&driver, &via_pci_driver); + } diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h -index ef8c500..01030c8 100644 +index ef8c500..e0053ce 100644 --- a/drivers/gpu/drm/via/via_drv.h +++ b/drivers/gpu/drm/via/via_drv.h @@ -53,7 +53,7 @@ typedef struct drm_via_ring_buffer { @@ -44102,6 +45001,15 @@ index ef8c500..01030c8 100644 drm_via_state_t hc_state; char pci_buf[VIA_PCI_BUF_SIZE]; const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE]; +@@ -117,7 +117,7 @@ enum via_family { + #define VIA_WRITE8(reg, val) DRM_WRITE8(VIA_BASE, reg, val) + + extern const struct drm_ioctl_desc via_ioctls[]; +-extern int via_max_ioctl; ++extern const int via_max_ioctl; + + extern int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv); + extern int via_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv); diff --git a/drivers/gpu/drm/via/via_irq.c b/drivers/gpu/drm/via/via_irq.c index 1319433..a993b0c 100644 --- a/drivers/gpu/drm/via/via_irq.c @@ -51351,6 +52259,60 @@ index 445071c..6be9e60 100644 .kind = "geneve", .maxtype = IFLA_GENEVE_MAX, .policy = geneve_policy, +diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c +index 7c4a415..5a1e985 100644 +--- a/drivers/net/hamradio/6pack.c ++++ b/drivers/net/hamradio/6pack.c +@@ -683,14 +683,20 @@ static void sixpack_close(struct tty_struct *tty) + if (!atomic_dec_and_test(&sp->refcnt)) + down(&sp->dead_sem); + +- unregister_netdev(sp->dev); ++ /* We must stop the queue to avoid potentially scribbling ++ * on the free buffers. The sp->dead_sem is not sufficient ++ * to protect us from sp->xbuff access. ++ */ ++ netif_stop_queue(sp->dev); + +- del_timer(&sp->tx_t); +- del_timer(&sp->resync_t); ++ del_timer_sync(&sp->tx_t); ++ del_timer_sync(&sp->resync_t); + + /* Free all 6pack frame buffers. */ + kfree(sp->rbuff); + kfree(sp->xbuff); ++ ++ unregister_netdev(sp->dev); + } + + /* Perform I/O control on an active 6pack channel. */ +diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c +index 216bfd3..85828f1 100644 +--- a/drivers/net/hamradio/mkiss.c ++++ b/drivers/net/hamradio/mkiss.c +@@ -797,14 +797,19 @@ static void mkiss_close(struct tty_struct *tty) + */ + if (!atomic_dec_and_test(&ax->refcnt)) + down(&ax->dead_sem); +- +- unregister_netdev(ax->dev); ++ /* ++ * Halt the transmit queue so that a new transmit cannot scribble ++ * on our buffers ++ */ ++ netif_stop_queue(ax->dev); + + /* Free all AX25 frame buffers. */ + kfree(ax->rbuff); + kfree(ax->xbuff); + + ax->tty = NULL; ++ ++ unregister_netdev(ax->dev); + } + + /* Perform I/O control on an active ax25 channel. */ diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index 5fa98f5..322f0f8 100644 --- a/drivers/net/hyperv/hyperv_net.h @@ -80831,7 +81793,7 @@ index 14db05d..687f6d8 100644 #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */ diff --git a/fs/namei.c b/fs/namei.c -index 33e9495..0c1096b 100644 +index 33e9495..4b9d9fb 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -336,17 +336,32 @@ int generic_permission(struct inode *inode, int mask) @@ -81111,17 +82073,7 @@ index 33e9495..0c1096b 100644 } out_no_open: path->dentry = dentry; -@@ -3066,6 +3187,9 @@ static int do_last(struct nameidata *nd, - if (error) - return error; - -+ if (!gr_acl_handle_hidden_file(dir, nd->path.mnt)) -+ return -ENOENT; -+ - audit_inode(nd->name, dir, LOOKUP_PARENT); - /* trailing slashes? */ - if (unlikely(nd->last.name[nd->last.len])) -@@ -3108,11 +3232,24 @@ retry_lookup: +@@ -3108,11 +3229,24 @@ retry_lookup: goto finish_open_created; } @@ -81147,7 +82099,7 @@ index 33e9495..0c1096b 100644 /* * If atomic_open() acquired write access it is dropped now due to -@@ -3148,6 +3285,11 @@ finish_lookup: +@@ -3148,6 +3282,11 @@ finish_lookup: if (unlikely(error)) return error; @@ -81159,7 +82111,7 @@ index 33e9495..0c1096b 100644 if (unlikely(d_is_symlink(path.dentry)) && !(open_flag & O_PATH)) { path_to_nameidata(&path, nd); return -ELOOP; -@@ -3170,6 +3312,12 @@ finish_open: +@@ -3170,6 +3309,12 @@ finish_open: path_put(&save_parent); return error; } @@ -81172,7 +82124,7 @@ index 33e9495..0c1096b 100644 audit_inode(nd->name, nd->path.dentry, 0); error = -EISDIR; if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry)) -@@ -3436,9 +3584,11 @@ static struct dentry *filename_create(int dfd, struct filename *name, +@@ -3436,9 +3581,11 @@ static struct dentry *filename_create(int dfd, struct filename *name, goto unlock; error = -EEXIST; @@ -81186,7 +82138,7 @@ index 33e9495..0c1096b 100644 /* * Special case - lookup gave negative, but... we had foo/bar/ * From the vfs_mknod() POV we just have a negative dentry - -@@ -3492,6 +3642,20 @@ inline struct dentry *user_path_create(int dfd, const char __user *pathname, +@@ -3492,6 +3639,20 @@ inline struct dentry *user_path_create(int dfd, const char __user *pathname, } EXPORT_SYMBOL(user_path_create); @@ -81207,7 +82159,7 @@ index 33e9495..0c1096b 100644 int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) { int error = may_create(dir, dentry); -@@ -3555,6 +3719,17 @@ retry: +@@ -3555,6 +3716,17 @@ retry: if (!IS_POSIXACL(path.dentry->d_inode)) mode &= ~current_umask(); @@ -81225,7 +82177,7 @@ index 33e9495..0c1096b 100644 error = security_path_mknod(&path, dentry, mode, dev); if (error) goto out; -@@ -3570,6 +3745,8 @@ retry: +@@ -3570,6 +3742,8 @@ retry: error = vfs_mknod(path.dentry->d_inode,dentry,mode,0); break; } @@ -81234,7 +82186,7 @@ index 33e9495..0c1096b 100644 out: done_path_create(&path, dentry); if (retry_estale(error, lookup_flags)) { -@@ -3624,9 +3801,16 @@ retry: +@@ -3624,9 +3798,16 @@ retry: if (!IS_POSIXACL(path.dentry->d_inode)) mode &= ~current_umask(); @@ -81251,7 +82203,7 @@ index 33e9495..0c1096b 100644 done_path_create(&path, dentry); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; -@@ -3659,7 +3843,7 @@ void dentry_unhash(struct dentry *dentry) +@@ -3659,7 +3840,7 @@ void dentry_unhash(struct dentry *dentry) { shrink_dcache_parent(dentry); spin_lock(&dentry->d_lock); @@ -81260,7 +82212,7 @@ index 33e9495..0c1096b 100644 __d_drop(dentry); spin_unlock(&dentry->d_lock); } -@@ -3712,6 +3896,8 @@ static long do_rmdir(int dfd, const char __user *pathname) +@@ -3712,6 +3893,8 @@ static long do_rmdir(int dfd, const char __user *pathname) struct path path; struct qstr last; int type; @@ -81269,7 +82221,7 @@ index 33e9495..0c1096b 100644 unsigned int lookup_flags = 0; retry: name = user_path_parent(dfd, pathname, -@@ -3744,10 +3930,20 @@ retry: +@@ -3744,10 +3927,20 @@ retry: error = -ENOENT; goto exit3; } @@ -81290,7 +82242,7 @@ index 33e9495..0c1096b 100644 exit3: dput(dentry); exit2: -@@ -3842,6 +4038,8 @@ static long do_unlinkat(int dfd, const char __user *pathname) +@@ -3842,6 +4035,8 @@ static long do_unlinkat(int dfd, const char __user *pathname) int type; struct inode *inode = NULL; struct inode *delegated_inode = NULL; @@ -81299,7 +82251,7 @@ index 33e9495..0c1096b 100644 unsigned int lookup_flags = 0; retry: name = user_path_parent(dfd, pathname, -@@ -3868,10 +4066,21 @@ retry_deleg: +@@ -3868,10 +4063,21 @@ retry_deleg: if (d_is_negative(dentry)) goto slashes; ihold(inode); @@ -81321,7 +82273,7 @@ index 33e9495..0c1096b 100644 exit2: dput(dentry); } -@@ -3960,9 +4169,17 @@ retry: +@@ -3960,9 +4166,17 @@ retry: if (IS_ERR(dentry)) goto out_putname; @@ -81339,7 +82291,7 @@ index 33e9495..0c1096b 100644 done_path_create(&path, dentry); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; -@@ -4066,6 +4283,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, +@@ -4066,6 +4280,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, struct dentry *new_dentry; struct path old_path, new_path; struct inode *delegated_inode = NULL; @@ -81347,7 +82299,7 @@ index 33e9495..0c1096b 100644 int how = 0; int error; -@@ -4089,7 +4307,7 @@ retry: +@@ -4089,7 +4304,7 @@ retry: if (error) return error; @@ -81356,7 +82308,7 @@ index 33e9495..0c1096b 100644 (how & LOOKUP_REVAL)); error = PTR_ERR(new_dentry); if (IS_ERR(new_dentry)) -@@ -4101,11 +4319,26 @@ retry: +@@ -4101,11 +4316,26 @@ retry: error = may_linkat(&old_path); if (unlikely(error)) goto out_dput; @@ -81383,7 +82335,7 @@ index 33e9495..0c1096b 100644 done_path_create(&new_path, new_dentry); if (delegated_inode) { error = break_deleg_wait(&delegated_inode); -@@ -4420,6 +4653,20 @@ retry_deleg: +@@ -4420,6 +4650,20 @@ retry_deleg: if (new_dentry == trap) goto exit5; @@ -81404,7 +82356,7 @@ index 33e9495..0c1096b 100644 error = security_path_rename(&old_path, old_dentry, &new_path, new_dentry, flags); if (error) -@@ -4427,6 +4674,9 @@ retry_deleg: +@@ -4427,6 +4671,9 @@ retry_deleg: error = vfs_rename(old_path.dentry->d_inode, old_dentry, new_path.dentry->d_inode, new_dentry, &delegated_inode, flags); @@ -81414,7 +82366,7 @@ index 33e9495..0c1096b 100644 exit5: dput(new_dentry); exit4: -@@ -4483,14 +4733,24 @@ EXPORT_SYMBOL(vfs_whiteout); +@@ -4483,14 +4730,24 @@ EXPORT_SYMBOL(vfs_whiteout); int readlink_copy(char __user *buffer, int buflen, const char *link) { @@ -83243,7 +84195,7 @@ index 50493ed..248166b 100644 } fs_initcall(proc_devices_init); diff --git a/fs/proc/fd.c b/fs/proc/fd.c -index 6e5fcd0..06ea074 100644 +index 6e5fcd0..3841f4e 100644 --- a/fs/proc/fd.c +++ b/fs/proc/fd.c @@ -27,7 +27,8 @@ static int seq_show(struct seq_file *m, void *v) @@ -83256,7 +84208,15 @@ index 6e5fcd0..06ea074 100644 put_task_struct(task); if (files) { -@@ -291,11 +292,21 @@ static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry, +@@ -258,6 +259,7 @@ static int proc_readfd_common(struct file *file, struct dir_context *ctx, + name, len, instantiate, p, + (void *)(unsigned long)fd)) + goto out_fd_loop; ++ cond_resched(); + rcu_read_lock(); + } + rcu_read_unlock(); +@@ -291,11 +293,21 @@ static struct dentry *proc_lookupfd(struct inode *dir, struct dentry *dentry, */ int proc_fd_permission(struct inode *inode, int mask) { @@ -95423,10 +96383,10 @@ index 0000000..304c518 +} diff --git a/grsecurity/grsec_sig.c b/grsecurity/grsec_sig.c new file mode 100644 -index 0000000..3860c7e +index 0000000..1e6f893 --- /dev/null +++ b/grsecurity/grsec_sig.c -@@ -0,0 +1,236 @@ +@@ -0,0 +1,243 @@ +#include <linux/kernel.h> +#include <linux/sched.h> +#include <linux/fs.h> @@ -95581,6 +96541,7 @@ index 0000000..3860c7e +void gr_handle_kernel_exploit(void) +{ +#ifdef CONFIG_GRKERNSEC_KERN_LOCKOUT ++ static unsigned int num_banned_users __read_only; + const struct cred *cred; + struct task_struct *tsk, *tsk2; + struct user_struct *user; @@ -95594,6 +96555,12 @@ index 0000000..3860c7e + if (gr_is_global_root(uid)) + panic("grsec: halting the system due to suspicious kernel crash caused by root"); + else { ++ pax_open_kernel(); ++ num_banned_users++; ++ pax_close_kernel(); ++ if (num_banned_users > 8) ++ panic("grsec: halting the system due to suspicious kernel crash caused by a large number of different users"); ++ + /* kill all the processes of this user, hold a reference + to their creds struct, and prevent them from creating + another process until system reset @@ -97263,7 +98230,7 @@ index c9fe145..9fb2337 100644 struct crypto_instance { struct crypto_alg alg; diff --git a/include/drm/drmP.h b/include/drm/drmP.h -index 8b5ce7c..984979b 100644 +index 8b5ce7c..a0ee191 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -59,6 +59,7 @@ @@ -97301,6 +98268,15 @@ index 8b5ce7c..984979b 100644 /** * Creates a driver or general drm_ioctl_desc array entry for the given +@@ -630,7 +633,7 @@ struct drm_driver { + + /* List of devices hanging off this driver with stealth attach. */ + struct list_head legacy_dev_list; +-}; ++} __do_const; + + enum drm_minor_type { + DRM_MINOR_LEGACY, @@ -648,7 +651,8 @@ struct drm_info_list { int (*show)(struct seq_file*, void*); /** show callback */ u32 driver_features; /**< Required driver features for this entry */ @@ -98459,6 +99435,36 @@ index 674e3e2..f68af19 100644 void do_close_on_exec(struct files_struct *); int iterate_fd(struct files_struct *, unsigned, int (*)(const void *, struct file *, unsigned), +diff --git a/include/linux/filter.h b/include/linux/filter.h +index fa2cab9..d42a5b8 100644 +--- a/include/linux/filter.h ++++ b/include/linux/filter.h +@@ -459,6 +459,25 @@ static inline void bpf_jit_free(struct bpf_prog *fp) + + #define BPF_ANC BIT(15) + ++static inline bool bpf_needs_clear_a(const struct sock_filter *first) ++{ ++ switch (first->code) { ++ case BPF_RET | BPF_K: ++ case BPF_LD | BPF_W | BPF_LEN: ++ return false; ++ ++ case BPF_LD | BPF_W | BPF_ABS: ++ case BPF_LD | BPF_H | BPF_ABS: ++ case BPF_LD | BPF_B | BPF_ABS: ++ if (first->k == SKF_AD_OFF + SKF_AD_ALU_XOR_X) ++ return true; ++ return false; ++ ++ default: ++ return true; ++ } ++} ++ + static inline u16 bpf_anc_helper(const struct sock_filter *ftest) + { + BUG_ON(ftest->code & BPF_ANC); diff --git a/include/linux/fs.h b/include/linux/fs.h index 72d8a84..4027250 100644 --- a/include/linux/fs.h @@ -98630,6 +99636,18 @@ index 7ee1774..72505b8 100644 } /* +diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h +index 6cd8c0e..47420d4 100644 +--- a/include/linux/ftrace.h ++++ b/include/linux/ftrace.h +@@ -575,6 +575,7 @@ extern int ftrace_arch_read_dyn_info(char *buf, int size); + + extern int skip_trace(unsigned long ip); + extern void ftrace_module_init(struct module *mod); ++extern void ftrace_release_mod(struct module *mod); + + extern void ftrace_disable_daemon(void); + extern void ftrace_enable_daemon(void); diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 2adbfa6..abfd2e6 100644 --- a/include/linux/genhd.h @@ -102292,7 +103310,7 @@ index 556ec1e..38c19c9 100644 /* diff --git a/include/linux/sched.h b/include/linux/sched.h -index b7b9501..dc6b96f 100644 +index b7b9501..46d7e52 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -7,7 +7,7 @@ @@ -102359,7 +103377,14 @@ index b7b9501..dc6b96f 100644 /* * Bits in flags field of signal_struct. -@@ -836,6 +861,14 @@ struct user_struct { +@@ -830,12 +855,21 @@ struct user_struct { + unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */ + #endif + unsigned long locked_shm; /* How many pages of mlocked shm ? */ ++ unsigned long unix_inflight; /* How many files in flight in unix sockets */ + + #ifdef CONFIG_KEYS + struct key *uid_keyring; /* UID specific keyring */ struct key *session_keyring; /* UID's default session keyring */ #endif @@ -102374,7 +103399,7 @@ index b7b9501..dc6b96f 100644 /* Hash table maintenance information */ struct hlist_node uidhash_node; kuid_t uid; -@@ -843,7 +876,7 @@ struct user_struct { +@@ -843,7 +877,7 @@ struct user_struct { #ifdef CONFIG_PERF_EVENTS atomic_long_t locked_vm; #endif @@ -102383,7 +103408,7 @@ index b7b9501..dc6b96f 100644 extern int uids_sysfs_init(void); -@@ -1378,6 +1411,9 @@ struct tlbflush_unmap_batch { +@@ -1378,6 +1412,9 @@ struct tlbflush_unmap_batch { struct task_struct { volatile long state; /* -1 unrunnable, 0 runnable, >0 stopped */ void *stack; @@ -102393,7 +103418,7 @@ index b7b9501..dc6b96f 100644 atomic_t usage; unsigned int flags; /* per process flags, defined below */ unsigned int ptrace; -@@ -1510,8 +1546,8 @@ struct task_struct { +@@ -1510,8 +1547,8 @@ struct task_struct { struct list_head thread_node; struct completion *vfork_done; /* for vfork() */ @@ -102404,7 +103429,7 @@ index b7b9501..dc6b96f 100644 cputime_t utime, stime, utimescaled, stimescaled; cputime_t gtime; -@@ -1534,11 +1570,6 @@ struct task_struct { +@@ -1534,11 +1571,6 @@ struct task_struct { struct task_cputime cputime_expires; struct list_head cpu_timers[3]; @@ -102416,7 +103441,7 @@ index b7b9501..dc6b96f 100644 char comm[TASK_COMM_LEN]; /* executable name excluding path - access with [gs]et_task_comm (which lock it with task_lock()) -@@ -1554,6 +1585,8 @@ struct task_struct { +@@ -1554,6 +1586,8 @@ struct task_struct { /* hung task detection */ unsigned long last_switch_count; #endif @@ -102425,7 +103450,7 @@ index b7b9501..dc6b96f 100644 /* filesystem information */ struct fs_struct *fs; /* open file information */ -@@ -1630,6 +1663,10 @@ struct task_struct { +@@ -1630,6 +1664,10 @@ struct task_struct { gfp_t lockdep_reclaim_gfp; #endif @@ -102436,7 +103461,7 @@ index b7b9501..dc6b96f 100644 /* journalling filesystem info */ void *journal_info; -@@ -1668,6 +1705,10 @@ struct task_struct { +@@ -1668,6 +1706,10 @@ struct task_struct { /* cg_list protected by css_set_lock and tsk->alloc_lock */ struct list_head cg_list; #endif @@ -102447,7 +103472,7 @@ index b7b9501..dc6b96f 100644 #ifdef CONFIG_FUTEX struct robust_list_head __user *robust_list; #ifdef CONFIG_COMPAT -@@ -1783,7 +1824,7 @@ struct task_struct { +@@ -1783,7 +1825,7 @@ struct task_struct { * Number of functions that haven't been traced * because of depth overrun. */ @@ -102456,7 +103481,7 @@ index b7b9501..dc6b96f 100644 /* Pause for the tracing */ atomic_t tracing_graph_pause; #endif -@@ -1812,22 +1853,89 @@ struct task_struct { +@@ -1812,22 +1854,89 @@ struct task_struct { unsigned long task_state_change; #endif int pagefault_disabled; @@ -102556,7 +103581,7 @@ index b7b9501..dc6b96f 100644 /* Future-safe accessor for struct task_struct's cpus_allowed. */ #define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed) -@@ -1909,7 +2017,7 @@ struct pid_namespace; +@@ -1909,7 +2018,7 @@ struct pid_namespace; pid_t __task_pid_nr_ns(struct task_struct *task, enum pid_type type, struct pid_namespace *ns); @@ -102565,7 +103590,7 @@ index b7b9501..dc6b96f 100644 { return tsk->pid; } -@@ -2270,6 +2378,25 @@ extern u64 sched_clock_cpu(int cpu); +@@ -2270,6 +2379,25 @@ extern u64 sched_clock_cpu(int cpu); extern void sched_clock_init(void); @@ -102591,7 +103616,7 @@ index b7b9501..dc6b96f 100644 #ifndef CONFIG_HAVE_UNSTABLE_SCHED_CLOCK static inline void sched_clock_tick(void) { -@@ -2398,7 +2525,9 @@ extern void set_curr_task(int cpu, struct task_struct *p); +@@ -2398,7 +2526,9 @@ extern void set_curr_task(int cpu, struct task_struct *p); void yield(void); union thread_union { @@ -102601,7 +103626,7 @@ index b7b9501..dc6b96f 100644 unsigned long stack[THREAD_SIZE/sizeof(long)]; }; -@@ -2431,6 +2560,7 @@ extern struct pid_namespace init_pid_ns; +@@ -2431,6 +2561,7 @@ extern struct pid_namespace init_pid_ns; */ extern struct task_struct *find_task_by_vpid(pid_t nr); @@ -102609,7 +103634,7 @@ index b7b9501..dc6b96f 100644 extern struct task_struct *find_task_by_pid_ns(pid_t nr, struct pid_namespace *ns); -@@ -2462,7 +2592,7 @@ extern void proc_caches_init(void); +@@ -2462,7 +2593,7 @@ extern void proc_caches_init(void); extern void flush_signals(struct task_struct *); extern void ignore_signals(struct task_struct *); extern void flush_signal_handlers(struct task_struct *, int force_default); @@ -102618,7 +103643,7 @@ index b7b9501..dc6b96f 100644 static inline int dequeue_signal_lock(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) { -@@ -2608,7 +2738,7 @@ extern void __cleanup_sighand(struct sighand_struct *); +@@ -2608,7 +2739,7 @@ extern void __cleanup_sighand(struct sighand_struct *); extern void exit_itimers(struct signal_struct *); extern void flush_itimer_signals(void); @@ -102627,7 +103652,7 @@ index b7b9501..dc6b96f 100644 extern int do_execve(struct filename *, const char __user * const __user *, -@@ -2723,11 +2853,13 @@ static inline int thread_group_empty(struct task_struct *p) +@@ -2723,11 +2854,13 @@ static inline int thread_group_empty(struct task_struct *p) * It must not be nested with write_lock_irq(&tasklist_lock), * neither inside nor outside. */ @@ -102641,7 +103666,7 @@ index b7b9501..dc6b96f 100644 static inline void task_unlock(struct task_struct *p) { spin_unlock(&p->alloc_lock); -@@ -2813,9 +2945,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p) +@@ -2813,9 +2946,9 @@ static inline unsigned long *end_of_stack(struct task_struct *p) #define task_stack_end_corrupted(task) \ (*(end_of_stack(task)) != STACK_END_MAGIC) @@ -106457,6 +107482,27 @@ index 35bac8e..8de1d69 100644 if (!access_ok(VERIFY_READ, uattr, 1)) return -EFAULT; +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index b074b23..36c6efe 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -1058,6 +1058,16 @@ static int check_alu_op(struct reg_state *regs, struct bpf_insn *insn) + return -EINVAL; + } + ++ if ((opcode == BPF_LSH || opcode == BPF_RSH || ++ opcode == BPF_ARSH) && BPF_SRC(insn->code) == BPF_K) { ++ int size = BPF_CLASS(insn->code) == BPF_ALU64 ? 64 : 32; ++ ++ if (insn->imm < 0 || insn->imm >= size) { ++ verbose("invalid shift %d\n", insn->imm); ++ return -EINVAL; ++ } ++ } ++ + /* pattern match 'bpf_add Rx, imm' instruction */ + if (opcode == BPF_ADD && BPF_CLASS(insn->code) == BPF_ALU64 && + regs[insn->dst_reg].type == FRAME_PTR && diff --git a/kernel/capability.c b/kernel/capability.c index 45432b5..988f1e4 100644 --- a/kernel/capability.c @@ -108612,7 +109658,7 @@ index 4cccea6..4382db9 100644 debug_mutex_free_waiter(&waiter); mutex_release(&lock->dep_map, 1, ip); diff --git a/kernel/module.c b/kernel/module.c -index 8f051a1..07da01a 100644 +index 8f051a1..e1be102 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -59,6 +59,7 @@ @@ -109532,9 +110578,16 @@ index 8f051a1..07da01a 100644 free_unload: module_unload_free(mod); unlink_mod: -@@ -3572,7 +3757,8 @@ static int load_module(struct load_info *info, const char __user *uargs, +@@ -3571,8 +3756,15 @@ static int load_module(struct load_info *info, const char __user *uargs, + synchronize_sched(); mutex_unlock(&module_mutex); free_module: ++ /* ++ * Ftrace needs to clean up what it initialized. ++ * This does nothing if ftrace_module_init() wasn't called, ++ * but it must be called outside of module_mutex. ++ */ ++ ftrace_release_mod(mod); /* Free lock-classes; relies on the preceding sync_rcu() */ - lockdep_free_key_range(mod->module_core, mod->core_size); + lockdep_free_key_range(mod->module_core_rx, mod->core_size_rx); @@ -109542,7 +110595,7 @@ index 8f051a1..07da01a 100644 module_deallocate(mod, info); free_copy: -@@ -3649,10 +3835,16 @@ static const char *get_ksymbol(struct module *mod, +@@ -3649,10 +3841,16 @@ static const char *get_ksymbol(struct module *mod, unsigned long nextval; /* At worse, next value is at end of module */ @@ -109562,7 +110615,7 @@ index 8f051a1..07da01a 100644 /* Scan for closest preceding symbol, and next symbol. (ELF starts real symbols at 1). */ -@@ -3899,7 +4091,7 @@ static int m_show(struct seq_file *m, void *p) +@@ -3899,7 +4097,7 @@ static int m_show(struct seq_file *m, void *p) return 0; seq_printf(m, "%s %u", @@ -109571,7 +110624,7 @@ index 8f051a1..07da01a 100644 print_unload_info(m, mod); /* Informative for users. */ -@@ -3908,7 +4100,7 @@ static int m_show(struct seq_file *m, void *p) +@@ -3908,7 +4106,7 @@ static int m_show(struct seq_file *m, void *p) mod->state == MODULE_STATE_COMING ? "Loading" : "Live"); /* Used by oprofile and other similar tools. */ @@ -109580,7 +110633,7 @@ index 8f051a1..07da01a 100644 /* Taints info */ if (mod->taints) -@@ -3944,7 +4136,17 @@ static const struct file_operations proc_modules_operations = { +@@ -3944,7 +4142,17 @@ static const struct file_operations proc_modules_operations = { static int __init proc_modules_init(void) { @@ -109598,7 +110651,7 @@ index 8f051a1..07da01a 100644 return 0; } module_init(proc_modules_init); -@@ -4005,7 +4207,8 @@ struct module *__module_address(unsigned long addr) +@@ -4005,7 +4213,8 @@ struct module *__module_address(unsigned long addr) { struct module *mod; @@ -109608,7 +110661,7 @@ index 8f051a1..07da01a 100644 return NULL; module_assert_mutex_or_preempt(); -@@ -4048,11 +4251,20 @@ bool is_module_text_address(unsigned long addr) +@@ -4048,11 +4257,20 @@ bool is_module_text_address(unsigned long addr) */ struct module *__module_text_address(unsigned long addr) { @@ -117431,7 +118484,7 @@ index 48ce829..4c30cd3 100644 return -ENOMEM; diff --git a/mm/slab.c b/mm/slab.c -index 4fcc5dd..09e0eee 100644 +index 4fcc5dd..8fb1a86 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -116,6 +116,7 @@ @@ -117486,6 +118539,15 @@ index 4fcc5dd..09e0eee 100644 slab_state = PARTIAL_NODE; setup_kmalloc_cache_index_table(); +@@ -1691,7 +1696,7 @@ static void store_stackinfo(struct kmem_cache *cachep, unsigned long *addr, + + while (!kstack_end(sptr)) { + svalue = *sptr++; +- if (kernel_text_address(svalue)) { ++ if (kernel_text_address(ktva_ktla(svalue))) { + *addr++ = svalue; + size -= sizeof(unsigned long); + if (size <= sizeof(unsigned long)) @@ -2074,7 +2079,7 @@ __kmem_cache_alias(const char *name, size_t size, size_t align, cachep = find_mergeable(size, align, flags, name, ctor); @@ -120234,8 +121296,27 @@ index b94b1d2..da3ed7c 100644 } EXPORT_SYMBOL(dev_load); +diff --git a/net/core/dst.c b/net/core/dst.c +index d6a5a0b..8852021 100644 +--- a/net/core/dst.c ++++ b/net/core/dst.c +@@ -301,12 +301,13 @@ void dst_release(struct dst_entry *dst) + { + if (dst) { + int newrefcnt; ++ unsigned short nocache = dst->flags & DST_NOCACHE; + + newrefcnt = atomic_dec_return(&dst->__refcnt); + if (unlikely(newrefcnt < 0)) + net_warn_ratelimited("%s: dst:%p refcnt:%d\n", + __func__, dst, newrefcnt); +- if (!newrefcnt && unlikely(dst->flags & DST_NOCACHE)) ++ if (!newrefcnt && unlikely(nocache)) + call_rcu(&dst->rcu_head, dst_destroy_rcu); + } + } diff --git a/net/core/filter.c b/net/core/filter.c -index bb18c36..90998d5 100644 +index bb18c36..a0c92a7 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -584,7 +584,11 @@ do_pass: @@ -120260,7 +121341,19 @@ index bb18c36..90998d5 100644 masks = kmalloc_array(flen, sizeof(*masks), GFP_KERNEL); if (!masks) -@@ -1057,7 +1061,7 @@ int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog) +@@ -781,6 +785,11 @@ static int bpf_check_classic(const struct sock_filter *filter, + if (ftest->k == 0) + return -EINVAL; + break; ++ case BPF_ALU | BPF_LSH | BPF_K: ++ case BPF_ALU | BPF_RSH | BPF_K: ++ if (ftest->k >= 32) ++ return -EINVAL; ++ break; + case BPF_LD | BPF_MEM: + case BPF_LDX | BPF_MEM: + case BPF_ST: +@@ -1057,7 +1066,7 @@ int bpf_prog_create(struct bpf_prog **pfp, struct sock_fprog_kern *fprog) if (!fp) return -ENOMEM; @@ -124776,7 +125869,7 @@ index 7ec667d..b5c2cf2 100644 sch->handle = handle; diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c -index e82a1ad..7def03d 100644 +index e82a1ad..a7df216b 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -349,7 +349,7 @@ void netif_carrier_on(struct net_device *dev) @@ -124797,6 +125890,18 @@ index e82a1ad..7def03d 100644 linkwatch_fire_event(dev); } } +@@ -658,8 +658,10 @@ static void qdisc_rcu_free(struct rcu_head *head) + { + struct Qdisc *qdisc = container_of(head, struct Qdisc, rcu_head); + +- if (qdisc_is_percpu_stats(qdisc)) ++ if (qdisc_is_percpu_stats(qdisc)) { + free_percpu(qdisc->cpu_bstats); ++ free_percpu(qdisc->cpu_qstats); ++ } + + kfree((char *) qdisc - qdisc->padded); + } diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index e917d27..13e2a4c 100644 --- a/net/sctp/ipv6.c @@ -124872,9 +125977,18 @@ index 3d9ea9a..d3aee1a 100644 static int sctp_v4_protosw_init(void) diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c -index 6098d4c..9d87fbd 100644 +index 6098d4c..9920c54 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c +@@ -63,7 +63,7 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, + static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, + sctp_state_t state, + struct sctp_endpoint *ep, +- struct sctp_association *asoc, ++ struct sctp_association **asoc, + void *event_arg, + sctp_disposition_t status, + sctp_cmd_seq_t *commands, @@ -443,7 +443,7 @@ static void sctp_generate_sack_event(unsigned long data) sctp_generate_timeout_event(asoc, SCTP_EVENT_TIMEOUT_SACK); } @@ -124884,6 +125998,128 @@ index 6098d4c..9d87fbd 100644 NULL, sctp_generate_t1_cookie_event, sctp_generate_t1_init_event, +@@ -1123,7 +1123,7 @@ int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype, + debug_post_sfn(); + + error = sctp_side_effects(event_type, subtype, state, +- ep, asoc, event_arg, status, ++ ep, &asoc, event_arg, status, + &commands, gfp); + debug_post_sfx(); + +@@ -1136,7 +1136,7 @@ int sctp_do_sm(struct net *net, sctp_event_t event_type, sctp_subtype_t subtype, + static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, + sctp_state_t state, + struct sctp_endpoint *ep, +- struct sctp_association *asoc, ++ struct sctp_association **asoc, + void *event_arg, + sctp_disposition_t status, + sctp_cmd_seq_t *commands, +@@ -1151,7 +1151,7 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, + * disposition SCTP_DISPOSITION_CONSUME. + */ + if (0 != (error = sctp_cmd_interpreter(event_type, subtype, state, +- ep, asoc, ++ ep, *asoc, + event_arg, status, + commands, gfp))) + goto bail; +@@ -1174,11 +1174,12 @@ static int sctp_side_effects(sctp_event_t event_type, sctp_subtype_t subtype, + break; + + case SCTP_DISPOSITION_DELETE_TCB: ++ case SCTP_DISPOSITION_ABORT: + /* This should now be a command. */ ++ *asoc = NULL; + break; + + case SCTP_DISPOSITION_CONSUME: +- case SCTP_DISPOSITION_ABORT: + /* + * We should no longer have much work to do here as the + * real work has been done as explicit commands above. +diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c +index d7eaa73..9042a5d 100644 +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -2976,7 +2976,7 @@ sctp_disposition_t sctp_sf_eat_data_6_2(struct net *net, + SCTP_INC_STATS(net, SCTP_MIB_IN_DATA_CHUNK_DISCARDS); + goto discard_force; + case SCTP_IERROR_NO_DATA: +- goto consume; ++ return SCTP_DISPOSITION_ABORT; + case SCTP_IERROR_PROTO_VIOLATION: + return sctp_sf_abort_violation(net, ep, asoc, chunk, commands, + (u8 *)chunk->subh.data_hdr, sizeof(sctp_datahdr_t)); +@@ -3043,9 +3043,6 @@ discard_noforce: + sctp_add_cmd_sf(commands, SCTP_CMD_GEN_SACK, force); + + return SCTP_DISPOSITION_DISCARD; +-consume: +- return SCTP_DISPOSITION_CONSUME; +- + } + + /* +@@ -3093,7 +3090,7 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(struct net *net, + case SCTP_IERROR_BAD_STREAM: + break; + case SCTP_IERROR_NO_DATA: +- goto consume; ++ return SCTP_DISPOSITION_ABORT; + case SCTP_IERROR_PROTO_VIOLATION: + return sctp_sf_abort_violation(net, ep, asoc, chunk, commands, + (u8 *)chunk->subh.data_hdr, sizeof(sctp_datahdr_t)); +@@ -3119,7 +3116,6 @@ sctp_disposition_t sctp_sf_eat_data_fast_4_4(struct net *net, + SCTP_TO(SCTP_EVENT_TIMEOUT_T2_SHUTDOWN)); + } + +-consume: + return SCTP_DISPOSITION_CONSUME; + } + +@@ -4825,9 +4821,6 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort( + * if necessary to fill gaps. + */ + struct sctp_chunk *abort = arg; +- sctp_disposition_t retval; +- +- retval = SCTP_DISPOSITION_CONSUME; + + sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); + +@@ -4844,7 +4837,7 @@ sctp_disposition_t sctp_sf_do_9_1_prm_abort( + SCTP_INC_STATS(net, SCTP_MIB_ABORTEDS); + SCTP_DEC_STATS(net, SCTP_MIB_CURRESTAB); + +- return retval; ++ return SCTP_DISPOSITION_ABORT; + } + + /* We tried an illegal operation on an association which is closed. */ +@@ -4959,12 +4952,10 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort( + sctp_cmd_seq_t *commands) + { + struct sctp_chunk *abort = arg; +- sctp_disposition_t retval; + + /* Stop T1-init timer */ + sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_STOP, + SCTP_TO(SCTP_EVENT_TIMEOUT_T1_INIT)); +- retval = SCTP_DISPOSITION_CONSUME; + + sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort)); + +@@ -4983,7 +4974,7 @@ sctp_disposition_t sctp_sf_cookie_wait_prm_abort( + sctp_add_cmd_sf(commands, SCTP_CMD_INIT_FAILED, + SCTP_PERR(SCTP_ERROR_USER_ABORT)); + +- return retval; ++ return SCTP_DISPOSITION_ABORT; + } + + /* diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 3ec88be..a8d9d222 100644 --- a/net/sctp/socket.c @@ -125016,10 +126252,10 @@ index 3ec88be..a8d9d222 100644 return -ENOMEM; diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c -index 26d50c5..dfae665 100644 +index 26d50c5..289fe22 100644 --- a/net/sctp/sysctl.c +++ b/net/sctp/sysctl.c -@@ -317,7 +317,7 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, +@@ -317,10 +317,10 @@ static int proc_sctp_do_hmac_alg(struct ctl_table *ctl, int write, loff_t *ppos) { struct net *net = current->nsproxy->net_ns; @@ -125027,7 +126263,11 @@ index 26d50c5..dfae665 100644 + ctl_table_no_const tbl; bool changed = false; char *none = "none"; - char tmp[8]; +- char tmp[8]; ++ char tmp[8] = {0}; + int ret; + + memset(&tbl, 0, sizeof(struct ctl_table)); @@ -365,7 +365,7 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write, struct net *net = current->nsproxy->net_ns; unsigned int min = *(unsigned int *) ctl->extra1; @@ -125468,7 +126708,7 @@ index 621ca7b..78bf76b 100644 static int unix_gid_parse(struct cache_detail *cd, char *mesg, int mlen) diff --git a/net/sunrpc/xprtrdma/svc_rdma.c b/net/sunrpc/xprtrdma/svc_rdma.c -index 2cd252f..eefac51 100644 +index 2cd252f..94dc8cb 100644 --- a/net/sunrpc/xprtrdma/svc_rdma.c +++ b/net/sunrpc/xprtrdma/svc_rdma.c @@ -61,15 +61,15 @@ unsigned int svcrdma_max_req_size = RPCRDMA_MAX_REQ_SIZE; @@ -125496,6 +126736,27 @@ index 2cd252f..eefac51 100644 /* Temporary NFS request map and context caches */ struct kmem_cache *svc_rdma_map_cachep; +@@ -87,17 +87,17 @@ static int read_reset_stat(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, + loff_t *ppos) + { +- atomic_t *stat = (atomic_t *)table->data; ++ atomic_unchecked_t *stat = (atomic_unchecked_t *)table->data; + + if (!stat) + return -EINVAL; + + if (write) +- atomic_set(stat, 0); ++ atomic_set_unchecked(stat, 0); + else { + char str_buf[32]; + char *data; +- int len = snprintf(str_buf, 32, "%d\n", atomic_read(stat)); ++ int len = snprintf(str_buf, 32, "%d\n", atomic_read_unchecked(stat)); + if (len >= 32) + return -EFAULT; + len = strlen(str_buf); @@ -109,7 +109,7 @@ static int read_reset_stat(struct ctl_table *table, int write, len -= *ppos; if (len > *lenp) @@ -125749,7 +127010,7 @@ index 350cca3..a108fc5 100644 sub->evt.event = htohl(event, sub->swap); sub->evt.found_lower = htohl(found_lower, sub->swap); diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c -index 128b098..38013fc 100644 +index 128b098..b66988b 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -918,6 +918,12 @@ static struct sock *unix_find_other(struct net *net, @@ -125913,7 +127174,52 @@ index 128b098..38013fc 100644 out: return err; } -@@ -2772,9 +2805,13 @@ static int unix_seq_show(struct seq_file *seq, void *v) +@@ -1498,6 +1531,21 @@ static void unix_destruct_scm(struct sk_buff *skb) + sock_wfree(skb); + } + ++/* ++ * The "user->unix_inflight" variable is protected by the garbage ++ * collection lock, and we just read it locklessly here. If you go ++ * over the limit, there might be a tiny race in actually noticing ++ * it across threads. Tough. ++ */ ++static inline bool too_many_unix_fds(struct task_struct *p) ++{ ++ struct user_struct *user = current_user(); ++ ++ if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE))) ++ return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN); ++ return false; ++} ++ + #define MAX_RECURSION_LEVEL 4 + + static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) +@@ -1506,6 +1554,9 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) + unsigned char max_level = 0; + int unix_sock_count = 0; + ++ if (too_many_unix_fds(current)) ++ return -ETOOMANYREFS; ++ + for (i = scm->fp->count - 1; i >= 0; i--) { + struct sock *sk = unix_get_socket(scm->fp->fp[i]); + +@@ -1527,10 +1578,8 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb) + if (!UNIXCB(skb).fp) + return -ENOMEM; + +- if (unix_sock_count) { +- for (i = scm->fp->count - 1; i >= 0; i--) +- unix_inflight(scm->fp->fp[i]); +- } ++ for (i = scm->fp->count - 1; i >= 0; i--) ++ unix_inflight(scm->fp->fp[i]); + return max_level; + } + +@@ -2772,9 +2821,13 @@ static int unix_seq_show(struct seq_file *seq, void *v) seq_puts(seq, "Num RefCount Protocol Flags Type St " "Inode Path\n"); else { @@ -125928,7 +127234,7 @@ index 128b098..38013fc 100644 seq_printf(seq, "%pK: %08X %08X %08X %04X %02X %5lu", s, -@@ -2799,10 +2836,29 @@ static int unix_seq_show(struct seq_file *seq, void *v) +@@ -2799,10 +2852,29 @@ static int unix_seq_show(struct seq_file *seq, void *v) seq_putc(seq, '@'); i++; } @@ -125962,6 +127268,56 @@ index 128b098..38013fc 100644 seq_putc(seq, '\n'); } +diff --git a/net/unix/garbage.c b/net/unix/garbage.c +index a73a226..8fcdc22 100644 +--- a/net/unix/garbage.c ++++ b/net/unix/garbage.c +@@ -120,11 +120,11 @@ void unix_inflight(struct file *fp) + { + struct sock *s = unix_get_socket(fp); + ++ spin_lock(&unix_gc_lock); ++ + if (s) { + struct unix_sock *u = unix_sk(s); + +- spin_lock(&unix_gc_lock); +- + if (atomic_long_inc_return(&u->inflight) == 1) { + BUG_ON(!list_empty(&u->link)); + list_add_tail(&u->link, &gc_inflight_list); +@@ -132,25 +132,28 @@ void unix_inflight(struct file *fp) + BUG_ON(list_empty(&u->link)); + } + unix_tot_inflight++; +- spin_unlock(&unix_gc_lock); + } ++ fp->f_cred->user->unix_inflight++; ++ spin_unlock(&unix_gc_lock); + } + + void unix_notinflight(struct file *fp) + { + struct sock *s = unix_get_socket(fp); + ++ spin_lock(&unix_gc_lock); ++ + if (s) { + struct unix_sock *u = unix_sk(s); + +- spin_lock(&unix_gc_lock); + BUG_ON(list_empty(&u->link)); + + if (atomic_long_dec_and_test(&u->inflight)) + list_del_init(&u->link); + unix_tot_inflight--; +- spin_unlock(&unix_gc_lock); + } ++ fp->f_cred->user->unix_inflight--; ++ spin_unlock(&unix_gc_lock); + } + + static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *), diff --git a/net/unix/sysctl_net_unix.c b/net/unix/sysctl_net_unix.c index b3d5150..ff3a837 100644 --- a/net/unix/sysctl_net_unix.c @@ -131812,12 +133168,12 @@ index 0000000..7514850 +fi diff --git a/tools/gcc/initify_plugin.c b/tools/gcc/initify_plugin.c new file mode 100644 -index 0000000..a518073 +index 0000000..9431b53 --- /dev/null +++ b/tools/gcc/initify_plugin.c -@@ -0,0 +1,581 @@ +@@ -0,0 +1,588 @@ +/* -+ * Copyright 2011-2016 by Emese Revfy <re.emese@gmail.com> ++ * Copyright 2015-2016 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 + * + * Homepage: @@ -131836,7 +133192,7 @@ index 0000000..a518073 +int plugin_is_GPL_compatible; + +static struct plugin_info initify_plugin_info = { -+ .version = "20160104", ++ .version = "20160113", + .help = "initify_plugin\n", +}; + @@ -132022,11 +133378,18 @@ index 0000000..a518073 + +static bool is_same_vardecl(const_tree op, const_tree vardecl) +{ ++ const_tree decl; ++ + if (op == vardecl) + return true; -+ if (!DECL_P(op)) ++ if (TREE_CODE(op) == SSA_NAME) ++ decl = SSA_NAME_VAR(op); ++ else ++ decl = op; ++ if (decl == NULL_TREE || !DECL_P(decl)) + return false; -+ return DECL_NAME(op) && !strcmp(DECL_NAME_POINTER(op), DECL_NAME_POINTER(vardecl)); ++ ++ return DECL_NAME(decl) && !strcmp(DECL_NAME_POINTER(decl), DECL_NAME_POINTER(vardecl)); +} + +static bool search_same_vardecl(const_tree value, const_tree vardecl) @@ -134607,10 +135970,10 @@ index 0000000..f74d85a +targets += size_overflow_hash.h size_overflow_hash_aux.h disable_size_overflow_hash.h diff --git a/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data b/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data new file mode 100644 -index 0000000..5276d6e +index 0000000..e141179 --- /dev/null +++ b/tools/gcc/size_overflow_plugin/disable_size_overflow_hash.data -@@ -0,0 +1,12433 @@ +@@ -0,0 +1,12434 @@ +disable_so_interrupt_pnode_gru_message_queue_desc_4 interrupt_pnode gru_message_queue_desc 0 4 NULL +disable_so_bch_btree_insert_fndecl_12 bch_btree_insert fndecl 0 12 NULL +disable_so_macvlan_sync_address_fndecl_22 macvlan_sync_address fndecl 0 22 NULL nohasharray @@ -147044,6 +148407,7 @@ index 0000000..5276d6e +enable_so_deh_location_reiserfs_de_head_7682 deh_location reiserfs_de_head 0 7682 NULL +enable_so_deh_offset_reiserfs_de_head_42314 deh_offset reiserfs_de_head 0 42314 NULL +enable_so_dsack_tcp_options_received_27706 dsack tcp_options_received 0 27706 NULL ++enable_so_inbufBits_bunzip_data_13788 inbufBits bunzip_data 0 13788 NULL diff --git a/tools/gcc/size_overflow_plugin/generate_size_overflow_hash.sh b/tools/gcc/size_overflow_plugin/generate_size_overflow_hash.sh new file mode 100644 index 0000000..be9724d @@ -149287,10 +150651,10 @@ index 0000000..fc58e16 +} diff --git a/tools/gcc/size_overflow_plugin/size_overflow_hash.data b/tools/gcc/size_overflow_plugin/size_overflow_hash.data new file mode 100644 -index 0000000..3fc86c1 +index 0000000..0a36c4a --- /dev/null +++ b/tools/gcc/size_overflow_plugin/size_overflow_hash.data -@@ -0,0 +1,21744 @@ +@@ -0,0 +1,21743 @@ +enable_so_recv_ctrl_pipe_us_data_0 recv_ctrl_pipe us_data 0 0 NULL +enable_so___earlyonly_bootmem_alloc_fndecl_3 __earlyonly_bootmem_alloc fndecl 2-3-4 3 NULL +enable_so_size_ttm_mem_reg_8 size ttm_mem_reg 0 8 NULL @@ -153871,8 +155235,7 @@ index 0000000..3fc86c1 +enable_so_usbhs_dma_calc_received_size_fndecl_13783 usbhs_dma_calc_received_size fndecl 0-3 13783 NULL +enable_so_build_data_key_fndecl_13784 build_data_key fndecl 2 13784 NULL +enable_so_iwl_trans_read_mem32_fndecl_13786 iwl_trans_read_mem32 fndecl 0 13786 NULL -+enable_so_ept_get_level1_sp_gpa_fndecl_13788 ept_get_level1_sp_gpa fndecl 0 13788 NULL nohasharray -+enable_so_inbufBits_bunzip_data_13788 inbufBits bunzip_data 0 13788 &enable_so_ept_get_level1_sp_gpa_fndecl_13788 ++enable_so_ept_get_level1_sp_gpa_fndecl_13788 ept_get_level1_sp_gpa fndecl 0 13788 NULL +enable_so_smk_write_load_fndecl_13790 smk_write_load fndecl 3 13790 NULL +enable_so_num_channels_xilly_endpoint_13791 num_channels xilly_endpoint 0 13791 NULL +enable_so_tipc_conn_sendmsg_fndecl_13792 tipc_conn_sendmsg fndecl 5 13792 NULL |