diff options
Diffstat (limited to '3.14.48')
-rw-r--r-- | 3.14.48/0000_README | 10 | ||||
-rw-r--r-- | 3.14.48/1046_linux-3.14.47.patch | 1395 | ||||
-rw-r--r-- | 3.14.48/1047_linux-3.14.48.patch | 1019 | ||||
-rw-r--r-- | 3.14.48/4420_grsecurity-3.1-3.14.48-201507251417.patch (renamed from 3.14.48/4420_grsecurity-3.1-3.14.48-201507111210.patch) | 2066 |
4 files changed, 1549 insertions, 2941 deletions
diff --git a/3.14.48/0000_README b/3.14.48/0000_README index 44ff3ab..2207222 100644 --- a/3.14.48/0000_README +++ b/3.14.48/0000_README @@ -2,15 +2,7 @@ README ----------------------------------------------------------------------------- Individual Patch Descriptions: ----------------------------------------------------------------------------- -Patch: 1046_linux-3.14.47.patch -From: http://www.kernel.org -Desc: Linux 3.14.47 - -Patch: 1047_linux-3.14.48.patch -From: http://www.kernel.org -Desc: Linux 3.14.48 - -Patch: 4420_grsecurity-3.1-3.14.48-201507111210.patch +Patch: 4420_grsecurity-3.1-3.14.48-201507251417.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.14.48/1046_linux-3.14.47.patch b/3.14.48/1046_linux-3.14.47.patch deleted file mode 100644 index 4dc0c5a..0000000 --- a/3.14.48/1046_linux-3.14.47.patch +++ /dev/null @@ -1,1395 +0,0 @@ -diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt -index 6cd63a9..bc6d617 100644 ---- a/Documentation/virtual/kvm/api.txt -+++ b/Documentation/virtual/kvm/api.txt -@@ -2344,7 +2344,8 @@ should be created before this ioctl is invoked. - - Possible features: - - KVM_ARM_VCPU_POWER_OFF: Starts the CPU in a power-off state. -- Depends on KVM_CAP_ARM_PSCI. -+ Depends on KVM_CAP_ARM_PSCI. If not set, the CPU will be powered on -+ and execute guest code when KVM_RUN is called. - - KVM_ARM_VCPU_EL1_32BIT: Starts the CPU in a 32bit mode. - Depends on KVM_CAP_ARM_EL1_32BIT (arm64 only). - -diff --git a/Makefile b/Makefile -index def39fd..f9041e6 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 3 - PATCHLEVEL = 14 --SUBLEVEL = 46 -+SUBLEVEL = 47 - EXTRAVERSION = - NAME = Remembering Coco - -diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h -index 0fa90c9..853e2be 100644 ---- a/arch/arm/include/asm/kvm_emulate.h -+++ b/arch/arm/include/asm/kvm_emulate.h -@@ -33,6 +33,11 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu); - void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); - void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); - -+static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) -+{ -+ vcpu->arch.hcr = HCR_GUEST_MASK; -+} -+ - static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu) - { - return 1; -diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h -index 0cbdb8e..9f79231 100644 ---- a/arch/arm/include/asm/kvm_mmu.h -+++ b/arch/arm/include/asm/kvm_mmu.h -@@ -47,6 +47,7 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t); - void free_boot_hyp_pgd(void); - void free_hyp_pgds(void); - -+void stage2_unmap_vm(struct kvm *kvm); - int kvm_alloc_stage2_pgd(struct kvm *kvm); - void kvm_free_stage2_pgd(struct kvm *kvm); - int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, -@@ -78,17 +79,6 @@ static inline void kvm_set_pte(pte_t *pte, pte_t new_pte) - flush_pmd_entry(pte); - } - --static inline bool kvm_is_write_fault(unsigned long hsr) --{ -- unsigned long hsr_ec = hsr >> HSR_EC_SHIFT; -- if (hsr_ec == HSR_EC_IABT) -- return false; -- else if ((hsr & HSR_ISV) && !(hsr & HSR_WNR)) -- return false; -- else -- return true; --} -- - static inline void kvm_clean_pgd(pgd_t *pgd) - { - clean_dcache_area(pgd, PTRS_PER_S2_PGD * sizeof(pgd_t)); -diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c -index df6e75e..2e74a61 100644 ---- a/arch/arm/kvm/arm.c -+++ b/arch/arm/kvm/arm.c -@@ -220,6 +220,11 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id) - int err; - struct kvm_vcpu *vcpu; - -+ if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) { -+ err = -EBUSY; -+ goto out; -+ } -+ - vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); - if (!vcpu) { - err = -ENOMEM; -@@ -427,9 +432,9 @@ static void update_vttbr(struct kvm *kvm) - - /* update vttbr to be used with the new vmid */ - pgd_phys = virt_to_phys(kvm->arch.pgd); -+ BUG_ON(pgd_phys & ~VTTBR_BADDR_MASK); - vmid = ((u64)(kvm->arch.vmid) << VTTBR_VMID_SHIFT) & VTTBR_VMID_MASK; -- kvm->arch.vttbr = pgd_phys & VTTBR_BADDR_MASK; -- kvm->arch.vttbr |= vmid; -+ kvm->arch.vttbr = pgd_phys | vmid; - - spin_unlock(&kvm_vmid_lock); - } -@@ -676,10 +681,21 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu, - return ret; - - /* -+ * Ensure a rebooted VM will fault in RAM pages and detect if the -+ * guest MMU is turned off and flush the caches as needed. -+ */ -+ if (vcpu->arch.has_run_once) -+ stage2_unmap_vm(vcpu->kvm); -+ -+ vcpu_reset_hcr(vcpu); -+ -+ /* - * Handle the "start in power-off" case by marking the VCPU as paused. - */ -- if (__test_and_clear_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) -+ if (test_bit(KVM_ARM_VCPU_POWER_OFF, vcpu->arch.features)) - vcpu->arch.pause = true; -+ else -+ vcpu->arch.pause = false; - - return 0; - } -@@ -825,7 +841,8 @@ static int hyp_init_cpu_notify(struct notifier_block *self, - switch (action) { - case CPU_STARTING: - case CPU_STARTING_FROZEN: -- cpu_init_hyp_mode(NULL); -+ if (__hyp_get_vectors() == hyp_default_vectors) -+ cpu_init_hyp_mode(NULL); - break; - } - -diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c -index b23a59c..2786eae 100644 ---- a/arch/arm/kvm/guest.c -+++ b/arch/arm/kvm/guest.c -@@ -38,7 +38,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { - - int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) - { -- vcpu->arch.hcr = HCR_GUEST_MASK; - return 0; - } - -diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c -index 70ed2c1..524b4b5 100644 ---- a/arch/arm/kvm/mmu.c -+++ b/arch/arm/kvm/mmu.c -@@ -197,7 +197,8 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp, - pgd = pgdp + pgd_index(addr); - do { - next = kvm_pgd_addr_end(addr, end); -- unmap_puds(kvm, pgd, addr, next); -+ if (!pgd_none(*pgd)) -+ unmap_puds(kvm, pgd, addr, next); - } while (pgd++, addr = next, addr != end); - } - -@@ -555,6 +556,71 @@ static void unmap_stage2_range(struct kvm *kvm, phys_addr_t start, u64 size) - unmap_range(kvm, kvm->arch.pgd, start, size); - } - -+static void stage2_unmap_memslot(struct kvm *kvm, -+ struct kvm_memory_slot *memslot) -+{ -+ hva_t hva = memslot->userspace_addr; -+ phys_addr_t addr = memslot->base_gfn << PAGE_SHIFT; -+ phys_addr_t size = PAGE_SIZE * memslot->npages; -+ hva_t reg_end = hva + size; -+ -+ /* -+ * A memory region could potentially cover multiple VMAs, and any holes -+ * between them, so iterate over all of them to find out if we should -+ * unmap any of them. -+ * -+ * +--------------------------------------------+ -+ * +---------------+----------------+ +----------------+ -+ * | : VMA 1 | VMA 2 | | VMA 3 : | -+ * +---------------+----------------+ +----------------+ -+ * | memory region | -+ * +--------------------------------------------+ -+ */ -+ do { -+ struct vm_area_struct *vma = find_vma(current->mm, hva); -+ hva_t vm_start, vm_end; -+ -+ if (!vma || vma->vm_start >= reg_end) -+ break; -+ -+ /* -+ * Take the intersection of this VMA with the memory region -+ */ -+ vm_start = max(hva, vma->vm_start); -+ vm_end = min(reg_end, vma->vm_end); -+ -+ if (!(vma->vm_flags & VM_PFNMAP)) { -+ gpa_t gpa = addr + (vm_start - memslot->userspace_addr); -+ unmap_stage2_range(kvm, gpa, vm_end - vm_start); -+ } -+ hva = vm_end; -+ } while (hva < reg_end); -+} -+ -+/** -+ * stage2_unmap_vm - Unmap Stage-2 RAM mappings -+ * @kvm: The struct kvm pointer -+ * -+ * Go through the memregions and unmap any reguler RAM -+ * backing memory already mapped to the VM. -+ */ -+void stage2_unmap_vm(struct kvm *kvm) -+{ -+ struct kvm_memslots *slots; -+ struct kvm_memory_slot *memslot; -+ int idx; -+ -+ idx = srcu_read_lock(&kvm->srcu); -+ spin_lock(&kvm->mmu_lock); -+ -+ slots = kvm_memslots(kvm); -+ kvm_for_each_memslot(memslot, slots) -+ stage2_unmap_memslot(kvm, memslot); -+ -+ spin_unlock(&kvm->mmu_lock); -+ srcu_read_unlock(&kvm->srcu, idx); -+} -+ - /** - * kvm_free_stage2_pgd - free all stage-2 tables - * @kvm: The KVM struct pointer for the VM. -@@ -746,6 +812,19 @@ static bool transparent_hugepage_adjust(pfn_t *pfnp, phys_addr_t *ipap) - return false; - } - -+static bool kvm_is_write_fault(struct kvm_vcpu *vcpu) -+{ -+ if (kvm_vcpu_trap_is_iabt(vcpu)) -+ return false; -+ -+ return kvm_vcpu_dabt_iswrite(vcpu); -+} -+ -+static bool kvm_is_device_pfn(unsigned long pfn) -+{ -+ return !pfn_valid(pfn); -+} -+ - static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, - struct kvm_memory_slot *memslot, - unsigned long fault_status) -@@ -761,7 +840,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, - pfn_t pfn; - pgprot_t mem_type = PAGE_S2; - -- write_fault = kvm_is_write_fault(kvm_vcpu_get_hsr(vcpu)); -+ write_fault = kvm_is_write_fault(vcpu); - if (fault_status == FSC_PERM && !write_fault) { - kvm_err("Unexpected L2 read permission error\n"); - return -EFAULT; -@@ -770,6 +849,12 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, - /* Let's check if we will get back a huge page backed by hugetlbfs */ - down_read(¤t->mm->mmap_sem); - vma = find_vma_intersection(current->mm, hva, hva + 1); -+ if (unlikely(!vma)) { -+ kvm_err("Failed to find VMA for hva 0x%lx\n", hva); -+ up_read(¤t->mm->mmap_sem); -+ return -EFAULT; -+ } -+ - if (is_vm_hugetlb_page(vma)) { - hugetlb = true; - gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT; -@@ -810,7 +895,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, - if (is_error_pfn(pfn)) - return -EFAULT; - -- if (kvm_is_mmio_pfn(pfn)) -+ if (kvm_is_device_pfn(pfn)) - mem_type = PAGE_S2_DEVICE; - - spin_lock(&kvm->mmu_lock); -@@ -836,7 +921,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, - } - coherent_cache_guest_page(vcpu, hva, PAGE_SIZE); - ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, -- mem_type == PAGE_S2_DEVICE); -+ pgprot_val(mem_type) == pgprot_val(PAGE_S2_DEVICE)); - } - - -@@ -912,6 +997,9 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu, struct kvm_run *run) - - memslot = gfn_to_memslot(vcpu->kvm, gfn); - -+ /* Userspace should not be able to register out-of-bounds IPAs */ -+ VM_BUG_ON(fault_ipa >= KVM_PHYS_SIZE); -+ - ret = user_mem_abort(vcpu, fault_ipa, memslot, fault_status); - if (ret == 0) - ret = 1; -@@ -1136,6 +1224,14 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, - struct kvm_userspace_memory_region *mem, - enum kvm_mr_change change) - { -+ /* -+ * Prevent userspace from creating a memory region outside of the IPA -+ * space addressable by the KVM guest IPA space. -+ */ -+ if (memslot->base_gfn + memslot->npages >= -+ (KVM_PHYS_SIZE >> PAGE_SHIFT)) -+ return -EFAULT; -+ - return 0; - } - -diff --git a/arch/arm/mach-dove/board-dt.c b/arch/arm/mach-dove/board-dt.c -index 49fa9ab..7a7a09a5 100644 ---- a/arch/arm/mach-dove/board-dt.c -+++ b/arch/arm/mach-dove/board-dt.c -@@ -26,7 +26,7 @@ static void __init dove_dt_init(void) - #ifdef CONFIG_CACHE_TAUROS2 - tauros2_init(0); - #endif -- BUG_ON(mvebu_mbus_dt_init()); -+ BUG_ON(mvebu_mbus_dt_init(false)); - of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); - } - -diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c -index 01a5765..b509556 100644 ---- a/arch/arm/mach-imx/clk-imx6q.c -+++ b/arch/arm/mach-imx/clk-imx6q.c -@@ -406,7 +406,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) - clk[gpmi_io] = imx_clk_gate2("gpmi_io", "enfc", base + 0x78, 28); - clk[gpmi_apb] = imx_clk_gate2("gpmi_apb", "usdhc3", base + 0x78, 30); - clk[rom] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); -- clk[sata] = imx_clk_gate2("sata", "ipg", base + 0x7c, 4); -+ clk[sata] = imx_clk_gate2("sata", "ahb", base + 0x7c, 4); - clk[sdma] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); - clk[spba] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); - clk[spdif] = imx_clk_gate2("spdif", "spdif_podf", base + 0x7c, 14); -diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c -index 7818815..79e629d 100644 ---- a/arch/arm/mach-kirkwood/board-dt.c -+++ b/arch/arm/mach-kirkwood/board-dt.c -@@ -116,7 +116,7 @@ static void __init kirkwood_dt_init(void) - */ - writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG); - -- BUG_ON(mvebu_mbus_dt_init()); -+ BUG_ON(mvebu_mbus_dt_init(false)); - - kirkwood_l2_init(); - -diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c -index f6c9d1d..79c3766a 100644 ---- a/arch/arm/mach-mvebu/armada-370-xp.c -+++ b/arch/arm/mach-mvebu/armada-370-xp.c -@@ -41,7 +41,7 @@ static void __init armada_370_xp_timer_and_clk_init(void) - of_clk_init(NULL); - clocksource_of_init(); - coherency_init(); -- BUG_ON(mvebu_mbus_dt_init()); -+ BUG_ON(mvebu_mbus_dt_init(coherency_available())); - #ifdef CONFIG_CACHE_L2X0 - l2x0_of_init(0, ~0UL); - #endif -diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c -index c295c10..49bad4d 100644 ---- a/arch/arm/mach-mvebu/coherency.c -+++ b/arch/arm/mach-mvebu/coherency.c -@@ -121,6 +121,20 @@ static struct notifier_block mvebu_hwcc_platform_nb = { - .notifier_call = mvebu_hwcc_platform_notifier, - }; - -+/* -+ * Keep track of whether we have IO hardware coherency enabled or not. -+ * On Armada 370's we will not be using it for example. We need to make -+ * that available [through coherency_available()] so the mbus controller -+ * doesn't enable the IO coherency bit in the attribute bits of the -+ * chip selects. -+ */ -+static int coherency_enabled; -+ -+int coherency_available(void) -+{ -+ return coherency_enabled; -+} -+ - int __init coherency_init(void) - { - struct device_node *np; -@@ -164,6 +178,7 @@ int __init coherency_init(void) - coherency_base = of_iomap(np, 0); - coherency_cpu_base = of_iomap(np, 1); - set_cpu_coherent(cpu_logical_map(smp_processor_id()), 0); -+ coherency_enabled = 1; - of_node_put(np); - } - -diff --git a/arch/arm/mach-mvebu/coherency.h b/arch/arm/mach-mvebu/coherency.h -index 760226c..63e18c6 100644 ---- a/arch/arm/mach-mvebu/coherency.h -+++ b/arch/arm/mach-mvebu/coherency.h -@@ -17,6 +17,7 @@ - extern unsigned long coherency_phys_base; - - int set_cpu_coherent(unsigned int cpu_id, int smp_group_id); -+int coherency_available(void); - int coherency_init(void); - - #endif /* __MACH_370_XP_COHERENCY_H */ -diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h -index 00fbaa7..ea68925 100644 ---- a/arch/arm64/include/asm/kvm_arm.h -+++ b/arch/arm64/include/asm/kvm_arm.h -@@ -18,6 +18,7 @@ - #ifndef __ARM64_KVM_ARM_H__ - #define __ARM64_KVM_ARM_H__ - -+#include <asm/memory.h> - #include <asm/types.h> - - /* Hyp Configuration Register (HCR) bits */ -@@ -122,6 +123,17 @@ - #define VTCR_EL2_T0SZ_MASK 0x3f - #define VTCR_EL2_T0SZ_40B 24 - -+/* -+ * We configure the Stage-2 page tables to always restrict the IPA space to be -+ * 40 bits wide (T0SZ = 24). Systems with a PARange smaller than 40 bits are -+ * not known to exist and will break with this configuration. -+ * -+ * Note that when using 4K pages, we concatenate two first level page tables -+ * together. -+ * -+ * The magic numbers used for VTTBR_X in this patch can be found in Tables -+ * D4-23 and D4-25 in ARM DDI 0487A.b. -+ */ - #ifdef CONFIG_ARM64_64K_PAGES - /* - * Stage2 translation configuration: -@@ -151,9 +163,9 @@ - #endif - - #define VTTBR_BADDR_SHIFT (VTTBR_X - 1) --#define VTTBR_BADDR_MASK (((1LLU << (40 - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT) --#define VTTBR_VMID_SHIFT (48LLU) --#define VTTBR_VMID_MASK (0xffLLU << VTTBR_VMID_SHIFT) -+#define VTTBR_BADDR_MASK (((UL(1) << (PHYS_MASK_SHIFT - VTTBR_X)) - 1) << VTTBR_BADDR_SHIFT) -+#define VTTBR_VMID_SHIFT (UL(48)) -+#define VTTBR_VMID_MASK (UL(0xFF) << VTTBR_VMID_SHIFT) - - /* Hyp System Trap Register */ - #define HSTR_EL2_TTEE (1 << 16) -@@ -176,13 +188,13 @@ - - /* Exception Syndrome Register (ESR) bits */ - #define ESR_EL2_EC_SHIFT (26) --#define ESR_EL2_EC (0x3fU << ESR_EL2_EC_SHIFT) --#define ESR_EL2_IL (1U << 25) -+#define ESR_EL2_EC (UL(0x3f) << ESR_EL2_EC_SHIFT) -+#define ESR_EL2_IL (UL(1) << 25) - #define ESR_EL2_ISS (ESR_EL2_IL - 1) - #define ESR_EL2_ISV_SHIFT (24) --#define ESR_EL2_ISV (1U << ESR_EL2_ISV_SHIFT) -+#define ESR_EL2_ISV (UL(1) << ESR_EL2_ISV_SHIFT) - #define ESR_EL2_SAS_SHIFT (22) --#define ESR_EL2_SAS (3U << ESR_EL2_SAS_SHIFT) -+#define ESR_EL2_SAS (UL(3) << ESR_EL2_SAS_SHIFT) - #define ESR_EL2_SSE (1 << 21) - #define ESR_EL2_SRT_SHIFT (16) - #define ESR_EL2_SRT_MASK (0x1f << ESR_EL2_SRT_SHIFT) -@@ -196,16 +208,16 @@ - #define ESR_EL2_FSC_TYPE (0x3c) - - #define ESR_EL2_CV_SHIFT (24) --#define ESR_EL2_CV (1U << ESR_EL2_CV_SHIFT) -+#define ESR_EL2_CV (UL(1) << ESR_EL2_CV_SHIFT) - #define ESR_EL2_COND_SHIFT (20) --#define ESR_EL2_COND (0xfU << ESR_EL2_COND_SHIFT) -+#define ESR_EL2_COND (UL(0xf) << ESR_EL2_COND_SHIFT) - - - #define FSC_FAULT (0x04) - #define FSC_PERM (0x0c) - - /* Hyp Prefetch Fault Address Register (HPFAR/HDFAR) */ --#define HPFAR_MASK (~0xFUL) -+#define HPFAR_MASK (~UL(0xf)) - - #define ESR_EL2_EC_UNKNOWN (0x00) - #define ESR_EL2_EC_WFI (0x01) -diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h -index dd8ecfc3..681cb90 100644 ---- a/arch/arm64/include/asm/kvm_emulate.h -+++ b/arch/arm64/include/asm/kvm_emulate.h -@@ -38,6 +38,11 @@ void kvm_inject_undefined(struct kvm_vcpu *vcpu); - void kvm_inject_dabt(struct kvm_vcpu *vcpu, unsigned long addr); - void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); - -+static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) -+{ -+ vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS; -+} -+ - static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu) - { - return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pc; -diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h -index 8e138c7..0d51874 100644 ---- a/arch/arm64/include/asm/kvm_mmu.h -+++ b/arch/arm64/include/asm/kvm_mmu.h -@@ -59,10 +59,9 @@ - #define KERN_TO_HYP(kva) ((unsigned long)kva - PAGE_OFFSET + HYP_PAGE_OFFSET) - - /* -- * Align KVM with the kernel's view of physical memory. Should be -- * 40bit IPA, with PGD being 8kB aligned in the 4KB page configuration. -+ * We currently only support a 40bit IPA. - */ --#define KVM_PHYS_SHIFT PHYS_MASK_SHIFT -+#define KVM_PHYS_SHIFT (40) - #define KVM_PHYS_SIZE (1UL << KVM_PHYS_SHIFT) - #define KVM_PHYS_MASK (KVM_PHYS_SIZE - 1UL) - -@@ -75,6 +74,7 @@ int create_hyp_io_mappings(void *from, void *to, phys_addr_t); - void free_boot_hyp_pgd(void); - void free_hyp_pgds(void); - -+void stage2_unmap_vm(struct kvm *kvm); - int kvm_alloc_stage2_pgd(struct kvm *kvm); - void kvm_free_stage2_pgd(struct kvm *kvm); - int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa, -@@ -93,19 +93,6 @@ void kvm_clear_hyp_idmap(void); - #define kvm_set_pte(ptep, pte) set_pte(ptep, pte) - #define kvm_set_pmd(pmdp, pmd) set_pmd(pmdp, pmd) - --static inline bool kvm_is_write_fault(unsigned long esr) --{ -- unsigned long esr_ec = esr >> ESR_EL2_EC_SHIFT; -- -- if (esr_ec == ESR_EL2_EC_IABT) -- return false; -- -- if ((esr & ESR_EL2_ISV) && !(esr & ESR_EL2_WNR)) -- return false; -- -- return true; --} -- - static inline void kvm_clean_pgd(pgd_t *pgd) {} - static inline void kvm_clean_pmd_entry(pmd_t *pmd) {} - static inline void kvm_clean_pte(pte_t *pte) {} -diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c -index 0874557..a8d81fa 100644 ---- a/arch/arm64/kvm/guest.c -+++ b/arch/arm64/kvm/guest.c -@@ -38,7 +38,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { - - int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) - { -- vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS; - return 0; - } - -diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c -index 3974881..b76159a 100644 ---- a/arch/arm64/mm/dma-mapping.c -+++ b/arch/arm64/mm/dma-mapping.c -@@ -54,8 +54,7 @@ static void *arm64_swiotlb_alloc_coherent(struct device *dev, size_t size, - - *dma_handle = phys_to_dma(dev, page_to_phys(page)); - addr = page_address(page); -- if (flags & __GFP_ZERO) -- memset(addr, 0, size); -+ memset(addr, 0, size); - return addr; - } else { - return swiotlb_alloc_coherent(dev, size, dma_handle, flags); -diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index 2f645c9..5dab54a 100644 ---- a/arch/x86/Kconfig -+++ b/arch/x86/Kconfig -@@ -160,7 +160,7 @@ config SBUS - - config NEED_DMA_MAP_STATE - def_bool y -- depends on X86_64 || INTEL_IOMMU || DMA_API_DEBUG -+ depends on X86_64 || INTEL_IOMMU || DMA_API_DEBUG || SWIOTLB - - config NEED_SG_DMA_LENGTH - def_bool y -diff --git a/arch/x86/kernel/cpu/microcode/intel_early.c b/arch/x86/kernel/cpu/microcode/intel_early.c -index 18f7391..43a07bf 100644 ---- a/arch/x86/kernel/cpu/microcode/intel_early.c -+++ b/arch/x86/kernel/cpu/microcode/intel_early.c -@@ -321,7 +321,7 @@ get_matching_model_microcode(int cpu, unsigned long start, - unsigned int mc_saved_count = mc_saved_data->mc_saved_count; - int i; - -- while (leftover) { -+ while (leftover && mc_saved_count < ARRAY_SIZE(mc_saved_tmp)) { - mc_header = (struct microcode_header_intel *)ucode_ptr; - - mc_size = get_totalsize(mc_header); -diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c -index a1f5b18..490fee1 100644 ---- a/arch/x86/kernel/kprobes/core.c -+++ b/arch/x86/kernel/kprobes/core.c -@@ -326,13 +326,16 @@ int __kprobes __copy_instruction(u8 *dest, u8 *src) - { - struct insn insn; - kprobe_opcode_t buf[MAX_INSN_SIZE]; -+ int length; - - kernel_insn_init(&insn, (void *)recover_probed_instruction(buf, (unsigned long)src)); - insn_get_length(&insn); -+ length = insn.length; -+ - /* Another subsystem puts a breakpoint, failed to recover */ - if (insn.opcode.bytes[0] == BREAKPOINT_INSTRUCTION) - return 0; -- memcpy(dest, insn.kaddr, insn.length); -+ memcpy(dest, insn.kaddr, length); - - #ifdef CONFIG_X86_64 - if (insn_rip_relative(&insn)) { -@@ -362,7 +365,7 @@ int __kprobes __copy_instruction(u8 *dest, u8 *src) - *(s32 *) disp = (s32) newdisp; - } - #endif -- return insn.length; -+ return length; - } - - static int __kprobes arch_copy_kprobe(struct kprobe *p) -diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c -index 9643eda6..0746334 100644 ---- a/arch/x86/kvm/svm.c -+++ b/arch/x86/kvm/svm.c -@@ -495,8 +495,10 @@ static void skip_emulated_instruction(struct kvm_vcpu *vcpu) - { - struct vcpu_svm *svm = to_svm(vcpu); - -- if (svm->vmcb->control.next_rip != 0) -+ if (svm->vmcb->control.next_rip != 0) { -+ WARN_ON(!static_cpu_has(X86_FEATURE_NRIPS)); - svm->next_rip = svm->vmcb->control.next_rip; -+ } - - if (!svm->next_rip) { - if (emulate_instruction(vcpu, EMULTYPE_SKIP) != -@@ -4246,7 +4248,9 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu, - break; - } - -- vmcb->control.next_rip = info->next_rip; -+ /* TODO: Advertise NRIPS to guest hypervisor unconditionally */ -+ if (static_cpu_has(X86_FEATURE_NRIPS)) -+ vmcb->control.next_rip = info->next_rip; - vmcb->control.exit_code = icpt_info.exit_code; - vmexit = nested_svm_exit_handled(svm); - -diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c -index e990dee..1aa0130 100644 ---- a/drivers/bus/mvebu-mbus.c -+++ b/drivers/bus/mvebu-mbus.c -@@ -701,7 +701,6 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, - phys_addr_t sdramwins_phys_base, - size_t sdramwins_size) - { -- struct device_node *np; - int win; - - mbus->mbuswins_base = ioremap(mbuswins_phys_base, mbuswins_size); -@@ -714,12 +713,6 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, - return -ENOMEM; - } - -- np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"); -- if (np) { -- mbus->hw_io_coherency = 1; -- of_node_put(np); -- } -- - for (win = 0; win < mbus->soc->num_wins; win++) - mvebu_mbus_disable_window(mbus, win); - -@@ -889,7 +882,7 @@ static void __init mvebu_mbus_get_pcie_resources(struct device_node *np, - } - } - --int __init mvebu_mbus_dt_init(void) -+int __init mvebu_mbus_dt_init(bool is_coherent) - { - struct resource mbuswins_res, sdramwins_res; - struct device_node *np, *controller; -@@ -928,6 +921,8 @@ int __init mvebu_mbus_dt_init(void) - return -EINVAL; - } - -+ mbus_state.hw_io_coherency = is_coherent; -+ - /* Get optional pcie-{mem,io}-aperture properties */ - mvebu_mbus_get_pcie_resources(np, &mbus_state.pcie_mem_aperture, - &mbus_state.pcie_io_aperture); -diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c -index c611bcc..3e623ab 100644 ---- a/drivers/edac/sb_edac.c -+++ b/drivers/edac/sb_edac.c -@@ -765,7 +765,7 @@ static void get_memory_layout(const struct mem_ctl_info *mci) - u32 reg; - u64 limit, prv = 0; - u64 tmp_mb; -- u32 mb, kb; -+ u32 gb, mb; - u32 rir_way; - - /* -@@ -775,15 +775,17 @@ static void get_memory_layout(const struct mem_ctl_info *mci) - pvt->tolm = pvt->info.get_tolm(pvt); - tmp_mb = (1 + pvt->tolm) >> 20; - -- mb = div_u64_rem(tmp_mb, 1000, &kb); -- edac_dbg(0, "TOLM: %u.%03u GB (0x%016Lx)\n", mb, kb, (u64)pvt->tolm); -+ gb = div_u64_rem(tmp_mb, 1024, &mb); -+ edac_dbg(0, "TOLM: %u.%03u GB (0x%016Lx)\n", -+ gb, (mb*1000)/1024, (u64)pvt->tolm); - - /* Address range is already 45:25 */ - pvt->tohm = pvt->info.get_tohm(pvt); - tmp_mb = (1 + pvt->tohm) >> 20; - -- mb = div_u64_rem(tmp_mb, 1000, &kb); -- edac_dbg(0, "TOHM: %u.%03u GB (0x%016Lx)\n", mb, kb, (u64)pvt->tohm); -+ gb = div_u64_rem(tmp_mb, 1024, &mb); -+ edac_dbg(0, "TOHM: %u.%03u GB (0x%016Lx)\n", -+ gb, (mb*1000)/1024, (u64)pvt->tohm); - - /* - * Step 2) Get SAD range and SAD Interleave list -@@ -805,11 +807,11 @@ static void get_memory_layout(const struct mem_ctl_info *mci) - break; - - tmp_mb = (limit + 1) >> 20; -- mb = div_u64_rem(tmp_mb, 1000, &kb); -+ gb = div_u64_rem(tmp_mb, 1024, &mb); - edac_dbg(0, "SAD#%d %s up to %u.%03u GB (0x%016Lx) Interleave: %s reg=0x%08x\n", - n_sads, - get_dram_attr(reg), -- mb, kb, -+ gb, (mb*1000)/1024, - ((u64)tmp_mb) << 20L, - INTERLEAVE_MODE(reg) ? "8:6" : "[8:6]XOR[18:16]", - reg); -@@ -840,9 +842,9 @@ static void get_memory_layout(const struct mem_ctl_info *mci) - break; - tmp_mb = (limit + 1) >> 20; - -- mb = div_u64_rem(tmp_mb, 1000, &kb); -+ gb = div_u64_rem(tmp_mb, 1024, &mb); - edac_dbg(0, "TAD#%d: up to %u.%03u GB (0x%016Lx), socket interleave %d, memory interleave %d, TGT: %d, %d, %d, %d, reg=0x%08x\n", -- n_tads, mb, kb, -+ n_tads, gb, (mb*1000)/1024, - ((u64)tmp_mb) << 20L, - (u32)TAD_SOCK(reg), - (u32)TAD_CH(reg), -@@ -865,10 +867,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci) - tad_ch_nilv_offset[j], - ®); - tmp_mb = TAD_OFFSET(reg) >> 20; -- mb = div_u64_rem(tmp_mb, 1000, &kb); -+ gb = div_u64_rem(tmp_mb, 1024, &mb); - edac_dbg(0, "TAD CH#%d, offset #%d: %u.%03u GB (0x%016Lx), reg=0x%08x\n", - i, j, -- mb, kb, -+ gb, (mb*1000)/1024, - ((u64)tmp_mb) << 20L, - reg); - } -@@ -890,10 +892,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci) - - tmp_mb = RIR_LIMIT(reg) >> 20; - rir_way = 1 << RIR_WAY(reg); -- mb = div_u64_rem(tmp_mb, 1000, &kb); -+ gb = div_u64_rem(tmp_mb, 1024, &mb); - edac_dbg(0, "CH#%d RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d, reg=0x%08x\n", - i, j, -- mb, kb, -+ gb, (mb*1000)/1024, - ((u64)tmp_mb) << 20L, - rir_way, - reg); -@@ -904,10 +906,10 @@ static void get_memory_layout(const struct mem_ctl_info *mci) - ®); - tmp_mb = RIR_OFFSET(reg) << 6; - -- mb = div_u64_rem(tmp_mb, 1000, &kb); -+ gb = div_u64_rem(tmp_mb, 1024, &mb); - edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n", - i, j, k, -- mb, kb, -+ gb, (mb*1000)/1024, - ((u64)tmp_mb) << 20L, - (u32)RIR_RNK_TGT(reg), - reg); -@@ -945,7 +947,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci, - u8 ch_way, sck_way, pkg, sad_ha = 0; - u32 tad_offset; - u32 rir_way; -- u32 mb, kb; -+ u32 mb, gb; - u64 ch_addr, offset, limit = 0, prv = 0; - - -@@ -1183,10 +1185,10 @@ static int get_memory_error_data(struct mem_ctl_info *mci, - continue; - - limit = RIR_LIMIT(reg); -- mb = div_u64_rem(limit >> 20, 1000, &kb); -+ gb = div_u64_rem(limit >> 20, 1024, &mb); - edac_dbg(0, "RIR#%d, limit: %u.%03u GB (0x%016Lx), way: %d\n", - n_rir, -- mb, kb, -+ gb, (mb*1000)/1024, - limit, - 1 << RIR_WAY(reg)); - if (ch_addr <= limit) -diff --git a/drivers/net/ethernet/mellanox/mlx4/en_tx.c b/drivers/net/ethernet/mellanox/mlx4/en_tx.c -index 019a04a..a467261 100644 ---- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c -+++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c -@@ -810,8 +810,11 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff *skb, struct net_device *dev) - tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f; - tx_desc->ctrl.srcrb_flags = priv->ctrl_flags; - if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) { -- tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM | -- MLX4_WQE_CTRL_TCP_UDP_CSUM); -+ if (!skb->encapsulation) -+ tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM | -+ MLX4_WQE_CTRL_TCP_UDP_CSUM); -+ else -+ tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM); - ring->tx_csum++; - } - -diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c -index 528bff5..85d370e 100644 ---- a/drivers/scsi/hpsa.c -+++ b/drivers/scsi/hpsa.c -@@ -3984,10 +3984,6 @@ static int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) - - /* Save the PCI command register */ - pci_read_config_word(pdev, 4, &command_register); -- /* Turn the board off. This is so that later pci_restore_state() -- * won't turn the board on before the rest of config space is ready. -- */ -- pci_disable_device(pdev); - pci_save_state(pdev); - - /* find the first memory BAR, so we can find the cfg table */ -@@ -4035,11 +4031,6 @@ static int hpsa_kdump_hard_reset_controller(struct pci_dev *pdev) - goto unmap_cfgtable; - - pci_restore_state(pdev); -- rc = pci_enable_device(pdev); -- if (rc) { -- dev_warn(&pdev->dev, "failed to enable device.\n"); -- goto unmap_cfgtable; -- } - pci_write_config_word(pdev, 4, command_register); - - /* Some devices (notably the HP Smart Array 5i Controller) -@@ -4525,6 +4516,23 @@ static int hpsa_init_reset_devices(struct pci_dev *pdev) - if (!reset_devices) - return 0; - -+ /* kdump kernel is loading, we don't know in which state is -+ * the pci interface. The dev->enable_cnt is equal zero -+ * so we call enable+disable, wait a while and switch it on. -+ */ -+ rc = pci_enable_device(pdev); -+ if (rc) { -+ dev_warn(&pdev->dev, "Failed to enable PCI device\n"); -+ return -ENODEV; -+ } -+ pci_disable_device(pdev); -+ msleep(260); /* a randomly chosen number */ -+ rc = pci_enable_device(pdev); -+ if (rc) { -+ dev_warn(&pdev->dev, "failed to enable device.\n"); -+ return -ENODEV; -+ } -+ pci_set_master(pdev); - /* Reset the controller with a PCI power-cycle or via doorbell */ - rc = hpsa_kdump_hard_reset_controller(pdev); - -@@ -4533,10 +4541,11 @@ static int hpsa_init_reset_devices(struct pci_dev *pdev) - * "performant mode". Or, it might be 640x, which can't reset - * due to concerns about shared bbwc between 6402/6404 pair. - */ -- if (rc == -ENOTSUPP) -- return rc; /* just try to do the kdump anyhow. */ -- if (rc) -- return -ENODEV; -+ if (rc) { -+ if (rc != -ENOTSUPP) /* just try to do the kdump anyhow. */ -+ rc = -ENODEV; -+ goto out_disable; -+ } - - /* Now try to get the controller to respond to a no-op */ - dev_warn(&pdev->dev, "Waiting for controller to respond to no-op\n"); -@@ -4547,7 +4556,11 @@ static int hpsa_init_reset_devices(struct pci_dev *pdev) - dev_warn(&pdev->dev, "no-op failed%s\n", - (i < 11 ? "; re-trying" : "")); - } -- return 0; -+ -+out_disable: -+ -+ pci_disable_device(pdev); -+ return rc; - } - - static int hpsa_allocate_cmd_pool(struct ctlr_info *h) -@@ -4690,6 +4703,7 @@ static void hpsa_undo_allocations_after_kdump_soft_reset(struct ctlr_info *h) - iounmap(h->transtable); - if (h->cfgtable) - iounmap(h->cfgtable); -+ pci_disable_device(h->pdev); - pci_release_regions(h->pdev); - kfree(h); - } -diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c -index 93de3ba..f8ffee4 100644 ---- a/fs/btrfs/ctree.c -+++ b/fs/btrfs/ctree.c -@@ -2963,7 +2963,7 @@ done: - */ - if (!p->leave_spinning) - btrfs_set_path_blocking(p); -- if (ret < 0) -+ if (ret < 0 && !p->skip_release_on_error) - btrfs_release_path(p); - return ret; - } -diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h -index d3511cc..3b39eb4 100644 ---- a/fs/btrfs/ctree.h -+++ b/fs/btrfs/ctree.h -@@ -608,6 +608,7 @@ struct btrfs_path { - unsigned int skip_locking:1; - unsigned int leave_spinning:1; - unsigned int search_commit_root:1; -+ unsigned int skip_release_on_error:1; - }; - - /* -@@ -3609,6 +3610,10 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, - int verify_dir_item(struct btrfs_root *root, - struct extent_buffer *leaf, - struct btrfs_dir_item *dir_item); -+struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, -+ struct btrfs_path *path, -+ const char *name, -+ int name_len); - - /* orphan.c */ - int btrfs_insert_orphan_item(struct btrfs_trans_handle *trans, -diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c -index a0691df..9521a93 100644 ---- a/fs/btrfs/dir-item.c -+++ b/fs/btrfs/dir-item.c -@@ -21,10 +21,6 @@ - #include "hash.h" - #include "transaction.h" - --static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, -- struct btrfs_path *path, -- const char *name, int name_len); -- - /* - * insert a name into a directory, doing overflow properly if there is a hash - * collision. data_size indicates how big the item inserted should be. On -@@ -383,9 +379,9 @@ struct btrfs_dir_item *btrfs_lookup_xattr(struct btrfs_trans_handle *trans, - * this walks through all the entries in a dir item and finds one - * for a specific name. - */ --static struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, -- struct btrfs_path *path, -- const char *name, int name_len) -+struct btrfs_dir_item *btrfs_match_dir_item_name(struct btrfs_root *root, -+ struct btrfs_path *path, -+ const char *name, int name_len) - { - struct btrfs_dir_item *dir_item; - unsigned long name_ptr; -diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c -index 488e987..618e86c 100644 ---- a/fs/btrfs/xattr.c -+++ b/fs/btrfs/xattr.c -@@ -29,6 +29,7 @@ - #include "xattr.h" - #include "disk-io.h" - #include "props.h" -+#include "locking.h" - - - ssize_t __btrfs_getxattr(struct inode *inode, const char *name, -@@ -91,7 +92,7 @@ static int do_setxattr(struct btrfs_trans_handle *trans, - struct inode *inode, const char *name, - const void *value, size_t size, int flags) - { -- struct btrfs_dir_item *di; -+ struct btrfs_dir_item *di = NULL; - struct btrfs_root *root = BTRFS_I(inode)->root; - struct btrfs_path *path; - size_t name_len = strlen(name); -@@ -103,84 +104,119 @@ static int do_setxattr(struct btrfs_trans_handle *trans, - path = btrfs_alloc_path(); - if (!path) - return -ENOMEM; -+ path->skip_release_on_error = 1; -+ -+ if (!value) { -+ di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), -+ name, name_len, -1); -+ if (!di && (flags & XATTR_REPLACE)) -+ ret = -ENODATA; -+ else if (di) -+ ret = btrfs_delete_one_dir_name(trans, root, path, di); -+ goto out; -+ } - -+ /* -+ * For a replace we can't just do the insert blindly. -+ * Do a lookup first (read-only btrfs_search_slot), and return if xattr -+ * doesn't exist. If it exists, fall down below to the insert/replace -+ * path - we can't race with a concurrent xattr delete, because the VFS -+ * locks the inode's i_mutex before calling setxattr or removexattr. -+ */ - if (flags & XATTR_REPLACE) { -- di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), name, -- name_len, -1); -- if (IS_ERR(di)) { -- ret = PTR_ERR(di); -- goto out; -- } else if (!di) { -+ ASSERT(mutex_is_locked(&inode->i_mutex)); -+ di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), -+ name, name_len, 0); -+ if (!di) { - ret = -ENODATA; - goto out; - } -- ret = btrfs_delete_one_dir_name(trans, root, path, di); -- if (ret) -- goto out; - btrfs_release_path(path); -+ di = NULL; -+ } - -+ ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), -+ name, name_len, value, size); -+ if (ret == -EOVERFLOW) { - /* -- * remove the attribute -+ * We have an existing item in a leaf, split_leaf couldn't -+ * expand it. That item might have or not a dir_item that -+ * matches our target xattr, so lets check. - */ -- if (!value) -- goto out; -- } else { -- di = btrfs_lookup_xattr(NULL, root, path, btrfs_ino(inode), -- name, name_len, 0); -- if (IS_ERR(di)) { -- ret = PTR_ERR(di); -+ ret = 0; -+ btrfs_assert_tree_locked(path->nodes[0]); -+ di = btrfs_match_dir_item_name(root, path, name, name_len); -+ if (!di && !(flags & XATTR_REPLACE)) { -+ ret = -ENOSPC; - goto out; - } -- if (!di && !value) -- goto out; -- btrfs_release_path(path); -+ } else if (ret == -EEXIST) { -+ ret = 0; -+ di = btrfs_match_dir_item_name(root, path, name, name_len); -+ ASSERT(di); /* logic error */ -+ } else if (ret) { -+ goto out; - } - --again: -- ret = btrfs_insert_xattr_item(trans, root, path, btrfs_ino(inode), -- name, name_len, value, size); -- /* -- * If we're setting an xattr to a new value but the new value is say -- * exactly BTRFS_MAX_XATTR_SIZE, we could end up with EOVERFLOW getting -- * back from split_leaf. This is because it thinks we'll be extending -- * the existing item size, but we're asking for enough space to add the -- * item itself. So if we get EOVERFLOW just set ret to EEXIST and let -- * the rest of the function figure it out. -- */ -- if (ret == -EOVERFLOW) -+ if (di && (flags & XATTR_CREATE)) { - ret = -EEXIST; -+ goto out; -+ } - -- if (ret == -EEXIST) { -- if (flags & XATTR_CREATE) -- goto out; -+ if (di) { - /* -- * We can't use the path we already have since we won't have the -- * proper locking for a delete, so release the path and -- * re-lookup to delete the thing. -+ * We're doing a replace, and it must be atomic, that is, at -+ * any point in time we have either the old or the new xattr -+ * value in the tree. We don't want readers (getxattr and -+ * listxattrs) to miss a value, this is specially important -+ * for ACLs. - */ -- btrfs_release_path(path); -- di = btrfs_lookup_xattr(trans, root, path, btrfs_ino(inode), -- name, name_len, -1); -- if (IS_ERR(di)) { -- ret = PTR_ERR(di); -- goto out; -- } else if (!di) { -- /* Shouldn't happen but just in case... */ -- btrfs_release_path(path); -- goto again; -+ const int slot = path->slots[0]; -+ struct extent_buffer *leaf = path->nodes[0]; -+ const u16 old_data_len = btrfs_dir_data_len(leaf, di); -+ const u32 item_size = btrfs_item_size_nr(leaf, slot); -+ const u32 data_size = sizeof(*di) + name_len + size; -+ struct btrfs_item *item; -+ unsigned long data_ptr; -+ char *ptr; -+ -+ if (size > old_data_len) { -+ if (btrfs_leaf_free_space(root, leaf) < -+ (size - old_data_len)) { -+ ret = -ENOSPC; -+ goto out; -+ } - } - -- ret = btrfs_delete_one_dir_name(trans, root, path, di); -- if (ret) -- goto out; -+ if (old_data_len + name_len + sizeof(*di) == item_size) { -+ /* No other xattrs packed in the same leaf item. */ -+ if (size > old_data_len) -+ btrfs_extend_item(root, path, -+ size - old_data_len); -+ else if (size < old_data_len) -+ btrfs_truncate_item(root, path, data_size, 1); -+ } else { -+ /* There are other xattrs packed in the same item. */ -+ ret = btrfs_delete_one_dir_name(trans, root, path, di); -+ if (ret) -+ goto out; -+ btrfs_extend_item(root, path, data_size); -+ } - -+ item = btrfs_item_nr(slot); -+ ptr = btrfs_item_ptr(leaf, slot, char); -+ ptr += btrfs_item_size(leaf, item) - data_size; -+ di = (struct btrfs_dir_item *)ptr; -+ btrfs_set_dir_data_len(leaf, di, size); -+ data_ptr = ((unsigned long)(di + 1)) + name_len; -+ write_extent_buffer(leaf, value, data_ptr, size); -+ btrfs_mark_buffer_dirty(leaf); -+ } else { - /* -- * We have a value to set, so go back and try to insert it now. -+ * Insert, and we had space for the xattr, so path->slots[0] is -+ * where our xattr dir_item is and btrfs_insert_xattr_item() -+ * filled it. - */ -- if (value) { -- btrfs_release_path(path); -- goto again; -- } - } - out: - btrfs_free_path(path); -diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c -index 7fe30f6..35f54bc 100644 ---- a/fs/ocfs2/file.c -+++ b/fs/ocfs2/file.c -@@ -2478,9 +2478,7 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, - struct address_space *mapping = out->f_mapping; - struct inode *inode = mapping->host; - struct splice_desc sd = { -- .total_len = len, - .flags = flags, -- .pos = *ppos, - .u.file = out, - }; - -@@ -2490,6 +2488,12 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, - out->f_path.dentry->d_name.len, - out->f_path.dentry->d_name.name, len); - -+ ret = generic_write_checks(out, ppos, &len, 0); -+ if (ret) -+ return ret; -+ sd.total_len = len; -+ sd.pos = *ppos; -+ - pipe_lock(pipe); - - splice_from_pipe_begin(&sd); -diff --git a/fs/splice.c b/fs/splice.c -index 12028fa..f345d53 100644 ---- a/fs/splice.c -+++ b/fs/splice.c -@@ -1012,13 +1012,17 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, - struct address_space *mapping = out->f_mapping; - struct inode *inode = mapping->host; - struct splice_desc sd = { -- .total_len = len, - .flags = flags, -- .pos = *ppos, - .u.file = out, - }; - ssize_t ret; - -+ ret = generic_write_checks(out, ppos, &len, S_ISBLK(inode->i_mode)); -+ if (ret) -+ return ret; -+ sd.total_len = len; -+ sd.pos = *ppos; -+ - pipe_lock(pipe); - - splice_from_pipe_begin(&sd); -diff --git a/include/linux/mbus.h b/include/linux/mbus.h -index 345b8c5..550c88f 100644 ---- a/include/linux/mbus.h -+++ b/include/linux/mbus.h -@@ -73,6 +73,6 @@ int mvebu_mbus_del_window(phys_addr_t base, size_t size); - int mvebu_mbus_init(const char *soc, phys_addr_t mbus_phys_base, - size_t mbus_size, phys_addr_t sdram_phys_base, - size_t sdram_size); --int mvebu_mbus_dt_init(void); -+int mvebu_mbus_dt_init(bool is_coherent); - - #endif /* __LINUX_MBUS_H */ -diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c -index c68e5e0..99de240 100644 ---- a/net/netfilter/nf_tables_api.c -+++ b/net/netfilter/nf_tables_api.c -@@ -855,7 +855,10 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, - - if (nla[NFTA_CHAIN_POLICY]) { - if ((chain != NULL && -- !(chain->flags & NFT_BASE_CHAIN)) || -+ !(chain->flags & NFT_BASE_CHAIN))) -+ return -EOPNOTSUPP; -+ -+ if (chain == NULL && - nla[NFTA_CHAIN_HOOK] == NULL) - return -EOPNOTSUPP; - -diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c -index 9e287cb..54330fb 100644 ---- a/net/netfilter/nfnetlink_cthelper.c -+++ b/net/netfilter/nfnetlink_cthelper.c -@@ -77,6 +77,9 @@ nfnl_cthelper_parse_tuple(struct nf_conntrack_tuple *tuple, - if (!tb[NFCTH_TUPLE_L3PROTONUM] || !tb[NFCTH_TUPLE_L4PROTONUM]) - return -EINVAL; - -+ /* Not all fields are initialized so first zero the tuple */ -+ memset(tuple, 0, sizeof(struct nf_conntrack_tuple)); -+ - tuple->src.l3num = ntohs(nla_get_be16(tb[NFCTH_TUPLE_L3PROTONUM])); - tuple->dst.protonum = nla_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]); - -@@ -86,7 +89,7 @@ nfnl_cthelper_parse_tuple(struct nf_conntrack_tuple *tuple, - static int - nfnl_cthelper_from_nlattr(struct nlattr *attr, struct nf_conn *ct) - { -- const struct nf_conn_help *help = nfct_help(ct); -+ struct nf_conn_help *help = nfct_help(ct); - - if (attr == NULL) - return -EINVAL; -@@ -94,7 +97,7 @@ nfnl_cthelper_from_nlattr(struct nlattr *attr, struct nf_conn *ct) - if (help->helper->data_len == 0) - return -EINVAL; - -- memcpy(&help->data, nla_data(attr), help->helper->data_len); -+ memcpy(help->data, nla_data(attr), help->helper->data_len); - return 0; - } - -diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c -index 7350723..9695895 100644 ---- a/net/netfilter/nft_compat.c -+++ b/net/netfilter/nft_compat.c -@@ -82,6 +82,9 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par, - entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; - break; - case AF_INET6: -+ if (proto) -+ entry->e6.ipv6.flags |= IP6T_F_PROTO; -+ - entry->e6.ipv6.proto = proto; - entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; - break; -@@ -313,6 +316,9 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx, - entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; - break; - case AF_INET6: -+ if (proto) -+ entry->e6.ipv6.flags |= IP6T_F_PROTO; -+ - entry->e6.ipv6.proto = proto; - entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; - break; -diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c -index 1316e55..c324a52 100644 ---- a/virt/kvm/arm/vgic.c -+++ b/virt/kvm/arm/vgic.c -@@ -674,7 +674,7 @@ static bool read_set_clear_sgi_pend_reg(struct kvm_vcpu *vcpu, - { - struct vgic_dist *dist = &vcpu->kvm->arch.vgic; - int sgi; -- int min_sgi = (offset & ~0x3) * 4; -+ int min_sgi = (offset & ~0x3); - int max_sgi = min_sgi + 3; - int vcpu_id = vcpu->vcpu_id; - u32 reg = 0; -@@ -695,7 +695,7 @@ static bool write_set_clear_sgi_pend_reg(struct kvm_vcpu *vcpu, - { - struct vgic_dist *dist = &vcpu->kvm->arch.vgic; - int sgi; -- int min_sgi = (offset & ~0x3) * 4; -+ int min_sgi = (offset & ~0x3); - int max_sgi = min_sgi + 3; - int vcpu_id = vcpu->vcpu_id; - u32 reg; -@@ -1387,7 +1387,8 @@ out: - int kvm_vgic_inject_irq(struct kvm *kvm, int cpuid, unsigned int irq_num, - bool level) - { -- if (vgic_update_irq_state(kvm, cpuid, irq_num, level)) -+ if (likely(vgic_initialized(kvm)) && -+ vgic_update_irq_state(kvm, cpuid, irq_num, level)) - vgic_kick_vcpus(kvm); - - return 0; -@@ -1610,7 +1611,7 @@ out: - - int kvm_vgic_create(struct kvm *kvm) - { -- int i, vcpu_lock_idx = -1, ret = 0; -+ int i, vcpu_lock_idx = -1, ret; - struct kvm_vcpu *vcpu; - - mutex_lock(&kvm->lock); -@@ -1625,6 +1626,7 @@ int kvm_vgic_create(struct kvm *kvm) - * vcpu->mutex. By grabbing the vcpu->mutex of all VCPUs we ensure - * that no other VCPUs are run while we create the vgic. - */ -+ ret = -EBUSY; - kvm_for_each_vcpu(i, vcpu, kvm) { - if (!mutex_trylock(&vcpu->mutex)) - goto out_unlock; -@@ -1632,11 +1634,10 @@ int kvm_vgic_create(struct kvm *kvm) - } - - kvm_for_each_vcpu(i, vcpu, kvm) { -- if (vcpu->arch.has_run_once) { -- ret = -EBUSY; -+ if (vcpu->arch.has_run_once) - goto out_unlock; -- } - } -+ ret = 0; - - spin_lock_init(&kvm->arch.vgic.lock); - kvm->arch.vgic.vctrl_base = vgic_vctrl_base; diff --git a/3.14.48/1047_linux-3.14.48.patch b/3.14.48/1047_linux-3.14.48.patch deleted file mode 100644 index 3a7169d..0000000 --- a/3.14.48/1047_linux-3.14.48.patch +++ /dev/null @@ -1,1019 +0,0 @@ -diff --git a/Makefile b/Makefile -index f9041e6..25393e8 100644 ---- a/Makefile -+++ b/Makefile -@@ -1,6 +1,6 @@ - VERSION = 3 - PATCHLEVEL = 14 --SUBLEVEL = 47 -+SUBLEVEL = 48 - EXTRAVERSION = - NAME = Remembering Coco - -diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h -index 9f79231..7d35af3 100644 ---- a/arch/arm/include/asm/kvm_mmu.h -+++ b/arch/arm/include/asm/kvm_mmu.h -@@ -117,13 +117,14 @@ static inline void kvm_set_s2pmd_writable(pmd_t *pmd) - (__boundary - 1 < (end) - 1)? __boundary: (end); \ - }) - -+#define kvm_pgd_index(addr) pgd_index(addr) -+ - static inline bool kvm_page_empty(void *ptr) - { - struct page *ptr_page = virt_to_page(ptr); - return page_count(ptr_page) == 1; - } - -- - #define kvm_pte_table_empty(ptep) kvm_page_empty(ptep) - #define kvm_pmd_table_empty(pmdp) kvm_page_empty(pmdp) - #define kvm_pud_table_empty(pudp) (0) -diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c -index 2e74a61..f6a52a2 100644 ---- a/arch/arm/kvm/arm.c -+++ b/arch/arm/kvm/arm.c -@@ -441,6 +441,7 @@ static void update_vttbr(struct kvm *kvm) - - static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) - { -+ struct kvm *kvm = vcpu->kvm; - int ret; - - if (likely(vcpu->arch.has_run_once)) -@@ -452,12 +453,20 @@ static int kvm_vcpu_first_run_init(struct kvm_vcpu *vcpu) - * Initialize the VGIC before running a vcpu the first time on - * this VM. - */ -- if (unlikely(!vgic_initialized(vcpu->kvm))) { -- ret = kvm_vgic_init(vcpu->kvm); -+ if (unlikely(!vgic_initialized(kvm))) { -+ ret = kvm_vgic_init(kvm); - if (ret) - return ret; - } - -+ /* -+ * Enable the arch timers only if we have an in-kernel VGIC -+ * and it has been properly initialized, since we cannot handle -+ * interrupts from the virtual timer with a userspace gic. -+ */ -+ if (irqchip_in_kernel(kvm) && vgic_initialized(kvm)) -+ kvm_timer_enable(kvm); -+ - return 0; - } - -diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S -index 0d68d40..a1467e7 100644 ---- a/arch/arm/kvm/interrupts.S -+++ b/arch/arm/kvm/interrupts.S -@@ -159,13 +159,9 @@ __kvm_vcpu_return: - @ Don't trap coprocessor accesses for host kernel - set_hstr vmexit - set_hdcr vmexit -- set_hcptr vmexit, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11)) -+ set_hcptr vmexit, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11)), after_vfp_restore - - #ifdef CONFIG_VFPv3 -- @ Save floating point registers we if let guest use them. -- tst r2, #(HCPTR_TCP(10) | HCPTR_TCP(11)) -- bne after_vfp_restore -- - @ Switch VFP/NEON hardware state to the host's - add r7, vcpu, #VCPU_VFP_GUEST - store_vfp_state r7 -@@ -177,6 +173,8 @@ after_vfp_restore: - @ Restore FPEXC_EN which we clobbered on entry - pop {r2} - VFPFMXR FPEXC, r2 -+#else -+after_vfp_restore: - #endif - - @ Reset Hyp-role -@@ -467,7 +465,7 @@ switch_to_guest_vfp: - push {r3-r7} - - @ NEON/VFP used. Turn on VFP access. -- set_hcptr vmexit, (HCPTR_TCP(10) | HCPTR_TCP(11)) -+ set_hcptr vmtrap, (HCPTR_TCP(10) | HCPTR_TCP(11)) - - @ Switch VFP/NEON hardware state to the guest's - add r7, r0, #VCPU_VFP_HOST -diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S -index 76af9302..2973b2d 100644 ---- a/arch/arm/kvm/interrupts_head.S -+++ b/arch/arm/kvm/interrupts_head.S -@@ -578,8 +578,13 @@ vcpu .req r0 @ vcpu pointer always in r0 - .endm - - /* Configures the HCPTR (Hyp Coprocessor Trap Register) on entry/return -- * (hardware reset value is 0). Keep previous value in r2. */ --.macro set_hcptr operation, mask -+ * (hardware reset value is 0). Keep previous value in r2. -+ * An ISB is emited on vmexit/vmtrap, but executed on vmexit only if -+ * VFP wasn't already enabled (always executed on vmtrap). -+ * If a label is specified with vmexit, it is branched to if VFP wasn't -+ * enabled. -+ */ -+.macro set_hcptr operation, mask, label = none - mrc p15, 4, r2, c1, c1, 2 - ldr r3, =\mask - .if \operation == vmentry -@@ -588,6 +593,17 @@ vcpu .req r0 @ vcpu pointer always in r0 - bic r3, r2, r3 @ Don't trap defined coproc-accesses - .endif - mcr p15, 4, r3, c1, c1, 2 -+ .if \operation != vmentry -+ .if \operation == vmexit -+ tst r2, #(HCPTR_TCP(10) | HCPTR_TCP(11)) -+ beq 1f -+ .endif -+ isb -+ .if \label != none -+ b \label -+ .endif -+1: -+ .endif - .endm - - /* Configures the HDCR (Hyp Debug Configuration Register) on entry/return -diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c -index 524b4b5..c612e37 100644 ---- a/arch/arm/kvm/mmu.c -+++ b/arch/arm/kvm/mmu.c -@@ -194,7 +194,7 @@ static void unmap_range(struct kvm *kvm, pgd_t *pgdp, - phys_addr_t addr = start, end = start + size; - phys_addr_t next; - -- pgd = pgdp + pgd_index(addr); -+ pgd = pgdp + kvm_pgd_index(addr); - do { - next = kvm_pgd_addr_end(addr, end); - if (!pgd_none(*pgd)) -@@ -264,7 +264,7 @@ static void stage2_flush_memslot(struct kvm *kvm, - phys_addr_t next; - pgd_t *pgd; - -- pgd = kvm->arch.pgd + pgd_index(addr); -+ pgd = kvm->arch.pgd + kvm_pgd_index(addr); - do { - next = kvm_pgd_addr_end(addr, end); - stage2_flush_puds(kvm, pgd, addr, next); -@@ -649,7 +649,7 @@ static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache - pud_t *pud; - pmd_t *pmd; - -- pgd = kvm->arch.pgd + pgd_index(addr); -+ pgd = kvm->arch.pgd + kvm_pgd_index(addr); - pud = pud_offset(pgd, addr); - if (pud_none(*pud)) { - if (!cache) -diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h -index 681cb90..91f33c2 100644 ---- a/arch/arm64/include/asm/kvm_emulate.h -+++ b/arch/arm64/include/asm/kvm_emulate.h -@@ -41,6 +41,8 @@ void kvm_inject_pabt(struct kvm_vcpu *vcpu, unsigned long addr); - static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu) - { - vcpu->arch.hcr_el2 = HCR_GUEST_FLAGS; -+ if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) -+ vcpu->arch.hcr_el2 &= ~HCR_RW; - } - - static inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu) -diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h -index 0d51874..15a8a86 100644 ---- a/arch/arm64/include/asm/kvm_mmu.h -+++ b/arch/arm64/include/asm/kvm_mmu.h -@@ -69,6 +69,8 @@ - #define PTRS_PER_S2_PGD (1 << (KVM_PHYS_SHIFT - PGDIR_SHIFT)) - #define S2_PGD_ORDER get_order(PTRS_PER_S2_PGD * sizeof(pgd_t)) - -+#define kvm_pgd_index(addr) (((addr) >> PGDIR_SHIFT) & (PTRS_PER_S2_PGD - 1)) -+ - int create_hyp_mappings(void *from, void *to); - int create_hyp_io_mappings(void *from, void *to, phys_addr_t); - void free_boot_hyp_pgd(void); -diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S -index 5dfc8331..3aaf3bc 100644 ---- a/arch/arm64/kvm/hyp.S -+++ b/arch/arm64/kvm/hyp.S -@@ -629,6 +629,7 @@ ENTRY(__kvm_tlb_flush_vmid_ipa) - * Instead, we invalidate Stage-2 for this IPA, and the - * whole of Stage-1. Weep... - */ -+ lsr x1, x1, #12 - tlbi ipas2e1is, x1 - /* - * We have to ensure completion of the invalidation at Stage-2, -diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c -index 70a7816..0b43265 100644 ---- a/arch/arm64/kvm/reset.c -+++ b/arch/arm64/kvm/reset.c -@@ -90,7 +90,6 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) - if (!cpu_has_32bit_el1()) - return -EINVAL; - cpu_reset = &default_regs_reset32; -- vcpu->arch.hcr_el2 &= ~HCR_RW; - } else { - cpu_reset = &default_regs_reset; - } -diff --git a/arch/mips/include/asm/mach-generic/spaces.h b/arch/mips/include/asm/mach-generic/spaces.h -index 9488fa5..afc96ec 100644 ---- a/arch/mips/include/asm/mach-generic/spaces.h -+++ b/arch/mips/include/asm/mach-generic/spaces.h -@@ -94,7 +94,11 @@ - #endif - - #ifndef FIXADDR_TOP -+#ifdef CONFIG_KVM_GUEST -+#define FIXADDR_TOP ((unsigned long)(long)(int)0x7ffe0000) -+#else - #define FIXADDR_TOP ((unsigned long)(long)(int)0xfffe0000) - #endif -+#endif - - #endif /* __ASM_MACH_GENERIC_SPACES_H */ -diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c -index 38265dc..65dfbd0 100644 ---- a/arch/powerpc/perf/core-book3s.c -+++ b/arch/powerpc/perf/core-book3s.c -@@ -124,7 +124,16 @@ static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {} - - static bool regs_use_siar(struct pt_regs *regs) - { -- return !!regs->result; -+ /* -+ * When we take a performance monitor exception the regs are setup -+ * using perf_read_regs() which overloads some fields, in particular -+ * regs->result to tell us whether to use SIAR. -+ * -+ * However if the regs are from another exception, eg. a syscall, then -+ * they have not been setup using perf_read_regs() and so regs->result -+ * is something random. -+ */ -+ return ((TRAP(regs) == 0xf00) && regs->result); - } - - /* -diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c -index 27bb554..7ef2862 100644 ---- a/arch/sparc/kernel/ldc.c -+++ b/arch/sparc/kernel/ldc.c -@@ -2307,7 +2307,7 @@ void *ldc_alloc_exp_dring(struct ldc_channel *lp, unsigned int len, - if (len & (8UL - 1)) - return ERR_PTR(-EINVAL); - -- buf = kzalloc(len, GFP_KERNEL); -+ buf = kzalloc(len, GFP_ATOMIC); - if (!buf) - return ERR_PTR(-ENOMEM); - -diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index 5dab54a..96e743a 100644 ---- a/arch/x86/Kconfig -+++ b/arch/x86/Kconfig -@@ -2440,9 +2440,19 @@ config X86_DMA_REMAP - depends on STA2X11 - - config IOSF_MBI -- tristate -- default m -+ tristate "Intel System On Chip IOSF Sideband support" - depends on PCI -+ ---help--- -+ Enables sideband access to mailbox registers on SoC's. The sideband is -+ available on the following platforms. This list is not meant to be -+ exclusive. -+ - BayTrail -+ - Cherryview -+ - Braswell -+ - Quark -+ -+ You should say Y if you are running a kernel on one of these -+ platforms. - - source "net/Kconfig" - -diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h -index e9dc029..ac03bd7 100644 ---- a/arch/x86/include/asm/kvm_host.h -+++ b/arch/x86/include/asm/kvm_host.h -@@ -571,7 +571,7 @@ struct kvm_arch { - struct kvm_pic *vpic; - struct kvm_ioapic *vioapic; - struct kvm_pit *vpit; -- int vapics_in_nmi_mode; -+ atomic_t vapics_in_nmi_mode; - struct mutex apic_map_lock; - struct kvm_apic_map *apic_map; - -diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c -index 298781d..1406ffd 100644 ---- a/arch/x86/kvm/i8254.c -+++ b/arch/x86/kvm/i8254.c -@@ -305,7 +305,7 @@ static void pit_do_work(struct kthread_work *work) - * LVT0 to NMI delivery. Other PIC interrupts are just sent to - * VCPU0, and only if its LVT0 is in EXTINT mode. - */ -- if (kvm->arch.vapics_in_nmi_mode > 0) -+ if (atomic_read(&kvm->arch.vapics_in_nmi_mode) > 0) - kvm_for_each_vcpu(i, vcpu, kvm) - kvm_apic_nmi_wd_deliver(vcpu); - } -diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c -index 453e5fb..6456734 100644 ---- a/arch/x86/kvm/lapic.c -+++ b/arch/x86/kvm/lapic.c -@@ -1109,10 +1109,10 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val) - if (!nmi_wd_enabled) { - apic_debug("Receive NMI setting on APIC_LVT0 " - "for cpu %d\n", apic->vcpu->vcpu_id); -- apic->vcpu->kvm->arch.vapics_in_nmi_mode++; -+ atomic_inc(&apic->vcpu->kvm->arch.vapics_in_nmi_mode); - } - } else if (nmi_wd_enabled) -- apic->vcpu->kvm->arch.vapics_in_nmi_mode--; -+ atomic_dec(&apic->vcpu->kvm->arch.vapics_in_nmi_mode); - } - - static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) -diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c -index 4f25ec0..bf00138 100644 ---- a/arch/x86/pci/acpi.c -+++ b/arch/x86/pci/acpi.c -@@ -84,6 +84,17 @@ static const struct dmi_system_id pci_crs_quirks[] __initconst = { - DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"), - }, - }, -+ /* https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/931368 */ -+ /* https://bugs.launchpad.net/ubuntu/+source/alsa-driver/+bug/1033299 */ -+ { -+ .callback = set_use_crs, -+ .ident = "Foxconn K8M890-8237A", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "Foxconn"), -+ DMI_MATCH(DMI_BOARD_NAME, "K8M890-8237A"), -+ DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"), -+ }, -+ }, - - /* Now for the blacklist.. */ - -@@ -124,8 +135,10 @@ void __init pci_acpi_crs_quirks(void) - { - int year; - -- if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008) -- pci_use_crs = false; -+ if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008) { -+ if (iomem_resource.end <= 0xffffffff) -+ pci_use_crs = false; -+ } - - dmi_check_system(pci_crs_quirks); - -diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c -index 533a509..fbc693b 100644 ---- a/drivers/cpufreq/intel_pstate.c -+++ b/drivers/cpufreq/intel_pstate.c -@@ -417,7 +417,7 @@ static void byt_set_pstate(struct cpudata *cpudata, int pstate) - - val |= vid; - -- wrmsrl(MSR_IA32_PERF_CTL, val); -+ wrmsrl_on_cpu(cpudata->cpu, MSR_IA32_PERF_CTL, val); - } - - #define BYT_BCLK_FREQS 5 -diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c -index 5967667..1f35487 100644 ---- a/drivers/crypto/talitos.c -+++ b/drivers/crypto/talitos.c -@@ -927,7 +927,8 @@ static int sg_to_link_tbl(struct scatterlist *sg, int sg_count, - sg_count--; - link_tbl_ptr--; - } -- be16_add_cpu(&link_tbl_ptr->len, cryptlen); -+ link_tbl_ptr->len = cpu_to_be16(be16_to_cpu(link_tbl_ptr->len) -+ + cryptlen); - - /* tag end of link table */ - link_tbl_ptr->j_extent = DESC_PTR_LNKTBL_RETURN; -@@ -2563,6 +2564,7 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev, - break; - default: - dev_err(dev, "unknown algorithm type %d\n", t_alg->algt.type); -+ kfree(t_alg); - return ERR_PTR(-EINVAL); - } - -diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c -index 9cbef59..9359740 100644 ---- a/drivers/iommu/amd_iommu.c -+++ b/drivers/iommu/amd_iommu.c -@@ -1922,9 +1922,15 @@ static void free_pt_##LVL (unsigned long __pt) \ - pt = (u64 *)__pt; \ - \ - for (i = 0; i < 512; ++i) { \ -+ /* PTE present? */ \ - if (!IOMMU_PTE_PRESENT(pt[i])) \ - continue; \ - \ -+ /* Large PTE? */ \ -+ if (PM_PTE_LEVEL(pt[i]) == 0 || \ -+ PM_PTE_LEVEL(pt[i]) == 7) \ -+ continue; \ -+ \ - p = (unsigned long)IOMMU_PTE_PAGE(pt[i]); \ - FN(p); \ - } \ -diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c -index 25f7419..62c3fb9 100644 ---- a/drivers/net/phy/phy_device.c -+++ b/drivers/net/phy/phy_device.c -@@ -765,10 +765,11 @@ static int genphy_config_advert(struct phy_device *phydev) - if (phydev->supported & (SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full)) { - adv |= ethtool_adv_to_mii_ctrl1000_t(advertise); -- if (adv != oldadv) -- changed = 1; - } - -+ if (adv != oldadv) -+ changed = 1; -+ - err = phy_write(phydev, MII_CTRL1000, adv); - if (err < 0) - return err; -diff --git a/fs/dcache.c b/fs/dcache.c -index 1d7e8a3..aa24f7d 100644 ---- a/fs/dcache.c -+++ b/fs/dcache.c -@@ -2905,17 +2905,6 @@ restart: - vfsmnt = &mnt->mnt; - continue; - } -- /* -- * Filesystems needing to implement special "root names" -- * should do so with ->d_dname() -- */ -- if (IS_ROOT(dentry) && -- (dentry->d_name.len != 1 || -- dentry->d_name.name[0] != '/')) { -- WARN(1, "Root dentry has weird name <%.*s>\n", -- (int) dentry->d_name.len, -- dentry->d_name.name); -- } - if (!error) - error = is_mounted(vfsmnt) ? 1 : 2; - break; -diff --git a/fs/inode.c b/fs/inode.c -index e846a32..644875b 100644 ---- a/fs/inode.c -+++ b/fs/inode.c -@@ -1631,8 +1631,8 @@ int file_remove_suid(struct file *file) - error = security_inode_killpriv(dentry); - if (!error && killsuid) - error = __remove_suid(dentry, killsuid); -- if (!error && (inode->i_sb->s_flags & MS_NOSEC)) -- inode->i_flags |= S_NOSEC; -+ if (!error) -+ inode_has_no_xattr(inode); - - return error; - } -diff --git a/fs/namespace.c b/fs/namespace.c -index 2faa7ea..fc99d18 100644 ---- a/fs/namespace.c -+++ b/fs/namespace.c -@@ -3031,11 +3031,15 @@ bool fs_fully_visible(struct file_system_type *type) - if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root) - continue; - -- /* This mount is not fully visible if there are any child mounts -- * that cover anything except for empty directories. -+ /* This mount is not fully visible if there are any -+ * locked child mounts that cover anything except for -+ * empty directories. - */ - list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) { - struct inode *inode = child->mnt_mountpoint->d_inode; -+ /* Only worry about locked mounts */ -+ if (!(mnt->mnt.mnt_flags & MNT_LOCKED)) -+ continue; - if (!S_ISDIR(inode->i_mode)) - goto next; - if (inode->i_nlink > 2) -diff --git a/include/kvm/arm_arch_timer.h b/include/kvm/arm_arch_timer.h -index 6d9aedd..327b155 100644 ---- a/include/kvm/arm_arch_timer.h -+++ b/include/kvm/arm_arch_timer.h -@@ -60,7 +60,8 @@ struct arch_timer_cpu { - - #ifdef CONFIG_KVM_ARM_TIMER - int kvm_timer_hyp_init(void); --int kvm_timer_init(struct kvm *kvm); -+void kvm_timer_enable(struct kvm *kvm); -+void kvm_timer_init(struct kvm *kvm); - void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, - const struct kvm_irq_level *irq); - void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu); -@@ -73,11 +74,8 @@ static inline int kvm_timer_hyp_init(void) - return 0; - }; - --static inline int kvm_timer_init(struct kvm *kvm) --{ -- return 0; --} -- -+static inline void kvm_timer_enable(struct kvm *kvm) {} -+static inline void kvm_timer_init(struct kvm *kvm) {} - static inline void kvm_timer_vcpu_reset(struct kvm_vcpu *vcpu, - const struct kvm_irq_level *irq) {} - static inline void kvm_timer_vcpu_init(struct kvm_vcpu *vcpu) {} -diff --git a/include/net/netns/sctp.h b/include/net/netns/sctp.h -index 3573a81..8ba379f 100644 ---- a/include/net/netns/sctp.h -+++ b/include/net/netns/sctp.h -@@ -31,6 +31,7 @@ struct netns_sctp { - struct list_head addr_waitq; - struct timer_list addr_wq_timer; - struct list_head auto_asconf_splist; -+ /* Lock that protects both addr_waitq and auto_asconf_splist */ - spinlock_t addr_wq_lock; - - /* Lock that protects the local_addr_list writers */ -diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h -index 0dfcc92..2c2d388 100644 ---- a/include/net/sctp/structs.h -+++ b/include/net/sctp/structs.h -@@ -219,6 +219,10 @@ struct sctp_sock { - atomic_t pd_mode; - /* Receive to here while partial delivery is in effect. */ - struct sk_buff_head pd_lobby; -+ -+ /* These must be the last fields, as they will skipped on copies, -+ * like on accept and peeloff operations -+ */ - struct list_head auto_asconf_list; - int do_auto_asconf; - }; -diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c -index a9a4a1b..8d423bc 100644 ---- a/net/bridge/br_ioctl.c -+++ b/net/bridge/br_ioctl.c -@@ -247,9 +247,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) - if (!ns_capable(dev_net(dev)->user_ns, CAP_NET_ADMIN)) - return -EPERM; - -- spin_lock_bh(&br->lock); - br_stp_set_bridge_priority(br, args[1]); -- spin_unlock_bh(&br->lock); - return 0; - - case BRCTL_SET_PORT_PRIORITY: -diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c -index 11a2e6c..7bbc8fe 100644 ---- a/net/bridge/br_multicast.c -+++ b/net/bridge/br_multicast.c -@@ -1086,6 +1086,9 @@ static void br_multicast_add_router(struct net_bridge *br, - struct net_bridge_port *p; - struct hlist_node *slot = NULL; - -+ if (!hlist_unhashed(&port->rlist)) -+ return; -+ - hlist_for_each_entry(p, &br->router_list, rlist) { - if ((unsigned long) port >= (unsigned long) p) - break; -@@ -1113,12 +1116,8 @@ static void br_multicast_mark_router(struct net_bridge *br, - if (port->multicast_router != 1) - return; - -- if (!hlist_unhashed(&port->rlist)) -- goto timer; -- - br_multicast_add_router(br, port); - --timer: - mod_timer(&port->multicast_router_timer, - now + br->multicast_querier_interval); - } -diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c -index 189ba1e..9a0005a 100644 ---- a/net/bridge/br_stp_if.c -+++ b/net/bridge/br_stp_if.c -@@ -243,12 +243,13 @@ bool br_stp_recalculate_bridge_id(struct net_bridge *br) - return true; - } - --/* called under bridge lock */ -+/* Acquires and releases bridge lock */ - void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio) - { - struct net_bridge_port *p; - int wasroot; - -+ spin_lock_bh(&br->lock); - wasroot = br_is_root_bridge(br); - - list_for_each_entry(p, &br->port_list, list) { -@@ -266,6 +267,7 @@ void br_stp_set_bridge_priority(struct net_bridge *br, u16 newprio) - br_port_state_selection(br); - if (br_is_root_bridge(br) && !wasroot) - br_become_root_bridge(br); -+ spin_unlock_bh(&br->lock); - } - - /* called under bridge lock */ -diff --git a/net/core/neighbour.c b/net/core/neighbour.c -index 7d95f69..0f062c6 100644 ---- a/net/core/neighbour.c -+++ b/net/core/neighbour.c -@@ -976,6 +976,8 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) - rc = 0; - if (neigh->nud_state & (NUD_CONNECTED | NUD_DELAY | NUD_PROBE)) - goto out_unlock_bh; -+ if (neigh->dead) -+ goto out_dead; - - if (!(neigh->nud_state & (NUD_STALE | NUD_INCOMPLETE))) { - if (NEIGH_VAR(neigh->parms, MCAST_PROBES) + -@@ -1032,6 +1034,13 @@ out_unlock_bh: - write_unlock(&neigh->lock); - local_bh_enable(); - return rc; -+ -+out_dead: -+ if (neigh->nud_state & NUD_STALE) -+ goto out_unlock_bh; -+ write_unlock_bh(&neigh->lock); -+ kfree_skb(skb); -+ return 1; - } - EXPORT_SYMBOL(__neigh_event_send); - -@@ -1095,6 +1104,8 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, - if (!(flags & NEIGH_UPDATE_F_ADMIN) && - (old & (NUD_NOARP | NUD_PERMANENT))) - goto out; -+ if (neigh->dead) -+ goto out; - - if (!(new & NUD_VALID)) { - neigh_del_timer(neigh); -@@ -1244,6 +1255,8 @@ EXPORT_SYMBOL(neigh_update); - */ - void __neigh_set_probe_once(struct neighbour *neigh) - { -+ if (neigh->dead) -+ return; - neigh->updated = jiffies; - if (!(neigh->nud_state & NUD_FAILED)) - return; -diff --git a/net/core/skbuff.c b/net/core/skbuff.c -index 69ec61a..8207f8d 100644 ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -368,9 +368,11 @@ refill: - for (order = NETDEV_FRAG_PAGE_MAX_ORDER; ;) { - gfp_t gfp = gfp_mask; - -- if (order) -+ if (order) { - gfp |= __GFP_COMP | __GFP_NOWARN | - __GFP_NOMEMALLOC; -+ gfp &= ~__GFP_WAIT; -+ } - nc->frag.page = alloc_pages(gfp, order); - if (likely(nc->frag.page)) - break; -diff --git a/net/core/sock.c b/net/core/sock.c -index 650dd58..8ebfa52 100644 ---- a/net/core/sock.c -+++ b/net/core/sock.c -@@ -1914,8 +1914,10 @@ bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t prio) - do { - gfp_t gfp = prio; - -- if (order) -+ if (order) { - gfp |= __GFP_COMP | __GFP_NOWARN | __GFP_NORETRY; -+ gfp &= ~__GFP_WAIT; -+ } - pfrag->page = alloc_pages(gfp, order); - if (likely(pfrag->page)) { - pfrag->offset = 0; -diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c -index 07bd8ed..951fe55 100644 ---- a/net/ipv4/af_inet.c -+++ b/net/ipv4/af_inet.c -@@ -228,6 +228,8 @@ int inet_listen(struct socket *sock, int backlog) - err = 0; - if (err) - goto out; -+ -+ tcp_fastopen_init_key_once(true); - } - err = inet_csk_listen_start(sk, backlog); - if (err) -diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c -index 29d240b..dc45221 100644 ---- a/net/ipv4/tcp.c -+++ b/net/ipv4/tcp.c -@@ -2684,10 +2684,13 @@ static int do_tcp_setsockopt(struct sock *sk, int level, - - case TCP_FASTOPEN: - if (val >= 0 && ((1 << sk->sk_state) & (TCPF_CLOSE | -- TCPF_LISTEN))) -+ TCPF_LISTEN))) { -+ tcp_fastopen_init_key_once(true); -+ - err = fastopen_init_queue(sk, val); -- else -+ } else { - err = -EINVAL; -+ } - break; - case TCP_TIMESTAMP: - if (!tp->repair) -diff --git a/net/ipv4/tcp_fastopen.c b/net/ipv4/tcp_fastopen.c -index f195d93..ee6518d 100644 ---- a/net/ipv4/tcp_fastopen.c -+++ b/net/ipv4/tcp_fastopen.c -@@ -84,8 +84,6 @@ void tcp_fastopen_cookie_gen(__be32 src, __be32 dst, - __be32 path[4] = { src, dst, 0, 0 }; - struct tcp_fastopen_context *ctx; - -- tcp_fastopen_init_key_once(true); -- - rcu_read_lock(); - ctx = rcu_dereference(tcp_fastopen_ctx); - if (ctx) { -diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c -index 48b1817..84a60b8 100644 ---- a/net/packet/af_packet.c -+++ b/net/packet/af_packet.c -@@ -1264,16 +1264,6 @@ static void packet_sock_destruct(struct sock *sk) - sk_refcnt_debug_dec(sk); - } - --static int fanout_rr_next(struct packet_fanout *f, unsigned int num) --{ -- int x = atomic_read(&f->rr_cur) + 1; -- -- if (x >= num) -- x = 0; -- -- return x; --} -- - static unsigned int fanout_demux_hash(struct packet_fanout *f, - struct sk_buff *skb, - unsigned int num) -@@ -1285,13 +1275,9 @@ static unsigned int fanout_demux_lb(struct packet_fanout *f, - struct sk_buff *skb, - unsigned int num) - { -- int cur, old; -+ unsigned int val = atomic_inc_return(&f->rr_cur); - -- cur = atomic_read(&f->rr_cur); -- while ((old = atomic_cmpxchg(&f->rr_cur, cur, -- fanout_rr_next(f, num))) != cur) -- cur = old; -- return cur; -+ return val % num; - } - - static unsigned int fanout_demux_cpu(struct packet_fanout *f, -@@ -1345,7 +1331,7 @@ static int packet_rcv_fanout(struct sk_buff *skb, struct net_device *dev, - struct packet_type *pt, struct net_device *orig_dev) - { - struct packet_fanout *f = pt->af_packet_priv; -- unsigned int num = f->num_members; -+ unsigned int num = ACCESS_ONCE(f->num_members); - struct packet_sock *po; - unsigned int idx; - -diff --git a/net/sctp/output.c b/net/sctp/output.c -index 740ca5f..e39e6d5 100644 ---- a/net/sctp/output.c -+++ b/net/sctp/output.c -@@ -599,7 +599,9 @@ out: - return err; - no_route: - kfree_skb(nskb); -- IP_INC_STATS(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES); -+ -+ if (asoc) -+ IP_INC_STATS(sock_net(asoc->base.sk), IPSTATS_MIB_OUTNOROUTES); - - /* FIXME: Returning the 'err' will effect all the associations - * associated with a socket, although only one of the paths of the -diff --git a/net/sctp/socket.c b/net/sctp/socket.c -index 604a6ac..f940fdc 100644 ---- a/net/sctp/socket.c -+++ b/net/sctp/socket.c -@@ -1532,8 +1532,10 @@ static void sctp_close(struct sock *sk, long timeout) - - /* Supposedly, no process has access to the socket, but - * the net layers still may. -+ * Also, sctp_destroy_sock() needs to be called with addr_wq_lock -+ * held and that should be grabbed before socket lock. - */ -- local_bh_disable(); -+ spin_lock_bh(&net->sctp.addr_wq_lock); - bh_lock_sock(sk); - - /* Hold the sock, since sk_common_release() will put sock_put() -@@ -1543,7 +1545,7 @@ static void sctp_close(struct sock *sk, long timeout) - sk_common_release(sk); - - bh_unlock_sock(sk); -- local_bh_enable(); -+ spin_unlock_bh(&net->sctp.addr_wq_lock); - - sock_put(sk); - -@@ -3511,6 +3513,7 @@ static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval, - if ((val && sp->do_auto_asconf) || (!val && !sp->do_auto_asconf)) - return 0; - -+ spin_lock_bh(&sock_net(sk)->sctp.addr_wq_lock); - if (val == 0 && sp->do_auto_asconf) { - list_del(&sp->auto_asconf_list); - sp->do_auto_asconf = 0; -@@ -3519,6 +3522,7 @@ static int sctp_setsockopt_auto_asconf(struct sock *sk, char __user *optval, - &sock_net(sk)->sctp.auto_asconf_splist); - sp->do_auto_asconf = 1; - } -+ spin_unlock_bh(&sock_net(sk)->sctp.addr_wq_lock); - return 0; - } - -@@ -4009,18 +4013,28 @@ static int sctp_init_sock(struct sock *sk) - local_bh_disable(); - percpu_counter_inc(&sctp_sockets_allocated); - sock_prot_inuse_add(net, sk->sk_prot, 1); -+ -+ /* Nothing can fail after this block, otherwise -+ * sctp_destroy_sock() will be called without addr_wq_lock held -+ */ - if (net->sctp.default_auto_asconf) { -+ spin_lock(&sock_net(sk)->sctp.addr_wq_lock); - list_add_tail(&sp->auto_asconf_list, - &net->sctp.auto_asconf_splist); - sp->do_auto_asconf = 1; -- } else -+ spin_unlock(&sock_net(sk)->sctp.addr_wq_lock); -+ } else { - sp->do_auto_asconf = 0; -+ } -+ - local_bh_enable(); - - return 0; - } - --/* Cleanup any SCTP per socket resources. */ -+/* Cleanup any SCTP per socket resources. Must be called with -+ * sock_net(sk)->sctp.addr_wq_lock held if sp->do_auto_asconf is true -+ */ - static void sctp_destroy_sock(struct sock *sk) - { - struct sctp_sock *sp; -@@ -6973,6 +6987,19 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk, - newinet->mc_list = NULL; - } - -+static inline void sctp_copy_descendant(struct sock *sk_to, -+ const struct sock *sk_from) -+{ -+ int ancestor_size = sizeof(struct inet_sock) + -+ sizeof(struct sctp_sock) - -+ offsetof(struct sctp_sock, auto_asconf_list); -+ -+ if (sk_from->sk_family == PF_INET6) -+ ancestor_size += sizeof(struct ipv6_pinfo); -+ -+ __inet_sk_copy_descendant(sk_to, sk_from, ancestor_size); -+} -+ - /* Populate the fields of the newsk from the oldsk and migrate the assoc - * and its messages to the newsk. - */ -@@ -6987,7 +7014,6 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, - struct sk_buff *skb, *tmp; - struct sctp_ulpevent *event; - struct sctp_bind_hashbucket *head; -- struct list_head tmplist; - - /* Migrate socket buffer sizes and all the socket level options to the - * new socket. -@@ -6995,12 +7021,7 @@ static void sctp_sock_migrate(struct sock *oldsk, struct sock *newsk, - newsk->sk_sndbuf = oldsk->sk_sndbuf; - newsk->sk_rcvbuf = oldsk->sk_rcvbuf; - /* Brute force copy old sctp opt. */ -- if (oldsp->do_auto_asconf) { -- memcpy(&tmplist, &newsp->auto_asconf_list, sizeof(tmplist)); -- inet_sk_copy_descendant(newsk, oldsk); -- memcpy(&newsp->auto_asconf_list, &tmplist, sizeof(tmplist)); -- } else -- inet_sk_copy_descendant(newsk, oldsk); -+ sctp_copy_descendant(newsk, oldsk); - - /* Restore the ep value that was overwritten with the above structure - * copy. -diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c -index 5081e80..c6fe405 100644 ---- a/virt/kvm/arm/arch_timer.c -+++ b/virt/kvm/arm/arch_timer.c -@@ -61,12 +61,14 @@ static void timer_disarm(struct arch_timer_cpu *timer) - - static void kvm_timer_inject_irq(struct kvm_vcpu *vcpu) - { -+ int ret; - struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu; - - timer->cntv_ctl |= ARCH_TIMER_CTRL_IT_MASK; -- kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, -- timer->irq->irq, -- timer->irq->level); -+ ret = kvm_vgic_inject_irq(vcpu->kvm, vcpu->vcpu_id, -+ timer->irq->irq, -+ timer->irq->level); -+ WARN_ON(ret); - } - - static irqreturn_t kvm_arch_timer_handler(int irq, void *dev_id) -@@ -307,12 +309,24 @@ void kvm_timer_vcpu_terminate(struct kvm_vcpu *vcpu) - timer_disarm(timer); - } - --int kvm_timer_init(struct kvm *kvm) -+void kvm_timer_enable(struct kvm *kvm) - { -- if (timecounter && wqueue) { -- kvm->arch.timer.cntvoff = kvm_phys_timer_read(); -+ if (kvm->arch.timer.enabled) -+ return; -+ -+ /* -+ * There is a potential race here between VCPUs starting for the first -+ * time, which may be enabling the timer multiple times. That doesn't -+ * hurt though, because we're just setting a variable to the same -+ * variable that it already was. The important thing is that all -+ * VCPUs have the enabled variable set, before entering the guest, if -+ * the arch timers are enabled. -+ */ -+ if (timecounter && wqueue) - kvm->arch.timer.enabled = 1; -- } -+} - -- return 0; -+void kvm_timer_init(struct kvm *kvm) -+{ -+ kvm->arch.timer.cntvoff = kvm_phys_timer_read(); - } -diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c -index c324a52..152ec76 100644 ---- a/virt/kvm/arm/vgic.c -+++ b/virt/kvm/arm/vgic.c -@@ -1042,6 +1042,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) - lr, irq, vgic_cpu->vgic_lr[lr]); - BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); - vgic_cpu->vgic_lr[lr] |= GICH_LR_PENDING_BIT; -+ __clear_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr); - return true; - } - -@@ -1055,6 +1056,7 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) - vgic_cpu->vgic_lr[lr] = MK_LR_PEND(sgi_source_id, irq); - vgic_cpu->vgic_irq_lr_map[irq] = lr; - set_bit(lr, vgic_cpu->lr_used); -+ __clear_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr); - - if (!vgic_irq_is_edge(vcpu, irq)) - vgic_cpu->vgic_lr[lr] |= GICH_LR_EOI; -@@ -1209,6 +1211,14 @@ static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) - if (vgic_cpu->vgic_misr & GICH_MISR_U) - vgic_cpu->vgic_hcr &= ~GICH_HCR_UIE; - -+ /* -+ * In the next iterations of the vcpu loop, if we sync the vgic state -+ * after flushing it, but before entering the guest (this happens for -+ * pending signals and vmid rollovers), then make sure we don't pick -+ * up any old maintenance interrupts here. -+ */ -+ memset(vgic_cpu->vgic_eisr, 0, sizeof(vgic_cpu->vgic_eisr[0]) * 2); -+ - return level_pending; - } - diff --git a/3.14.48/4420_grsecurity-3.1-3.14.48-201507111210.patch b/3.14.48/4420_grsecurity-3.1-3.14.48-201507251417.patch index 8faa105..59a0c47 100644 --- a/3.14.48/4420_grsecurity-3.1-3.14.48-201507111210.patch +++ b/3.14.48/4420_grsecurity-3.1-3.14.48-201507251417.patch @@ -294,6 +294,39 @@ index 5d91ba1..ef1d374 100644 pcbit= [HW,ISDN] pcd. [PARIDE] +diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt +index 855d9b3..154c500 100644 +--- a/Documentation/sysctl/kernel.txt ++++ b/Documentation/sysctl/kernel.txt +@@ -41,6 +41,7 @@ show up in /proc/sys/kernel: + - kptr_restrict + - kstack_depth_to_print [ X86 only ] + - l2cr [ PPC only ] ++- modify_ldt [ X86 only ] + - modprobe ==> Documentation/debugging-modules.txt + - modules_disabled + - msg_next_id [ sysv ipc ] +@@ -381,6 +382,20 @@ This flag controls the L2 cache of G3 processor boards. If + + ============================================================== + ++modify_ldt: (X86 only) ++ ++Enables (1) or disables (0) the modify_ldt syscall. Modifying the LDT ++(Local Descriptor Table) may be needed to run a 16-bit or segmented code ++such as Dosemu or Wine. This is done via a system call which is not needed ++to run portable applications, and which can sometimes be abused to exploit ++some weaknesses of the architecture, opening new vulnerabilities. ++ ++This sysctl allows one to increase the system's security by disabling the ++system call, or to restore compatibility with specific applications when it ++was already disabled. ++ ++============================================================== ++ + modules_disabled: + + A toggle value indicating if modules are allowed to be loaded diff --git a/Makefile b/Makefile index 25393e8..65e3b07 100644 --- a/Makefile @@ -4767,6 +4800,105 @@ index f15c22e..d830561 100644 } } +diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c +index 6adf591..00ad1e9 100644 +--- a/arch/arm/net/bpf_jit_32.c ++++ b/arch/arm/net/bpf_jit_32.c +@@ -73,32 +73,52 @@ struct jit_ctx { + + int bpf_jit_enable __read_mostly; + +-static u64 jit_get_skb_b(struct sk_buff *skb, unsigned offset) ++static inline int call_neg_helper(struct sk_buff *skb, int offset, void *ret, ++ unsigned int size) ++{ ++ void *ptr = bpf_internal_load_pointer_neg_helper(skb, offset, size); ++ ++ if (!ptr) ++ return -EFAULT; ++ memcpy(ret, ptr, size); ++ return 0; ++} ++ ++static u64 jit_get_skb_b(struct sk_buff *skb, int offset) + { + u8 ret; + int err; + +- err = skb_copy_bits(skb, offset, &ret, 1); ++ if (offset < 0) ++ err = call_neg_helper(skb, offset, &ret, 1); ++ else ++ err = skb_copy_bits(skb, offset, &ret, 1); + + return (u64)err << 32 | ret; + } + +-static u64 jit_get_skb_h(struct sk_buff *skb, unsigned offset) ++static u64 jit_get_skb_h(struct sk_buff *skb, int offset) + { + u16 ret; + int err; + +- err = skb_copy_bits(skb, offset, &ret, 2); ++ if (offset < 0) ++ err = call_neg_helper(skb, offset, &ret, 2); ++ else ++ err = skb_copy_bits(skb, offset, &ret, 2); + + return (u64)err << 32 | ntohs(ret); + } + +-static u64 jit_get_skb_w(struct sk_buff *skb, unsigned offset) ++static u64 jit_get_skb_w(struct sk_buff *skb, int offset) + { + u32 ret; + int err; + +- err = skb_copy_bits(skb, offset, &ret, 4); ++ if (offset < 0) ++ err = call_neg_helper(skb, offset, &ret, 4); ++ else ++ err = skb_copy_bits(skb, offset, &ret, 4); + + return (u64)err << 32 | ntohl(ret); + } +@@ -523,9 +543,6 @@ static int build_body(struct jit_ctx *ctx) + case BPF_S_LD_B_ABS: + load_order = 0; + load: +- /* the interpreter will deal with the negative K */ +- if ((int)k < 0) +- return -ENOTSUPP; + emit_mov_i(r_off, k, ctx); + load_common: + ctx->seen |= SEEN_DATA | SEEN_CALL; +@@ -534,12 +551,24 @@ load_common: + emit(ARM_SUB_I(r_scratch, r_skb_hl, + 1 << load_order), ctx); + emit(ARM_CMP_R(r_scratch, r_off), ctx); +- condt = ARM_COND_HS; ++ condt = ARM_COND_GE; + } else { + emit(ARM_CMP_R(r_skb_hl, r_off), ctx); + condt = ARM_COND_HI; + } + ++ /* ++ * test for negative offset, only if we are ++ * currently scheduled to take the fast ++ * path. this will update the flags so that ++ * the slowpath instruction are ignored if the ++ * offset is negative. ++ * ++ * for loard_order == 0 the HI condition will ++ * make loads at offset 0 take the slow path too. ++ */ ++ _emit(condt, ARM_CMP_I(r_off, 0), ctx); ++ + _emit(condt, ARM_ADD_R(r_scratch, r_off, r_skb_data), + 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 @@ -12396,7 +12528,7 @@ index ad8f795..2c7eec6 100644 /* * Memory returned by kmalloc() may be used for DMA, so we must make diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index 96e743a..7f93c3a 100644 +index 96e743a..ca34a86 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -22,6 +22,7 @@ config X86_64 @@ -12499,6 +12631,29 @@ index 96e743a..7f93c3a 100644 ---help--- Map the 32-bit VDSO to the predictable old-style address too. +@@ -1914,6 +1921,22 @@ config CMDLINE_OVERRIDE + This is used to work around broken boot loaders. This should + be set to 'N' under normal conditions. + ++config DEFAULT_MODIFY_LDT_SYSCALL ++ bool "Allow userspace to modify the LDT by default" ++ default y ++ ++ ---help--- ++ Modifying the LDT (Local Descriptor Table) may be needed to run a ++ 16-bit or segmented code such as Dosemu or Wine. This is done via ++ a system call which is not needed to run portable applications, ++ and which can sometimes be abused to exploit some weaknesses of ++ the architecture, opening new vulnerabilities. ++ ++ For this reason this option allows one to enable or disable the ++ feature at runtime. It is recommended to say 'N' here to leave ++ the system protected, and to enable it at runtime only if needed ++ by setting the sys.kernel.modify_ldt sysctl. ++ + endmenu + + config ARCH_ENABLE_MEMORY_HOTPLUG diff --git a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu index f3aaf23..a1d3c49 100644 --- a/arch/x86/Kconfig.cpu @@ -26013,10 +26168,33 @@ index c2bedae..25e7ab60 100644 .name = "data", .mode = S_IRUGO, diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c -index c37886d..3f425e3 100644 +index c37886d..f43b63d 100644 --- a/arch/x86/kernel/ldt.c +++ b/arch/x86/kernel/ldt.c -@@ -66,13 +66,13 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload) +@@ -11,6 +11,7 @@ + #include <linux/sched.h> + #include <linux/string.h> + #include <linux/mm.h> ++#include <linux/ratelimit.h> + #include <linux/smp.h> + #include <linux/vmalloc.h> + #include <linux/uaccess.h> +@@ -20,6 +21,14 @@ + #include <asm/mmu_context.h> + #include <asm/syscalls.h> + ++#ifdef CONFIG_GRKERNSEC ++int sysctl_modify_ldt __read_only = 0; ++#elif defined(CONFIG_DEFAULT_MODIFY_LDT_SYSCALL) ++int sysctl_modify_ldt __read_only = 1; ++#else ++int sysctl_modify_ldt __read_only = 0; ++#endif ++ + #ifdef CONFIG_SMP + static void flush_ldt(void *current_mm) + { +@@ -66,13 +75,13 @@ static int alloc_ldt(mm_context_t *pc, int mincount, int reload) if (reload) { #ifdef CONFIG_SMP preempt_disable(); @@ -26032,7 +26210,7 @@ index c37886d..3f425e3 100644 #endif } if (oldsize) { -@@ -94,7 +94,7 @@ static inline int copy_ldt(mm_context_t *new, mm_context_t *old) +@@ -94,7 +103,7 @@ static inline int copy_ldt(mm_context_t *new, mm_context_t *old) return err; for (i = 0; i < old->size; i++) @@ -26041,7 +26219,7 @@ index c37886d..3f425e3 100644 return 0; } -@@ -115,6 +115,24 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) +@@ -115,6 +124,24 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) retval = copy_ldt(&mm->context, &old_mm->context); mutex_unlock(&old_mm->context.lock); } @@ -26066,7 +26244,7 @@ index c37886d..3f425e3 100644 return retval; } -@@ -229,6 +247,13 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) +@@ -229,6 +256,13 @@ static int write_ldt(void __user *ptr, unsigned long bytecount, int oldmode) } } @@ -26080,6 +26258,22 @@ index c37886d..3f425e3 100644 if (!IS_ENABLED(CONFIG_X86_16BIT) && !ldt_info.seg_32bit) { error = -EINVAL; goto out_unlock; +@@ -254,6 +288,15 @@ asmlinkage int sys_modify_ldt(int func, void __user *ptr, + { + int ret = -ENOSYS; + ++ if (!sysctl_modify_ldt) { ++ printk_ratelimited(KERN_INFO ++ "Denied a call to modify_ldt() from %s[%d] (uid: %d)." ++ " Adjust sysctl if this was not an exploit attempt.\n", ++ current->comm, task_pid_nr(current), ++ from_kuid_munged(current_user_ns(), current_uid())); ++ return ret; ++ } ++ + switch (func) { + case 0: + ret = read_ldt(ptr, bytecount); diff --git a/arch/x86/kernel/machine_kexec_32.c b/arch/x86/kernel/machine_kexec_32.c index 1667b1d..16492c5 100644 --- a/arch/x86/kernel/machine_kexec_32.c @@ -48521,6 +48715,74 @@ index dff0977..6df4b1d 100644 adapter->vfinfo[vf].spoofchk_enabled = setting; regval = IXGBE_READ_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg)); +diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c +index 96fc7fe..1c776d6 100644 +--- a/drivers/net/ethernet/marvell/mvneta.c ++++ b/drivers/net/ethernet/marvell/mvneta.c +@@ -1441,7 +1441,7 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, + struct mvneta_rx_queue *rxq) + { + struct net_device *dev = pp->dev; +- int rx_done, rx_filled; ++ int rx_done; + u32 rcvd_pkts = 0; + u32 rcvd_bytes = 0; + +@@ -1452,7 +1452,6 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, + rx_todo = rx_done; + + rx_done = 0; +- rx_filled = 0; + + /* Fairness NAPI loop */ + while (rx_done < rx_todo) { +@@ -1463,7 +1462,6 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, + int rx_bytes, err; + + rx_done++; +- rx_filled++; + rx_status = rx_desc->status; + rx_bytes = rx_desc->data_size - (ETH_FCS_LEN + MVNETA_MH_SIZE); + data = (unsigned char *)rx_desc->buf_cookie; +@@ -1503,6 +1501,14 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, + continue; + } + ++ /* Refill processing */ ++ err = mvneta_rx_refill(pp, rx_desc); ++ if (err) { ++ netdev_err(dev, "Linux processing - Can't refill\n"); ++ rxq->missed++; ++ goto err_drop_frame; ++ } ++ + skb = build_skb(data, pp->frag_size > PAGE_SIZE ? 0 : pp->frag_size); + if (!skb) + goto err_drop_frame; +@@ -1522,14 +1528,6 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, + mvneta_rx_csum(pp, rx_status, skb); + + napi_gro_receive(&pp->napi, skb); +- +- /* Refill processing */ +- err = mvneta_rx_refill(pp, rx_desc); +- if (err) { +- netdev_err(dev, "Linux processing - Can't refill\n"); +- rxq->missed++; +- rx_filled--; +- } + } + + if (rcvd_pkts) { +@@ -1542,7 +1540,7 @@ static int mvneta_rx(struct mvneta_port *pp, int rx_todo, + } + + /* Update rxq management counters */ +- mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_filled); ++ mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done); + + return rx_done; + } diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index 9eeddbd..6d9e10d 100644 --- a/drivers/net/ethernet/neterion/s2io.c @@ -48824,7 +49086,7 @@ index fbf7dcd..ad71499 100644 }; diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c -index e8c21f9..747b848 100644 +index e8c21f9..6ecd8cc 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c @@ -422,7 +422,7 @@ static void macvtap_setup(struct net_device *dev) @@ -48854,6 +49116,14 @@ index e8c21f9..747b848 100644 .notifier_call = macvtap_device_event, }; +@@ -1250,6 +1250,7 @@ static void macvtap_exit(void) + class_unregister(macvtap_class); + cdev_del(&macvtap_cdev); + unregister_chrdev_region(macvtap_major, MACVTAP_NUM_DEVS); ++ idr_destroy(&minor_idr); + } + module_exit(macvtap_exit); + diff --git a/drivers/net/nlmon.c b/drivers/net/nlmon.c index d2bb12b..d6c921e 100644 --- a/drivers/net/nlmon.c @@ -49148,6 +49418,51 @@ index 841b608..198a8b7 100644 #define VIRTNET_DRIVER_VERSION "1.0.0" +diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c +index 0fa3b44..e913fc9 100644 +--- a/drivers/net/vmxnet3/vmxnet3_drv.c ++++ b/drivers/net/vmxnet3/vmxnet3_drv.c +@@ -1156,7 +1156,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, + static const u32 rxprod_reg[2] = { + VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2 + }; +- u32 num_rxd = 0; ++ u32 num_pkts = 0; + bool skip_page_frags = false; + struct Vmxnet3_RxCompDesc *rcd; + struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx; +@@ -1174,13 +1174,12 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, + struct Vmxnet3_RxDesc *rxd; + u32 idx, ring_idx; + struct vmxnet3_cmd_ring *ring = NULL; +- if (num_rxd >= quota) { ++ if (num_pkts >= quota) { + /* we may stop even before we see the EOP desc of + * the current pkt + */ + break; + } +- num_rxd++; + BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2); + idx = rcd->rxdIdx; + ring_idx = rcd->rqID < adapter->num_rx_queues ? 0 : 1; +@@ -1312,6 +1311,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, + napi_gro_receive(&rq->napi, skb); + + ctx->skb = NULL; ++ num_pkts++; + } + + rcd_done: +@@ -1342,7 +1342,7 @@ rcd_done: + &rq->comp_ring.base[rq->comp_ring.next2proc].rcd, &rxComp); + } + +- return num_rxd; ++ return num_pkts; + } + + diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 5988910..be561a2 100644 --- a/drivers/net/vxlan.c @@ -52600,6 +52915,21 @@ index 40d8592..8e89146 100644 int block_sectors = 0; long error_sector; struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk); +diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c +index a1d6986..f310982 100644 +--- a/drivers/scsi/st.c ++++ b/drivers/scsi/st.c +@@ -1262,9 +1262,9 @@ static int st_open(struct inode *inode, struct file *filp) + spin_lock(&st_use_lock); + STp->in_use = 0; + spin_unlock(&st_use_lock); +- scsi_tape_put(STp); + if (resumed) + scsi_autopm_put_device(STp->device); ++ scsi_tape_put(STp); + return retval; + + } diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index d6563ec..a1c5da2 100644 --- a/drivers/spi/spi.c @@ -65676,10 +66006,20 @@ index c71e886..61d3d44b 100644 if (retval > 0) retval = 0; diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c -index bb7991c..481e21a 100644 +index bb7991c..9c2bc01 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c -@@ -1312,7 +1312,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) +@@ -540,8 +540,7 @@ static struct inode *v9fs_qid_iget(struct super_block *sb, + unlock_new_inode(inode); + return inode; + error: +- unlock_new_inode(inode); +- iput(inode); ++ iget_failed(inode); + return ERR_PTR(retval); + + } +@@ -1312,7 +1311,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd) void v9fs_vfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) { @@ -65688,6 +66028,20 @@ index bb7991c..481e21a 100644 p9_debug(P9_DEBUG_VFS, " %s %s\n", dentry->d_name.name, IS_ERR(s) ? "<error>" : s); +diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c +index 59dc8e8..de8606c 100644 +--- a/fs/9p/vfs_inode_dotl.c ++++ b/fs/9p/vfs_inode_dotl.c +@@ -149,8 +149,7 @@ static struct inode *v9fs_qid_iget_dotl(struct super_block *sb, + unlock_new_inode(inode); + return inode; + error: +- unlock_new_inode(inode); +- iput(inode); ++ iget_failed(inode); + return ERR_PTR(retval); + + } diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index 370b24c..ff0be7b 100644 --- a/fs/Kconfig.binfmt @@ -68121,7 +68475,7 @@ index a93f7e6..d58bcbe 100644 return 0; while (nr) { diff --git a/fs/dcache.c b/fs/dcache.c -index aa24f7d..befb5fd 100644 +index aa24f7d..8f1bf8c 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -250,7 +250,7 @@ static void __d_free(struct rcu_head *head) @@ -68133,7 +68487,17 @@ index aa24f7d..befb5fd 100644 this_cpu_dec(nr_dentry); if (dentry->d_op && dentry->d_op->d_release) dentry->d_op->d_release(dentry); -@@ -596,7 +596,7 @@ repeat: +@@ -587,6 +587,9 @@ repeat: + if (unlikely(d_unhashed(dentry))) + goto kill_it; + ++ if (unlikely(dentry->d_flags & DCACHE_DISCONNECTED)) ++ goto kill_it; ++ + if (unlikely(dentry->d_flags & DCACHE_OP_DELETE)) { + if (dentry->d_op->d_delete(dentry)) + goto kill_it; +@@ -596,7 +599,7 @@ repeat: dentry->d_flags |= DCACHE_REFERENCED; dentry_lru_add(dentry); @@ -68142,7 +68506,7 @@ index aa24f7d..befb5fd 100644 spin_unlock(&dentry->d_lock); return; -@@ -651,7 +651,7 @@ int d_invalidate(struct dentry * dentry) +@@ -651,7 +654,7 @@ int d_invalidate(struct dentry * dentry) * We also need to leave mountpoints alone, * directory or not. */ @@ -68151,7 +68515,7 @@ index aa24f7d..befb5fd 100644 if (S_ISDIR(dentry->d_inode->i_mode) || d_mountpoint(dentry)) { spin_unlock(&dentry->d_lock); return -EBUSY; -@@ -667,7 +667,7 @@ EXPORT_SYMBOL(d_invalidate); +@@ -667,7 +670,7 @@ EXPORT_SYMBOL(d_invalidate); /* This must be called with d_lock held */ static inline void __dget_dlock(struct dentry *dentry) { @@ -68160,7 +68524,7 @@ index aa24f7d..befb5fd 100644 } static inline void __dget(struct dentry *dentry) -@@ -708,8 +708,8 @@ repeat: +@@ -708,8 +711,8 @@ repeat: goto repeat; } rcu_read_unlock(); @@ -68171,7 +68535,7 @@ index aa24f7d..befb5fd 100644 spin_unlock(&ret->d_lock); return ret; } -@@ -792,7 +792,7 @@ restart: +@@ -792,7 +795,7 @@ restart: spin_lock(&inode->i_lock); hlist_for_each_entry(dentry, &inode->i_dentry, d_u.d_alias) { spin_lock(&dentry->d_lock); @@ -68180,7 +68544,7 @@ index aa24f7d..befb5fd 100644 /* * inform the fs via d_prune that this dentry * is about to be unhashed and destroyed. -@@ -884,7 +884,7 @@ static void shrink_dentry_list(struct list_head *list) +@@ -884,7 +887,7 @@ static void shrink_dentry_list(struct list_head *list) * We found an inuse dentry which was not removed from * the LRU because of laziness during lookup. Do not free it. */ @@ -68189,7 +68553,7 @@ index aa24f7d..befb5fd 100644 spin_unlock(&dentry->d_lock); continue; } -@@ -930,7 +930,7 @@ dentry_lru_isolate(struct list_head *item, spinlock_t *lru_lock, void *arg) +@@ -930,7 +933,7 @@ dentry_lru_isolate(struct list_head *item, spinlock_t *lru_lock, void *arg) * counts, just remove them from the LRU. Otherwise give them * another pass through the LRU. */ @@ -68198,7 +68562,7 @@ index aa24f7d..befb5fd 100644 d_lru_isolate(dentry); spin_unlock(&dentry->d_lock); return LRU_REMOVED; -@@ -1269,7 +1269,7 @@ static enum d_walk_ret select_collect(void *_data, struct dentry *dentry) +@@ -1269,7 +1272,7 @@ static enum d_walk_ret select_collect(void *_data, struct dentry *dentry) * loop in shrink_dcache_parent() might not make any progress * and loop forever. */ @@ -68207,7 +68571,7 @@ index aa24f7d..befb5fd 100644 dentry_lru_del(dentry); } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) { /* -@@ -1323,11 +1323,11 @@ static enum d_walk_ret umount_collect(void *_data, struct dentry *dentry) +@@ -1323,11 +1326,11 @@ static enum d_walk_ret umount_collect(void *_data, struct dentry *dentry) struct select_data *data = _data; enum d_walk_ret ret = D_WALK_CONTINUE; @@ -68221,7 +68585,7 @@ index aa24f7d..befb5fd 100644 goto out; printk(KERN_ERR "BUG: Dentry %p{i=%lx,n=%s}" -@@ -1337,7 +1337,7 @@ static enum d_walk_ret umount_collect(void *_data, struct dentry *dentry) +@@ -1337,7 +1340,7 @@ static enum d_walk_ret umount_collect(void *_data, struct dentry *dentry) dentry->d_inode ? dentry->d_inode->i_ino : 0UL, dentry->d_name.name, @@ -68230,7 +68594,7 @@ index aa24f7d..befb5fd 100644 dentry->d_sb->s_type->name, dentry->d_sb->s_id); BUG(); -@@ -1495,7 +1495,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) +@@ -1495,7 +1498,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) */ dentry->d_iname[DNAME_INLINE_LEN-1] = 0; if (name->len > DNAME_INLINE_LEN-1) { @@ -68239,7 +68603,7 @@ index aa24f7d..befb5fd 100644 if (!dname) { kmem_cache_free(dentry_cache, dentry); return NULL; -@@ -1513,7 +1513,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) +@@ -1513,7 +1516,7 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) smp_wmb(); dentry->d_name.name = dname; @@ -68248,7 +68612,7 @@ index aa24f7d..befb5fd 100644 dentry->d_flags = 0; spin_lock_init(&dentry->d_lock); seqcount_init(&dentry->d_seq); -@@ -1522,6 +1522,9 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) +@@ -1522,6 +1525,9 @@ struct dentry *__d_alloc(struct super_block *sb, const struct qstr *name) dentry->d_sb = sb; dentry->d_op = NULL; dentry->d_fsdata = NULL; @@ -68258,7 +68622,7 @@ index aa24f7d..befb5fd 100644 INIT_HLIST_BL_NODE(&dentry->d_hash); INIT_LIST_HEAD(&dentry->d_lru); INIT_LIST_HEAD(&dentry->d_subdirs); -@@ -2276,7 +2279,7 @@ struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name) +@@ -2276,7 +2282,7 @@ struct dentry *__d_lookup(const struct dentry *parent, const struct qstr *name) goto next; } @@ -68267,7 +68631,7 @@ index aa24f7d..befb5fd 100644 found = dentry; spin_unlock(&dentry->d_lock); break; -@@ -2375,7 +2378,7 @@ again: +@@ -2375,7 +2381,7 @@ again: spin_lock(&dentry->d_lock); inode = dentry->d_inode; isdir = S_ISDIR(inode->i_mode); @@ -68276,7 +68640,7 @@ index aa24f7d..befb5fd 100644 if (!spin_trylock(&inode->i_lock)) { spin_unlock(&dentry->d_lock); cpu_relax(); -@@ -3308,7 +3311,7 @@ static enum d_walk_ret d_genocide_kill(void *data, struct dentry *dentry) +@@ -3308,7 +3314,7 @@ static enum d_walk_ret d_genocide_kill(void *data, struct dentry *dentry) if (!(dentry->d_flags & DCACHE_GENOCIDE)) { dentry->d_flags |= DCACHE_GENOCIDE; @@ -68285,7 +68649,7 @@ index aa24f7d..befb5fd 100644 } } return D_WALK_CONTINUE; -@@ -3424,7 +3427,8 @@ void __init vfs_caches_init(unsigned long mempages) +@@ -3424,7 +3430,8 @@ void __init vfs_caches_init(unsigned long mempages) mempages -= reserve; names_cachep = kmem_cache_create("names_cache", PATH_MAX, 0, @@ -82401,7 +82765,7 @@ index 0000000..25f54ef +}; diff --git a/grsecurity/gracl_policy.c b/grsecurity/gracl_policy.c new file mode 100644 -index 0000000..fd26052 +index 0000000..7dc01b3 --- /dev/null +++ b/grsecurity/gracl_policy.c @@ -0,0 +1,1781 @@ @@ -82860,7 +83224,7 @@ index 0000000..fd26052 + get_fs_root(reaper->fs, &gr_real_root); + +#ifdef CONFIG_GRKERNSEC_RBAC_DEBUG -+ printk(KERN_ALERT "Obtained real root device=%d, inode=%lu\n", __get_dev(gr_real_root.dentry), gr_real_root.dentry->d_inode->i_ino); ++ printk(KERN_ALERT "Obtained real root device=%d, inode=%lu\n", gr_get_dev_from_dentry(gr_real_root.dentry), gr_get_ino_from_dentry(gr_real_root.dentry)); +#endif + + fakefs_obj_rw = kzalloc(sizeof(struct acl_object_label), GFP_KERNEL); @@ -85841,7 +86205,7 @@ index 0000000..8ca18bf +} diff --git a/grsecurity/grsec_init.c b/grsecurity/grsec_init.c new file mode 100644 -index 0000000..4ed9e7d +index 0000000..a364c58 --- /dev/null +++ b/grsecurity/grsec_init.c @@ -0,0 +1,290 @@ @@ -85854,61 +86218,61 @@ index 0000000..4ed9e7d +#include <linux/percpu.h> +#include <linux/module.h> + -+int grsec_enable_ptrace_readexec; -+int grsec_enable_setxid; -+int grsec_enable_symlinkown; -+kgid_t grsec_symlinkown_gid; -+int grsec_enable_brute; -+int grsec_enable_link; -+int grsec_enable_dmesg; -+int grsec_enable_harden_ptrace; -+int grsec_enable_harden_ipc; -+int grsec_enable_fifo; -+int grsec_enable_execlog; -+int grsec_enable_signal; -+int grsec_enable_forkfail; -+int grsec_enable_audit_ptrace; -+int grsec_enable_time; -+int grsec_enable_group; -+kgid_t grsec_audit_gid; -+int grsec_enable_chdir; -+int grsec_enable_mount; -+int grsec_enable_rofs; -+int grsec_deny_new_usb; -+int grsec_enable_chroot_findtask; -+int grsec_enable_chroot_mount; -+int grsec_enable_chroot_shmat; -+int grsec_enable_chroot_fchdir; -+int grsec_enable_chroot_double; -+int grsec_enable_chroot_pivot; -+int grsec_enable_chroot_chdir; -+int grsec_enable_chroot_chmod; -+int grsec_enable_chroot_mknod; -+int grsec_enable_chroot_nice; -+int grsec_enable_chroot_execlog; -+int grsec_enable_chroot_caps; -+int grsec_enable_chroot_rename; -+int grsec_enable_chroot_sysctl; -+int grsec_enable_chroot_unix; -+int grsec_enable_tpe; -+kgid_t grsec_tpe_gid; -+int grsec_enable_blackhole; ++int grsec_enable_ptrace_readexec __read_only; ++int grsec_enable_setxid __read_only; ++int grsec_enable_symlinkown __read_only; ++kgid_t grsec_symlinkown_gid __read_only; ++int grsec_enable_brute __read_only; ++int grsec_enable_link __read_only; ++int grsec_enable_dmesg __read_only; ++int grsec_enable_harden_ptrace __read_only; ++int grsec_enable_harden_ipc __read_only; ++int grsec_enable_fifo __read_only; ++int grsec_enable_execlog __read_only; ++int grsec_enable_signal __read_only; ++int grsec_enable_forkfail __read_only; ++int grsec_enable_audit_ptrace __read_only; ++int grsec_enable_time __read_only; ++int grsec_enable_group __read_only; ++kgid_t grsec_audit_gid __read_only; ++int grsec_enable_chdir __read_only; ++int grsec_enable_mount __read_only; ++int grsec_enable_rofs __read_only; ++int grsec_deny_new_usb __read_only; ++int grsec_enable_chroot_findtask __read_only; ++int grsec_enable_chroot_mount __read_only; ++int grsec_enable_chroot_shmat __read_only; ++int grsec_enable_chroot_fchdir __read_only; ++int grsec_enable_chroot_double __read_only; ++int grsec_enable_chroot_pivot __read_only; ++int grsec_enable_chroot_chdir __read_only; ++int grsec_enable_chroot_chmod __read_only; ++int grsec_enable_chroot_mknod __read_only; ++int grsec_enable_chroot_nice __read_only; ++int grsec_enable_chroot_execlog __read_only; ++int grsec_enable_chroot_caps __read_only; ++int grsec_enable_chroot_rename __read_only; ++int grsec_enable_chroot_sysctl __read_only; ++int grsec_enable_chroot_unix __read_only; ++int grsec_enable_tpe __read_only; ++kgid_t grsec_tpe_gid __read_only; ++int grsec_enable_blackhole __read_only; +#ifdef CONFIG_IPV6_MODULE +EXPORT_SYMBOL_GPL(grsec_enable_blackhole); +#endif -+int grsec_lastack_retries; -+int grsec_enable_tpe_all; -+int grsec_enable_tpe_invert; -+int grsec_enable_socket_all; -+kgid_t grsec_socket_all_gid; -+int grsec_enable_socket_client; -+kgid_t grsec_socket_client_gid; -+int grsec_enable_socket_server; -+kgid_t grsec_socket_server_gid; -+int grsec_resource_logging; -+int grsec_disable_privio; -+int grsec_enable_log_rwxmaps; -+int grsec_lock; ++int grsec_lastack_retries __read_only; ++int grsec_enable_tpe_all __read_only; ++int grsec_enable_tpe_invert __read_only; ++int grsec_enable_socket_all __read_only; ++kgid_t grsec_socket_all_gid __read_only; ++int grsec_enable_socket_client __read_only; ++kgid_t grsec_socket_client_gid __read_only; ++int grsec_enable_socket_server __read_only; ++kgid_t grsec_socket_server_gid __read_only; ++int grsec_resource_logging __read_only; ++int grsec_disable_privio __read_only; ++int grsec_enable_log_rwxmaps __read_only; ++int grsec_lock __read_only; + +DEFINE_SPINLOCK(grsec_alert_lock); +unsigned long grsec_alert_wtime = 0; @@ -87332,7 +87696,7 @@ index 0000000..a523bd2 +} diff --git a/grsecurity/grsec_sysctl.c b/grsecurity/grsec_sysctl.c new file mode 100644 -index 0000000..cce889e +index 0000000..aaec43c --- /dev/null +++ b/grsecurity/grsec_sysctl.c @@ -0,0 +1,488 @@ @@ -87371,7 +87735,7 @@ index 0000000..cce889e + .data = &grsec_disable_privio, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#endif @@ -87381,7 +87745,7 @@ index 0000000..cce889e + .data = &grsec_enable_link, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_SYMLINKOWN @@ -87390,14 +87754,14 @@ index 0000000..cce889e + .data = &grsec_enable_symlinkown, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, + { + .procname = "symlinkown_gid", + .data = &grsec_symlinkown_gid, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_BRUTE @@ -87406,7 +87770,7 @@ index 0000000..cce889e + .data = &grsec_enable_brute, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_FIFO @@ -87415,7 +87779,7 @@ index 0000000..cce889e + .data = &grsec_enable_fifo, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_PTRACE_READEXEC @@ -87424,7 +87788,7 @@ index 0000000..cce889e + .data = &grsec_enable_ptrace_readexec, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_SETXID @@ -87433,7 +87797,7 @@ index 0000000..cce889e + .data = &grsec_enable_setxid, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_BLACKHOLE @@ -87442,14 +87806,14 @@ index 0000000..cce889e + .data = &grsec_enable_blackhole, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, + { + .procname = "lastack_retries", + .data = &grsec_lastack_retries, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_EXECLOG @@ -87458,7 +87822,7 @@ index 0000000..cce889e + .data = &grsec_enable_execlog, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_RWXMAP_LOG @@ -87467,7 +87831,7 @@ index 0000000..cce889e + .data = &grsec_enable_log_rwxmaps, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_SIGNAL @@ -87476,7 +87840,7 @@ index 0000000..cce889e + .data = &grsec_enable_signal, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_FORKFAIL @@ -87485,7 +87849,7 @@ index 0000000..cce889e + .data = &grsec_enable_forkfail, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_TIME @@ -87494,7 +87858,7 @@ index 0000000..cce889e + .data = &grsec_enable_time, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_SHMAT @@ -87503,7 +87867,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_shmat, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_UNIX @@ -87512,7 +87876,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_unix, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_MOUNT @@ -87521,7 +87885,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_mount, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR @@ -87530,7 +87894,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_fchdir, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_DOUBLE @@ -87539,7 +87903,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_double, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_PIVOT @@ -87548,7 +87912,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_pivot, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_CHDIR @@ -87557,7 +87921,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_chdir, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_CHMOD @@ -87566,7 +87930,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_chmod, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_MKNOD @@ -87575,7 +87939,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_mknod, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_NICE @@ -87584,7 +87948,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_nice, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_EXECLOG @@ -87593,7 +87957,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_execlog, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_CAPS @@ -87602,7 +87966,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_caps, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_RENAME @@ -87611,7 +87975,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_rename, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_SYSCTL @@ -87620,7 +87984,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_sysctl, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_TPE @@ -87629,14 +87993,14 @@ index 0000000..cce889e + .data = &grsec_enable_tpe, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, + { + .procname = "tpe_gid", + .data = &grsec_tpe_gid, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_TPE_INVERT @@ -87645,7 +88009,7 @@ index 0000000..cce889e + .data = &grsec_enable_tpe_invert, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_TPE_ALL @@ -87654,7 +88018,7 @@ index 0000000..cce889e + .data = &grsec_enable_tpe_all, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_SOCKET_ALL @@ -87663,14 +88027,14 @@ index 0000000..cce889e + .data = &grsec_enable_socket_all, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, + { + .procname = "socket_all_gid", + .data = &grsec_socket_all_gid, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_SOCKET_CLIENT @@ -87679,14 +88043,14 @@ index 0000000..cce889e + .data = &grsec_enable_socket_client, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, + { + .procname = "socket_client_gid", + .data = &grsec_socket_client_gid, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_SOCKET_SERVER @@ -87695,14 +88059,14 @@ index 0000000..cce889e + .data = &grsec_enable_socket_server, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, + { + .procname = "socket_server_gid", + .data = &grsec_socket_server_gid, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_AUDIT_GROUP @@ -87711,14 +88075,14 @@ index 0000000..cce889e + .data = &grsec_enable_group, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, + { + .procname = "audit_gid", + .data = &grsec_audit_gid, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_AUDIT_CHDIR @@ -87727,7 +88091,7 @@ index 0000000..cce889e + .data = &grsec_enable_chdir, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_AUDIT_MOUNT @@ -87736,7 +88100,7 @@ index 0000000..cce889e + .data = &grsec_enable_mount, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_DMESG @@ -87745,7 +88109,7 @@ index 0000000..cce889e + .data = &grsec_enable_dmesg, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK @@ -87754,7 +88118,7 @@ index 0000000..cce889e + .data = &grsec_enable_chroot_findtask, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_RESLOG @@ -87763,7 +88127,7 @@ index 0000000..cce889e + .data = &grsec_resource_logging, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_AUDIT_PTRACE @@ -87772,7 +88136,7 @@ index 0000000..cce889e + .data = &grsec_enable_audit_ptrace, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_HARDEN_PTRACE @@ -87781,7 +88145,7 @@ index 0000000..cce889e + .data = &grsec_enable_harden_ptrace, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_HARDEN_IPC @@ -87790,7 +88154,7 @@ index 0000000..cce889e + .data = &grsec_enable_harden_ipc, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif + { @@ -87798,7 +88162,7 @@ index 0000000..cce889e + .data = &grsec_lock, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif +#ifdef CONFIG_GRKERNSEC_ROFS @@ -87807,7 +88171,7 @@ index 0000000..cce889e + .data = &grsec_enable_rofs, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec_minmax, ++ .proc_handler = &proc_dointvec_minmax_secure, + .extra1 = &one, + .extra2 = &one, + }, @@ -87818,7 +88182,7 @@ index 0000000..cce889e + .data = &grsec_deny_new_usb, + .maxlen = sizeof(int), + .mode = 0600, -+ .proc_handler = &proc_dointvec, ++ .proc_handler = &proc_dointvec_secure, + }, +#endif + { } @@ -89080,8 +89444,31 @@ index 939533d..cf0a57c 100644 /** * struct clk_init_data - holds init data that's common to all clocks and is +diff --git a/include/linux/clkdev.h b/include/linux/clkdev.h +index 94bad77..a39e810 100644 +--- a/include/linux/clkdev.h ++++ b/include/linux/clkdev.h +@@ -32,7 +32,7 @@ struct clk_lookup { + } + + struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id, +- const char *dev_fmt, ...); ++ const char *dev_fmt, ...) __printf(3, 4); + + void clkdev_add(struct clk_lookup *cl); + void clkdev_drop(struct clk_lookup *cl); +@@ -40,7 +40,8 @@ void clkdev_drop(struct clk_lookup *cl); + void clkdev_add_table(struct clk_lookup *, size_t); + int clk_add_alias(const char *, const char *, char *, struct device *); + +-int clk_register_clkdev(struct clk *, const char *, const char *, ...); ++int clk_register_clkdev(struct clk *, const char *, const char *, ...) ++ __printf(3, 4); + int clk_register_clkdevs(struct clk *, struct clk_lookup *, size_t); + + #ifdef CONFIG_COMMON_CLK diff --git a/include/linux/compat.h b/include/linux/compat.h -index 3f448c6..8dd869d 100644 +index 3f448c6..4d53187 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h @@ -313,7 +313,7 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, @@ -89102,6 +89489,15 @@ index 3f448c6..8dd869d 100644 asmlinkage long compat_sys_keyctl(u32 option, u32 arg2, u32 arg3, u32 arg4, u32 arg5); asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u32); +@@ -405,7 +405,7 @@ asmlinkage long compat_sys_settimeofday(struct compat_timeval __user *tv, + + asmlinkage long compat_sys_adjtimex(struct compat_timex __user *utp); + +-extern int compat_printk(const char *fmt, ...); ++extern __printf(1, 2) int compat_printk(const char *fmt, ...); + extern void sigset_from_compat(sigset_t *set, const compat_sigset_t *compat); + extern void sigset_to_compat(compat_sigset_t *compat, const sigset_t *set); + @@ -420,7 +420,7 @@ extern int compat_ptrace_request(struct task_struct *child, extern long compat_arch_ptrace(struct task_struct *child, compat_long_t request, compat_ulong_t addr, compat_ulong_t data); @@ -89151,10 +89547,10 @@ index 2507fd2..55203f8 100644 * Mark a position in code as unreachable. This can be used to * suppress control flow warnings after asm blocks that transfer diff --git a/include/linux/compiler-gcc5.h b/include/linux/compiler-gcc5.h -index cdd1cc2..9c1ee22 100644 +index cdd1cc2..d062745 100644 --- a/include/linux/compiler-gcc5.h +++ b/include/linux/compiler-gcc5.h -@@ -28,6 +28,31 @@ +@@ -28,6 +28,30 @@ # define __compiletime_error(message) __attribute__((error(message))) #endif /* __CHECKER__ */ @@ -89174,7 +89570,6 @@ index cdd1cc2..9c1ee22 100644 +#endif + +#ifdef SIZE_OVERFLOW_PLUGIN -+#error not yet +#define __size_overflow(...) __attribute__((size_overflow(__VA_ARGS__))) +#define __intentional_overflow(...) __attribute__((intentional_overflow(__VA_ARGS__))) +#endif @@ -89186,7 +89581,7 @@ index cdd1cc2..9c1ee22 100644 /* * Mark a position in code as unreachable. This can be used to * suppress control flow warnings after asm blocks that transfer -@@ -53,7 +78,6 @@ +@@ -53,7 +77,6 @@ * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58670 * * Work it around via a compiler barrier quirk suggested by Jakub Jelinek. @@ -89368,19 +89763,20 @@ index 5d5aaae..0ea9b84 100644 extern bool completion_done(struct completion *x); diff --git a/include/linux/configfs.h b/include/linux/configfs.h -index 34025df..2a6ee32 100644 +index 34025df..9c263df 100644 --- a/include/linux/configfs.h +++ b/include/linux/configfs.h -@@ -64,7 +64,7 @@ struct config_item { +@@ -64,7 +64,8 @@ struct config_item { struct dentry *ci_dentry; }; -extern int config_item_set_name(struct config_item *, const char *, ...); -+extern __printf(2, 3) int config_item_set_name(struct config_item *, const char *, ...); ++extern __printf(2, 3) ++int config_item_set_name(struct config_item *, const char *, ...); static inline char *config_item_name(struct config_item * item) { -@@ -125,7 +125,7 @@ struct configfs_attribute { +@@ -125,7 +126,7 @@ struct configfs_attribute { const char *ca_name; struct module *ca_owner; umode_t ca_mode; @@ -89568,7 +89964,7 @@ index 653589e..4ef254a 100644 return c | 0x20; } diff --git a/include/linux/dcache.h b/include/linux/dcache.h -index 0f0eb1c..776283e 100644 +index 0f0eb1c..3c17a3d 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -123,6 +123,9 @@ struct dentry { @@ -89590,6 +89986,16 @@ index 0f0eb1c..776283e 100644 /* * dentry->d_lock spinlock nesting subclasses: +@@ -328,7 +331,8 @@ extern int d_validate(struct dentry *, struct dentry *); + /* + * helper function for dentry_operations.d_dname() members + */ +-extern char *dynamic_dname(struct dentry *, char *, int, const char *, ...); ++extern __printf(4, 5) ++char *dynamic_dname(struct dentry *, char *, int, const char *, ...); + extern char *simple_dname(struct dentry *, char *, int); + + extern char *__d_path(const struct path *, const struct path *, char *, int); diff --git a/include/linux/decompress/mm.h b/include/linux/decompress/mm.h index 7925bf0..d5143d2 100644 --- a/include/linux/decompress/mm.h @@ -89617,7 +90023,7 @@ index d48dc00..211ee54 100644 /** * struct devfreq - Device devfreq structure diff --git a/include/linux/device.h b/include/linux/device.h -index 952b010..d5b7691 100644 +index 952b010..2f65744 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -310,7 +310,7 @@ struct subsys_interface { @@ -89652,6 +90058,23 @@ index 952b010..d5b7691 100644 ssize_t device_show_ulong(struct device *dev, struct device_attribute *attr, char *buf); +@@ -956,12 +957,10 @@ extern int __must_check device_reprobe(struct device *dev); + /* + * Easy functions for dynamically creating devices on the fly + */ +-extern struct device *device_create_vargs(struct class *cls, +- struct device *parent, +- dev_t devt, +- void *drvdata, +- const char *fmt, +- va_list vargs); ++extern __printf(5, 0) ++struct device *device_create_vargs(struct class *cls, struct device *parent, ++ dev_t devt, void *drvdata, ++ const char *fmt, va_list vargs); + extern __printf(5, 6) + struct device *device_create(struct class *cls, struct device *parent, + dev_t devt, void *drvdata, diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index fd4aee2..1f28db9 100644 --- a/include/linux/dma-mapping.h @@ -91739,6 +92162,42 @@ index 6883e19..e854fcb 100644 /* This macro allows us to keep printk typechecking */ static __printf(1, 2) +diff --git a/include/linux/kernel.h b/include/linux/kernel.h +index 196d1ea..86a6927 100644 +--- a/include/linux/kernel.h ++++ b/include/linux/kernel.h +@@ -397,7 +397,8 @@ extern __printf(3, 0) + int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); + extern __printf(2, 3) + char *kasprintf(gfp_t gfp, const char *fmt, ...); +-extern char *kvasprintf(gfp_t gfp, const char *fmt, va_list args); ++extern __printf(2, 0) ++char *kvasprintf(gfp_t gfp, const char *fmt, va_list args); + + extern __scanf(2, 3) + int sscanf(const char *, const char *, ...); +@@ -670,10 +671,10 @@ do { \ + __ftrace_vprintk(_THIS_IP_, fmt, vargs); \ + } while (0) + +-extern int ++extern __printf(2, 0) int + __ftrace_vbprintk(unsigned long ip, const char *fmt, va_list ap); + +-extern int ++extern __printf(2, 0) int + __ftrace_vprintk(unsigned long ip, const char *fmt, va_list ap); + + extern void ftrace_dump(enum ftrace_dump_mode oops_dump_mode); +@@ -693,7 +694,7 @@ int trace_printk(const char *fmt, ...) + { + return 0; + } +-static inline int ++static __printf(1, 0) inline int + ftrace_vprintk(const char *fmt, va_list ap) + { + return 0; diff --git a/include/linux/key-type.h b/include/linux/key-type.h index a74c3a8..28d3f21 100644 --- a/include/linux/key-type.h @@ -91807,10 +92266,22 @@ index 0555cc6..40116ce 100644 char **envp; int wait; diff --git a/include/linux/kobject.h b/include/linux/kobject.h -index 926afb6..58dd6e5 100644 +index 926afb6..e4d3dd9 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h -@@ -116,7 +116,7 @@ struct kobj_type { +@@ -78,8 +78,9 @@ struct kobject { + + extern __printf(2, 3) + int kobject_set_name(struct kobject *kobj, const char *name, ...); +-extern int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, +- va_list vargs); ++extern __printf(2, 0) ++int kobject_set_name_vargs(struct kobject *kobj, const char *fmt, ++ va_list vargs); + + static inline const char *kobject_name(const struct kobject *kobj) + { +@@ -116,7 +117,7 @@ struct kobj_type { struct attribute **default_attrs; const struct kobj_ns_type_operations *(*child_ns_type)(struct kobject *kobj); const void *(*namespace)(struct kobject *kobj); @@ -91819,7 +92290,7 @@ index 926afb6..58dd6e5 100644 struct kobj_uevent_env { char *envp[UEVENT_NUM_ENVP]; -@@ -139,6 +139,7 @@ struct kobj_attribute { +@@ -139,6 +140,7 @@ struct kobj_attribute { ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count); }; @@ -91827,7 +92298,7 @@ index 926afb6..58dd6e5 100644 extern const struct sysfs_ops kobj_sysfs_ops; -@@ -166,7 +167,7 @@ struct kset { +@@ -166,7 +168,7 @@ struct kset { spinlock_t list_lock; struct kobject kobj; const struct kset_uevent_ops *uevent_ops; @@ -92388,7 +92859,7 @@ index 87079fc..7724b1f 100644 /* * Standard errno values are used for errors, but some have specific diff --git a/include/linux/mmiotrace.h b/include/linux/mmiotrace.h -index c5d5278..f0b68c8 100644 +index c5d5278..85cd5ce 100644 --- a/include/linux/mmiotrace.h +++ b/include/linux/mmiotrace.h @@ -46,7 +46,7 @@ extern int kmmio_handler(struct pt_regs *regs, unsigned long addr); @@ -92409,6 +92880,14 @@ index c5d5278..f0b68c8 100644 { } +@@ -106,6 +106,6 @@ extern void enable_mmiotrace(void); + extern void disable_mmiotrace(void); + extern void mmio_trace_rw(struct mmiotrace_rw *rw); + extern void mmio_trace_mapping(struct mmiotrace_map *map); +-extern int mmio_trace_printk(const char *fmt, va_list args); ++extern __printf(1, 0) int mmio_trace_printk(const char *fmt, va_list args); + + #endif /* _LINUX_MMIOTRACE_H */ diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index ac819bf..838afec 100644 --- a/include/linux/mmzone.h @@ -93159,7 +93638,7 @@ index 1841b58..fbeebf8 100644 #define preempt_set_need_resched() \ do { \ diff --git a/include/linux/printk.h b/include/linux/printk.h -index cbf094f..86007b7 100644 +index cbf094f..630d761 100644 --- a/include/linux/printk.h +++ b/include/linux/printk.h @@ -114,6 +114,8 @@ static inline __printf(1, 2) __cold @@ -93171,7 +93650,7 @@ index cbf094f..86007b7 100644 #ifdef CONFIG_PRINTK asmlinkage __printf(5, 0) int vprintk_emit(int facility, int level, -@@ -148,7 +150,6 @@ extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, +@@ -148,13 +150,12 @@ extern bool printk_timed_ratelimit(unsigned long *caller_jiffies, extern int printk_delay_msec; extern int dmesg_restrict; @@ -93179,6 +93658,22 @@ index cbf094f..86007b7 100644 extern void wake_up_klogd(void); + void log_buf_kexec_setup(void); + void __init setup_log_buf(int early); +-void dump_stack_set_arch_desc(const char *fmt, ...); ++__printf(1, 2) void dump_stack_set_arch_desc(const char *fmt, ...); + void dump_stack_print_info(const char *log_lvl); + void show_regs_print_info(const char *log_lvl); + #else +@@ -195,7 +196,7 @@ static inline void setup_log_buf(int early) + { + } + +-static inline void dump_stack_set_arch_desc(const char *fmt, ...) ++static inline __printf(1, 2) void dump_stack_set_arch_desc(const char *fmt, ...) + { + } + diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h index 608e60a..bbcb1a0 100644 --- a/include/linux/proc_fs.h @@ -94377,10 +94872,10 @@ index 27b3b0b..e093dd9 100644 extern void register_syscore_ops(struct syscore_ops *ops); extern void unregister_syscore_ops(struct syscore_ops *ops); diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h -index 14a8ff2..fa95f3a 100644 +index 14a8ff2..65dc1e2 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h -@@ -34,13 +34,13 @@ struct ctl_table_root; +@@ -34,17 +34,21 @@ struct ctl_table_root; struct ctl_table_header; struct ctl_dir; @@ -94395,8 +94890,16 @@ index 14a8ff2..fa95f3a 100644 + void __user *, size_t *, loff_t *); extern int proc_dointvec(struct ctl_table *, int, void __user *, size_t *, loff_t *); ++extern int proc_dointvec_secure(struct ctl_table *, int, ++ void __user *, size_t *, loff_t *); extern int proc_dointvec_minmax(struct ctl_table *, int, -@@ -115,7 +115,9 @@ struct ctl_table + void __user *, size_t *, loff_t *); ++extern int proc_dointvec_minmax_secure(struct ctl_table *, int, ++ void __user *, size_t *, loff_t *); + extern int proc_dointvec_jiffies(struct ctl_table *, int, + void __user *, size_t *, loff_t *); + extern int proc_dointvec_userhz_jiffies(struct ctl_table *, int, +@@ -115,7 +119,9 @@ struct ctl_table struct ctl_table_poll *poll; void *extra1; void *extra2; @@ -97574,10 +98077,10 @@ index c18b1f1..b9a0132 100644 return -ENOMEM; diff --git a/kernel/cred.c b/kernel/cred.c -index e0573a4..20fb164 100644 +index e0573a4..3907beb 100644 --- a/kernel/cred.c +++ b/kernel/cred.c -@@ -164,6 +164,16 @@ void exit_creds(struct task_struct *tsk) +@@ -164,6 +164,15 @@ void exit_creds(struct task_struct *tsk) validate_creds(cred); alter_cred_subscribers(cred, -1); put_cred(cred); @@ -97587,14 +98090,13 @@ index e0573a4..20fb164 100644 + if (cred != NULL) { + tsk->delayed_cred = NULL; + validate_creds(cred); -+ alter_cred_subscribers(cred, -1); + put_cred(cred); + } +#endif } /** -@@ -411,7 +421,7 @@ static bool cred_cap_issubset(const struct cred *set, const struct cred *subset) +@@ -411,7 +420,7 @@ static bool cred_cap_issubset(const struct cred *set, const struct cred *subset) * Always returns 0 thus allowing this function to be tail-called at the end * of, say, sys_setgid(). */ @@ -97603,7 +98105,7 @@ index e0573a4..20fb164 100644 { struct task_struct *task = current; const struct cred *old = task->real_cred; -@@ -430,6 +440,8 @@ int commit_creds(struct cred *new) +@@ -430,6 +439,8 @@ int commit_creds(struct cred *new) get_cred(new); /* we will require a ref for the subj creds too */ @@ -97612,7 +98114,7 @@ index e0573a4..20fb164 100644 /* dumpability changes */ if (!uid_eq(old->euid, new->euid) || !gid_eq(old->egid, new->egid) || -@@ -479,6 +491,108 @@ int commit_creds(struct cred *new) +@@ -479,6 +490,108 @@ int commit_creds(struct cred *new) put_cred(old); return 0; } @@ -97808,7 +98310,7 @@ index 449518e..2658dd6 100644 #ifdef CONFIG_MODULE_UNLOAD { diff --git a/kernel/events/core.c b/kernel/events/core.c -index 60146fe..2e89117 100644 +index 60146fe..7037710 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -159,8 +159,15 @@ static struct srcu_struct pmus_srcu; @@ -97819,11 +98321,11 @@ index 60146fe..2e89117 100644 */ -int sysctl_perf_event_paranoid __read_mostly = 1; +#ifdef CONFIG_GRKERNSEC_PERF_HARDEN -+int sysctl_perf_event_legitimately_concerned __read_mostly = 3; ++int sysctl_perf_event_legitimately_concerned __read_only = 3; +#elif defined(CONFIG_GRKERNSEC_HIDESYM) -+int sysctl_perf_event_legitimately_concerned __read_mostly = 2; ++int sysctl_perf_event_legitimately_concerned __read_only = 2; +#else -+int sysctl_perf_event_legitimately_concerned __read_mostly = 1; ++int sysctl_perf_event_legitimately_concerned __read_only = 1; +#endif /* Minimum for 512 kiB + 1 user control page */ @@ -99388,7 +99890,7 @@ index 1d96dd0..994ff19 100644 default: diff --git a/kernel/module.c b/kernel/module.c -index 1d679a6..acc7443 100644 +index 1d679a6..b67e85e 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -61,6 +61,7 @@ @@ -99399,6 +99901,15 @@ index 1d679a6..acc7443 100644 #include <uapi/linux/module.h> #include "module-internal.h" +@@ -147,7 +148,7 @@ module_param(sig_enforce, bool_enable_only, 0644); + #endif /* CONFIG_MODULE_SIG */ + + /* Block module loading/unloading? */ +-int modules_disabled = 0; ++int modules_disabled __read_only = 0; + core_param(nomodule, modules_disabled, bint, 0); + + /* Waiting for a module to finish initializing? */ @@ -157,7 +158,8 @@ static BLOCKING_NOTIFIER_HEAD(module_notify_list); /* Bounds of module allocation, for speeding __module_address. @@ -100607,9 +101118,21 @@ index f1fe7ec..7d4e641 100644 if (pm_wakeup_pending()) { diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c -index a755ad7..bf7e534 100644 +index a755ad7..ba98f34 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c +@@ -359,9 +359,9 @@ static void log_store(int facility, int level, + } + + #ifdef CONFIG_SECURITY_DMESG_RESTRICT +-int dmesg_restrict = 1; ++int dmesg_restrict __read_only = 1; + #else +-int dmesg_restrict; ++int dmesg_restrict __read_only; + #endif + + static int syslog_action_restricted(int type) @@ -385,6 +385,11 @@ static int check_syslog_permissions(int type, bool from_file) if (from_file && type != SYSLOG_ACTION_OPEN) return 0; @@ -102248,7 +102771,7 @@ index c0a58be..95e292b 100644 if (!retval) { if (old_rlim) diff --git a/kernel/sysctl.c b/kernel/sysctl.c -index c1b26e1..bc7b50d 100644 +index c1b26e1..947cae6 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -94,7 +94,6 @@ @@ -102259,7 +102782,11 @@ index c1b26e1..bc7b50d 100644 /* External variables not in a header file. */ extern int max_threads; extern int suid_dumpable; -@@ -118,19 +117,18 @@ extern int blk_iopoll_enabled; +@@ -115,22 +114,22 @@ extern int sysctl_nr_trim_pages; + #ifdef CONFIG_BLOCK + extern int blk_iopoll_enabled; + #endif ++extern int sysctl_modify_ldt; /* Constants used for minimum and maximum */ #ifdef CONFIG_LOCKUP_DETECTOR @@ -102288,18 +102815,19 @@ index c1b26e1..bc7b50d 100644 #endif /* this is needed for the proc_doulongvec_minmax of vm_dirty_bytes */ -@@ -181,10 +179,8 @@ static int proc_taint(struct ctl_table *table, int write, +@@ -181,10 +180,8 @@ static int proc_taint(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); #endif -#ifdef CONFIG_PRINTK - static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, +-static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, ++static int proc_dointvec_minmax_secure_sysadmin(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); -#endif static int proc_dointvec_minmax_coredump(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos); -@@ -215,6 +211,8 @@ static int sysrq_sysctl_handler(ctl_table *table, int write, +@@ -215,6 +212,8 @@ static int sysrq_sysctl_handler(ctl_table *table, int write, #endif @@ -102308,7 +102836,7 @@ index c1b26e1..bc7b50d 100644 static struct ctl_table kern_table[]; static struct ctl_table vm_table[]; static struct ctl_table fs_table[]; -@@ -229,6 +227,20 @@ extern struct ctl_table epoll_table[]; +@@ -229,6 +228,20 @@ extern struct ctl_table epoll_table[]; int sysctl_legacy_va_layout; #endif @@ -102329,7 +102857,7 @@ index c1b26e1..bc7b50d 100644 /* The default sysctl tables: */ static struct ctl_table sysctl_base_table[] = { -@@ -277,6 +289,22 @@ static int max_extfrag_threshold = 1000; +@@ -277,6 +290,22 @@ static int max_extfrag_threshold = 1000; #endif static struct ctl_table kern_table[] = { @@ -102352,7 +102880,7 @@ index c1b26e1..bc7b50d 100644 { .procname = "sched_child_runs_first", .data = &sysctl_sched_child_runs_first, -@@ -639,7 +667,7 @@ static struct ctl_table kern_table[] = { +@@ -639,7 +668,7 @@ static struct ctl_table kern_table[] = { .data = &modprobe_path, .maxlen = KMOD_PATH_LEN, .mode = 0644, @@ -102361,7 +102889,21 @@ index c1b26e1..bc7b50d 100644 }, { .procname = "modules_disabled", -@@ -806,16 +834,20 @@ static struct ctl_table kern_table[] = { +@@ -647,7 +676,7 @@ static struct ctl_table kern_table[] = { + .maxlen = sizeof(int), + .mode = 0644, + /* only handle a transition from default "0" to "1" */ +- .proc_handler = proc_dointvec_minmax, ++ .proc_handler = proc_dointvec_minmax_secure, + .extra1 = &one, + .extra2 = &one, + }, +@@ -802,20 +831,24 @@ static struct ctl_table kern_table[] = { + .data = &dmesg_restrict, + .maxlen = sizeof(int), + .mode = 0644, +- .proc_handler = proc_dointvec_minmax_sysadmin, ++ .proc_handler = proc_dointvec_minmax_secure_sysadmin, .extra1 = &zero, .extra2 = &one, }, @@ -102371,7 +102913,8 @@ index c1b26e1..bc7b50d 100644 .data = &kptr_restrict, .maxlen = sizeof(int), .mode = 0644, - .proc_handler = proc_dointvec_minmax_sysadmin, +- .proc_handler = proc_dointvec_minmax_sysadmin, ++ .proc_handler = proc_dointvec_minmax_secure_sysadmin, +#ifdef CONFIG_GRKERNSEC_HIDESYM + .extra1 = &two, +#else @@ -102383,7 +102926,23 @@ index c1b26e1..bc7b50d 100644 { .procname = "ngroups_max", .data = &ngroups_max, -@@ -1060,10 +1092,17 @@ static struct ctl_table kern_table[] = { +@@ -929,6 +962,15 @@ static struct ctl_table kern_table[] = { + .mode = 0644, + .proc_handler = proc_dointvec, + }, ++ { ++ .procname = "modify_ldt", ++ .data = &sysctl_modify_ldt, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec_minmax_secure_sysadmin, ++ .extra1 = &zero, ++ .extra2 = &one, ++ }, + #endif + #if defined(CONFIG_MMU) + { +@@ -1060,10 +1102,17 @@ static struct ctl_table kern_table[] = { */ { .procname = "perf_event_paranoid", @@ -102394,7 +102953,7 @@ index c1b26e1..bc7b50d 100644 .mode = 0644, - .proc_handler = proc_dointvec, + /* go ahead, be a hero */ -+ .proc_handler = proc_dointvec_minmax_sysadmin, ++ .proc_handler = proc_dointvec_minmax_secure_sysadmin, + .extra1 = &neg_one, +#ifdef CONFIG_GRKERNSEC_PERF_HARDEN + .extra2 = &three, @@ -102404,7 +102963,7 @@ index c1b26e1..bc7b50d 100644 }, { .procname = "perf_event_mlock_kb", -@@ -1334,6 +1373,13 @@ static struct ctl_table vm_table[] = { +@@ -1334,6 +1383,13 @@ static struct ctl_table vm_table[] = { .proc_handler = proc_dointvec_minmax, .extra1 = &zero, }, @@ -102418,7 +102977,7 @@ index c1b26e1..bc7b50d 100644 #else { .procname = "nr_trim_pages", -@@ -1798,6 +1844,16 @@ int proc_dostring(struct ctl_table *table, int write, +@@ -1798,6 +1854,16 @@ int proc_dostring(struct ctl_table *table, int write, buffer, lenp, ppos); } @@ -102435,7 +102994,7 @@ index c1b26e1..bc7b50d 100644 static size_t proc_skip_spaces(char **buf) { size_t ret; -@@ -1903,6 +1959,8 @@ static int proc_put_long(void __user **buf, size_t *size, unsigned long val, +@@ -1903,6 +1969,8 @@ static int proc_put_long(void __user **buf, size_t *size, unsigned long val, len = strlen(tmp); if (len > *size) len = *size; @@ -102444,7 +103003,52 @@ index c1b26e1..bc7b50d 100644 if (copy_to_user(*buf, tmp, len)) return -EFAULT; *size -= len; -@@ -2067,7 +2125,7 @@ int proc_dointvec(struct ctl_table *table, int write, +@@ -2060,6 +2128,44 @@ int proc_dointvec(struct ctl_table *table, int write, + NULL,NULL); + } + ++static int do_proc_dointvec_conv_secure(bool *negp, unsigned long *lvalp, ++ int *valp, ++ int write, void *data) ++{ ++ if (write) { ++ if (*negp) { ++ if (*lvalp > (unsigned long) INT_MAX + 1) ++ return -EINVAL; ++ pax_open_kernel(); ++ *valp = -*lvalp; ++ pax_close_kernel(); ++ } else { ++ if (*lvalp > (unsigned long) INT_MAX) ++ return -EINVAL; ++ pax_open_kernel(); ++ *valp = *lvalp; ++ pax_close_kernel(); ++ } ++ } else { ++ int val = *valp; ++ if (val < 0) { ++ *negp = true; ++ *lvalp = (unsigned long)-val; ++ } else { ++ *negp = false; ++ *lvalp = (unsigned long)val; ++ } ++ } ++ return 0; ++} ++ ++int proc_dointvec_secure(struct ctl_table *table, int write, ++ void __user *buffer, size_t *lenp, loff_t *ppos) ++{ ++ return do_proc_dointvec(table,write,buffer,lenp,ppos, ++ do_proc_dointvec_conv_secure,NULL); ++} ++ + /* + * Taint values can only be increased + * This means we can safely use a temporary. +@@ -2067,7 +2173,7 @@ int proc_dointvec(struct ctl_table *table, int write, static int proc_taint(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { @@ -102453,23 +103057,77 @@ index c1b26e1..bc7b50d 100644 unsigned long tmptaint = get_taint(); int err; -@@ -2095,7 +2153,6 @@ static int proc_taint(struct ctl_table *table, int write, +@@ -2095,16 +2201,14 @@ static int proc_taint(struct ctl_table *table, int write, return err; } -#ifdef CONFIG_PRINTK - static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, +-static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, ++static int proc_dointvec_minmax_secure_sysadmin(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { -@@ -2104,7 +2161,6 @@ static int proc_dointvec_minmax_sysadmin(struct ctl_table *table, int write, + if (write && !capable(CAP_SYS_ADMIN)) + return -EPERM; - return proc_dointvec_minmax(table, write, buffer, lenp, ppos); +- return proc_dointvec_minmax(table, write, buffer, lenp, ppos); ++ return proc_dointvec_minmax_secure(table, write, buffer, lenp, ppos); } -#endif struct do_proc_dointvec_minmax_conv_param { int *min; -@@ -2651,6 +2707,12 @@ int proc_dostring(struct ctl_table *table, int write, +@@ -2135,6 +2239,32 @@ static int do_proc_dointvec_minmax_conv(bool *negp, unsigned long *lvalp, + return 0; + } + ++static int do_proc_dointvec_minmax_conv_secure(bool *negp, unsigned long *lvalp, ++ int *valp, ++ int write, void *data) ++{ ++ struct do_proc_dointvec_minmax_conv_param *param = data; ++ if (write) { ++ int val = *negp ? -*lvalp : *lvalp; ++ if ((param->min && *param->min > val) || ++ (param->max && *param->max < val)) ++ return -EINVAL; ++ pax_open_kernel(); ++ *valp = val; ++ pax_close_kernel(); ++ } else { ++ int val = *valp; ++ if (val < 0) { ++ *negp = true; ++ *lvalp = (unsigned long)-val; ++ } else { ++ *negp = false; ++ *lvalp = (unsigned long)val; ++ } ++ } ++ return 0; ++} ++ + /** + * proc_dointvec_minmax - read a vector of integers with min/max values + * @table: the sysctl table +@@ -2162,6 +2292,17 @@ int proc_dointvec_minmax(struct ctl_table *table, int write, + do_proc_dointvec_minmax_conv, ¶m); + } + ++int proc_dointvec_minmax_secure(struct ctl_table *table, int write, ++ void __user *buffer, size_t *lenp, loff_t *ppos) ++{ ++ struct do_proc_dointvec_minmax_conv_param param = { ++ .min = (int *) table->extra1, ++ .max = (int *) table->extra2, ++ }; ++ return do_proc_dointvec(table, write, buffer, lenp, ppos, ++ do_proc_dointvec_minmax_conv_secure, ¶m); ++} ++ + static void validate_coredump_safety(void) + { + #ifdef CONFIG_COREDUMP +@@ -2651,6 +2792,12 @@ int proc_dostring(struct ctl_table *table, int write, return -ENOSYS; } @@ -102482,7 +103140,7 @@ index c1b26e1..bc7b50d 100644 int proc_dointvec(struct ctl_table *table, int write, void __user *buffer, size_t *lenp, loff_t *ppos) { -@@ -2707,5 +2769,6 @@ EXPORT_SYMBOL(proc_dointvec_minmax); +@@ -2707,5 +2854,6 @@ EXPORT_SYMBOL(proc_dointvec_minmax); EXPORT_SYMBOL(proc_dointvec_userhz_jiffies); EXPORT_SYMBOL(proc_dointvec_ms_jiffies); EXPORT_SYMBOL(proc_dostring); @@ -103832,10 +104490,22 @@ index bd2bea9..6b3c95e 100644 return false; diff --git a/lib/kobject.c b/lib/kobject.c -index cb14aea..8c53cdb 100644 +index cb14aea..7ae9777 100644 --- a/lib/kobject.c +++ b/lib/kobject.c -@@ -931,9 +931,9 @@ EXPORT_SYMBOL_GPL(kset_create_and_add); +@@ -340,8 +340,9 @@ error: + } + EXPORT_SYMBOL(kobject_init); + +-static int kobject_add_varg(struct kobject *kobj, struct kobject *parent, +- const char *fmt, va_list vargs) ++static __printf(3, 0) int kobject_add_varg(struct kobject *kobj, ++ struct kobject *parent, ++ const char *fmt, va_list vargs) + { + int retval; + +@@ -931,9 +932,9 @@ EXPORT_SYMBOL_GPL(kset_create_and_add); static DEFINE_SPINLOCK(kobj_ns_type_lock); @@ -104334,7 +105004,7 @@ index 4f5b1dd..7cab418 100644 +} +EXPORT_SYMBOL(copy_to_user_overflow); diff --git a/lib/vsprintf.c b/lib/vsprintf.c -index 185b6d3..823c48c 100644 +index 185b6d3..c82c105 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -16,6 +16,9 @@ @@ -104351,10 +105021,11 @@ index 185b6d3..823c48c 100644 return number(buf, end, num, spec); } +-int kptr_restrict __read_mostly; +#ifdef CONFIG_GRKERNSEC_HIDESYM -+int kptr_restrict __read_mostly = 2; ++int kptr_restrict __read_only = 2; +#else - int kptr_restrict __read_mostly; ++int kptr_restrict __read_only; +#endif /* @@ -109843,6 +110514,18 @@ index 0447d5d..3cf4728 100644 __AAL_STAT_ITEMS #undef __HANDLE_ITEM } +diff --git a/net/ax25/ax25_subr.c b/net/ax25/ax25_subr.c +index 1997538..3b78e84 100644 +--- a/net/ax25/ax25_subr.c ++++ b/net/ax25/ax25_subr.c +@@ -264,6 +264,7 @@ void ax25_disconnect(ax25_cb *ax25, int reason) + { + ax25_clear_queues(ax25); + ++ ax25_stop_heartbeat(ax25); + ax25_stop_t1timer(ax25); + ax25_stop_t2timer(ax25); + ax25_stop_t3timer(ax25); diff --git a/net/ax25/sysctl_net_ax25.c b/net/ax25/sysctl_net_ax25.c index 919a5ce..cc6b444 100644 --- a/net/ax25/sysctl_net_ax25.c @@ -110513,10 +111196,87 @@ index d125290..e86e034 100644 a0 = a[0]; a1 = a[1]; diff --git a/net/core/datagram.c b/net/core/datagram.c -index a16ed7b..eb44d17 100644 +index a16ed7b..689402b 100644 --- a/net/core/datagram.c +++ b/net/core/datagram.c -@@ -301,7 +301,7 @@ int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags) +@@ -130,6 +130,35 @@ out_noerr: + goto out; + } + ++static int skb_set_peeked(struct sk_buff *skb) ++{ ++ struct sk_buff *nskb; ++ ++ if (skb->peeked) ++ return 0; ++ ++ /* We have to unshare an skb before modifying it. */ ++ if (!skb_shared(skb)) ++ goto done; ++ ++ nskb = skb_clone(skb, GFP_ATOMIC); ++ if (!nskb) ++ return -ENOMEM; ++ ++ skb->prev->next = nskb; ++ skb->next->prev = nskb; ++ nskb->prev = skb->prev; ++ nskb->next = skb->next; ++ ++ consume_skb(skb); ++ skb = nskb; ++ ++done: ++ skb->peeked = 1; ++ ++ return 0; ++} ++ + /** + * __skb_recv_datagram - Receive a datagram skbuff + * @sk: socket +@@ -164,7 +193,9 @@ out_noerr: + struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, + int *peeked, int *off, int *err) + { ++ struct sk_buff_head *queue = &sk->sk_receive_queue; + struct sk_buff *skb, *last; ++ unsigned long cpu_flags; + long timeo; + /* + * Caller is allowed not to check sk->sk_err before skb_recv_datagram() +@@ -183,8 +214,6 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, + * Look at current nfs client by the way... + * However, this function was correct in any case. 8) + */ +- unsigned long cpu_flags; +- struct sk_buff_head *queue = &sk->sk_receive_queue; + int _off = *off; + + last = (struct sk_buff *)queue; +@@ -198,7 +227,11 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, + _off -= skb->len; + continue; + } +- skb->peeked = 1; ++ ++ error = skb_set_peeked(skb); ++ if (error) ++ goto unlock_err; ++ + atomic_inc(&skb->users); + } else + __skb_unlink(skb, queue); +@@ -222,6 +255,8 @@ struct sk_buff *__skb_recv_datagram(struct sock *sk, unsigned int flags, + + return NULL; + ++unlock_err: ++ spin_unlock_irqrestore(&queue->lock, cpu_flags); + no_packet: + *err = error; + return NULL; +@@ -301,7 +336,7 @@ int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags) } kfree_skb(skb); @@ -110645,6 +111405,21 @@ index cf999e0..c59a9754 100644 } } EXPORT_SYMBOL(dev_load); +diff --git a/net/core/dst.c b/net/core/dst.c +index 15b6792..0d70357 100644 +--- a/net/core/dst.c ++++ b/net/core/dst.c +@@ -282,7 +282,9 @@ void dst_release(struct dst_entry *dst) + int newrefcnt; + + newrefcnt = atomic_dec_return(&dst->__refcnt); +- WARN_ON(newrefcnt < 0); ++ if (unlikely(newrefcnt < 0)) ++ net_warn_ratelimited("%s: dst:%p refcnt:%d\n", ++ __func__, dst, newrefcnt); + if (unlikely(dst->flags & DST_NOCACHE) && !newrefcnt) + call_rcu(&dst->rcu_head, dst_destroy_rcu); + } diff --git a/net/core/filter.c b/net/core/filter.c index ebce437..9fed9d0 100644 --- a/net/core/filter.c @@ -110942,7 +111717,7 @@ index ca68d32..236499d 100644 pr_warn("cannot create /proc/net/%s\n", PG_PROC_DIR); return -ENODEV; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c -index 8aadd6a..adf3f59 100644 +index 8aadd6a..5063f2a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -58,7 +58,7 @@ struct rtnl_link { @@ -110980,7 +111755,25 @@ index 8aadd6a..adf3f59 100644 } EXPORT_SYMBOL_GPL(__rtnl_link_unregister); -@@ -2006,6 +2009,10 @@ replay: +@@ -1605,10 +1608,13 @@ static int do_setlink(const struct sk_buff *skb, + goto errout; + + nla_for_each_nested(attr, tb[IFLA_VF_PORTS], rem) { +- if (nla_type(attr) != IFLA_VF_PORT) +- continue; +- err = nla_parse_nested(port, IFLA_PORT_MAX, +- attr, ifla_port_policy); ++ if (nla_type(attr) != IFLA_VF_PORT || ++ nla_len(attr) < NLA_HDRLEN) { ++ err = -EINVAL; ++ goto errout; ++ } ++ err = nla_parse_nested(port, IFLA_PORT_MAX, attr, ++ ifla_port_policy); + if (err < 0) + goto errout; + if (!port[IFLA_PORT_VF]) { +@@ -2006,6 +2012,10 @@ replay: if (IS_ERR(dest_net)) return PTR_ERR(dest_net); @@ -110991,7 +111784,7 @@ index 8aadd6a..adf3f59 100644 dev = rtnl_create_link(dest_net, ifname, ops, tb); if (IS_ERR(dev)) { err = PTR_ERR(dev); -@@ -2693,6 +2700,9 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) +@@ -2693,6 +2703,9 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) if (br_spec) { nla_for_each_nested(attr, br_spec, rem) { if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { @@ -111001,7 +111794,7 @@ index 8aadd6a..adf3f59 100644 have_flags = true; flags = nla_get_u16(attr); break; -@@ -2763,6 +2773,9 @@ static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) +@@ -2763,6 +2776,9 @@ static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) if (br_spec) { nla_for_each_nested(attr, br_spec, rem) { if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { @@ -115635,6 +116428,35 @@ index 8e3cf49..4a8e322 100644 } static int cls_bpf_change(struct net *net, struct sk_buff *in_skb, +diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c +index ba5bc92..1232a25 100644 +--- a/net/sched/sch_fq_codel.c ++++ b/net/sched/sch_fq_codel.c +@@ -167,6 +167,15 @@ static unsigned int fq_codel_drop(struct Qdisc *sch) + return idx; + } + ++static unsigned int fq_codel_qdisc_drop(struct Qdisc *sch) ++{ ++ unsigned int prev_backlog; ++ ++ prev_backlog = sch->qstats.backlog; ++ fq_codel_drop(sch); ++ return prev_backlog - sch->qstats.backlog; ++} ++ + static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch) + { + struct fq_codel_sched_data *q = qdisc_priv(sch); +@@ -600,7 +609,7 @@ static struct Qdisc_ops fq_codel_qdisc_ops __read_mostly = { + .enqueue = fq_codel_enqueue, + .dequeue = fq_codel_dequeue, + .peek = qdisc_peek_dequeued, +- .drop = fq_codel_drop, ++ .drop = fq_codel_qdisc_drop, + .init = fq_codel_init, + .reset = fq_codel_reset, + .destroy = fq_codel_destroy, diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 2b1738e..a9d0fc9 100644 --- a/net/sctp/ipv6.c @@ -120467,10 +121289,10 @@ index 0000000..0c96d8a +} diff --git a/tools/gcc/constify_plugin.c b/tools/gcc/constify_plugin.c new file mode 100644 -index 0000000..da184c5 +index 0000000..c5de280 --- /dev/null +++ b/tools/gcc/constify_plugin.c -@@ -0,0 +1,564 @@ +@@ -0,0 +1,568 @@ +/* + * Copyright 2011 by Emese Revfy <re.emese@gmail.com> + * Copyright 2011-2015 by PaX Team <pageexec@freemail.hu> @@ -120912,7 +121734,7 @@ index 0000000..da184c5 + .optinfo_flags = OPTGROUP_NONE, +#endif +#if BUILDING_GCC_VERSION >= 5000 -+#elif BUILDING_GCC_VERSION >= 4009 ++#elif BUILDING_GCC_VERSION == 4009 + .has_gate = false, + .has_execute = true, +#else @@ -120937,7 +121759,11 @@ index 0000000..da184c5 +class check_local_variables_pass : public gimple_opt_pass { +public: + check_local_variables_pass() : gimple_opt_pass(check_local_variables_pass_data, g) {} ++#if BUILDING_GCC_VERSION >= 5000 ++ virtual unsigned int execute(function *) { return check_local_variables(); } ++#else + unsigned int execute() { return check_local_variables(); } ++#endif +}; +} + @@ -121037,10 +121863,10 @@ index 0000000..da184c5 +} diff --git a/tools/gcc/gcc-common.h b/tools/gcc/gcc-common.h new file mode 100644 -index 0000000..1d20e32 +index 0000000..70924d4 --- /dev/null +++ b/tools/gcc/gcc-common.h -@@ -0,0 +1,689 @@ +@@ -0,0 +1,787 @@ +#ifndef GCC_COMMON_H_INCLUDED +#define GCC_COMMON_H_INCLUDED + @@ -121119,6 +121945,8 @@ index 0000000..1d20e32 +#include "tree-flow.h" +#else +#include "tree-cfgcleanup.h" ++#include "tree-ssa-operands.h" ++#include "tree-into-ssa.h" +#endif + +#if BUILDING_GCC_VERSION >= 4008 @@ -121449,6 +122277,76 @@ index 0000000..1d20e32 +typedef union gimple_statement_d gdebug; +typedef union gimple_statement_d gphi; +typedef union gimple_statement_d greturn; ++ ++static inline gasm *as_a_gasm(gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline const gasm *as_a_const_gasm(const_gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline gassign *as_a_gassign(gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline const gassign *as_a_const_gassign(const_gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline gcall *as_a_gcall(gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline const gcall *as_a_const_gcall(const_gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline gcond *as_a_gcond(gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline const gcond *as_a_const_gcond(const_gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline gdebug *as_a_gdebug(gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline const gdebug *as_a_const_gdebug(const_gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline gphi *as_a_gphi(gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline const gphi *as_a_const_gphi(const_gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline greturn *as_a_greturn(gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline const greturn *as_a_const_greturn(const_gimple stmt) ++{ ++ return stmt; ++} +#endif + +#if BUILDING_GCC_VERSION == 4008 @@ -121468,34 +122366,35 @@ index 0000000..1d20e32 +#if BUILDING_GCC_VERSION <= 4009 +#define TODO_verify_il 0 +#define AVAIL_INTERPOSABLE AVAIL_OVERWRITABLE -+#endif + -+#if BUILDING_GCC_VERSION == 4009 -+typedef struct gimple_statement_base gasm; -+typedef struct gimple_statement_base gassign; -+typedef struct gimple_statement_base gcall; -+typedef struct gimple_statement_base gcond; -+typedef struct gimple_statement_base gdebug; -+typedef struct gimple_statement_base gphi; -+typedef struct gimple_statement_base greturn; -+#endif ++#define section_name_prefix LTO_SECTION_NAME_PREFIX ++#define fatal_error(loc, gmsgid, ...) fatal_error((gmsgid), __VA_ARGS__) + -+#if BUILDING_GCC_VERSION <= 4009 +typedef struct rtx_def rtx_insn; + +static inline void set_decl_section_name(tree node, const char *value) +{ + DECL_SECTION_NAME(node) = build_string(strlen(value) + 1, value); +} ++#endif ++ ++#if BUILDING_GCC_VERSION == 4009 ++typedef struct gimple_statement_asm gasm; ++typedef struct gimple_statement_base gassign; ++typedef struct gimple_statement_call gcall; ++typedef struct gimple_statement_base gcond; ++typedef struct gimple_statement_base gdebug; ++typedef struct gimple_statement_phi gphi; ++typedef struct gimple_statement_base greturn; + +static inline gasm *as_a_gasm(gimple stmt) +{ -+ return stmt; ++ return as_a<gasm>(stmt); +} + +static inline const gasm *as_a_const_gasm(const_gimple stmt) +{ -+ return stmt; ++ return as_a<const gasm>(stmt); +} + +static inline gassign *as_a_gassign(gimple stmt) @@ -121510,24 +122409,44 @@ index 0000000..1d20e32 + +static inline gcall *as_a_gcall(gimple stmt) +{ -+ return stmt; ++ return as_a<gcall>(stmt); +} + +static inline const gcall *as_a_const_gcall(const_gimple stmt) +{ ++ return as_a<const gcall>(stmt); ++} ++ ++static inline gcond *as_a_gcond(gimple stmt) ++{ + return stmt; +} + -+static inline gphi *as_a_gphi(gimple stmt) ++static inline const gcond *as_a_const_gcond(const_gimple stmt) +{ + return stmt; +} + -+static inline const gphi *as_a_const_gphi(const_gimple stmt) ++static inline gdebug *as_a_gdebug(gimple stmt) +{ + return stmt; +} + ++static inline const gdebug *as_a_const_gdebug(const_gimple stmt) ++{ ++ return stmt; ++} ++ ++static inline gphi *as_a_gphi(gimple stmt) ++{ ++ return as_a<gphi>(stmt); ++} ++ ++static inline const gphi *as_a_const_gphi(const_gimple stmt) ++{ ++ return as_a<const gphi>(stmt); ++} ++ +static inline greturn *as_a_greturn(gimple stmt) +{ + return stmt; @@ -121589,6 +122508,11 @@ index 0000000..1d20e32 + varpool_node::add(decl); +} + ++static inline unsigned int rebuild_cgraph_edges(void) ++{ ++ return cgraph_edge::rebuild_edges(); ++} ++ +static inline cgraph_node_ptr cgraph_function_node(cgraph_node_ptr node, enum availability *availability) +{ + return node->function_symbol(availability); @@ -122973,10 +123897,10 @@ index 0000000..ac6f9b4 +} diff --git a/tools/gcc/randomize_layout_plugin.c b/tools/gcc/randomize_layout_plugin.c new file mode 100644 -index 0000000..713be61 +index 0000000..40dcfa9 --- /dev/null +++ b/tools/gcc/randomize_layout_plugin.c -@@ -0,0 +1,918 @@ +@@ -0,0 +1,922 @@ +/* + * Copyright 2014,2015 by Open Source Security, Inc., Brad Spengler <spender@grsecurity.net> + * and PaX Team <pageexec@freemail.hu> @@ -123822,7 +124746,11 @@ index 0000000..713be61 +class randomize_layout_bad_cast : public gimple_opt_pass { +public: + randomize_layout_bad_cast() : gimple_opt_pass(randomize_layout_bad_cast_data, g) {} ++#if BUILDING_GCC_VERSION >= 5000 ++ virtual unsigned int execute(function *) { return find_bad_casts(); } ++#else + unsigned int execute() { return find_bad_casts(); } ++#endif +}; +} +#endif @@ -124039,15 +124967,16 @@ index 0000000..12b1e3b +exit 0 diff --git a/tools/gcc/size_overflow_plugin/insert_size_overflow_asm.c b/tools/gcc/size_overflow_plugin/insert_size_overflow_asm.c new file mode 100644 -index 0000000..c43901f +index 0000000..495983ff --- /dev/null +++ b/tools/gcc/size_overflow_plugin/insert_size_overflow_asm.c -@@ -0,0 +1,748 @@ +@@ -0,0 +1,762 @@ +/* -+ * Copyright 2011-2014 by Emese Revfy <re.emese@gmail.com> ++ * Copyright 2011-2015 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 + * + * Homepage: ++ * https://github.com/ephox-gcc-plugins + * http://www.grsecurity.net/~ephox/overflow_plugin/ + * + * Documentation: @@ -124065,8 +124994,8 @@ index 0000000..c43901f +#include "gcc-common.h" +#include "size_overflow.h" + -+static void search_size_overflow_attribute(struct pointer_set_t *visited, tree lhs); -+static enum mark search_intentional(struct pointer_set_t *visited, const_tree lhs); ++static void search_size_overflow_attribute(gimple_set *visited, tree lhs); ++static enum mark search_intentional(gimple_set *visited, const_tree lhs); + +// data for the size_overflow asm stmt +struct asm_data { @@ -124100,7 +125029,7 @@ index 0000000..c43901f + +static void create_asm_stmt(const char *str, tree str_input, tree str_output, struct asm_data *asm_data) +{ -+ gimple asm_stmt; ++ gasm *asm_stmt; + gimple_stmt_iterator gsi; +#if BUILDING_GCC_VERSION <= 4007 + VEC(tree, gc) *input, *output = NULL; @@ -124113,7 +125042,7 @@ index 0000000..c43901f + if (asm_data->output) + output = create_asm_io_list(str_output, asm_data->output); + -+ asm_stmt = gimple_build_asm_vec(str, input, output, NULL, NULL); ++ asm_stmt = as_a_gasm(gimple_build_asm_vec(str, input, output, NULL, NULL)); + gsi = gsi_for_stmt(asm_data->def_stmt); + gsi_insert_after(&gsi, asm_stmt, GSI_NEW_STMT); + @@ -124128,13 +125057,13 @@ index 0000000..c43901f + SSA_NAME_DEF_STMT(asm_data->input) = asm_data->def_stmt; +} + -+static enum mark search_intentional_phi(struct pointer_set_t *visited, const_tree result) ++static enum mark search_intentional_phi(gimple_set *visited, const_tree result) +{ + enum mark cur_fndecl_attr; -+ gimple phi = get_def_stmt(result); ++ gphi *phi = as_a_gphi(get_def_stmt(result)); + unsigned int i, n = gimple_phi_num_args(phi); + -+ pointer_set_insert(visited, phi); ++ pointer_set_insert(visited, (gimple)phi); + for (i = 0; i < n; i++) { + tree arg = gimple_phi_arg_def(phi, i); + @@ -124145,11 +125074,11 @@ index 0000000..c43901f + return MARK_NO; +} + -+static enum mark search_intentional_binary(struct pointer_set_t *visited, const_tree lhs) ++static enum mark search_intentional_binary(gimple_set *visited, const_tree lhs) +{ + enum mark cur_fndecl_attr; + const_tree rhs1, rhs2; -+ gimple def_stmt = get_def_stmt(lhs); ++ gassign *def_stmt = as_a_gassign(get_def_stmt(lhs)); + + rhs1 = gimple_assign_rhs1(def_stmt); + rhs2 = gimple_assign_rhs2(def_stmt); @@ -124161,7 +125090,7 @@ index 0000000..c43901f +} + +// Look up the intentional_overflow attribute on the caller and the callee functions. -+static enum mark search_intentional(struct pointer_set_t *visited, const_tree lhs) ++static enum mark search_intentional(gimple_set *visited, const_tree lhs) +{ + const_gimple def_stmt; + @@ -124179,7 +125108,7 @@ index 0000000..c43901f + case GIMPLE_NOP: + return search_intentional(visited, SSA_NAME_VAR(lhs)); + case GIMPLE_ASM: -+ if (is_size_overflow_intentional_asm_turn_off(def_stmt)) ++ if (is_size_overflow_intentional_asm_turn_off(as_a_const_gasm(def_stmt))) + return MARK_TURN_OFF; + return MARK_NO; + case GIMPLE_CALL: @@ -124189,7 +125118,7 @@ index 0000000..c43901f + case GIMPLE_ASSIGN: + switch (gimple_num_ops(def_stmt)) { + case 2: -+ return search_intentional(visited, gimple_assign_rhs1(def_stmt)); ++ return search_intentional(visited, gimple_assign_rhs1(as_a_const_gassign(def_stmt))); + case 3: + return search_intentional_binary(visited, lhs); + } @@ -124206,7 +125135,7 @@ index 0000000..c43901f +static enum mark check_intentional_attribute_gimple(const_tree arg, const_gimple stmt, unsigned int argnum) +{ + const_tree fndecl; -+ struct pointer_set_t *visited; ++ gimple_set *visited; + enum mark cur_fndecl_attr, decl_attr = MARK_NO; + + fndecl = get_interesting_orig_fndecl(stmt, argnum); @@ -124249,7 +125178,7 @@ index 0000000..c43901f + is_missing_function(orig_fndecl, num); +} + -+static void search_size_overflow_attribute_phi(struct pointer_set_t *visited, const_tree result) ++static void search_size_overflow_attribute_phi(gimple_set *visited, const_tree result) +{ + gimple phi = get_def_stmt(result); + unsigned int i, n = gimple_phi_num_args(phi); @@ -124262,7 +125191,7 @@ index 0000000..c43901f + } +} + -+static void search_size_overflow_attribute_binary(struct pointer_set_t *visited, const_tree lhs) ++static void search_size_overflow_attribute_binary(gimple_set *visited, const_tree lhs) +{ + const_gimple def_stmt = get_def_stmt(lhs); + tree rhs1, rhs2; @@ -124274,7 +125203,7 @@ index 0000000..c43901f + search_size_overflow_attribute(visited, rhs2); +} + -+static void search_size_overflow_attribute(struct pointer_set_t *visited, tree lhs) ++static void search_size_overflow_attribute(gimple_set *visited, tree lhs) +{ + const_gimple def_stmt; + @@ -124324,18 +125253,20 @@ index 0000000..c43901f +{ + tree fndecl = NULL_TREE; + tree lhs; -+ struct pointer_set_t *visited; ++ gimple_set *visited; + + if (is_turn_off_intentional_attr(DECL_ORIGIN(current_function_decl))) + return; + + if (num == 0) { + gcc_assert(gimple_code(stmt) == GIMPLE_RETURN); -+ lhs = gimple_return_retval(stmt); ++ lhs = gimple_return_retval(as_a_const_greturn(stmt)); + } else { -+ gcc_assert(is_gimple_call(stmt)); -+ lhs = gimple_call_arg(stmt, num - 1); -+ fndecl = gimple_call_fndecl(stmt); ++ const gcall *call = as_a_const_gcall(stmt); ++ ++ gcc_assert(is_gimple_call(call)); ++ lhs = gimple_call_arg(call, num - 1); ++ fndecl = gimple_call_fndecl(call); + } + + if (fndecl != NULL_TREE && is_turn_off_intentional_attr(DECL_ORIGIN(fndecl))) @@ -124359,9 +125290,9 @@ index 0000000..c43901f + asm_data->output = create_new_var(TREE_TYPE(asm_data->output)); + asm_data->output = make_ssa_name(asm_data->output, stmt); + if (gimple_code(stmt) == GIMPLE_RETURN) -+ gimple_return_set_retval(stmt, asm_data->output); ++ gimple_return_set_retval(as_a_greturn(stmt), asm_data->output); + else -+ gimple_call_set_arg(stmt, argnum - 1, asm_data->output); ++ gimple_call_set_arg(as_a_gcall(stmt), argnum - 1, asm_data->output); + update_stmt(stmt); +} + @@ -124441,7 +125372,7 @@ index 0000000..c43901f + break; + } + case GIMPLE_ASM: -+ if (is_size_overflow_asm(asm_data->def_stmt)) { ++ if (is_size_overflow_asm(as_a_const_gasm(asm_data->def_stmt))) { + asm_data->input = NULL_TREE; + break; + } @@ -124472,7 +125403,7 @@ index 0000000..c43901f + search_missing_size_overflow_attribute_gimple(stmt, argnum); + + asm_data.def_stmt = get_def_stmt(asm_data.output); -+ if (is_size_overflow_intentional_asm_turn_off(asm_data.def_stmt)) ++ if (gimple_code(asm_data.def_stmt) == GIMPLE_ASM && is_size_overflow_intentional_asm_turn_off(as_a_const_gasm(asm_data.def_stmt))) + return; + + create_asm_input(stmt, argnum, &asm_data); @@ -124522,7 +125453,7 @@ index 0000000..c43901f + return true; +} + -+static void walk_use_def_ptr(struct pointer_set_t *visited, const_tree lhs) ++static void walk_use_def_ptr(gimple_set *visited, const_tree lhs) +{ + gimple def_stmt; + @@ -124539,28 +125470,33 @@ index 0000000..c43901f + case GIMPLE_CALL: + break; + case GIMPLE_PHI: { -+ unsigned int i, n = gimple_phi_num_args(def_stmt); ++ gphi *phi = as_a_gphi(def_stmt); ++ unsigned int i, n = gimple_phi_num_args(phi); + + pointer_set_insert(visited, def_stmt); + + for (i = 0; i < n; i++) { -+ tree arg = gimple_phi_arg_def(def_stmt, i); ++ tree arg = gimple_phi_arg_def(phi, i); + + walk_use_def_ptr(visited, arg); + } ++ break; + } -+ case GIMPLE_ASSIGN: -+ switch (gimple_num_ops(def_stmt)) { ++ case GIMPLE_ASSIGN: { ++ gassign *assign = as_a_gassign(def_stmt); ++ ++ switch (gimple_num_ops(assign)) { + case 2: -+ walk_use_def_ptr(visited, gimple_assign_rhs1(def_stmt)); ++ walk_use_def_ptr(visited, gimple_assign_rhs1(assign)); + return; + case 3: -+ walk_use_def_ptr(visited, gimple_assign_rhs1(def_stmt)); -+ walk_use_def_ptr(visited, gimple_assign_rhs2(def_stmt)); ++ walk_use_def_ptr(visited, gimple_assign_rhs1(assign)); ++ walk_use_def_ptr(visited, gimple_assign_rhs2(assign)); + return; + default: + return; + } ++ } + default: + debug_gimple_stmt((gimple)def_stmt); + error("%s: unknown gimple code", __func__); @@ -124571,7 +125507,7 @@ index 0000000..c43901f +// Look for a ptr - ptr expression (e.g., cpuset_common_file_read() s - page) +static void insert_mark_not_intentional_asm_at_ptr(const_tree arg) +{ -+ struct pointer_set_t *visited; ++ gimple_set *visited; + + visited = pointer_set_create(); + walk_use_def_ptr(visited, arg); @@ -124579,7 +125515,7 @@ index 0000000..c43901f +} + +// Determine the return value and insert the asm stmt to mark the return stmt. -+static void insert_asm_ret(gimple stmt) ++static void insert_asm_ret(greturn *stmt) +{ + tree ret; + @@ -124588,7 +125524,7 @@ index 0000000..c43901f +} + +// Determine the correct arg index and arg and insert the asm stmt to mark the stmt. -+static void insert_asm_arg(gimple stmt, unsigned int orig_argnum) ++static void insert_asm_arg(gcall *stmt, unsigned int orig_argnum) +{ + tree arg; + unsigned int argnum; @@ -124665,7 +125601,7 @@ index 0000000..c43901f + * Look up the intentional_overflow attribute that turns off ipa based duplication + * on the callee function. + */ -+static bool is_mark_turn_off_attribute(gimple stmt) ++static bool is_mark_turn_off_attribute(gcall *stmt) +{ + enum mark mark; + const_tree fndecl = gimple_call_fndecl(stmt); @@ -124677,7 +125613,7 @@ index 0000000..c43901f +} + +// If the argument(s) of the callee function is/are in the hash table or are marked by an attribute then mark the call stmt with an asm stmt -+static void handle_interesting_function(gimple stmt) ++static void handle_interesting_function(gcall *stmt) +{ + unsigned int argnum; + tree fndecl; @@ -124703,7 +125639,7 @@ index 0000000..c43901f +} + +// If the return value of the caller function is in hash table (its index is 0) then mark the return stmt with an asm stmt -+static void handle_interesting_ret(gimple stmt) ++static void handle_interesting_ret(greturn *stmt) +{ + bool orig_argnums[MAX_PARAM + 1] = {false}; + @@ -124724,13 +125660,13 @@ index 0000000..c43901f + for (gsi = gsi_start_bb(bb); !gsi_end_p(gsi); gsi_next(&gsi)) { + gimple stmt = gsi_stmt(gsi); + -+ if (is_size_overflow_asm(stmt)) ++ if (gimple_code(stmt) == GIMPLE_ASM && is_size_overflow_asm(as_a_const_gasm(stmt))) + continue; + + if (is_gimple_call(stmt)) -+ handle_interesting_function(stmt); ++ handle_interesting_function(as_a_gcall(stmt)); + else if (gimple_code(stmt) == GIMPLE_RETURN) -+ handle_interesting_ret(stmt); ++ handle_interesting_ret(as_a_greturn(stmt)); + } + } + return 0; @@ -124742,6 +125678,7 @@ index 0000000..c43901f + * that the ipa pass will detect and insert the size overflow checks for. + */ +#if BUILDING_GCC_VERSION >= 4009 ++namespace { +static const struct pass_data insert_size_overflow_asm_pass_data = { +#else +static struct gimple_opt_pass insert_size_overflow_asm_pass = { @@ -124752,7 +125689,8 @@ index 0000000..c43901f +#if BUILDING_GCC_VERSION >= 4008 + .optinfo_flags = OPTGROUP_NONE, +#endif -+#if BUILDING_GCC_VERSION >= 4009 ++#if BUILDING_GCC_VERSION >= 5000 ++#elif BUILDING_GCC_VERSION == 4009 + .has_gate = false, + .has_execute = true, +#else @@ -124774,34 +125712,39 @@ index 0000000..c43901f +}; + +#if BUILDING_GCC_VERSION >= 4009 -+namespace { +class insert_size_overflow_asm_pass : public gimple_opt_pass { +public: + insert_size_overflow_asm_pass() : gimple_opt_pass(insert_size_overflow_asm_pass_data, g) {} ++#if BUILDING_GCC_VERSION >= 5000 ++ virtual unsigned int execute(function *) { return search_interesting_functions(); } ++#else + unsigned int execute() { return search_interesting_functions(); } ++#endif +}; +} -+#endif + -+struct opt_pass *make_insert_size_overflow_asm_pass(void) ++opt_pass *make_insert_size_overflow_asm_pass(void) +{ -+#if BUILDING_GCC_VERSION >= 4009 + return new insert_size_overflow_asm_pass(); ++} +#else ++struct opt_pass *make_insert_size_overflow_asm_pass(void) ++{ + return &insert_size_overflow_asm_pass.pass; -+#endif +} ++#endif diff --git a/tools/gcc/size_overflow_plugin/insert_size_overflow_check_core.c b/tools/gcc/size_overflow_plugin/insert_size_overflow_check_core.c new file mode 100644 -index 0000000..73f0a12 +index 0000000..0766e39 --- /dev/null +++ b/tools/gcc/size_overflow_plugin/insert_size_overflow_check_core.c -@@ -0,0 +1,943 @@ +@@ -0,0 +1,931 @@ +/* -+ * Copyright 2011-2014 by Emese Revfy <re.emese@gmail.com> ++ * Copyright 2011-2015 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 + * + * Homepage: ++ * https://github.com/ephox-gcc-plugins + * http://www.grsecurity.net/~ephox/overflow_plugin/ + * + * Documentation: @@ -124865,19 +125808,6 @@ index 0000000..73f0a12 + return new_type; +} + -+static tree get_lhs(const_gimple stmt) -+{ -+ switch (gimple_code(stmt)) { -+ case GIMPLE_ASSIGN: -+ case GIMPLE_CALL: -+ return gimple_get_lhs(stmt); -+ case GIMPLE_PHI: -+ return gimple_phi_result(stmt); -+ default: -+ return NULL_TREE; -+ } -+} -+ +static tree cast_to_new_size_overflow_type(struct visited *visited, gimple stmt, tree rhs, tree size_overflow_type, bool before) +{ + gimple_stmt_iterator gsi; @@ -124951,7 +125881,7 @@ index 0000000..73f0a12 + return cast_to_new_size_overflow_type(visited, oldstmt, rhs1, dst_type, before); +} + -+tree dup_assign(struct visited *visited, gimple oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3) ++tree dup_assign(struct visited *visited, gassign *oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3) +{ + gimple stmt; + gimple_stmt_iterator gsi; @@ -125020,13 +125950,14 @@ index 0000000..73f0a12 + assign = build_cast_stmt(visited, size_overflow_type, arg, phi_ssa_name, &gsi, BEFORE_STMT, false); + pointer_set_insert(visited->my_stmts, assign); + -+ return gimple_assign_lhs(assign); ++ return get_lhs(assign); +} + +static tree use_phi_ssa_name(struct visited *visited, tree ssa_name_var, tree new_arg) +{ + gimple_stmt_iterator gsi; -+ gimple assign, def_stmt = get_def_stmt(new_arg); ++ gimple assign; ++ gimple def_stmt = get_def_stmt(new_arg); + + if (gimple_code(def_stmt) == GIMPLE_PHI) { + gsi = gsi_after_labels(gimple_bb(def_stmt)); @@ -125037,7 +125968,7 @@ index 0000000..73f0a12 + } + + pointer_set_insert(visited->my_stmts, assign); -+ return gimple_assign_lhs(assign); ++ return get_lhs(assign); +} + +static tree cast_visited_phi_arg(struct visited *visited, tree ssa_name_var, tree arg, tree size_overflow_type) @@ -125054,13 +125985,12 @@ index 0000000..73f0a12 + + assign = build_cast_stmt(visited, size_overflow_type, arg, ssa_name_var, &gsi, BEFORE_STMT, false); + pointer_set_insert(visited->my_stmts, assign); -+ return gimple_assign_lhs(assign); ++ return get_lhs(assign); +} + -+static tree create_new_phi_arg(struct visited *visited, tree ssa_name_var, tree new_arg, gimple oldstmt, unsigned int i) ++static tree create_new_phi_arg(struct visited *visited, tree ssa_name_var, tree new_arg, gphi *oldstmt, unsigned int i) +{ -+ tree size_overflow_type; -+ tree arg; ++ tree size_overflow_type, arg; + const_gimple def_stmt; + + if (new_arg != NULL_TREE && is_gimple_constant(new_arg)) @@ -125077,7 +126007,7 @@ index 0000000..73f0a12 + case GIMPLE_NOP: { + basic_block bb; + -+ bb = gimple_phi_arg_edge(oldstmt, i)->src; ++ bb = gimple_phi_arg_edge(as_a_gphi(oldstmt), i)->src; + return cast_parm_decl(visited, ssa_name_var, arg, size_overflow_type, bb); + } + case GIMPLE_ASM: { @@ -125087,7 +126017,7 @@ index 0000000..73f0a12 + gsi = gsi_for_stmt(stmt); + assign = build_cast_stmt(visited, size_overflow_type, arg, ssa_name_var, &gsi, AFTER_STMT, false); + pointer_set_insert(visited->my_stmts, assign); -+ return gimple_assign_lhs(assign); ++ return get_lhs(assign); + } + default: + gcc_assert(new_arg != NULL_TREE); @@ -125096,10 +126026,10 @@ index 0000000..73f0a12 + } +} + -+static gimple overflow_create_phi_node(struct visited *visited, gimple oldstmt, tree result) ++static gphi *overflow_create_phi_node(struct visited *visited, gphi *oldstmt, tree result) +{ + basic_block bb; -+ gimple phi; ++ gphi *phi; + gimple_seq seq; + gimple_stmt_iterator gsi = gsi_for_stmt(oldstmt); + @@ -125112,7 +126042,7 @@ index 0000000..73f0a12 + result = create_new_var(size_overflow_type); + } + -+ phi = create_phi_node(result, bb); ++ phi = as_a_gphi(create_phi_node(result, bb)); + gimple_phi_set_result(phi, make_ssa_name(result, phi)); + seq = phi_nodes(bb); + gsi = gsi_last(seq); @@ -125125,12 +126055,12 @@ index 0000000..73f0a12 +} + +#if BUILDING_GCC_VERSION <= 4007 -+static tree create_new_phi_node(struct visited *visited, VEC(tree, heap) **args, tree ssa_name_var, gimple oldstmt) ++static tree create_new_phi_node(struct visited *visited, VEC(tree, heap) **args, tree ssa_name_var, gphi *oldstmt) +#else -+static tree create_new_phi_node(struct visited *visited, vec<tree, va_heap, vl_embed> *&args, tree ssa_name_var, gimple oldstmt) ++static tree create_new_phi_node(struct visited *visited, vec<tree, va_heap, vl_embed> *&args, tree ssa_name_var, gphi *oldstmt) +#endif +{ -+ gimple new_phi; ++ gphi *new_phi; + unsigned int i; + tree arg, result; + location_t loc = gimple_location(oldstmt); @@ -125172,7 +126102,7 @@ index 0000000..73f0a12 +#else + vec<tree, va_heap, vl_embed> *args = NULL; +#endif -+ gimple oldstmt = get_def_stmt(orig_result); ++ gphi *oldstmt = as_a_gphi(get_def_stmt(orig_result)); + unsigned int i, len = gimple_phi_num_args(oldstmt); + + pointer_set_insert(visited->stmts, oldstmt); @@ -125205,7 +126135,7 @@ index 0000000..73f0a12 +#endif +} + -+static tree create_cast_assign(struct visited *visited, gimple stmt) ++static tree create_cast_assign(struct visited *visited, gassign *stmt) +{ + tree rhs1 = gimple_assign_rhs1(stmt); + tree lhs = gimple_assign_lhs(stmt); @@ -125218,7 +126148,7 @@ index 0000000..73f0a12 + return create_assign(visited, stmt, rhs1, AFTER_STMT); +} + -+static bool skip_lhs_cast_check(const_gimple stmt) ++static bool skip_lhs_cast_check(const gassign *stmt) +{ + const_tree rhs = gimple_assign_rhs1(stmt); + const_gimple def_stmt = get_def_stmt(rhs); @@ -125252,7 +126182,7 @@ index 0000000..73f0a12 + +static void insert_cond(basic_block cond_bb, tree arg, enum tree_code cond_code, tree type_value) +{ -+ gimple cond_stmt; ++ gcond *cond_stmt; + gimple_stmt_iterator gsi = gsi_last_bb(cond_bb); + + cond_stmt = gimple_build_cond(cond_code, arg, type_value, NULL_TREE, NULL_TREE); @@ -125262,7 +126192,7 @@ index 0000000..73f0a12 + +static void insert_cond_result(struct cgraph_node *caller_node, basic_block bb_true, const_gimple stmt, const_tree arg, bool min) +{ -+ gimple func_stmt; ++ gcall *func_stmt; + const_gimple def_stmt; + const_tree loc_line; + tree loc_file, ssa_name, current_func; @@ -125300,7 +126230,7 @@ index 0000000..73f0a12 + ssa_name = create_string_param(ssa_name); + + // void report_size_overflow(const char *file, unsigned int line, const char *func, const char *ssa_name) -+ func_stmt = gimple_build_call(report_size_overflow_decl, 4, loc_file, loc_line, current_func, ssa_name); ++ func_stmt = as_a_gcall(gimple_build_call(report_size_overflow_decl, 4, loc_file, loc_line, current_func, ssa_name)); + gsi_insert_after(&gsi, func_stmt, GSI_CONTINUE_LINKING); + + callee_node = cgraph_get_create_node(report_size_overflow_decl); @@ -125384,7 +126314,7 @@ index 0000000..73f0a12 + insert_check_size_overflow(caller_node, stmt, LT_EXPR, cast_rhs, type_min, before, MIN_CHECK); +} + -+static tree create_cast_overflow_check(struct visited *visited, struct cgraph_node *caller_node, tree new_rhs1, gimple stmt) ++static tree create_cast_overflow_check(struct visited *visited, struct cgraph_node *caller_node, tree new_rhs1, gassign *stmt) +{ + bool cast_lhs, cast_rhs; + tree lhs = gimple_assign_lhs(stmt); @@ -125437,7 +126367,7 @@ index 0000000..73f0a12 + return dup_assign(visited, stmt, lhs, new_rhs1, NULL_TREE, NULL_TREE); +} + -+static tree handle_unary_rhs(struct visited *visited, struct cgraph_node *caller_node, gimple stmt) ++static tree handle_unary_rhs(struct visited *visited, struct cgraph_node *caller_node, gassign *stmt) +{ + enum tree_code rhs_code; + tree rhs1, new_rhs1, lhs = gimple_assign_lhs(stmt); @@ -125472,10 +126402,10 @@ index 0000000..73f0a12 + return create_cast_overflow_check(visited, caller_node, new_rhs1, stmt); +} + -+static tree handle_unary_ops(struct visited *visited, struct cgraph_node *caller_node, gimple stmt) ++static tree handle_unary_ops(struct visited *visited, struct cgraph_node *caller_node, gassign *stmt) +{ + tree rhs1, lhs = gimple_assign_lhs(stmt); -+ gimple def_stmt = get_def_stmt(lhs); ++ gassign *def_stmt = as_a_gassign(get_def_stmt(lhs)); + + gcc_assert(gimple_code(def_stmt) != GIMPLE_NOP); + rhs1 = gimple_assign_rhs1(def_stmt); @@ -125534,7 +126464,7 @@ index 0000000..73f0a12 +} + +// Skip duplication when there is a minus expr and the type of rhs1 or rhs2 is a pointer_type. -+static bool is_a_ptr_minus(gimple stmt) ++static bool is_a_ptr_minus(gassign *stmt) +{ + const_tree rhs1, rhs2, ptr1_rhs, ptr2_rhs; + @@ -125562,7 +126492,7 @@ index 0000000..73f0a12 +{ + enum intentional_overflow_type res; + tree rhs1, rhs2, new_lhs; -+ gimple def_stmt = get_def_stmt(lhs); ++ gassign *def_stmt = as_a_gassign(get_def_stmt(lhs)); + tree new_rhs1 = NULL_TREE; + tree new_rhs2 = NULL_TREE; + @@ -125603,13 +126533,13 @@ index 0000000..73f0a12 + res = add_mul_intentional_overflow(def_stmt); + if (res != NO_INTENTIONAL_OVERFLOW) { + new_lhs = dup_assign(visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); -+ insert_cast_expr(visited, get_def_stmt(new_lhs), res); ++ insert_cast_expr(visited, as_a_gassign(get_def_stmt(new_lhs)), res); + return new_lhs; + } + + if (skip_expr_on_double_type(def_stmt)) { + new_lhs = dup_assign(visited, def_stmt, lhs, new_rhs1, new_rhs2, NULL_TREE); -+ insert_cast_expr(visited, get_def_stmt(new_lhs), NO_INTENTIONAL_OVERFLOW); ++ insert_cast_expr(visited, as_a_gassign(get_def_stmt(new_lhs)), NO_INTENTIONAL_OVERFLOW); + return new_lhs; + } + @@ -125646,7 +126576,7 @@ index 0000000..73f0a12 +static tree handle_ternary_ops(struct visited *visited, struct cgraph_node *caller_node, tree lhs) +{ + tree rhs1, rhs2, rhs3, new_rhs1, new_rhs2, new_rhs3, size_overflow_type; -+ gimple def_stmt = get_def_stmt(lhs); ++ gassign *def_stmt = as_a_gassign(get_def_stmt(lhs)); + + size_overflow_type = get_size_overflow_type(visited, def_stmt, lhs); + @@ -125725,7 +126655,7 @@ index 0000000..73f0a12 + case GIMPLE_ASSIGN: + switch (gimple_num_ops(def_stmt)) { + case 2: -+ return handle_unary_ops(visited, caller_node, def_stmt); ++ return handle_unary_ops(visited, caller_node, as_a_gassign(def_stmt)); + case 3: + return handle_binary_ops(visited, caller_node, lhs); +#if BUILDING_GCC_VERSION >= 4006 @@ -125742,16 +126672,17 @@ index 0000000..73f0a12 + diff --git a/tools/gcc/size_overflow_plugin/insert_size_overflow_check_ipa.c b/tools/gcc/size_overflow_plugin/insert_size_overflow_check_ipa.c new file mode 100644 -index 0000000..df50164 +index 0000000..e1e6e19 --- /dev/null +++ b/tools/gcc/size_overflow_plugin/insert_size_overflow_check_ipa.c -@@ -0,0 +1,1141 @@ +@@ -0,0 +1,1157 @@ +/* -+ * Copyright 2011-2014 by Emese Revfy <re.emese@gmail.com> ++ * Copyright 2011-2015 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 + * + * Homepage: + * http://www.grsecurity.net/~ephox/overflow_plugin/ ++ * https://github.com/ephox-gcc-plugins + * + * Documentation: + * http://forums.grsecurity.net/viewtopic.php?f=7&t=3043 @@ -125775,8 +126706,8 @@ index 0000000..df50164 + +unsigned int call_count; + -+static void set_conditions(struct pointer_set_t *visited, bool *interesting_conditions, const_tree lhs); -+static void walk_use_def(struct pointer_set_t *visited, struct interesting_node *cur_node, tree lhs); ++static void set_conditions(gimple_set *visited, bool *interesting_conditions, const_tree lhs); ++static void walk_use_def(gimple_set *visited, struct interesting_node *cur_node, tree lhs); + +struct visited_fns { + struct visited_fns *next; @@ -125946,9 +126877,9 @@ index 0000000..df50164 + return cnodes; +} + -+static void walk_phi_set_conditions(struct pointer_set_t *visited, bool *interesting_conditions, const_tree result) ++static void walk_phi_set_conditions(gimple_set *visited, bool *interesting_conditions, const_tree result) +{ -+ gimple phi = get_def_stmt(result); ++ gphi *phi = as_a_gphi(get_def_stmt(result)); + unsigned int i, n = gimple_phi_num_args(phi); + + pointer_set_insert(visited, phi); @@ -125964,7 +126895,7 @@ index 0000000..df50164 +}; + +// Search for constants, cast assignments and binary/ternary assignments -+static void set_conditions(struct pointer_set_t *visited, bool *interesting_conditions, const_tree lhs) ++static void set_conditions(gimple_set *visited, bool *interesting_conditions, const_tree lhs) +{ + gimple def_stmt = get_def_stmt(lhs); + @@ -125981,7 +126912,7 @@ index 0000000..df50164 + + switch (gimple_code(def_stmt)) { + case GIMPLE_CALL: -+ if (lhs == gimple_call_lhs(def_stmt)) ++ if (lhs == gimple_call_lhs(as_a_const_gcall(def_stmt))) + interesting_conditions[RET] = true; + return; + case GIMPLE_NOP: @@ -125990,11 +126921,13 @@ index 0000000..df50164 + case GIMPLE_PHI: + interesting_conditions[PHI] = true; + return walk_phi_set_conditions(visited, interesting_conditions, lhs); -+ case GIMPLE_ASSIGN: -+ if (gimple_num_ops(def_stmt) == 2) { -+ const_tree rhs = gimple_assign_rhs1(def_stmt); ++ case GIMPLE_ASSIGN: { ++ gassign *assign = as_a_gassign(def_stmt); ++ ++ if (gimple_num_ops(assign) == 2) { ++ const_tree rhs = gimple_assign_rhs1(assign); + -+ if (gimple_assign_cast_p(def_stmt)) ++ if (gimple_assign_cast_p(assign)) + interesting_conditions[CAST] = true; + + return set_conditions(visited, interesting_conditions, rhs); @@ -126002,6 +126935,7 @@ index 0000000..df50164 + interesting_conditions[NOT_UNARY] = true; + return; + } ++ } + default: + debug_gimple_stmt(def_stmt); + gcc_unreachable(); @@ -126011,7 +126945,7 @@ index 0000000..df50164 +// determine whether duplication will be necessary or not. +static void search_interesting_conditions(struct interesting_node *cur_node, bool *interesting_conditions) +{ -+ struct pointer_set_t *visited; ++ gimple_set *visited; + + if (gimple_assign_cast_p(cur_node->first_stmt)) + interesting_conditions[CAST] = true; @@ -126024,9 +126958,9 @@ index 0000000..df50164 +} + +// Remove the size_overflow asm stmt and create an assignment from the input and output of the asm -+static void replace_size_overflow_asm_with_assign(gimple asm_stmt, tree lhs, tree rhs) ++static void replace_size_overflow_asm_with_assign(gasm *asm_stmt, tree lhs, tree rhs) +{ -+ gimple assign; ++ gassign *assign; + gimple_stmt_iterator gsi; + + // already removed @@ -126067,13 +127001,13 @@ index 0000000..df50164 + if (!def_stmt || !gimple_assign_cast_p(def_stmt)) + return false; + -+ def_stmt = get_def_stmt(gimple_assign_rhs1(def_stmt)); ++ def_stmt = get_def_stmt(gimple_assign_rhs1(as_a_gassign(def_stmt))); + return def_stmt && gimple_code(def_stmt) == GIMPLE_ASM; +} + -+static void walk_use_def_phi(struct pointer_set_t *visited, struct interesting_node *cur_node, tree result) ++static void walk_use_def_phi(gimple_set *visited, struct interesting_node *cur_node, tree result) +{ -+ gimple phi = get_def_stmt(result); ++ gphi *phi = as_a_gphi(get_def_stmt(result)); + unsigned int i, n = gimple_phi_num_args(phi); + + pointer_set_insert(visited, phi); @@ -126084,9 +127018,9 @@ index 0000000..df50164 + } +} + -+static void walk_use_def_binary(struct pointer_set_t *visited, struct interesting_node *cur_node, tree lhs) ++static void walk_use_def_binary(gimple_set *visited, struct interesting_node *cur_node, tree lhs) +{ -+ gimple def_stmt = get_def_stmt(lhs); ++ gassign *def_stmt = as_a_gassign(get_def_stmt(lhs)); + tree rhs1, rhs2; + + rhs1 = gimple_assign_rhs1(def_stmt); @@ -126135,16 +127069,16 @@ index 0000000..df50164 +} + +// a size_overflow asm stmt in the control flow doesn't stop the recursion -+static void handle_asm_stmt(struct pointer_set_t *visited, struct interesting_node *cur_node, tree lhs, const_gimple stmt) ++static void handle_asm_stmt(gimple_set *visited, struct interesting_node *cur_node, tree lhs, const gasm *stmt) +{ -+ if (!is_size_overflow_asm(stmt)) ++ if (gimple_code(stmt) != GIMPLE_ASM || !is_size_overflow_asm(stmt)) + walk_use_def(visited, cur_node, SSA_NAME_VAR(lhs)); +} + +/* collect the parm_decls and fndecls (for checking a missing size_overflow attribute (ret or arg) or intentional_overflow) + * and component refs (for checking the intentional_overflow attribute). + */ -+static void walk_use_def(struct pointer_set_t *visited, struct interesting_node *cur_node, tree lhs) ++static void walk_use_def(gimple_set *visited, struct interesting_node *cur_node, tree lhs) +{ + const_gimple def_stmt; + @@ -126164,9 +127098,9 @@ index 0000000..df50164 + case GIMPLE_NOP: + return walk_use_def(visited, cur_node, SSA_NAME_VAR(lhs)); + case GIMPLE_ASM: -+ return handle_asm_stmt(visited, cur_node, lhs, def_stmt); ++ return handle_asm_stmt(visited, cur_node, lhs, as_a_const_gasm(def_stmt)); + case GIMPLE_CALL: { -+ tree fndecl = gimple_call_fndecl(def_stmt); ++ tree fndecl = gimple_call_fndecl(as_a_const_gcall(def_stmt)); + + if (fndecl == NULL_TREE) + return; @@ -126178,7 +127112,7 @@ index 0000000..df50164 + case GIMPLE_ASSIGN: + switch (gimple_num_ops(def_stmt)) { + case 2: -+ return walk_use_def(visited, cur_node, gimple_assign_rhs1(def_stmt)); ++ return walk_use_def(visited, cur_node, gimple_assign_rhs1(as_a_const_gassign(def_stmt))); + case 3: + return walk_use_def_binary(visited, cur_node, lhs); + } @@ -126192,7 +127126,7 @@ index 0000000..df50164 +// Collect all the last nodes for checking the intentional_overflow and size_overflow attributes +static void set_last_nodes(struct interesting_node *cur_node) +{ -+ struct pointer_set_t *visited; ++ gimple_set *visited; + + visited = pointer_set_create(); + walk_use_def(visited, cur_node, cur_node->node); @@ -126245,7 +127179,7 @@ index 0000000..df50164 + gimple_stmt_iterator gsi = gsi_for_stmt(stmt); + + assign = build_cast_stmt(visited, orig_type, new_node, CREATE_NEW_VAR, &gsi, BEFORE_STMT, false); -+ return gimple_assign_lhs(assign); ++ return get_lhs(assign); +} + +static void change_orig_node(struct visited *visited, struct interesting_node *cur_node, tree new_node) @@ -126256,10 +127190,10 @@ index 0000000..df50164 + + switch (gimple_code(stmt)) { + case GIMPLE_RETURN: -+ gimple_return_set_retval(stmt, cast_to_orig_type(visited, stmt, orig_node, new_node)); ++ gimple_return_set_retval(as_a_greturn(stmt), cast_to_orig_type(visited, stmt, orig_node, new_node)); + break; + case GIMPLE_CALL: -+ gimple_call_set_arg(stmt, cur_node->num - 1, cast_to_orig_type(visited, stmt, orig_node, new_node)); ++ gimple_call_set_arg(as_a_gcall(stmt), cur_node->num - 1, cast_to_orig_type(visited, stmt, orig_node, new_node)); + break; + case GIMPLE_ASSIGN: + switch (cur_node->num) { @@ -126278,7 +127212,7 @@ index 0000000..df50164 + gcc_unreachable(); + } + -+ set_rhs(stmt, cast_to_orig_type(visited, stmt, orig_node, new_node)); ++ set_rhs(as_a_gassign(stmt), cast_to_orig_type(visited, stmt, orig_node, new_node)); + break; + default: + debug_gimple_stmt(stmt); @@ -126365,7 +127299,7 @@ index 0000000..df50164 + intentional_attr_cur_fndecl: intentional_overflow attribute of the caller function + intentional_mark_from_gimple: the intentional overflow type of size_overflow asm stmt from gimple if it exists + */ -+static struct interesting_node *create_new_interesting_node(struct interesting_node *head, gimple first_stmt, tree node, unsigned int num, gimple asm_stmt) ++static struct interesting_node *create_new_interesting_node(struct interesting_node *head, gimple first_stmt, tree node, unsigned int num, gasm *asm_stmt) +{ + struct interesting_node *new_node; + tree fndecl; @@ -126385,7 +127319,7 @@ index 0000000..df50164 + return head; + + if (is_gimple_call(first_stmt)) -+ fndecl = gimple_call_fndecl(first_stmt); ++ fndecl = gimple_call_fndecl(as_a_const_gcall(first_stmt)); + else + fndecl = current_function_decl; + @@ -126421,7 +127355,7 @@ index 0000000..df50164 +/* Check the ret stmts in the functions on the next cgraph node list (these functions will be in the hash table and they are reachable from ipa). + * If the ret stmt is in the next cgraph node list then it's an interesting ret. + */ -+static struct interesting_node *handle_stmt_by_cgraph_nodes_ret(struct interesting_node *head, gimple stmt, struct next_cgraph_node *next_node) ++static struct interesting_node *handle_stmt_by_cgraph_nodes_ret(struct interesting_node *head, greturn *stmt, struct next_cgraph_node *next_node) +{ + struct next_cgraph_node *cur_node; + tree ret = gimple_return_retval(stmt); @@ -126442,7 +127376,7 @@ index 0000000..df50164 +/* Check the call stmts in the functions on the next cgraph node list (these functions will be in the hash table and they are reachable from ipa). + * If the call stmt is in the next cgraph node list then it's an interesting call. + */ -+static struct interesting_node *handle_stmt_by_cgraph_nodes_call(struct interesting_node *head, gimple stmt, struct next_cgraph_node *next_node) ++static struct interesting_node *handle_stmt_by_cgraph_nodes_call(struct interesting_node *head, gcall *stmt, struct next_cgraph_node *next_node) +{ + unsigned int argnum; + tree arg; @@ -126478,7 +127412,7 @@ index 0000000..df50164 +} + +// Get the index of the rhs node in an assignment -+static unsigned int get_assign_ops_count(const_gimple stmt, tree node) ++static unsigned int get_assign_ops_count(const gassign *stmt, tree node) +{ + const_tree rhs1, rhs2; + unsigned int ret; @@ -126506,7 +127440,7 @@ index 0000000..df50164 +} + +// Find the correct arg number of a call stmt. It is needed when the interesting function is a cloned function. -+static unsigned int find_arg_number_gimple(const_tree arg, const_gimple stmt) ++static unsigned int find_arg_number_gimple(const_tree arg, const gcall *stmt) +{ + unsigned int i; + @@ -126529,7 +127463,7 @@ index 0000000..df50164 +/* starting from the size_overflow asm stmt collect interesting stmts. They can be + * any of return, call or assignment stmts (because of inlining). + */ -+static struct interesting_node *get_interesting_ret_or_call(struct pointer_set_t *visited, struct interesting_node *head, tree node, gimple intentional_asm) ++static struct interesting_node *get_interesting_ret_or_call(tree_set *visited, struct interesting_node *head, tree node, gasm *intentional_asm) +{ + use_operand_p use_p; + imm_use_iterator imm_iter; @@ -126550,28 +127484,31 @@ index 0000000..df50164 + + switch (gimple_code(stmt)) { + case GIMPLE_CALL: -+ argnum = find_arg_number_gimple(node, stmt); ++ argnum = find_arg_number_gimple(node, as_a_gcall(stmt)); + head = create_new_interesting_node(head, stmt, node, argnum, intentional_asm); + break; + case GIMPLE_RETURN: + head = create_new_interesting_node(head, stmt, node, 0, intentional_asm); + break; + case GIMPLE_ASSIGN: -+ argnum = get_assign_ops_count(stmt, node); ++ argnum = get_assign_ops_count(as_a_const_gassign(stmt), node); + head = create_new_interesting_node(head, stmt, node, argnum, intentional_asm); + break; + case GIMPLE_PHI: { -+ tree result = gimple_phi_result(stmt); ++ tree result = gimple_phi_result(as_a_gphi(stmt)); + head = get_interesting_ret_or_call(visited, head, result, intentional_asm); + break; + } -+ case GIMPLE_ASM: -+ if (gimple_asm_noutputs(stmt) != 0) ++ case GIMPLE_ASM: { ++ gasm *asm_stmt = as_a_gasm(stmt); ++ ++ if (gimple_asm_noutputs(asm_stmt) != 0) + break; -+ if (!is_size_overflow_asm(stmt)) ++ if (!is_size_overflow_asm(asm_stmt)) + break; -+ head = create_new_interesting_node(head, stmt, node, 1, intentional_asm); ++ head = create_new_interesting_node(head, asm_stmt, node, 1, intentional_asm); + break; ++ } + case GIMPLE_COND: + case GIMPLE_SWITCH: + break; @@ -126586,66 +127523,71 @@ index 0000000..df50164 + +static void remove_size_overflow_asm(gimple stmt) +{ ++ gasm *asm_stmt; + gimple_stmt_iterator gsi; + tree input, output; + -+ if (!is_size_overflow_asm(stmt)) ++ if (gimple_code(stmt) != GIMPLE_ASM) + return; + -+ if (gimple_asm_noutputs(stmt) == 0) { -+ gsi = gsi_for_stmt(stmt); -+ ipa_remove_stmt_references(cgraph_get_create_node(current_function_decl), stmt); ++ asm_stmt = as_a_gasm(stmt); ++ if (!is_size_overflow_asm(asm_stmt)) ++ return; ++ ++ if (gimple_asm_noutputs(asm_stmt) == 0) { ++ gsi = gsi_for_stmt(asm_stmt); ++ ipa_remove_stmt_references(cgraph_get_create_node(current_function_decl), asm_stmt); + gsi_remove(&gsi, true); + return; + } + -+ input = gimple_asm_input_op(stmt, 0); -+ output = gimple_asm_output_op(stmt, 0); -+ replace_size_overflow_asm_with_assign(stmt, TREE_VALUE(output), TREE_VALUE(input)); ++ input = gimple_asm_input_op(asm_stmt, 0); ++ output = gimple_asm_output_op(asm_stmt, 0); ++ replace_size_overflow_asm_with_assign(asm_stmt, TREE_VALUE(output), TREE_VALUE(input)); +} + +/* handle the size_overflow asm stmts from the gimple pass and collect the interesting stmts. + * If the asm stmt is a parm_decl kind (noutputs == 0) then remove it. + * If it is a simple asm stmt then replace it with an assignment from the asm input to the asm output. + */ -+static struct interesting_node *handle_stmt_by_size_overflow_asm(gimple stmt, struct interesting_node *head) ++static struct interesting_node *handle_stmt_by_size_overflow_asm(gasm *asm_stmt, struct interesting_node *head) +{ + const_tree output; -+ struct pointer_set_t *visited; -+ gimple intentional_asm = NOT_INTENTIONAL_ASM; ++ tree_set *visited; ++ gasm *intentional_asm = NOT_INTENTIONAL_ASM; + -+ if (!is_size_overflow_asm(stmt)) ++ if (!is_size_overflow_asm(asm_stmt)) + return head; + -+ if (is_size_overflow_intentional_asm_yes(stmt) || is_size_overflow_intentional_asm_turn_off(stmt)) -+ intentional_asm = stmt; ++ if (is_size_overflow_intentional_asm_yes(asm_stmt) || is_size_overflow_intentional_asm_turn_off(asm_stmt)) ++ intentional_asm = asm_stmt; + -+ gcc_assert(gimple_asm_ninputs(stmt) == 1); ++ gcc_assert(gimple_asm_ninputs(asm_stmt) == 1); + -+ if (gimple_asm_noutputs(stmt) == 0 && is_size_overflow_intentional_asm_turn_off(stmt)) ++ if (gimple_asm_noutputs(asm_stmt) == 0 && is_size_overflow_intentional_asm_turn_off(asm_stmt)) + return head; + -+ if (gimple_asm_noutputs(stmt) == 0) { ++ if (gimple_asm_noutputs(asm_stmt) == 0) { + const_tree input; + -+ if (!is_size_overflow_intentional_asm_turn_off(stmt)) ++ if (!is_size_overflow_intentional_asm_turn_off(asm_stmt)) + return head; + -+ input = gimple_asm_input_op(stmt, 0); -+ remove_size_overflow_asm(stmt); ++ input = gimple_asm_input_op(asm_stmt, 0); ++ remove_size_overflow_asm(asm_stmt); + if (is_gimple_constant(TREE_VALUE(input))) + return head; -+ visited = pointer_set_create(); ++ visited = tree_pointer_set_create(); + head = get_interesting_ret_or_call(visited, head, TREE_VALUE(input), intentional_asm); + pointer_set_destroy(visited); + return head; + } + -+ if (!is_size_overflow_intentional_asm_yes(stmt) && !is_size_overflow_intentional_asm_turn_off(stmt)) -+ remove_size_overflow_asm(stmt); ++ if (!is_size_overflow_intentional_asm_yes(asm_stmt) && !is_size_overflow_intentional_asm_turn_off(asm_stmt)) ++ remove_size_overflow_asm(asm_stmt); + -+ visited = pointer_set_create(); -+ output = gimple_asm_output_op(stmt, 0); ++ visited = tree_pointer_set_create(); ++ output = gimple_asm_output_op(asm_stmt, 0); + head = get_interesting_ret_or_call(visited, head, TREE_VALUE(output), intentional_asm); + pointer_set_destroy(visited); + return head; @@ -126669,14 +127611,14 @@ index 0000000..df50164 + code = gimple_code(stmt); + + if (code == GIMPLE_ASM) -+ head = handle_stmt_by_size_overflow_asm(stmt, head); ++ head = handle_stmt_by_size_overflow_asm(as_a_gasm(stmt), head); + + if (!next_node) + continue; + if (code == GIMPLE_CALL) -+ head = handle_stmt_by_cgraph_nodes_call(head, stmt, next_node); ++ head = handle_stmt_by_cgraph_nodes_call(head, as_a_gcall(stmt), next_node); + if (code == GIMPLE_RETURN) -+ head = handle_stmt_by_cgraph_nodes_ret(head, stmt, next_node); ++ head = handle_stmt_by_cgraph_nodes_ret(head, as_a_greturn(stmt), next_node); + } + } + return head; @@ -126813,7 +127755,6 @@ index 0000000..df50164 + struct visited_fns *visited_fns = NULL; + + FOR_EACH_FUNCTION_WITH_GIMPLE_BODY(node) { -+ gcc_assert(cgraph_function_flags_ready); +#if BUILDING_GCC_VERSION <= 4007 + gcc_assert(node->reachable); +#endif @@ -126826,6 +127767,7 @@ index 0000000..df50164 +} + +#if BUILDING_GCC_VERSION >= 4009 ++namespace { +static const struct pass_data insert_size_overflow_check_data = { +#else +static struct ipa_opt_pass_d insert_size_overflow_check = { @@ -126836,7 +127778,8 @@ index 0000000..df50164 +#if BUILDING_GCC_VERSION >= 4008 + .optinfo_flags = OPTGROUP_NONE, +#endif -+#if BUILDING_GCC_VERSION >= 4009 ++#if BUILDING_GCC_VERSION >= 5000 ++#elif BUILDING_GCC_VERSION == 4009 + .has_gate = false, + .has_execute = true, +#else @@ -126869,36 +127812,40 @@ index 0000000..df50164 +}; + +#if BUILDING_GCC_VERSION >= 4009 -+namespace { +class insert_size_overflow_check : public ipa_opt_pass_d { +public: + insert_size_overflow_check() : ipa_opt_pass_d(insert_size_overflow_check_data, g, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL) {} ++#if BUILDING_GCC_VERSION >= 5000 ++ virtual unsigned int execute(function *) { return search_function(); } ++#else + unsigned int execute() { return search_function(); } ++#endif +}; +} -+#endif + -+struct opt_pass *make_insert_size_overflow_check(void) ++opt_pass *make_insert_size_overflow_check(void) +{ -+#if BUILDING_GCC_VERSION >= 4009 + return new insert_size_overflow_check(); ++} +#else ++struct opt_pass *make_insert_size_overflow_check(void) ++{ + return &insert_size_overflow_check.pass; -+#endif +} -+ ++#endif diff --git a/tools/gcc/size_overflow_plugin/intentional_overflow.c b/tools/gcc/size_overflow_plugin/intentional_overflow.c new file mode 100644 -index 0000000..d71d72a +index 0000000..eb62680 --- /dev/null +++ b/tools/gcc/size_overflow_plugin/intentional_overflow.c -@@ -0,0 +1,736 @@ +@@ -0,0 +1,748 @@ +/* -+ * Copyright 2011-2014 by Emese Revfy <re.emese@gmail.com> ++ * Copyright 2011-2015 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 + * + * Homepage: + * http://www.grsecurity.net/~ephox/overflow_plugin/ ++ * https://github.com/ephox-gcc-plugins + * + * Documentation: + * http://forums.grsecurity.net/viewtopic.php?f=7&t=3043 @@ -126943,7 +127890,7 @@ index 0000000..d71d72a + if (param_head == NULL_TREE) + return false; + -+ if (TREE_INT_CST_HIGH(TREE_VALUE(param_head)) == -1) ++ if (tree_to_shwi(TREE_VALUE(param_head)) == -1) + return true; + return false; +} @@ -127135,13 +128082,15 @@ index 0000000..d71d72a +{ + const_tree rhs1, lhs, rhs1_type, lhs_type; + enum machine_mode lhs_mode, rhs_mode; ++ const gassign *assign; + gimple def_stmt = get_def_stmt(no_const_rhs); + + if (!def_stmt || !gimple_assign_cast_p(def_stmt)) + return false; + -+ rhs1 = gimple_assign_rhs1(def_stmt); -+ lhs = gimple_assign_lhs(def_stmt); ++ assign = as_a_const_gassign(def_stmt); ++ rhs1 = gimple_assign_rhs1(assign); ++ lhs = gimple_assign_lhs(assign); + rhs1_type = TREE_TYPE(rhs1); + lhs_type = TREE_TYPE(lhs); + rhs_mode = TYPE_MODE(rhs1_type); @@ -127165,7 +128114,7 @@ index 0000000..d71d72a + return num; + if (is_gimple_debug(use_stmt)) + continue; -+ if (gimple_assign_cast_p(use_stmt) && is_size_overflow_type(gimple_assign_lhs(use_stmt))) ++ if (gimple_assign_cast_p(use_stmt) && is_size_overflow_type(gimple_assign_lhs(as_a_const_gassign(use_stmt)))) + continue; + num++; + } @@ -127181,12 +128130,14 @@ index 0000000..d71d72a +bool is_const_plus_unsigned_signed_truncation(const_tree lhs) +{ + tree rhs1, lhs_type, rhs_type, rhs2, not_const_rhs; ++ gassign *assign; + gimple def_stmt = get_def_stmt(lhs); + + if (!def_stmt || !gimple_assign_cast_p(def_stmt)) + return false; + -+ rhs1 = gimple_assign_rhs1(def_stmt); ++ assign = as_a_gassign(def_stmt); ++ rhs1 = gimple_assign_rhs1(assign); + rhs_type = TREE_TYPE(rhs1); + lhs_type = TREE_TYPE(lhs); + if (TYPE_UNSIGNED(lhs_type) || !TYPE_UNSIGNED(rhs_type)) @@ -127198,11 +128149,12 @@ index 0000000..d71d72a + if (!def_stmt || !is_gimple_assign(def_stmt) || gimple_num_ops(def_stmt) != 3) + return false; + -+ if (gimple_assign_rhs_code(def_stmt) != PLUS_EXPR) ++ assign = as_a_gassign(def_stmt); ++ if (gimple_assign_rhs_code(assign) != PLUS_EXPR) + return false; + -+ rhs1 = gimple_assign_rhs1(def_stmt); -+ rhs2 = gimple_assign_rhs2(def_stmt); ++ rhs1 = gimple_assign_rhs1(assign); ++ rhs2 = gimple_assign_rhs2(assign); + if (!is_gimple_constant(rhs1) && !is_gimple_constant(rhs2)) + return false; + @@ -127259,7 +128211,7 @@ index 0000000..d71d72a + return false; +} + -+bool is_a_constant_overflow(const_gimple stmt, const_tree rhs) ++bool is_a_constant_overflow(const gassign *stmt, const_tree rhs) +{ + if (gimple_assign_rhs_code(stmt) == MIN_EXPR) + return false; @@ -127273,7 +128225,7 @@ index 0000000..d71d72a + return true; +} + -+static tree change_assign_rhs(struct visited *visited, gimple stmt, const_tree orig_rhs, tree new_rhs) ++static tree change_assign_rhs(struct visited *visited, gassign *stmt, const_tree orig_rhs, tree new_rhs) +{ + gimple assign; + gimple_stmt_iterator gsi = gsi_for_stmt(stmt); @@ -127283,10 +128235,10 @@ index 0000000..d71d72a + + assign = build_cast_stmt(visited, origtype, new_rhs, CREATE_NEW_VAR, &gsi, BEFORE_STMT, false); + pointer_set_insert(visited->my_stmts, assign); -+ return gimple_assign_lhs(assign); ++ return get_lhs(assign); +} + -+tree handle_intentional_overflow(struct visited *visited, struct cgraph_node *caller_node, bool check_overflow, gimple stmt, tree change_rhs, tree new_rhs2) ++tree handle_intentional_overflow(struct visited *visited, struct cgraph_node *caller_node, bool check_overflow, gassign *stmt, tree change_rhs, tree new_rhs2) +{ + tree new_rhs, orig_rhs; + void (*gimple_assign_set_rhs)(gimple, tree); @@ -127317,9 +128269,10 @@ index 0000000..d71d72a + return create_assign(visited, stmt, lhs, AFTER_STMT); +} + -+static bool is_subtraction_special(struct visited *visited, const_gimple stmt) ++static bool is_subtraction_special(struct visited *visited, const gassign *stmt) +{ -+ gimple rhs1_def_stmt, rhs2_def_stmt; ++ gimple def_stmt_1, def_stmt_2; ++ const gassign *rhs1_def_stmt, *rhs2_def_stmt; + const_tree rhs1_def_stmt_rhs1, rhs2_def_stmt_rhs1, rhs1_def_stmt_lhs, rhs2_def_stmt_lhs; + enum machine_mode rhs1_def_stmt_rhs1_mode, rhs2_def_stmt_rhs1_mode, rhs1_def_stmt_lhs_mode, rhs2_def_stmt_lhs_mode; + const_tree rhs1 = gimple_assign_rhs1(stmt); @@ -127333,15 +128286,18 @@ index 0000000..d71d72a + if (gimple_assign_rhs_code(stmt) != MINUS_EXPR) + return false; + -+ rhs1_def_stmt = get_def_stmt(rhs1); -+ rhs2_def_stmt = get_def_stmt(rhs2); -+ if (!gimple_assign_cast_p(rhs1_def_stmt) || !gimple_assign_cast_p(rhs2_def_stmt)) ++ def_stmt_1 = get_def_stmt(rhs1); ++ def_stmt_2 = get_def_stmt(rhs2); ++ if (!gimple_assign_cast_p(def_stmt_1) || !gimple_assign_cast_p(def_stmt_2)) + return false; + ++ rhs1_def_stmt = as_a_const_gassign(def_stmt_1); ++ rhs2_def_stmt = as_a_const_gassign(def_stmt_2); + rhs1_def_stmt_rhs1 = gimple_assign_rhs1(rhs1_def_stmt); + rhs2_def_stmt_rhs1 = gimple_assign_rhs1(rhs2_def_stmt); + rhs1_def_stmt_lhs = gimple_assign_lhs(rhs1_def_stmt); + rhs2_def_stmt_lhs = gimple_assign_lhs(rhs2_def_stmt); ++ + rhs1_def_stmt_rhs1_mode = TYPE_MODE(TREE_TYPE(rhs1_def_stmt_rhs1)); + rhs2_def_stmt_rhs1_mode = TYPE_MODE(TREE_TYPE(rhs2_def_stmt_rhs1)); + rhs1_def_stmt_lhs_mode = TYPE_MODE(TREE_TYPE(rhs1_def_stmt_lhs)); @@ -127356,15 +128312,15 @@ index 0000000..d71d72a + return true; +} + -+static gimple create_binary_assign(struct visited *visited, enum tree_code code, gimple stmt, tree rhs1, tree rhs2) ++static gassign *create_binary_assign(struct visited *visited, enum tree_code code, gassign *stmt, tree rhs1, tree rhs2) +{ -+ gimple assign; ++ gassign *assign; + gimple_stmt_iterator gsi = gsi_for_stmt(stmt); + tree type = TREE_TYPE(rhs1); + tree lhs = create_new_var(type); + + gcc_assert(types_compatible_p(type, TREE_TYPE(rhs2))); -+ assign = gimple_build_assign_with_ops(code, lhs, rhs1, rhs2); ++ assign = as_a_gassign(gimple_build_assign_with_ops(code, lhs, rhs1, rhs2)); + gimple_assign_set_lhs(assign, make_ssa_name(lhs, assign)); + + gsi_insert_before(&gsi, assign, GSI_NEW_STMT); @@ -127384,11 +128340,11 @@ index 0000000..d71d72a + + gsi = gsi_for_stmt(stmt); + cast_stmt = build_cast_stmt(visited, intTI_type_node, node, CREATE_NEW_VAR, &gsi, BEFORE_STMT, false); -+ pointer_set_insert(visited->my_stmts, cast_stmt); -+ return gimple_assign_lhs(cast_stmt); ++ pointer_set_insert(visited->my_stmts, (gimple)cast_stmt); ++ return get_lhs(cast_stmt); +} + -+static tree get_def_stmt_rhs(struct visited *visited, const_tree var) ++static tree get_def_stmt_rhs(const_tree var) +{ + tree rhs1, def_stmt_rhs1; + gimple rhs1_def_stmt, def_stmt_rhs1_def_stmt, def_stmt; @@ -127396,14 +128352,13 @@ index 0000000..d71d72a + def_stmt = get_def_stmt(var); + if (!gimple_assign_cast_p(def_stmt)) + return NULL_TREE; -+ gcc_assert(gimple_code(def_stmt) != GIMPLE_NOP && pointer_set_contains(visited->my_stmts, def_stmt) && gimple_assign_cast_p(def_stmt)); + -+ rhs1 = gimple_assign_rhs1(def_stmt); ++ rhs1 = gimple_assign_rhs1(as_a_const_gassign(def_stmt)); + rhs1_def_stmt = get_def_stmt(rhs1); + if (!gimple_assign_cast_p(rhs1_def_stmt)) + return rhs1; + -+ def_stmt_rhs1 = gimple_assign_rhs1(rhs1_def_stmt); ++ def_stmt_rhs1 = gimple_assign_rhs1(as_a_const_gassign(rhs1_def_stmt)); + def_stmt_rhs1_def_stmt = get_def_stmt(def_stmt_rhs1); + + switch (gimple_code(def_stmt_rhs1_def_stmt)) { @@ -127424,7 +128379,7 @@ index 0000000..d71d72a +{ + tree new_rhs1, new_rhs2; + tree new_rhs1_def_stmt_rhs1, new_rhs2_def_stmt_rhs1, new_lhs; -+ gimple assign, stmt = get_def_stmt(lhs); ++ gassign *assign, *stmt = as_a_gassign(get_def_stmt(lhs)); + tree rhs1 = gimple_assign_rhs1(stmt); + tree rhs2 = gimple_assign_rhs2(stmt); + @@ -127434,8 +128389,8 @@ index 0000000..d71d72a + new_rhs1 = expand(visited, caller_node, rhs1); + new_rhs2 = expand(visited, caller_node, rhs2); + -+ new_rhs1_def_stmt_rhs1 = get_def_stmt_rhs(visited, new_rhs1); -+ new_rhs2_def_stmt_rhs1 = get_def_stmt_rhs(visited, new_rhs2); ++ new_rhs1_def_stmt_rhs1 = get_def_stmt_rhs(new_rhs1); ++ new_rhs2_def_stmt_rhs1 = get_def_stmt_rhs(new_rhs2); + + if (new_rhs1_def_stmt_rhs1 == NULL_TREE || new_rhs2_def_stmt_rhs1 == NULL_TREE) + return NULL_TREE; @@ -127478,6 +128433,7 @@ index 0000000..d71d72a + const_tree res; + tree rhs1, rhs2, def_rhs1, def_rhs2, const_rhs, def_const_rhs; + const_gimple def_stmt; ++ const gassign *assign, *def_assign; + + if (!stmt || gimple_code(stmt) == GIMPLE_NOP) + return false; @@ -127486,8 +128442,9 @@ index 0000000..d71d72a + if (gimple_assign_rhs_code(stmt) != MULT_EXPR) + return false; + -+ rhs1 = gimple_assign_rhs1(stmt); -+ rhs2 = gimple_assign_rhs2(stmt); ++ assign = as_a_const_gassign(stmt); ++ rhs1 = gimple_assign_rhs1(assign); ++ rhs2 = gimple_assign_rhs2(assign); + if (is_gimple_constant(rhs1)) { + const_rhs = rhs1; + def_stmt = get_def_stmt(rhs2); @@ -127503,8 +128460,9 @@ index 0000000..d71d72a + if (gimple_assign_rhs_code(def_stmt) != PLUS_EXPR && gimple_assign_rhs_code(def_stmt) != MINUS_EXPR) + return false; + -+ def_rhs1 = gimple_assign_rhs1(def_stmt); -+ def_rhs2 = gimple_assign_rhs2(def_stmt); ++ def_assign = as_a_const_gassign(def_stmt); ++ def_rhs1 = gimple_assign_rhs1(def_assign); ++ def_rhs2 = gimple_assign_rhs2(def_assign); + if (is_gimple_constant(def_rhs1)) + def_const_rhs = def_rhs1; + else if (is_gimple_constant(def_rhs2)) @@ -127512,13 +128470,13 @@ index 0000000..d71d72a + else + return false; + -+ res = fold_binary_loc(gimple_location(def_stmt), MULT_EXPR, TREE_TYPE(const_rhs), const_rhs, def_const_rhs); ++ res = fold_binary_loc(gimple_location(def_assign), MULT_EXPR, TREE_TYPE(const_rhs), const_rhs, def_const_rhs); + if (is_lt_signed_type_max(res) && is_gt_zero(res)) + return false; + return true; +} + -+enum intentional_overflow_type add_mul_intentional_overflow(const_gimple stmt) ++enum intentional_overflow_type add_mul_intentional_overflow(const gassign *stmt) +{ + const_gimple def_stmt_1, def_stmt_2; + const_tree rhs1, rhs2; @@ -127584,17 +128542,17 @@ index 0000000..d71d72a + + if (!is_gimple_assign(def_stmt) || gimple_num_ops(def_stmt) != 2) + return false; -+ rhs = gimple_assign_rhs1(def_stmt); ++ rhs = gimple_assign_rhs1(as_a_const_gassign(def_stmt)); + def_stmt = get_def_stmt(rhs); + if (!def_stmt) + return false; + return is_call_or_cast(def_stmt); +} + -+void unsigned_signed_cast_intentional_overflow(struct visited *visited, gimple stmt) ++void unsigned_signed_cast_intentional_overflow(struct visited *visited, gassign *stmt) +{ + unsigned int use_num; -+ gimple so_stmt; ++ gassign *so_stmt; + const_gimple def_stmt; + const_tree rhs1, rhs2; + tree rhs = gimple_assign_rhs1(stmt); @@ -127615,31 +128573,32 @@ index 0000000..d71d72a + if (!is_gimple_assign(def_stmt)) + return; + -+ rhs1 = gimple_assign_rhs1(def_stmt); ++ rhs1 = gimple_assign_rhs1(as_a_const_gassign(def_stmt)); + if (!is_unsigned_cast_or_call_def_stmt(rhs1)) + return; + -+ rhs2 = gimple_assign_rhs2(def_stmt); ++ rhs2 = gimple_assign_rhs2(as_a_const_gassign(def_stmt)); + if (!is_unsigned_cast_or_call_def_stmt(rhs2)) + return; + if (gimple_num_ops(def_stmt) == 3 && !is_gimple_constant(rhs1) && !is_gimple_constant(rhs2)) + return; + -+ so_stmt = get_dup_stmt(visited, stmt); ++ so_stmt = as_a_gassign(get_dup_stmt(visited, stmt)); + create_up_and_down_cast(visited, so_stmt, lhs_type, gimple_assign_rhs1(so_stmt)); +} + diff --git a/tools/gcc/size_overflow_plugin/misc.c b/tools/gcc/size_overflow_plugin/misc.c new file mode 100644 -index 0000000..4bddad2 +index 0000000..253b4a8b --- /dev/null +++ b/tools/gcc/size_overflow_plugin/misc.c -@@ -0,0 +1,203 @@ +@@ -0,0 +1,219 @@ +/* -+ * Copyright 2011-2014 by Emese Revfy <re.emese@gmail.com> ++ * Copyright 2011-2015 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 + * + * Homepage: ++ * https://github.com/ephox-gcc-plugins + * http://www.grsecurity.net/~ephox/overflow_plugin/ + * + * Documentation: @@ -127673,6 +128632,20 @@ index 0000000..4bddad2 + current_function_decl = NULL_TREE; +} + ++tree get_lhs(const_gimple stmt) ++{ ++ switch (gimple_code(stmt)) { ++ case GIMPLE_ASSIGN: ++ case GIMPLE_CALL: ++ return gimple_get_lhs(as_a_const_gassign(stmt)); ++ case GIMPLE_PHI: ++ return gimple_phi_result(as_a_const_gphi(stmt)); ++ default: ++ debug_gimple_stmt((gimple)stmt); ++ gcc_unreachable(); ++ } ++} ++ +static bool is_bool(const_tree node) +{ + const_tree type; @@ -127784,7 +128757,8 @@ index 0000000..4bddad2 + +gimple build_cast_stmt(struct visited *visited, tree dst_type, tree rhs, tree lhs, gimple_stmt_iterator *gsi, bool before, bool force) +{ -+ gimple assign, def_stmt; ++ gimple def_stmt; ++ gassign *assign; + + gcc_assert(dst_type != NULL_TREE && rhs != NULL_TREE); + gcc_assert(!is_gimple_constant(rhs)); @@ -127840,15 +128814,16 @@ index 0000000..4bddad2 + diff --git a/tools/gcc/size_overflow_plugin/remove_unnecessary_dup.c b/tools/gcc/size_overflow_plugin/remove_unnecessary_dup.c new file mode 100644 -index 0000000..7c9e6d1 +index 0000000..de5999d --- /dev/null +++ b/tools/gcc/size_overflow_plugin/remove_unnecessary_dup.c -@@ -0,0 +1,138 @@ +@@ -0,0 +1,139 @@ +/* -+ * Copyright 2011-2014 by Emese Revfy <re.emese@gmail.com> ++ * Copyright 2011-2015 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 + * + * Homepage: ++ * https://github.com/ephox-gcc-plugins + * http://www.grsecurity.net/~ephox/overflow_plugin/ + * + * Documentation: @@ -127866,7 +128841,7 @@ index 0000000..7c9e6d1 +#include "gcc-common.h" +#include "size_overflow.h" + -+bool skip_expr_on_double_type(const_gimple stmt) ++bool skip_expr_on_double_type(const gassign *stmt) +{ + enum tree_code code = gimple_assign_rhs_code(stmt); + @@ -127888,19 +128863,19 @@ index 0000000..7c9e6d1 + } +} + -+void create_up_and_down_cast(struct visited *visited, gimple use_stmt, tree orig_type, tree rhs) ++void create_up_and_down_cast(struct visited *visited, gassign *use_stmt, tree orig_type, tree rhs) +{ + const_tree orig_rhs1; + tree down_lhs, new_lhs, dup_type = TREE_TYPE(rhs); -+ gimple down_cast, up_cast; ++ const_gimple down_cast, up_cast; + gimple_stmt_iterator gsi = gsi_for_stmt(use_stmt); + + down_cast = build_cast_stmt(visited, orig_type, rhs, CREATE_NEW_VAR, &gsi, BEFORE_STMT, false); -+ down_lhs = gimple_assign_lhs(down_cast); ++ down_lhs = get_lhs(down_cast); + + gsi = gsi_for_stmt(use_stmt); + up_cast = build_cast_stmt(visited, dup_type, down_lhs, CREATE_NEW_VAR, &gsi, BEFORE_STMT, false); -+ new_lhs = gimple_assign_lhs(up_cast); ++ new_lhs = get_lhs(up_cast); + + orig_rhs1 = gimple_assign_rhs1(use_stmt); + if (operand_equal_p(orig_rhs1, rhs, 0)) @@ -127944,7 +128919,7 @@ index 0000000..7c9e6d1 + return new_type; +} + -+static void insert_cast_rhs(struct visited *visited, gimple stmt, tree rhs) ++static void insert_cast_rhs(struct visited *visited, gassign *stmt, tree rhs) +{ + tree type; + @@ -127959,7 +128934,7 @@ index 0000000..7c9e6d1 + create_up_and_down_cast(visited, stmt, type, rhs); +} + -+static void insert_cast(struct visited *visited, gimple stmt, tree rhs) ++static void insert_cast(struct visited *visited, gassign *stmt, tree rhs) +{ + if (LONG_TYPE_SIZE == GET_MODE_BITSIZE(SImode) && !is_size_overflow_type(rhs)) + return; @@ -127967,7 +128942,7 @@ index 0000000..7c9e6d1 + insert_cast_rhs(visited, stmt, rhs); +} + -+void insert_cast_expr(struct visited *visited, gimple stmt, enum intentional_overflow_type type) ++void insert_cast_expr(struct visited *visited, gassign *stmt, enum intentional_overflow_type type) +{ + tree rhs1, rhs2; + @@ -127984,10 +128959,10 @@ index 0000000..7c9e6d1 + diff --git a/tools/gcc/size_overflow_plugin/size_overflow.h b/tools/gcc/size_overflow_plugin/size_overflow.h new file mode 100644 -index 0000000..37f8fc3 +index 0000000..20732b1 --- /dev/null +++ b/tools/gcc/size_overflow_plugin/size_overflow.h -@@ -0,0 +1,127 @@ +@@ -0,0 +1,183 @@ +#ifndef SIZE_OVERFLOW_H +#define SIZE_OVERFLOW_H + @@ -128009,11 +128984,66 @@ index 0000000..37f8fc3 + NO_INTENTIONAL_OVERFLOW, RHS1_INTENTIONAL_OVERFLOW, RHS2_INTENTIONAL_OVERFLOW +}; + ++ ++#if BUILDING_GCC_VERSION >= 5000 ++typedef struct hash_set<const_gimple> gimple_set; ++ ++static inline bool pointer_set_insert(gimple_set *visited, const_gimple stmt) ++{ ++ return visited->add(stmt); ++} ++ ++static inline bool pointer_set_contains(gimple_set *visited, const_gimple stmt) ++{ ++ return visited->contains(stmt); ++} ++ ++static inline gimple_set* pointer_set_create(void) ++{ ++ return new hash_set<const_gimple>; ++} ++ ++static inline void pointer_set_destroy(gimple_set *visited) ++{ ++ delete visited; ++} ++ ++typedef struct hash_set<tree> tree_set; ++ ++static inline bool pointer_set_insert(tree_set *visited, tree node) ++{ ++ return visited->add(node); ++} ++ ++static inline bool pointer_set_contains(tree_set *visited, tree node) ++{ ++ return visited->contains(node); ++} ++ ++static inline tree_set *tree_pointer_set_create(void) ++{ ++ return new hash_set<tree>; ++} ++ ++static inline void pointer_set_destroy(tree_set *visited) ++{ ++ delete visited; ++} ++#else ++typedef struct pointer_set_t gimple_set; ++typedef struct pointer_set_t tree_set; ++ ++static inline tree_set *tree_pointer_set_create(void) ++{ ++ return pointer_set_create(); ++} ++#endif ++ +struct visited { -+ struct pointer_set_t *stmts; -+ struct pointer_set_t *my_stmts; -+ struct pointer_set_t *skip_expr_casts; -+ struct pointer_set_t *no_cast_check; ++ gimple_set *stmts; ++ gimple_set *my_stmts; ++ gimple_set *skip_expr_casts; ++ gimple_set *no_cast_check; +}; + +// size_overflow_plugin.c @@ -128044,10 +129074,10 @@ index 0000000..37f8fc3 + unsigned int num; + enum mark intentional_attr_decl; + enum mark intentional_attr_cur_fndecl; -+ gimple intentional_mark_from_gimple; ++ gasm *intentional_mark_from_gimple; +}; + -+extern bool is_size_overflow_asm(const_gimple stmt); ++extern bool is_size_overflow_asm(const gasm *stmt); +extern unsigned int get_function_num(const_tree node, const_tree orig_fndecl); +extern unsigned int get_correct_arg_count(unsigned int argnum, const_tree fndecl); +extern bool is_missing_function(const_tree orig_fndecl, unsigned int num); @@ -128062,8 +129092,8 @@ index 0000000..37f8fc3 + +// intentional_overflow.c +extern enum mark get_intentional_attr_type(const_tree node); -+extern bool is_size_overflow_intentional_asm_yes(const_gimple stmt); -+extern bool is_size_overflow_intentional_asm_turn_off(const_gimple stmt); ++extern bool is_size_overflow_intentional_asm_yes(const gasm *stmt); ++extern bool is_size_overflow_intentional_asm_turn_off(const gasm *stmt); +extern bool is_end_intentional_intentional_attr(const_tree decl, unsigned int argnum); +extern bool is_yes_intentional_attr(const_tree decl, unsigned int argnum); +extern bool is_turn_off_intentional_attr(const_tree decl); @@ -128071,12 +129101,12 @@ index 0000000..37f8fc3 +extern void check_intentional_attribute_ipa(struct interesting_node *cur_node); +extern bool is_a_cast_and_const_overflow(const_tree no_const_rhs); +extern bool is_const_plus_unsigned_signed_truncation(const_tree lhs); -+extern bool is_a_constant_overflow(const_gimple stmt, const_tree rhs); -+extern tree handle_intentional_overflow(struct visited *visited, struct cgraph_node *caller_node, bool check_overflow, gimple stmt, tree change_rhs, tree new_rhs2); ++extern bool is_a_constant_overflow(const gassign *stmt, const_tree rhs); ++extern tree handle_intentional_overflow(struct visited *visited, struct cgraph_node *caller_node, bool check_overflow, gassign *stmt, tree change_rhs, tree new_rhs2); +extern tree handle_integer_truncation(struct visited *visited, struct cgraph_node *caller_node, const_tree lhs); +extern bool is_a_neg_overflow(const_gimple stmt, const_tree rhs); -+extern enum intentional_overflow_type add_mul_intentional_overflow(const_gimple def_stmt); -+extern void unsigned_signed_cast_intentional_overflow(struct visited *visited, gimple stmt); ++extern enum intentional_overflow_type add_mul_intentional_overflow(const gassign *def_stmt); ++extern void unsigned_signed_cast_intentional_overflow(struct visited *visited, gassign *stmt); + + +// insert_size_overflow_check_ipa.c @@ -128093,6 +129123,7 @@ index 0000000..37f8fc3 +// misc.c +extern void set_current_function_decl(tree fndecl); +extern void unset_current_function_decl(void); ++extern tree get_lhs(const_gimple stmt); +extern gimple get_def_stmt(const_tree node); +extern tree create_new_var(tree type); +extern gimple build_cast_stmt(struct visited *visited, tree dst_type, tree rhs, tree lhs, gimple_stmt_iterator *gsi, bool before, bool force); @@ -128104,28 +129135,29 @@ index 0000000..37f8fc3 +// insert_size_overflow_check_core.c +extern tree expand(struct visited *visited, struct cgraph_node *caller_node, tree lhs); +extern void check_size_overflow(struct cgraph_node *caller_node, gimple stmt, tree size_overflow_type, tree cast_rhs, tree rhs, bool before); -+extern tree dup_assign(struct visited *visited, gimple oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3); ++extern tree dup_assign(struct visited *visited, gassign *oldstmt, const_tree node, tree rhs1, tree rhs2, tree __unused rhs3); +extern tree create_assign(struct visited *visited, gimple oldstmt, tree rhs1, bool before); + + +// remove_unnecessary_dup.c +extern struct opt_pass *make_remove_unnecessary_dup_pass(void); -+extern void insert_cast_expr(struct visited *visited, gimple stmt, enum intentional_overflow_type type); -+extern bool skip_expr_on_double_type(const_gimple stmt); -+extern void create_up_and_down_cast(struct visited *visited, gimple use_stmt, tree orig_type, tree rhs); ++extern void insert_cast_expr(struct visited *visited, gassign *stmt, enum intentional_overflow_type type); ++extern bool skip_expr_on_double_type(const gassign *stmt); ++extern void create_up_and_down_cast(struct visited *visited, gassign *use_stmt, tree orig_type, tree rhs); + +#endif diff --git a/tools/gcc/size_overflow_plugin/size_overflow_debug.c b/tools/gcc/size_overflow_plugin/size_overflow_debug.c new file mode 100644 -index 0000000..4378111 +index 0000000..176c32f --- /dev/null +++ b/tools/gcc/size_overflow_plugin/size_overflow_debug.c -@@ -0,0 +1,116 @@ +@@ -0,0 +1,123 @@ +/* -+ * Copyright 2011-2014 by Emese Revfy <re.emese@gmail.com> ++ * Copyright 2011-2015 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 + * + * Homepage: ++ * https://github.com/ephox-gcc-plugins + * http://www.grsecurity.net/~ephox/overflow_plugin/ + * + * Documentation: @@ -128142,7 +129174,7 @@ index 0000000..4378111 + +#include "gcc-common.h" + -+static unsigned int dump_functions(void) ++static unsigned int __unused dump_functions(void) +{ + struct cgraph_node *node; + @@ -128177,6 +129209,7 @@ index 0000000..4378111 +} + +#if BUILDING_GCC_VERSION >= 4009 ++namespace { +static const struct pass_data dump_pass_data = { +#else +static struct ipa_opt_pass_d dump_pass = { @@ -128187,7 +129220,8 @@ index 0000000..4378111 +#if BUILDING_GCC_VERSION >= 4008 + .optinfo_flags = OPTGROUP_NONE, +#endif -+#if BUILDING_GCC_VERSION >= 4009 ++#if BUILDING_GCC_VERSION >= 5000 ++#elif BUILDING_GCC_VERSION == 4009 + .has_gate = false, + .has_execute = true, +#else @@ -128220,23 +129254,27 @@ index 0000000..4378111 +}; + +#if BUILDING_GCC_VERSION >= 4009 -+namespace { +class dump_pass : public ipa_opt_pass_d { +public: + dump_pass() : ipa_opt_pass_d(dump_pass_data, g, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL) {} ++#if BUILDING_GCC_VERSION >= 5000 ++ virtual unsigned int execute(function *) { return dump_functions(); } ++#else + unsigned int execute() { return dump_functions(); } ++#endif +}; +} -+#endif + -+struct opt_pass *make_dump_pass(void) ++opt_pass *make_dump_pass(void) +{ -+#if BUILDING_GCC_VERSION >= 4009 + return new dump_pass(); ++} +#else ++struct opt_pass *make_dump_pass(void) ++{ + return &dump_pass.pass; -+#endif +} ++#endif 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..51560ee @@ -134404,15 +135442,16 @@ index 0000000..560cd7b +zpios_read_64734 zpios_read 3 64734 NULL diff --git a/tools/gcc/size_overflow_plugin/size_overflow_plugin.c b/tools/gcc/size_overflow_plugin/size_overflow_plugin.c new file mode 100644 -index 0000000..95f7abd +index 0000000..7e07890 --- /dev/null +++ b/tools/gcc/size_overflow_plugin/size_overflow_plugin.c -@@ -0,0 +1,259 @@ +@@ -0,0 +1,260 @@ +/* -+ * Copyright 2011-2014 by Emese Revfy <re.emese@gmail.com> ++ * Copyright 2011-2015 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 + * + * Homepage: ++ * https://github.com/ephox-gcc-plugins + * http://www.grsecurity.net/~ephox/overflow_plugin/ + * + * Documentation: @@ -134440,7 +135479,7 @@ index 0000000..95f7abd +tree size_overflow_type_TI; + +static struct plugin_info size_overflow_plugin_info = { -+ .version = "20140725", ++ .version = "20140725_01", + .help = "no-size-overflow\tturn off size overflow checking\n", +}; + @@ -134494,7 +135533,7 @@ index 0000000..95f7abd + return NULL_TREE; + } + -+ if (TREE_INT_CST_HIGH(TREE_VALUE(args)) != 0) ++ if (tree_to_shwi(TREE_VALUE(args)) != 0) + return NULL_TREE; + + for (; args; args = TREE_CHAIN(args)) { @@ -134669,15 +135708,16 @@ index 0000000..95f7abd +} diff --git a/tools/gcc/size_overflow_plugin/size_overflow_plugin_hash.c b/tools/gcc/size_overflow_plugin/size_overflow_plugin_hash.c new file mode 100644 -index 0000000..0888f6c +index 0000000..2a693fe --- /dev/null +++ b/tools/gcc/size_overflow_plugin/size_overflow_plugin_hash.c -@@ -0,0 +1,364 @@ +@@ -0,0 +1,355 @@ +/* -+ * Copyright 2011-2014 by Emese Revfy <re.emese@gmail.com> ++ * Copyright 2011-2015 by Emese Revfy <re.emese@gmail.com> + * Licensed under the GPL v2, or (at your option) v3 + * + * Homepage: ++ * https://github.com/ephox-gcc-plugins + * http://www.grsecurity.net/~ephox/overflow_plugin/ + * + * Documentation: @@ -134905,43 +135945,33 @@ index 0000000..0888f6c + return CANNOT_FIND_ARG; +} + -+static const char *get_asm_string(const_gimple stmt) -+{ -+ if (!stmt) -+ return NULL; -+ if (gimple_code(stmt) != GIMPLE_ASM) -+ return NULL; -+ -+ return gimple_asm_string(stmt); -+} -+ -+bool is_size_overflow_intentional_asm_turn_off(const_gimple stmt) ++bool is_size_overflow_intentional_asm_turn_off(const gasm *stmt) +{ + const char *str; + -+ str = get_asm_string(stmt); -+ if (!str) ++ if (!stmt) + return false; ++ str = gimple_asm_string(stmt); + return !strncmp(str, TURN_OFF_ASM_STR, sizeof(TURN_OFF_ASM_STR) - 1); +} + -+bool is_size_overflow_intentional_asm_yes(const_gimple stmt) ++bool is_size_overflow_intentional_asm_yes(const gasm *stmt) +{ + const char *str; + -+ str = get_asm_string(stmt); -+ if (!str) ++ if (!stmt) + return false; ++ str = gimple_asm_string(stmt); + return !strncmp(str, YES_ASM_STR, sizeof(YES_ASM_STR) - 1); +} + -+bool is_size_overflow_asm(const_gimple stmt) ++bool is_size_overflow_asm(const gasm *stmt) +{ + const char *str; + -+ str = get_asm_string(stmt); -+ if (!str) ++ if (!stmt) + return false; ++ str = gimple_asm_string(stmt); + return !strncmp(str, OK_ASM_STR, sizeof(OK_ASM_STR) - 1); +} + |