diff options
| author | Alexandre Oliva <lxoliva@fsfla.org> | 2015-12-11 23:31:33 +0000 |
|---|---|---|
| committer | Alexandre Oliva <lxoliva@fsfla.org> | 2015-12-11 23:31:33 +0000 |
| commit | 532c97980e6f86bd2ad36aff9bbcd8a260ae32fd (patch) | |
| tree | f73ef358bef0cb4a06e2b47c16f9f21a410d012e /freed-ora/current/f22 | |
| parent | 258616abf3b71a9c4f495786a4402e9518b15d1a (diff) | |
| download | linux-libre-raptor-532c97980e6f86bd2ad36aff9bbcd8a260ae32fd.tar.gz linux-libre-raptor-532c97980e6f86bd2ad36aff9bbcd8a260ae32fd.zip | |
4.2.6-201.fc22.gnu
Diffstat (limited to 'freed-ora/current/f22')
9 files changed, 1066 insertions, 1 deletions
diff --git a/freed-ora/current/f22/0001-KVM-x86-build-kvm_userspace_memory_region-in-x86_set.patch b/freed-ora/current/f22/0001-KVM-x86-build-kvm_userspace_memory_region-in-x86_set.patch new file mode 100644 index 000000000..6395b1746 --- /dev/null +++ b/freed-ora/current/f22/0001-KVM-x86-build-kvm_userspace_memory_region-in-x86_set.patch @@ -0,0 +1,169 @@ +From 1d8007bdee074fdffcf3539492d8a151a1fb3436 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini <pbonzini@redhat.com> +Date: Mon, 12 Oct 2015 13:38:32 +0200 +Subject: [PATCH] KVM: x86: build kvm_userspace_memory_region in + x86_set_memory_region +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The next patch will make x86_set_memory_region fill the +userspace_addr. Since the struct is not used untouched +anymore, it makes sense to build it in x86_set_memory_region +directly; it also simplifies the callers. + +Reported-by: Alexandre DERUMIER <aderumier@odiso.com> +Cc: stable@vger.kernel.org +Fixes: 9da0e4d5ac969909f6b435ce28ea28135a9cbd69 +Reviewed-by: Radim Krčmář <rkrcmar@redhat.com> +Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> +--- + arch/x86/include/asm/kvm_host.h | 6 ++---- + arch/x86/kvm/vmx.c | 26 ++++++-------------------- + arch/x86/kvm/x86.c | 31 +++++++++++++------------------ + 3 files changed, 21 insertions(+), 42 deletions(-) + +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index 49ec903..4e7ad7e 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -1199,9 +1199,7 @@ void kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err); + + int kvm_is_in_guest(void); + +-int __x86_set_memory_region(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem); +-int x86_set_memory_region(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem); ++int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size); ++int x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size); + + #endif /* _ASM_X86_KVM_HOST_H */ +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 18c30b4..8461e0c 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -4105,17 +4105,13 @@ static void seg_setup(int seg) + static int alloc_apic_access_page(struct kvm *kvm) + { + struct page *page; +- struct kvm_userspace_memory_region kvm_userspace_mem; + int r = 0; + + mutex_lock(&kvm->slots_lock); + if (kvm->arch.apic_access_page_done) + goto out; +- kvm_userspace_mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT; +- kvm_userspace_mem.flags = 0; +- kvm_userspace_mem.guest_phys_addr = APIC_DEFAULT_PHYS_BASE; +- kvm_userspace_mem.memory_size = PAGE_SIZE; +- r = __x86_set_memory_region(kvm, &kvm_userspace_mem); ++ r = __x86_set_memory_region(kvm, APIC_ACCESS_PAGE_PRIVATE_MEMSLOT, ++ APIC_DEFAULT_PHYS_BASE, PAGE_SIZE); + if (r) + goto out; + +@@ -4140,17 +4136,12 @@ static int alloc_identity_pagetable(struct kvm *kvm) + { + /* Called with kvm->slots_lock held. */ + +- struct kvm_userspace_memory_region kvm_userspace_mem; + int r = 0; + + BUG_ON(kvm->arch.ept_identity_pagetable_done); + +- kvm_userspace_mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT; +- kvm_userspace_mem.flags = 0; +- kvm_userspace_mem.guest_phys_addr = +- kvm->arch.ept_identity_map_addr; +- kvm_userspace_mem.memory_size = PAGE_SIZE; +- r = __x86_set_memory_region(kvm, &kvm_userspace_mem); ++ r = __x86_set_memory_region(kvm, IDENTITY_PAGETABLE_PRIVATE_MEMSLOT, ++ kvm->arch.ept_identity_map_addr, PAGE_SIZE); + + return r; + } +@@ -4949,14 +4940,9 @@ static int vmx_interrupt_allowed(struct kvm_vcpu *vcpu) + static int vmx_set_tss_addr(struct kvm *kvm, unsigned int addr) + { + int ret; +- struct kvm_userspace_memory_region tss_mem = { +- .slot = TSS_PRIVATE_MEMSLOT, +- .guest_phys_addr = addr, +- .memory_size = PAGE_SIZE * 3, +- .flags = 0, +- }; + +- ret = x86_set_memory_region(kvm, &tss_mem); ++ ret = x86_set_memory_region(kvm, TSS_PRIVATE_MEMSLOT, addr, ++ PAGE_SIZE * 3); + if (ret) + return ret; + kvm->arch.tss_addr = addr; +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 373328b..b12665b 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -7721,18 +7721,21 @@ void kvm_arch_sync_events(struct kvm *kvm) + kvm_free_pit(kvm); + } + +-int __x86_set_memory_region(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem) ++int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size) + { + int i, r; + + /* Called with kvm->slots_lock held. */ +- BUG_ON(mem->slot >= KVM_MEM_SLOTS_NUM); ++ if (WARN_ON(id >= KVM_MEM_SLOTS_NUM)) ++ return -EINVAL; + + for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { +- struct kvm_userspace_memory_region m = *mem; ++ struct kvm_userspace_memory_region m; + +- m.slot |= i << 16; ++ m.slot = id | (i << 16); ++ m.flags = 0; ++ m.guest_phys_addr = gpa; ++ m.memory_size = size; + r = __kvm_set_memory_region(kvm, &m); + if (r < 0) + return r; +@@ -7742,13 +7745,12 @@ int __x86_set_memory_region(struct kvm *kvm, + } + EXPORT_SYMBOL_GPL(__x86_set_memory_region); + +-int x86_set_memory_region(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem) ++int x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size) + { + int r; + + mutex_lock(&kvm->slots_lock); +- r = __x86_set_memory_region(kvm, mem); ++ r = __x86_set_memory_region(kvm, id, gpa, size); + mutex_unlock(&kvm->slots_lock); + + return r; +@@ -7763,16 +7765,9 @@ void kvm_arch_destroy_vm(struct kvm *kvm) + * unless the the memory map has changed due to process exit + * or fd copying. + */ +- struct kvm_userspace_memory_region mem; +- memset(&mem, 0, sizeof(mem)); +- mem.slot = APIC_ACCESS_PAGE_PRIVATE_MEMSLOT; +- x86_set_memory_region(kvm, &mem); +- +- mem.slot = IDENTITY_PAGETABLE_PRIVATE_MEMSLOT; +- x86_set_memory_region(kvm, &mem); +- +- mem.slot = TSS_PRIVATE_MEMSLOT; +- x86_set_memory_region(kvm, &mem); ++ x86_set_memory_region(kvm, APIC_ACCESS_PAGE_PRIVATE_MEMSLOT, 0, 0); ++ x86_set_memory_region(kvm, IDENTITY_PAGETABLE_PRIVATE_MEMSLOT, 0, 0); ++ x86_set_memory_region(kvm, TSS_PRIVATE_MEMSLOT, 0, 0); + } + kvm_iommu_unmap_guest(kvm); + kfree(kvm->arch.vpic); diff --git a/freed-ora/current/f22/0001-ipv6-Avoid-creating-RTF_CACHE-from-a-rt-that-is-not-.patch b/freed-ora/current/f22/0001-ipv6-Avoid-creating-RTF_CACHE-from-a-rt-that-is-not-.patch new file mode 100644 index 000000000..3390024d2 --- /dev/null +++ b/freed-ora/current/f22/0001-ipv6-Avoid-creating-RTF_CACHE-from-a-rt-that-is-not-.patch @@ -0,0 +1,91 @@ +From 0d3f6d297bfb7af24d0508460fdb3d1ec4903fa3 Mon Sep 17 00:00:00 2001 +From: Martin KaFai Lau <kafai@fb.com> +Date: Wed, 11 Nov 2015 11:51:06 -0800 +Subject: [PATCH] ipv6: Avoid creating RTF_CACHE from a rt that is not managed + by fib6 tree + +The original bug report: +https://bugzilla.redhat.com/show_bug.cgi?id=1272571 + +The setup has a IPv4 GRE tunnel running in a IPSec. The bug +happens when ndisc starts sending router solicitation at the gre +interface. The simplified oops stack is like: + +__lock_acquire+0x1b2/0x1c30 +lock_acquire+0xb9/0x140 +_raw_write_lock_bh+0x3f/0x50 +__ip6_ins_rt+0x2e/0x60 +ip6_ins_rt+0x49/0x50 +~~~~~~~~ +__ip6_rt_update_pmtu.part.54+0x145/0x250 +ip6_rt_update_pmtu+0x2e/0x40 +~~~~~~~~ +ip_tunnel_xmit+0x1f1/0xf40 +__gre_xmit+0x7a/0x90 +ipgre_xmit+0x15a/0x220 +dev_hard_start_xmit+0x2bd/0x480 +__dev_queue_xmit+0x696/0x730 +dev_queue_xmit+0x10/0x20 +neigh_direct_output+0x11/0x20 +ip6_finish_output2+0x21f/0x770 +ip6_finish_output+0xa7/0x1d0 +ip6_output+0x56/0x190 +~~~~~~~~ +ndisc_send_skb+0x1d9/0x400 +ndisc_send_rs+0x88/0xc0 +~~~~~~~~ + +The rt passed to ip6_rt_update_pmtu() is created by +icmp6_dst_alloc() and it is not managed by the fib6 tree, +so its rt6i_table == NULL. When __ip6_rt_update_pmtu() creates +a RTF_CACHE clone, the newly created clone also has rt6i_table == NULL +and it causes the ip6_ins_rt() oops. + +During pmtu update, we only want to create a RTF_CACHE clone +from a rt which is currently managed (or owned) by the +fib6 tree. It means either rt->rt6i_node != NULL or +rt is a RTF_PCPU clone. + +It is worth to note that rt6i_table may not be NULL even it is +not (yet) managed by the fib6 tree (e.g. addrconf_dst_alloc()). +Hence, rt6i_node is a better check instead of rt6i_table. + +Fixes: 45e4fd26683c ("ipv6: Only create RTF_CACHE routes after encountering pmtu") +Signed-off-by: Martin KaFai Lau <kafai@fb.com> +Reported-by: Chris Siebenmann <cks-rhbugzilla@cs.toronto.edu> +Cc: Chris Siebenmann <cks-rhbugzilla@cs.toronto.edu> +Cc: Hannes Frederic Sowa <hannes@stressinduktion.org> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + net/ipv6/route.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index c8bc9b4..74907c5 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -1322,6 +1322,12 @@ static void rt6_do_update_pmtu(struct rt6_info *rt, u32 mtu) + rt6_update_expires(rt, net->ipv6.sysctl.ip6_rt_mtu_expires); + } + ++static bool rt6_cache_allowed_for_pmtu(const struct rt6_info *rt) ++{ ++ return !(rt->rt6i_flags & RTF_CACHE) && ++ (rt->rt6i_flags & RTF_PCPU || rt->rt6i_node); ++} ++ + static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, + const struct ipv6hdr *iph, u32 mtu) + { +@@ -1335,7 +1341,7 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, + if (mtu >= dst_mtu(dst)) + return; + +- if (rt6->rt6i_flags & RTF_CACHE) { ++ if (!rt6_cache_allowed_for_pmtu(rt6)) { + rt6_do_update_pmtu(rt6, mtu); + } else { + const struct in6_addr *daddr, *saddr; +-- +2.5.0 + diff --git a/freed-ora/current/f22/0002-KVM-x86-map-unmap-private-slots-in-__x86_set_memory_.patch b/freed-ora/current/f22/0002-KVM-x86-map-unmap-private-slots-in-__x86_set_memory_.patch new file mode 100644 index 000000000..261c6e10f --- /dev/null +++ b/freed-ora/current/f22/0002-KVM-x86-map-unmap-private-slots-in-__x86_set_memory_.patch @@ -0,0 +1,134 @@ +From f0d648bdf0a5bbc91da6099d5282f77996558ea4 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini <pbonzini@redhat.com> +Date: Mon, 12 Oct 2015 13:56:27 +0200 +Subject: [PATCH] KVM: x86: map/unmap private slots in __x86_set_memory_region +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Otherwise, two copies (one of them never populated and thus bogus) +are allocated for the regular and SMM address spaces. This breaks +SMM with EPT but without unrestricted guest support, because the +SMM copy of the identity page map is all zeros. + +By moving the allocation to the caller we also remove the last +vestiges of kernel-allocated memory regions (not accessible anymore +in userspace since commit b74a07beed0e, "KVM: Remove kernel-allocated +memory regions", 2010-06-21); that is a nice bonus. + +Reported-by: Alexandre DERUMIER <aderumier@odiso.com> +Cc: stable@vger.kernel.org +Fixes: 9da0e4d5ac969909f6b435ce28ea28135a9cbd69 +Reviewed-by: Radim Krčmář <rkrcmar@redhat.com> +Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> +--- + arch/x86/kvm/x86.c | 62 ++++++++++++++++++++++++++---------------------------- + 1 file changed, 30 insertions(+), 32 deletions(-) + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 7bf8096..3ac33f8 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -7477,23 +7477,53 @@ void kvm_arch_sync_events(struct kvm *kvm) + int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size) + { + int i, r; ++ u64 hva; ++ struct kvm_memslots *slots = kvm_memslots(kvm); ++ struct kvm_memory_slot *slot, old; + + /* Called with kvm->slots_lock held. */ + if (WARN_ON(id >= KVM_MEM_SLOTS_NUM)) + return -EINVAL; + ++ slot = id_to_memslot(slots, id); ++ if (size) { ++ if (WARN_ON(slot->npages)) ++ return -EEXIST; ++ ++ /* ++ * MAP_SHARED to prevent internal slot pages from being moved ++ * by fork()/COW. ++ */ ++ hva = vm_mmap(NULL, 0, size, PROT_READ | PROT_WRITE, ++ MAP_SHARED | MAP_ANONYMOUS, 0); ++ if (IS_ERR((void *)hva)) ++ return PTR_ERR((void *)hva); ++ } else { ++ if (!slot->npages) ++ return 0; ++ ++ hva = 0; ++ } ++ ++ old = *slot; + for (i = 0; i < KVM_ADDRESS_SPACE_NUM; i++) { + struct kvm_userspace_memory_region m; + + m.slot = id | (i << 16); + m.flags = 0; + m.guest_phys_addr = gpa; ++ m.userspace_addr = hva; + m.memory_size = size; + r = __kvm_set_memory_region(kvm, &m); + if (r < 0) + return r; + } + ++ if (!size) { ++ r = vm_munmap(old.userspace_addr, old.npages * PAGE_SIZE); ++ WARN_ON(r < 0); ++ } ++ + return 0; + } + EXPORT_SYMBOL_GPL(__x86_set_memory_region); +@@ -7623,27 +7653,6 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + const struct kvm_userspace_memory_region *mem, + enum kvm_mr_change change) + { +- /* +- * Only private memory slots need to be mapped here since +- * KVM_SET_MEMORY_REGION ioctl is no longer supported. +- */ +- if ((memslot->id >= KVM_USER_MEM_SLOTS) && (change == KVM_MR_CREATE)) { +- unsigned long userspace_addr; +- +- /* +- * MAP_SHARED to prevent internal slot pages from being moved +- * by fork()/COW. +- */ +- userspace_addr = vm_mmap(NULL, 0, memslot->npages * PAGE_SIZE, +- PROT_READ | PROT_WRITE, +- MAP_SHARED | MAP_ANONYMOUS, 0); +- +- if (IS_ERR((void *)userspace_addr)) +- return PTR_ERR((void *)userspace_addr); +- +- memslot->userspace_addr = userspace_addr; +- } +- + return 0; + } + +@@ -7705,17 +7714,6 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, + { + int nr_mmu_pages = 0; + +- if (change == KVM_MR_DELETE && old->id >= KVM_USER_MEM_SLOTS) { +- int ret; +- +- ret = vm_munmap(old->userspace_addr, +- old->npages * PAGE_SIZE); +- if (ret < 0) +- printk(KERN_WARNING +- "kvm_vm_ioctl_set_memory_region: " +- "failed to munmap memory\n"); +- } +- + if (!kvm->arch.n_requested_mmu_pages) + nr_mmu_pages = kvm_mmu_calculate_mmu_pages(kvm); + +-- +2.5.0 + diff --git a/freed-ora/current/f22/0003-KVM-x86-fix-previous-commit-for-32-bit.patch b/freed-ora/current/f22/0003-KVM-x86-fix-previous-commit-for-32-bit.patch new file mode 100644 index 000000000..df99e60f0 --- /dev/null +++ b/freed-ora/current/f22/0003-KVM-x86-fix-previous-commit-for-32-bit.patch @@ -0,0 +1,30 @@ +From 25188b9986cf6b0cadcf1bc1d1693a2e9c50ed47 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini <pbonzini@redhat.com> +Date: Wed, 14 Oct 2015 15:51:08 +0200 +Subject: [PATCH] KVM: x86: fix previous commit for 32-bit + +Unfortunately I only noticed this after pushing. + +Fixes: f0d648bdf0a5bbc91da6099d5282f77996558ea4 +Cc: stable@vger.kernel.org +Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> +--- + arch/x86/kvm/x86.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index 6e03546..9a9a198 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -7482,7 +7482,7 @@ void kvm_arch_sync_events(struct kvm *kvm) + int __x86_set_memory_region(struct kvm *kvm, int id, gpa_t gpa, u32 size) + { + int i, r; +- u64 hva; ++ unsigned long hva; + struct kvm_memslots *slots = kvm_memslots(kvm); + struct kvm_memory_slot *slot, old; + +-- +2.5.0 + diff --git a/freed-ora/current/f22/ideapad-laptop-Add-Lenovo-Yoga-900-to-no_hw_rfkill-d.patch b/freed-ora/current/f22/ideapad-laptop-Add-Lenovo-Yoga-900-to-no_hw_rfkill-d.patch new file mode 100644 index 000000000..9f6e5db1c --- /dev/null +++ b/freed-ora/current/f22/ideapad-laptop-Add-Lenovo-Yoga-900-to-no_hw_rfkill-d.patch @@ -0,0 +1,41 @@ +From 332faabbaab64876396be48f1a1cf72b31d53a9d Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Mon, 9 Nov 2015 17:09:05 +0100 +Subject: [PATCH] ideapad-laptop: Add Lenovo Yoga 900 to no_hw_rfkill dmi list + +Like some of the other Yoga models the Lenovo Yoga 900 does not have a +hw rfkill switch, and trying to read the hw rfkill switch through the +ideapad module causes it to always reported blocking breaking wifi. + +This commit adds the Lenovo Yoga 900 to the no_hw_rfkill dmi list, fixing +the wifi breakage. + +BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1275490 +Cc: stable@vger.kernel.org +Reported-and-tested-by: Kevin Fenzi <kevin@scrye.com> +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +--- + drivers/platform/x86/ideapad-laptop.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c +index fce49f3c6ed6..d4a48b4d161a 100644 +--- a/drivers/platform/x86/ideapad-laptop.c ++++ b/drivers/platform/x86/ideapad-laptop.c +@@ -873,6 +873,13 @@ static const struct dmi_system_id no_hw_rfkill_list[] = { + DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 3 Pro-1370"), + }, + }, ++ { ++ .ident = "Lenovo Yoga 900", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo YOGA 900"), ++ }, ++ }, + {} + }; + +-- +2.4.3 + diff --git a/freed-ora/current/f22/kernel.spec b/freed-ora/current/f22/kernel.spec index 3f680c051..05e833fb4 100644 --- a/freed-ora/current/f22/kernel.spec +++ b/freed-ora/current/f22/kernel.spec @@ -40,7 +40,7 @@ Summary: The Linux kernel # For non-released -rc kernels, this will be appended after the rcX and # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3" # -%global baserelease 200 +%global baserelease 201 %global fedora_build %{baserelease} # base_sublevel is the kernel version we're starting with and patching @@ -687,6 +687,22 @@ Patch551: KVM-svm-unconditionally-intercept-DB.patch #rhbz 1269300 Patch552: megaraid_sas-Do-not-use-PAGE_SIZE-for-max_sectors.patch +#rhbz 1275490 +Patch553: ideapad-laptop-Add-Lenovo-Yoga-900-to-no_hw_rfkill-d.patch + +#rhbz 1279189 +Patch556: netfilter-ipset-Fix-extension-alignment.patch +Patch557: netfilter-ipset-Fix-hash-type-expiration.patch +Patch558: netfilter-ipset-Fix-hash-type-expire-release-empty-h.patch + +#rhbz 1272571 +Patch559: 0001-ipv6-Avoid-creating-RTF_CACHE-from-a-rt-that-is-not-.patch + +#rhbz 1278688 +Patch560: 0001-KVM-x86-build-kvm_userspace_memory_region-in-x86_set.patch +Patch561: 0002-KVM-x86-map-unmap-private-slots-in-__x86_set_memory_.patch +Patch562: 0003-KVM-x86-fix-previous-commit-for-32-bit.patch + # END OF PATCH DEFINITIONS %endif @@ -1531,6 +1547,22 @@ ApplyPatch KVM-svm-unconditionally-intercept-DB.patch #rhbz 1269300 ApplyPatch megaraid_sas-Do-not-use-PAGE_SIZE-for-max_sectors.patch +#rhbz 1275490 +ApplyPatch ideapad-laptop-Add-Lenovo-Yoga-900-to-no_hw_rfkill-d.patch + +#rhbz 1279189 +ApplyPatch netfilter-ipset-Fix-extension-alignment.patch +ApplyPatch netfilter-ipset-Fix-hash-type-expiration.patch +ApplyPatch netfilter-ipset-Fix-hash-type-expire-release-empty-h.patch + +#rhbz 1272571 +ApplyPatch 0001-ipv6-Avoid-creating-RTF_CACHE-from-a-rt-that-is-not-.patch + +#rhbz 1278688 +ApplyPatch 0001-KVM-x86-build-kvm_userspace_memory_region-in-x86_set.patch +ApplyPatch 0002-KVM-x86-map-unmap-private-slots-in-__x86_set_memory_.patch +ApplyPatch 0003-KVM-x86-fix-previous-commit-for-32-bit.patch + # END OF PATCH APPLICATIONS %endif @@ -2394,6 +2426,16 @@ fi # # %changelog +* Fri Nov 20 2015 Justin M. Forbes <jmforbes@fedoraproject.org> +- Fix for GRE tunnel running in IPSec (rhbz 1272571) +- Fix KVM on specific hardware (rhbz 1278688) + +* Mon Nov 16 2015 Josh Boyer <jwboyer@fedoraproject.org> +- Fix ipset netfilter issues (rhbz 1279189) + +* Tue Nov 10 2015 Josh Boyer <jwboyer@fedoraproject.org> +- Fix Yoga 900 rfkill switch issues (rhbz 1275490) + * Tue Nov 10 2015 Alexandre Oliva <lxoliva@fsfla.org> -libre - GNU Linux-libre 4.2.6-gnu. diff --git a/freed-ora/current/f22/netfilter-ipset-Fix-extension-alignment.patch b/freed-ora/current/f22/netfilter-ipset-Fix-extension-alignment.patch new file mode 100644 index 000000000..0a955e246 --- /dev/null +++ b/freed-ora/current/f22/netfilter-ipset-Fix-extension-alignment.patch @@ -0,0 +1,481 @@ +From 55301931f78c0fdbb8f76dfdb3f914e9eef1f273 Mon Sep 17 00:00:00 2001 +From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> +Date: Sat, 7 Nov 2015 11:21:47 +0100 +Subject: [PATCH 1/3] netfilter: ipset: Fix extension alignment + +The data extensions in ipset lacked the proper memory alignment and +thus could lead to kernel crash on several architectures. Therefore +the structures have been reorganized and alignment attributes added +where needed. The patch was tested on armv7h by Gerhard Wiesinger and +on x86_64, sparc64 by Jozsef Kadlecsik. + +Reported-by: Gerhard Wiesinger <lists@wiesinger.com> +Tested-by: Gerhard Wiesinger <lists@wiesinger.com> +Tested-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> +Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> +--- + include/linux/netfilter/ipset/ip_set.h | 2 +- + net/netfilter/ipset/ip_set_bitmap_gen.h | 17 +++----- + net/netfilter/ipset/ip_set_bitmap_ip.c | 14 ++----- + net/netfilter/ipset/ip_set_bitmap_ipmac.c | 64 ++++++++++++++----------------- + net/netfilter/ipset/ip_set_bitmap_port.c | 18 ++++----- + net/netfilter/ipset/ip_set_core.c | 14 ++++--- + net/netfilter/ipset/ip_set_hash_gen.h | 11 ++++-- + net/netfilter/ipset/ip_set_list_set.c | 5 ++- + 8 files changed, 65 insertions(+), 80 deletions(-) + +diff --git a/include/linux/netfilter/ipset/ip_set.h b/include/linux/netfilter/ipset/ip_set.h +index 48bb01edcf30..0e1f433cc4b7 100644 +--- a/include/linux/netfilter/ipset/ip_set.h ++++ b/include/linux/netfilter/ipset/ip_set.h +@@ -421,7 +421,7 @@ extern void ip_set_free(void *members); + extern int ip_set_get_ipaddr4(struct nlattr *nla, __be32 *ipaddr); + extern int ip_set_get_ipaddr6(struct nlattr *nla, union nf_inet_addr *ipaddr); + extern size_t ip_set_elem_len(struct ip_set *set, struct nlattr *tb[], +- size_t len); ++ size_t len, size_t align); + extern int ip_set_get_extensions(struct ip_set *set, struct nlattr *tb[], + struct ip_set_ext *ext); + +diff --git a/net/netfilter/ipset/ip_set_bitmap_gen.h b/net/netfilter/ipset/ip_set_bitmap_gen.h +index d05e759ed0fa..b0bc475f641e 100644 +--- a/net/netfilter/ipset/ip_set_bitmap_gen.h ++++ b/net/netfilter/ipset/ip_set_bitmap_gen.h +@@ -33,7 +33,7 @@ + #define mtype_gc IPSET_TOKEN(MTYPE, _gc) + #define mtype MTYPE + +-#define get_ext(set, map, id) ((map)->extensions + (set)->dsize * (id)) ++#define get_ext(set, map, id) ((map)->extensions + ((set)->dsize * (id))) + + static void + mtype_gc_init(struct ip_set *set, void (*gc)(unsigned long ul_set)) +@@ -67,12 +67,9 @@ mtype_destroy(struct ip_set *set) + del_timer_sync(&map->gc); + + ip_set_free(map->members); +- if (set->dsize) { +- if (set->extensions & IPSET_EXT_DESTROY) +- mtype_ext_cleanup(set); +- ip_set_free(map->extensions); +- } +- kfree(map); ++ if (set->dsize && set->extensions & IPSET_EXT_DESTROY) ++ mtype_ext_cleanup(set); ++ ip_set_free(map); + + set->data = NULL; + } +@@ -92,16 +89,14 @@ mtype_head(struct ip_set *set, struct sk_buff *skb) + { + const struct mtype *map = set->data; + struct nlattr *nested; ++ size_t memsize = sizeof(*map) + map->memsize; + + nested = ipset_nest_start(skb, IPSET_ATTR_DATA); + if (!nested) + goto nla_put_failure; + if (mtype_do_head(skb, map) || + nla_put_net32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1)) || +- nla_put_net32(skb, IPSET_ATTR_MEMSIZE, +- htonl(sizeof(*map) + +- map->memsize + +- set->dsize * map->elements))) ++ nla_put_net32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize))) + goto nla_put_failure; + if (unlikely(ip_set_put_flags(skb, set))) + goto nla_put_failure; +diff --git a/net/netfilter/ipset/ip_set_bitmap_ip.c b/net/netfilter/ipset/ip_set_bitmap_ip.c +index 64a564334418..4783efff0bde 100644 +--- a/net/netfilter/ipset/ip_set_bitmap_ip.c ++++ b/net/netfilter/ipset/ip_set_bitmap_ip.c +@@ -41,7 +41,6 @@ MODULE_ALIAS("ip_set_bitmap:ip"); + /* Type structure */ + struct bitmap_ip { + void *members; /* the set members */ +- void *extensions; /* data extensions */ + u32 first_ip; /* host byte order, included in range */ + u32 last_ip; /* host byte order, included in range */ + u32 elements; /* number of max elements in the set */ +@@ -49,6 +48,8 @@ struct bitmap_ip { + size_t memsize; /* members size */ + u8 netmask; /* subnet netmask */ + struct timer_list gc; /* garbage collection */ ++ unsigned char extensions[0] /* data extensions */ ++ __aligned(__alignof__(u64)); + }; + + /* ADT structure for generic function args */ +@@ -224,13 +225,6 @@ init_map_ip(struct ip_set *set, struct bitmap_ip *map, + map->members = ip_set_alloc(map->memsize); + if (!map->members) + return false; +- if (set->dsize) { +- map->extensions = ip_set_alloc(set->dsize * elements); +- if (!map->extensions) { +- kfree(map->members); +- return false; +- } +- } + map->first_ip = first_ip; + map->last_ip = last_ip; + map->elements = elements; +@@ -316,13 +310,13 @@ bitmap_ip_create(struct net *net, struct ip_set *set, struct nlattr *tb[], + pr_debug("hosts %u, elements %llu\n", + hosts, (unsigned long long)elements); + +- map = kzalloc(sizeof(*map), GFP_KERNEL); ++ set->dsize = ip_set_elem_len(set, tb, 0, 0); ++ map = ip_set_alloc(sizeof(*map) + elements * set->dsize); + if (!map) + return -ENOMEM; + + map->memsize = bitmap_bytes(0, elements - 1); + set->variant = &bitmap_ip; +- set->dsize = ip_set_elem_len(set, tb, 0); + if (!init_map_ip(set, map, first_ip, last_ip, + elements, hosts, netmask)) { + kfree(map); +diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c +index 1430535118fb..29dde208381d 100644 +--- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c ++++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c +@@ -47,24 +47,26 @@ enum { + /* Type structure */ + struct bitmap_ipmac { + void *members; /* the set members */ +- void *extensions; /* MAC + data extensions */ + u32 first_ip; /* host byte order, included in range */ + u32 last_ip; /* host byte order, included in range */ + u32 elements; /* number of max elements in the set */ + size_t memsize; /* members size */ + struct timer_list gc; /* garbage collector */ ++ unsigned char extensions[0] /* MAC + data extensions */ ++ __aligned(__alignof__(u64)); + }; + + /* ADT structure for generic function args */ + struct bitmap_ipmac_adt_elem { ++ unsigned char ether[ETH_ALEN] __aligned(2); + u16 id; +- unsigned char *ether; ++ u16 add_mac; + }; + + struct bitmap_ipmac_elem { + unsigned char ether[ETH_ALEN]; + unsigned char filled; +-} __attribute__ ((aligned)); ++} __aligned(__alignof__(u64)); + + static inline u32 + ip_to_id(const struct bitmap_ipmac *m, u32 ip) +@@ -72,11 +74,11 @@ ip_to_id(const struct bitmap_ipmac *m, u32 ip) + return ip - m->first_ip; + } + +-static inline struct bitmap_ipmac_elem * +-get_elem(void *extensions, u16 id, size_t dsize) +-{ +- return (struct bitmap_ipmac_elem *)(extensions + id * dsize); +-} ++#define get_elem(extensions, id, dsize) \ ++ (struct bitmap_ipmac_elem *)(extensions + (id) * (dsize)) ++ ++#define get_const_elem(extensions, id, dsize) \ ++ (const struct bitmap_ipmac_elem *)(extensions + (id) * (dsize)) + + /* Common functions */ + +@@ -88,10 +90,9 @@ bitmap_ipmac_do_test(const struct bitmap_ipmac_adt_elem *e, + + if (!test_bit(e->id, map->members)) + return 0; +- elem = get_elem(map->extensions, e->id, dsize); +- if (elem->filled == MAC_FILLED) +- return !e->ether || +- ether_addr_equal(e->ether, elem->ether); ++ elem = get_const_elem(map->extensions, e->id, dsize); ++ if (e->add_mac && elem->filled == MAC_FILLED) ++ return ether_addr_equal(e->ether, elem->ether); + /* Trigger kernel to fill out the ethernet address */ + return -EAGAIN; + } +@@ -103,7 +104,7 @@ bitmap_ipmac_gc_test(u16 id, const struct bitmap_ipmac *map, size_t dsize) + + if (!test_bit(id, map->members)) + return 0; +- elem = get_elem(map->extensions, id, dsize); ++ elem = get_const_elem(map->extensions, id, dsize); + /* Timer not started for the incomplete elements */ + return elem->filled == MAC_FILLED; + } +@@ -133,7 +134,7 @@ bitmap_ipmac_add_timeout(unsigned long *timeout, + * and we can reuse it later when MAC is filled out, + * possibly by the kernel + */ +- if (e->ether) ++ if (e->add_mac) + ip_set_timeout_set(timeout, t); + else + *timeout = t; +@@ -150,7 +151,7 @@ bitmap_ipmac_do_add(const struct bitmap_ipmac_adt_elem *e, + elem = get_elem(map->extensions, e->id, dsize); + if (test_bit(e->id, map->members)) { + if (elem->filled == MAC_FILLED) { +- if (e->ether && ++ if (e->add_mac && + (flags & IPSET_FLAG_EXIST) && + !ether_addr_equal(e->ether, elem->ether)) { + /* memcpy isn't atomic */ +@@ -159,7 +160,7 @@ bitmap_ipmac_do_add(const struct bitmap_ipmac_adt_elem *e, + ether_addr_copy(elem->ether, e->ether); + } + return IPSET_ADD_FAILED; +- } else if (!e->ether) ++ } else if (!e->add_mac) + /* Already added without ethernet address */ + return IPSET_ADD_FAILED; + /* Fill the MAC address and trigger the timer activation */ +@@ -168,7 +169,7 @@ bitmap_ipmac_do_add(const struct bitmap_ipmac_adt_elem *e, + ether_addr_copy(elem->ether, e->ether); + elem->filled = MAC_FILLED; + return IPSET_ADD_START_STORED_TIMEOUT; +- } else if (e->ether) { ++ } else if (e->add_mac) { + /* We can store MAC too */ + ether_addr_copy(elem->ether, e->ether); + elem->filled = MAC_FILLED; +@@ -191,7 +192,7 @@ bitmap_ipmac_do_list(struct sk_buff *skb, const struct bitmap_ipmac *map, + u32 id, size_t dsize) + { + const struct bitmap_ipmac_elem *elem = +- get_elem(map->extensions, id, dsize); ++ get_const_elem(map->extensions, id, dsize); + + return nla_put_ipaddr4(skb, IPSET_ATTR_IP, + htonl(map->first_ip + id)) || +@@ -213,7 +214,7 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb, + { + struct bitmap_ipmac *map = set->data; + ipset_adtfn adtfn = set->variant->adt[adt]; +- struct bitmap_ipmac_adt_elem e = { .id = 0 }; ++ struct bitmap_ipmac_adt_elem e = { .id = 0, .add_mac = 1 }; + struct ip_set_ext ext = IP_SET_INIT_KEXT(skb, opt, set); + u32 ip; + +@@ -231,7 +232,7 @@ bitmap_ipmac_kadt(struct ip_set *set, const struct sk_buff *skb, + return -EINVAL; + + e.id = ip_to_id(map, ip); +- e.ether = eth_hdr(skb)->h_source; ++ memcpy(e.ether, eth_hdr(skb)->h_source, ETH_ALEN); + + return adtfn(set, &e, &ext, &opt->ext, opt->cmdflags); + } +@@ -265,11 +266,10 @@ bitmap_ipmac_uadt(struct ip_set *set, struct nlattr *tb[], + return -IPSET_ERR_BITMAP_RANGE; + + e.id = ip_to_id(map, ip); +- if (tb[IPSET_ATTR_ETHER]) +- e.ether = nla_data(tb[IPSET_ATTR_ETHER]); +- else +- e.ether = NULL; +- ++ if (tb[IPSET_ATTR_ETHER]) { ++ memcpy(e.ether, nla_data(tb[IPSET_ATTR_ETHER]), ETH_ALEN); ++ e.add_mac = 1; ++ } + ret = adtfn(set, &e, &ext, &ext, flags); + + return ip_set_eexist(ret, flags) ? 0 : ret; +@@ -300,13 +300,6 @@ init_map_ipmac(struct ip_set *set, struct bitmap_ipmac *map, + map->members = ip_set_alloc(map->memsize); + if (!map->members) + return false; +- if (set->dsize) { +- map->extensions = ip_set_alloc(set->dsize * elements); +- if (!map->extensions) { +- kfree(map->members); +- return false; +- } +- } + map->first_ip = first_ip; + map->last_ip = last_ip; + map->elements = elements; +@@ -361,14 +354,15 @@ bitmap_ipmac_create(struct net *net, struct ip_set *set, struct nlattr *tb[], + if (elements > IPSET_BITMAP_MAX_RANGE + 1) + return -IPSET_ERR_BITMAP_RANGE_SIZE; + +- map = kzalloc(sizeof(*map), GFP_KERNEL); ++ set->dsize = ip_set_elem_len(set, tb, ++ sizeof(struct bitmap_ipmac_elem), ++ __alignof__(struct bitmap_ipmac_elem)); ++ map = ip_set_alloc(sizeof(*map) + elements * set->dsize); + if (!map) + return -ENOMEM; + + map->memsize = bitmap_bytes(0, elements - 1); + set->variant = &bitmap_ipmac; +- set->dsize = ip_set_elem_len(set, tb, +- sizeof(struct bitmap_ipmac_elem)); + if (!init_map_ipmac(set, map, first_ip, last_ip, elements)) { + kfree(map); + return -ENOMEM; +diff --git a/net/netfilter/ipset/ip_set_bitmap_port.c b/net/netfilter/ipset/ip_set_bitmap_port.c +index 5338ccd5da46..7f0c733358a4 100644 +--- a/net/netfilter/ipset/ip_set_bitmap_port.c ++++ b/net/netfilter/ipset/ip_set_bitmap_port.c +@@ -35,12 +35,13 @@ MODULE_ALIAS("ip_set_bitmap:port"); + /* Type structure */ + struct bitmap_port { + void *members; /* the set members */ +- void *extensions; /* data extensions */ + u16 first_port; /* host byte order, included in range */ + u16 last_port; /* host byte order, included in range */ + u32 elements; /* number of max elements in the set */ + size_t memsize; /* members size */ + struct timer_list gc; /* garbage collection */ ++ unsigned char extensions[0] /* data extensions */ ++ __aligned(__alignof__(u64)); + }; + + /* ADT structure for generic function args */ +@@ -209,13 +210,6 @@ init_map_port(struct ip_set *set, struct bitmap_port *map, + map->members = ip_set_alloc(map->memsize); + if (!map->members) + return false; +- if (set->dsize) { +- map->extensions = ip_set_alloc(set->dsize * map->elements); +- if (!map->extensions) { +- kfree(map->members); +- return false; +- } +- } + map->first_port = first_port; + map->last_port = last_port; + set->timeout = IPSET_NO_TIMEOUT; +@@ -232,6 +226,7 @@ bitmap_port_create(struct net *net, struct ip_set *set, struct nlattr *tb[], + { + struct bitmap_port *map; + u16 first_port, last_port; ++ u32 elements; + + if (unlikely(!ip_set_attr_netorder(tb, IPSET_ATTR_PORT) || + !ip_set_attr_netorder(tb, IPSET_ATTR_PORT_TO) || +@@ -248,14 +243,15 @@ bitmap_port_create(struct net *net, struct ip_set *set, struct nlattr *tb[], + last_port = tmp; + } + +- map = kzalloc(sizeof(*map), GFP_KERNEL); ++ elements = last_port - first_port + 1; ++ set->dsize = ip_set_elem_len(set, tb, 0, 0); ++ map = ip_set_alloc(sizeof(*map) + elements * set->dsize); + if (!map) + return -ENOMEM; + +- map->elements = last_port - first_port + 1; ++ map->elements = elements; + map->memsize = bitmap_bytes(0, map->elements); + set->variant = &bitmap_port; +- set->dsize = ip_set_elem_len(set, tb, 0); + if (!init_map_port(set, map, first_port, last_port)) { + kfree(map); + return -ENOMEM; +diff --git a/net/netfilter/ipset/ip_set_core.c b/net/netfilter/ipset/ip_set_core.c +index 338b4047776f..cab4bc06cddd 100644 +--- a/net/netfilter/ipset/ip_set_core.c ++++ b/net/netfilter/ipset/ip_set_core.c +@@ -364,25 +364,27 @@ add_extension(enum ip_set_ext_id id, u32 flags, struct nlattr *tb[]) + } + + size_t +-ip_set_elem_len(struct ip_set *set, struct nlattr *tb[], size_t len) ++ip_set_elem_len(struct ip_set *set, struct nlattr *tb[], size_t len, ++ size_t align) + { + enum ip_set_ext_id id; +- size_t offset = len; + u32 cadt_flags = 0; + + if (tb[IPSET_ATTR_CADT_FLAGS]) + cadt_flags = ip_set_get_h32(tb[IPSET_ATTR_CADT_FLAGS]); + if (cadt_flags & IPSET_FLAG_WITH_FORCEADD) + set->flags |= IPSET_CREATE_FLAG_FORCEADD; ++ if (!align) ++ align = 1; + for (id = 0; id < IPSET_EXT_ID_MAX; id++) { + if (!add_extension(id, cadt_flags, tb)) + continue; +- offset = ALIGN(offset, ip_set_extensions[id].align); +- set->offset[id] = offset; ++ len = ALIGN(len, ip_set_extensions[id].align); ++ set->offset[id] = len; + set->extensions |= ip_set_extensions[id].type; +- offset += ip_set_extensions[id].len; ++ len += ip_set_extensions[id].len; + } +- return offset; ++ return ALIGN(len, align); + } + EXPORT_SYMBOL_GPL(ip_set_elem_len); + +diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h +index 691b54fcaf2a..4ff22194ce55 100644 +--- a/net/netfilter/ipset/ip_set_hash_gen.h ++++ b/net/netfilter/ipset/ip_set_hash_gen.h +@@ -72,8 +72,9 @@ struct hbucket { + DECLARE_BITMAP(used, AHASH_MAX_TUNED); + u8 size; /* size of the array */ + u8 pos; /* position of the first free entry */ +- unsigned char value[0]; /* the array of the values */ +-} __attribute__ ((aligned)); ++ unsigned char value[0] /* the array of the values */ ++ __aligned(__alignof__(u64)); ++}; + + /* The hash table: the table size stored here in order to make resizing easy */ + struct htable { +@@ -1323,12 +1324,14 @@ IPSET_TOKEN(HTYPE, _create)(struct net *net, struct ip_set *set, + #endif + set->variant = &IPSET_TOKEN(HTYPE, 4_variant); + set->dsize = ip_set_elem_len(set, tb, +- sizeof(struct IPSET_TOKEN(HTYPE, 4_elem))); ++ sizeof(struct IPSET_TOKEN(HTYPE, 4_elem)), ++ __alignof__(struct IPSET_TOKEN(HTYPE, 4_elem))); + #ifndef IP_SET_PROTO_UNDEF + } else { + set->variant = &IPSET_TOKEN(HTYPE, 6_variant); + set->dsize = ip_set_elem_len(set, tb, +- sizeof(struct IPSET_TOKEN(HTYPE, 6_elem))); ++ sizeof(struct IPSET_TOKEN(HTYPE, 6_elem)), ++ __alignof__(struct IPSET_TOKEN(HTYPE, 6_elem))); + } + #endif + if (tb[IPSET_ATTR_TIMEOUT]) { +diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c +index 5a30ce6e8c90..bbede95c9f68 100644 +--- a/net/netfilter/ipset/ip_set_list_set.c ++++ b/net/netfilter/ipset/ip_set_list_set.c +@@ -31,7 +31,7 @@ struct set_elem { + struct rcu_head rcu; + struct list_head list; + ip_set_id_t id; +-}; ++} __aligned(__alignof__(u64)); + + struct set_adt_elem { + ip_set_id_t id; +@@ -618,7 +618,8 @@ list_set_create(struct net *net, struct ip_set *set, struct nlattr *tb[], + size = IP_SET_LIST_MIN_SIZE; + + set->variant = &set_variant; +- set->dsize = ip_set_elem_len(set, tb, sizeof(struct set_elem)); ++ set->dsize = ip_set_elem_len(set, tb, sizeof(struct set_elem), ++ __alignof__(struct set_elem)); + if (!init_list_set(net, set, size)) + return -ENOMEM; + if (tb[IPSET_ATTR_TIMEOUT]) { +-- +2.4.3 + diff --git a/freed-ora/current/f22/netfilter-ipset-Fix-hash-type-expiration.patch b/freed-ora/current/f22/netfilter-ipset-Fix-hash-type-expiration.patch new file mode 100644 index 000000000..16ba4387f --- /dev/null +++ b/freed-ora/current/f22/netfilter-ipset-Fix-hash-type-expiration.patch @@ -0,0 +1,30 @@ +From 7210b25e452780f0792e04dd9f84f3a02c582ab7 Mon Sep 17 00:00:00 2001 +From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> +Date: Sat, 7 Nov 2015 11:23:34 +0100 +Subject: [PATCH 2/3] netfilter: ipset: Fix hash:* type expiration + +Incorrect index was used when the data blob was shrinked at expiration, +which could lead to falsely expired entries and memory leak when +the comment extension was used too. + +Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> +--- + net/netfilter/ipset/ip_set_hash_gen.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h +index 4ff22194ce55..fa4f6374bb73 100644 +--- a/net/netfilter/ipset/ip_set_hash_gen.h ++++ b/net/netfilter/ipset/ip_set_hash_gen.h +@@ -523,7 +523,7 @@ mtype_expire(struct ip_set *set, struct htype *h, u8 nets_length, size_t dsize) + continue; + data = ahash_data(n, j, dsize); + memcpy(tmp->value + d * dsize, data, dsize); +- set_bit(j, tmp->used); ++ set_bit(d, tmp->used); + d++; + } + tmp->pos = d; +-- +2.4.3 + diff --git a/freed-ora/current/f22/netfilter-ipset-Fix-hash-type-expire-release-empty-h.patch b/freed-ora/current/f22/netfilter-ipset-Fix-hash-type-expire-release-empty-h.patch new file mode 100644 index 000000000..1f0d86373 --- /dev/null +++ b/freed-ora/current/f22/netfilter-ipset-Fix-hash-type-expire-release-empty-h.patch @@ -0,0 +1,47 @@ +From 03fdcf282c8fe212efae0d1229fb8594ffe60b17 Mon Sep 17 00:00:00 2001 +From: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> +Date: Sat, 7 Nov 2015 11:24:51 +0100 +Subject: [PATCH 3/3] netfilter: ipset: Fix hash type expire: release empty + hash bucket block + +When all entries are expired/all slots are empty, release the bucket. + +Signed-off-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> +--- + net/netfilter/ipset/ip_set_hash_gen.h | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/net/netfilter/ipset/ip_set_hash_gen.h b/net/netfilter/ipset/ip_set_hash_gen.h +index fa4f6374bb73..e5336ab36d67 100644 +--- a/net/netfilter/ipset/ip_set_hash_gen.h ++++ b/net/netfilter/ipset/ip_set_hash_gen.h +@@ -476,7 +476,7 @@ static void + mtype_expire(struct ip_set *set, struct htype *h, u8 nets_length, size_t dsize) + { + struct htable *t; +- struct hbucket *n; ++ struct hbucket *n, *tmp; + struct mtype_elem *data; + u32 i, j, d; + #ifdef IP_SET_HASH_WITH_NETS +@@ -511,9 +511,14 @@ mtype_expire(struct ip_set *set, struct htype *h, u8 nets_length, size_t dsize) + } + } + if (d >= AHASH_INIT_SIZE) { +- struct hbucket *tmp = kzalloc(sizeof(*tmp) + +- (n->size - AHASH_INIT_SIZE) * dsize, +- GFP_ATOMIC); ++ if (d >= n->size) { ++ rcu_assign_pointer(hbucket(t, i), NULL); ++ kfree_rcu(n, rcu); ++ continue; ++ } ++ tmp = kzalloc(sizeof(*tmp) + ++ (n->size - AHASH_INIT_SIZE) * dsize, ++ GFP_ATOMIC); + if (!tmp) + /* Still try to delete expired elements */ + continue; +-- +2.4.3 + |

