commit:     ca48410af3b76a4d555b0d1164701e9f9d311f35
Author:     Anthony G. Basile <blueness <AT> gentoo <DOT> org>
AuthorDate: Tue Oct 13 00:01:40 2015 +0000
Commit:     Anthony G. Basile <blueness <AT> gentoo <DOT> org>
CommitDate: Tue Oct 13 00:01:40 2015 +0000
URL:        
https://gitweb.gentoo.org/proj/hardened-patchset.git/commit/?id=ca48410a

grsecurity-3.1-4.2.3-201510111839

 4.2.3/0000_README                                  |   2 +-
 ...> 4420_grsecurity-3.1-4.2.3-201510111839.patch} | 534 +++++++++++++++++++--
 2 files changed, 500 insertions(+), 36 deletions(-)

diff --git a/4.2.3/0000_README b/4.2.3/0000_README
index 1d05b9f..f4ca83e 100644
--- a/4.2.3/0000_README
+++ b/4.2.3/0000_README
@@ -2,7 +2,7 @@ README
 -----------------------------------------------------------------------------
 Individual Patch Descriptions:
 -----------------------------------------------------------------------------
-Patch: 4420_grsecurity-3.1-4.2.3-201510092347.patch
+Patch: 4420_grsecurity-3.1-4.2.3-201510111839.patch
 From:  http://www.grsecurity.net
 Desc:  hardened-sources base patch from upstream grsecurity
 

diff --git a/4.2.3/4420_grsecurity-3.1-4.2.3-201510092347.patch 
b/4.2.3/4420_grsecurity-3.1-4.2.3-201510111839.patch
similarity index 99%
rename from 4.2.3/4420_grsecurity-3.1-4.2.3-201510092347.patch
rename to 4.2.3/4420_grsecurity-3.1-4.2.3-201510111839.patch
index 5075ca5..3eeb3c5 100644
--- a/4.2.3/4420_grsecurity-3.1-4.2.3-201510092347.patch
+++ b/4.2.3/4420_grsecurity-3.1-4.2.3-201510111839.patch
@@ -2834,6 +2834,29 @@ index 29e2991..7bc5757 100644
        mcr     p15, 0, r5, c3, c0, 0           @ load domain access register
        mcr     p15, 0, r4, c2, c0, 0           @ load page table pointer
  #endif
+diff --git a/arch/arm/kernel/module-plts.c b/arch/arm/kernel/module-plts.c
+index 097e2e2..3927085 100644
+--- a/arch/arm/kernel/module-plts.c
++++ b/arch/arm/kernel/module-plts.c
+@@ -30,17 +30,12 @@ struct plt_entries {
+       u32     lit[PLT_ENT_COUNT];
+ };
+ 
+-static bool in_init(const struct module *mod, u32 addr)
+-{
+-      return addr - (u32)mod->module_init < mod->init_size;
+-}
+-
+ u32 get_module_plt(struct module *mod, unsigned long loc, Elf32_Addr val)
+ {
+       struct plt_entries *plt, *plt_end;
+       int c, *count;
+ 
+-      if (in_init(mod, loc)) {
++      if (within_module_init(loc, mod)) {
+               plt = (void *)mod->arch.init_plt->sh_addr;
+               plt_end = (void *)plt + mod->arch.init_plt->sh_size;
+               count = &mod->arch.init_plt_count;
 diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
 index efdddcb..35e58f6 100644
 --- a/arch/arm/kernel/module.c
@@ -5045,6 +5068,20 @@ index 07e1ba44..ec8cbbb 100644
  #define access_ok(type, addr, size)   __range_ok(addr, size)
  #define user_addr_max                 get_fs
  
+diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
+index e8ca6ea..13671a9 100644
+--- a/arch/arm64/kernel/efi.c
++++ b/arch/arm64/kernel/efi.c
+@@ -258,7 +258,8 @@ static bool __init efi_virtmap_init(void)
+                */
+               if (!is_normal_ram(md))
+                       prot = __pgprot(PROT_DEVICE_nGnRE);
+-              else if (md->type == EFI_RUNTIME_SERVICES_CODE)
++              else if (md->type == EFI_RUNTIME_SERVICES_CODE ||
++                       !PAGE_ALIGNED(md->phys_addr))
+                       prot = PAGE_KERNEL_EXEC;
+               else
+                       prot = PAGE_KERNEL;
 diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c
 index d16a1ce..a5acc60 100644
 --- a/arch/arm64/mm/dma-mapping.c
@@ -7201,6 +7238,30 @@ index 5c81fdd..db158d3 100644
  int __virt_addr_valid(const volatile void *kaddr)
  {
        return pfn_valid(PFN_DOWN(virt_to_phys(kaddr)));
+diff --git a/arch/mips/net/bpf_jit_asm.S b/arch/mips/net/bpf_jit_asm.S
+index e927260..552e6ea 100644
+--- a/arch/mips/net/bpf_jit_asm.S
++++ b/arch/mips/net/bpf_jit_asm.S
+@@ -62,7 +62,9 @@ sk_load_word_positive:
+       is_offset_in_header(4, word)
+       /* Offset within header boundaries */
+       PTR_ADDU t1, $r_skb_data, offset
++      .set    reorder
+       lw      $r_A, 0(t1)
++      .set    noreorder
+ #ifdef CONFIG_CPU_LITTLE_ENDIAN
+       wsbh    t0, $r_A
+       rotr    $r_A, t0, 16
+@@ -78,7 +80,9 @@ sk_load_half_positive:
+       is_offset_in_header(2, half)
+       /* Offset within header boundaries */
+       PTR_ADDU t1, $r_skb_data, offset
++      .set    reorder
+       lh      $r_A, 0(t1)
++      .set    noreorder
+ #ifdef CONFIG_CPU_LITTLE_ENDIAN
+       wsbh    t0, $r_A
+       seh     $r_A, t0
 diff --git a/arch/mips/sgi-ip27/ip27-nmi.c b/arch/mips/sgi-ip27/ip27-nmi.c
 index a2358b4..7cead4f 100644
 --- a/arch/mips/sgi-ip27/ip27-nmi.c
@@ -24508,6 +24569,32 @@ index 83741a7..bd3507d 100644
  {
        .notifier_call = cpuid_class_cpu_callback,
  };
+diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
+index e068d66..74ca2fe 100644
+--- a/arch/x86/kernel/crash.c
++++ b/arch/x86/kernel/crash.c
+@@ -185,10 +185,9 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
+ }
+ 
+ #ifdef CONFIG_KEXEC_FILE
+-static int get_nr_ram_ranges_callback(unsigned long start_pfn,
+-                              unsigned long nr_pfn, void *arg)
++static int get_nr_ram_ranges_callback(u64 start, u64 end, void *arg)
+ {
+-      int *nr_ranges = arg;
++      unsigned int *nr_ranges = arg;
+ 
+       (*nr_ranges)++;
+       return 0;
+@@ -214,7 +213,7 @@ static void fill_up_crash_elf_data(struct crash_elf_data 
*ced,
+ 
+       ced->image = image;
+ 
+-      walk_system_ram_range(0, -1, &nr_ranges,
++      walk_system_ram_res(0, -1, &nr_ranges,
+                               get_nr_ram_ranges_callback);
+ 
+       ced->max_nr_ranges = nr_ranges;
 diff --git a/arch/x86/kernel/crash_dump_64.c b/arch/x86/kernel/crash_dump_64.c
 index afa64ad..dce67dd 100644
 --- a/arch/x86/kernel/crash_dump_64.c
@@ -34759,7 +34846,7 @@ index 9f0614d..92ae64a 100644
        p += get_opcode(p, &opcode);
        for (i = 0; i < ARRAY_SIZE(imm_wop); i++)
 diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c
-index fb0a9dd..6fc86ab 100644
+index fb0a9dd..8560f52 100644
 --- a/arch/x86/mm/pgtable.c
 +++ b/arch/x86/mm/pgtable.c
 @@ -98,10 +98,75 @@ static inline void pgd_list_del(pgd_t *pgd)
@@ -35047,7 +35134,7 @@ index fb0a9dd..6fc86ab 100644
        pgd_dtor(pgd);
        paravirt_pgd_free(mm, pgd);
        _pgd_free(pgd);
-@@ -544,6 +616,40 @@ void __init reserve_top_address(unsigned long reserve)
+@@ -544,6 +616,55 @@ void __init reserve_top_address(unsigned long reserve)
  
  int fixmaps_set;
  
@@ -35064,16 +35151,31 @@ index fb0a9dd..6fc86ab 100644
 +
 +#ifdef CONFIG_X86_VSYSCALL_EMULATION
 +      case VSYSCALL_PAGE:
++              break;
 +#endif
++
 +#ifdef CONFIG_PARAVIRT_CLOCK
 +      case PVCLOCK_FIXMAP_BEGIN ... PVCLOCK_FIXMAP_END:
-+#endif
 +              break;
++#endif
 +      }
 +
 +      pgd = pgd_offset_k(address);
-+      if (!(pgd_val(*pgd) & _PAGE_USER))
++      if (!(pgd_val(*pgd) & _PAGE_USER)) {
++#ifdef CONFIG_PAX_PER_CPU_PGD
++              unsigned int cpu;
++              pgd_t *pgd_cpu;
++
++              for_each_possible_cpu(cpu) {
++                      pgd_cpu = pgd_offset_cpu(cpu, kernel, address);
++                      set_pgd(pgd_cpu, __pgd(pgd_val(*pgd_cpu) | _PAGE_USER));
++
++                      pgd_cpu = pgd_offset_cpu(cpu, user, address);
++                      set_pgd(pgd_cpu, __pgd(pgd_val(*pgd_cpu) | _PAGE_USER));
++              }
++#endif
 +              set_pgd(pgd, __pgd(pgd_val(*pgd) | _PAGE_USER));
++      }
 +
 +      pud = pud_offset(pgd, address);
 +      if (!(pud_val(*pud) & _PAGE_USER))
@@ -35088,7 +35190,7 @@ index fb0a9dd..6fc86ab 100644
  void __native_set_fixmap(enum fixed_addresses idx, pte_t pte)
  {
        unsigned long address = __fix_to_virt(idx);
-@@ -554,6 +660,7 @@ void __native_set_fixmap(enum fixed_addresses idx, pte_t 
pte)
+@@ -554,6 +675,7 @@ void __native_set_fixmap(enum fixed_addresses idx, pte_t 
pte)
        }
        set_pte_vaddr(address, pte);
        fixmaps_set++;
@@ -35801,6 +35903,91 @@ index 9b83b90..2c256c5 100644
        return !(ret & 0xff00);
  }
  EXPORT_SYMBOL(pcibios_set_irq_routing);
+diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
+index e4308fe..c6835bf 100644
+--- a/arch/x86/platform/efi/efi.c
++++ b/arch/x86/platform/efi/efi.c
+@@ -705,6 +705,70 @@ out:
+ }
+ 
+ /*
++ * Iterate the EFI memory map in reverse order because the regions
++ * will be mapped top-down. The end result is the same as if we had
++ * mapped things forward, but doesn't require us to change the
++ * existing implementation of efi_map_region().
++ */
++static inline void *efi_map_next_entry_reverse(void *entry)
++{
++      /* Initial call */
++      if (!entry)
++              return memmap.map_end - memmap.desc_size;
++
++      entry -= memmap.desc_size;
++      if (entry < memmap.map)
++              return NULL;
++
++      return entry;
++}
++
++/*
++ * efi_map_next_entry - Return the next EFI memory map descriptor
++ * @entry: Previous EFI memory map descriptor
++ *
++ * This is a helper function to iterate over the EFI memory map, which
++ * we do in different orders depending on the current configuration.
++ *
++ * To begin traversing the memory map @entry must be %NULL.
++ *
++ * Returns %NULL when we reach the end of the memory map.
++ */
++static void *efi_map_next_entry(void *entry)
++{
++      if (!efi_enabled(EFI_OLD_MEMMAP) && efi_enabled(EFI_64BIT)) {
++              /*
++               * Starting in UEFI v2.5 the EFI_PROPERTIES_TABLE
++               * config table feature requires us to map all entries
++               * in the same order as they appear in the EFI memory
++               * map. That is to say, entry N must have a lower
++               * virtual address than entry N+1. This is because the
++               * firmware toolchain leaves relative references in
++               * the code/data sections, which are split and become
++               * separate EFI memory regions. Mapping things
++               * out-of-order leads to the firmware accessing
++               * unmapped addresses.
++               *
++               * Since we need to map things this way whether or not
++               * the kernel actually makes use of
++               * EFI_PROPERTIES_TABLE, let's just switch to this
++               * scheme by default for 64-bit.
++               */
++              return efi_map_next_entry_reverse(entry);
++      }
++
++      /* Initial call */
++      if (!entry)
++              return memmap.map;
++
++      entry += memmap.desc_size;
++      if (entry >= memmap.map_end)
++              return NULL;
++
++      return entry;
++}
++
++/*
+  * Map the efi memory ranges of the runtime services and update new_mmap with
+  * virtual addresses.
+  */
+@@ -714,7 +778,8 @@ static void * __init efi_map_regions(int *count, int 
*pg_shift)
+       unsigned long left = 0;
+       efi_memory_desc_t *md;
+ 
+-      for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
++      p = NULL;
++      while ((p = efi_map_next_entry(p))) {
+               md = p;
+               if (!(md->attribute & EFI_MEMORY_RUNTIME)) {
+ #ifdef CONFIG_X86_64
 diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c
 index ed5b673..24d2d53 100644
 --- a/arch/x86/platform/efi/efi_32.c
@@ -41269,6 +41456,130 @@ index 756eca8..2336d08 100644
        int error;
  
        /* new_var */
+diff --git a/drivers/firmware/efi/libstub/arm-stub.c 
b/drivers/firmware/efi/libstub/arm-stub.c
+index e29560e..950c87f 100644
+--- a/drivers/firmware/efi/libstub/arm-stub.c
++++ b/drivers/firmware/efi/libstub/arm-stub.c
+@@ -13,6 +13,7 @@
+  */
+ 
+ #include <linux/efi.h>
++#include <linux/sort.h>
+ #include <asm/efi.h>
+ 
+ #include "efistub.h"
+@@ -305,6 +306,44 @@ fail:
+  */
+ #define EFI_RT_VIRTUAL_BASE   0x40000000
+ 
++static int cmp_mem_desc(const void *l, const void *r)
++{
++      const efi_memory_desc_t *left = l, *right = r;
++
++      return (left->phys_addr > right->phys_addr) ? 1 : -1;
++}
++
++/*
++ * Returns whether region @left ends exactly where region @right starts,
++ * or false if either argument is NULL.
++ */
++static bool regions_are_adjacent(efi_memory_desc_t *left,
++                               efi_memory_desc_t *right)
++{
++      u64 left_end;
++
++      if (left == NULL || right == NULL)
++              return false;
++
++      left_end = left->phys_addr + left->num_pages * EFI_PAGE_SIZE;
++
++      return left_end == right->phys_addr;
++}
++
++/*
++ * Returns whether region @left and region @right have compatible memory type
++ * mapping attributes, and are both EFI_MEMORY_RUNTIME regions.
++ */
++static bool regions_have_compatible_memory_type_attrs(efi_memory_desc_t *left,
++                                                    efi_memory_desc_t *right)
++{
++      static const u64 mem_type_mask = EFI_MEMORY_WB | EFI_MEMORY_WT |
++                                       EFI_MEMORY_WC | EFI_MEMORY_UC |
++                                       EFI_MEMORY_RUNTIME;
++
++      return ((left->attribute ^ right->attribute) & mem_type_mask) == 0;
++}
++
+ /*
+  * efi_get_virtmap() - create a virtual mapping for the EFI memory map
+  *
+@@ -317,33 +356,52 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, 
unsigned long map_size,
+                    int *count)
+ {
+       u64 efi_virt_base = EFI_RT_VIRTUAL_BASE;
+-      efi_memory_desc_t *out = runtime_map;
++      efi_memory_desc_t *in, *prev = NULL, *out = runtime_map;
+       int l;
+ 
+-      for (l = 0; l < map_size; l += desc_size) {
+-              efi_memory_desc_t *in = (void *)memory_map + l;
++      /*
++       * To work around potential issues with the Properties Table feature
++       * introduced in UEFI 2.5, which may split PE/COFF executable images
++       * in memory into several RuntimeServicesCode and RuntimeServicesData
++       * regions, we need to preserve the relative offsets between adjacent
++       * EFI_MEMORY_RUNTIME regions with the same memory type attributes.
++       * The easiest way to find adjacent regions is to sort the memory map
++       * before traversing it.
++       */
++      sort(memory_map, map_size / desc_size, desc_size, cmp_mem_desc, NULL);
++
++      for (l = 0; l < map_size; l += desc_size, prev = in) {
+               u64 paddr, size;
+ 
++              in = (void *)memory_map + l;
+               if (!(in->attribute & EFI_MEMORY_RUNTIME))
+                       continue;
+ 
++              paddr = in->phys_addr;
++              size = in->num_pages * EFI_PAGE_SIZE;
++
+               /*
+                * Make the mapping compatible with 64k pages: this allows
+                * a 4k page size kernel to kexec a 64k page size kernel and
+                * vice versa.
+                */
+-              paddr = round_down(in->phys_addr, SZ_64K);
+-              size = round_up(in->num_pages * EFI_PAGE_SIZE +
+-                              in->phys_addr - paddr, SZ_64K);
++              if (!regions_are_adjacent(prev, in) ||
++                  !regions_have_compatible_memory_type_attrs(prev, in)) {
+ 
+-              /*
+-               * Avoid wasting memory on PTEs by choosing a virtual base that
+-               * is compatible with section mappings if this region has the
+-               * appropriate size and physical alignment. (Sections are 2 MB
+-               * on 4k granule kernels)
+-               */
+-              if (IS_ALIGNED(in->phys_addr, SZ_2M) && size >= SZ_2M)
+-                      efi_virt_base = round_up(efi_virt_base, SZ_2M);
++                      paddr = round_down(in->phys_addr, SZ_64K);
++                      size += in->phys_addr - paddr;
++
++                      /*
++                       * Avoid wasting memory on PTEs by choosing a virtual
++                       * base that is compatible with section mappings if this
++                       * region has the appropriate size and physical
++                       * alignment. (Sections are 2 MB on 4k granule kernels)
++                       */
++                      if (IS_ALIGNED(in->phys_addr, SZ_2M) && size >= SZ_2M)
++                              efi_virt_base = round_up(efi_virt_base, SZ_2M);
++                      else
++                              efi_virt_base = round_up(efi_virt_base, SZ_64K);
++              }
+ 
+               in->virt_addr = efi_virt_base + in->phys_addr - paddr;
+               efi_virt_base += size;
 diff --git a/drivers/firmware/efi/runtime-map.c 
b/drivers/firmware/efi/runtime-map.c
 index 5c55227..97f4978 100644
 --- a/drivers/firmware/efi/runtime-map.c
@@ -79778,7 +80089,7 @@ index 14db05d..687f6d8 100644
  #define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
  
 diff --git a/fs/namei.c b/fs/namei.c
-index 1c2105e..79d9ccb 100644
+index 1c2105e..e54c8ab 100644
 --- a/fs/namei.c
 +++ b/fs/namei.c
 @@ -336,17 +336,32 @@ int generic_permission(struct inode *inode, int mask)
@@ -79945,7 +80256,29 @@ index 1c2105e..79d9ccb 100644
        nd->last_type = LAST_BIND;
        res = inode->i_link;
        if (!res) {
-@@ -1665,6 +1737,23 @@ static int pick_link(struct nameidata *nd, struct path 
*link,
+@@ -1535,8 +1607,6 @@ static int lookup_fast(struct nameidata *nd,
+               negative = d_is_negative(dentry);
+               if (read_seqcount_retry(&dentry->d_seq, seq))
+                       return -ECHILD;
+-              if (negative)
+-                      return -ENOENT;
+ 
+               /*
+                * This sequence count validates that the parent had no
+@@ -1557,6 +1627,12 @@ static int lookup_fast(struct nameidata *nd,
+                               goto unlazy;
+                       }
+               }
++              /*
++               * Note: do negative dentry check after revalidation in
++               * case that drops it.
++               */
++              if (negative)
++                      return -ENOENT;
+               path->mnt = mnt;
+               path->dentry = dentry;
+               if (likely(__follow_mount_rcu(nd, path, inode, seqp)))
+@@ -1665,6 +1741,23 @@ static int pick_link(struct nameidata *nd, struct path 
*link,
                }
        }
  
@@ -79969,7 +80302,7 @@ index 1c2105e..79d9ccb 100644
        last = nd->stack + nd->depth++;
        last->link = *link;
        last->cookie = NULL;
-@@ -1804,7 +1893,7 @@ EXPORT_SYMBOL(full_name_hash);
+@@ -1804,7 +1897,7 @@ EXPORT_SYMBOL(full_name_hash);
  static inline u64 hash_name(const char *name)
  {
        unsigned long a, b, adata, bdata, mask, hash, len;
@@ -79978,7 +80311,7 @@ index 1c2105e..79d9ccb 100644
  
        hash = a = 0;
        len = -sizeof(unsigned long);
-@@ -1973,6 +2062,9 @@ static const char *path_init(struct nameidata *nd, 
unsigned flags)
+@@ -1973,6 +2066,9 @@ static const char *path_init(struct nameidata *nd, 
unsigned flags)
        nd->flags = flags | LOOKUP_JUMPED | LOOKUP_PARENT;
        nd->depth = 0;
        nd->total_link_count = 0;
@@ -79988,7 +80321,7 @@ index 1c2105e..79d9ccb 100644
        if (flags & LOOKUP_ROOT) {
                struct dentry *root = nd->root.dentry;
                struct inode *inode = root->d_inode;
-@@ -2110,6 +2202,11 @@ static int path_lookupat(struct nameidata *nd, unsigned 
flags, struct path *path
+@@ -2110,6 +2206,11 @@ static int path_lookupat(struct nameidata *nd, unsigned 
flags, struct path *path
        if (!err)
                err = complete_walk(nd);
  
@@ -80000,7 +80333,7 @@ index 1c2105e..79d9ccb 100644
        if (!err && nd->flags & LOOKUP_DIRECTORY)
                if (!d_can_lookup(nd->path.dentry))
                        err = -ENOTDIR;
-@@ -2158,6 +2255,10 @@ static int path_parentat(struct nameidata *nd, unsigned 
flags,
+@@ -2158,6 +2259,10 @@ static int path_parentat(struct nameidata *nd, unsigned 
flags,
        err = link_path_walk(s, nd);
        if (!err)
                err = complete_walk(nd);
@@ -80011,7 +80344,7 @@ index 1c2105e..79d9ccb 100644
        if (!err) {
                *parent = nd->path;
                nd->path.mnt = NULL;
-@@ -2689,6 +2790,13 @@ static int may_open(struct path *path, int acc_mode, 
int flag)
+@@ -2689,6 +2794,13 @@ static int may_open(struct path *path, int acc_mode, 
int flag)
        if (flag & O_NOATIME && !inode_owner_or_capable(inode))
                return -EPERM;
  
@@ -80025,7 +80358,7 @@ index 1c2105e..79d9ccb 100644
        return 0;
  }
  
-@@ -2955,6 +3063,18 @@ static int lookup_open(struct nameidata *nd, struct 
path *path,
+@@ -2955,6 +3067,18 @@ static int lookup_open(struct nameidata *nd, struct 
path *path,
        /* Negative dentry, just create the file */
        if (!dentry->d_inode && (op->open_flag & O_CREAT)) {
                umode_t mode = op->mode;
@@ -80044,7 +80377,7 @@ index 1c2105e..79d9ccb 100644
                if (!IS_POSIXACL(dir->d_inode))
                        mode &= ~current_umask();
                /*
-@@ -2976,6 +3096,8 @@ static int lookup_open(struct nameidata *nd, struct path 
*path,
+@@ -2976,6 +3100,8 @@ static int lookup_open(struct nameidata *nd, struct path 
*path,
                                   nd->flags & LOOKUP_EXCL);
                if (error)
                        goto out_dput;
@@ -80053,7 +80386,7 @@ index 1c2105e..79d9ccb 100644
        }
  out_no_open:
        path->dentry = dentry;
-@@ -3039,6 +3161,9 @@ static int do_last(struct nameidata *nd,
+@@ -3039,6 +3165,9 @@ static int do_last(struct nameidata *nd,
                if (error)
                        return error;
  
@@ -80063,7 +80396,7 @@ index 1c2105e..79d9ccb 100644
                audit_inode(nd->name, dir, LOOKUP_PARENT);
                /* trailing slashes? */
                if (unlikely(nd->last.name[nd->last.len]))
-@@ -3081,11 +3206,24 @@ retry_lookup:
+@@ -3081,11 +3210,24 @@ retry_lookup:
                goto finish_open_created;
        }
  
@@ -80089,7 +80422,7 @@ index 1c2105e..79d9ccb 100644
  
        /*
         * If atomic_open() acquired write access it is dropped now due to
-@@ -3121,6 +3259,11 @@ finish_lookup:
+@@ -3121,6 +3263,11 @@ finish_lookup:
        if (unlikely(error))
                return error;
  
@@ -80101,7 +80434,7 @@ index 1c2105e..79d9ccb 100644
        if (unlikely(d_is_symlink(path.dentry)) && !(open_flag & O_PATH)) {
                path_to_nameidata(&path, nd);
                return -ELOOP;
-@@ -3143,6 +3286,12 @@ finish_open:
+@@ -3143,6 +3290,12 @@ finish_open:
                path_put(&save_parent);
                return error;
        }
@@ -80114,7 +80447,7 @@ index 1c2105e..79d9ccb 100644
        audit_inode(nd->name, nd->path.dentry, 0);
        error = -EISDIR;
        if ((open_flag & O_CREAT) && d_is_dir(nd->path.dentry))
-@@ -3409,9 +3558,11 @@ static struct dentry *filename_create(int dfd, struct 
filename *name,
+@@ -3409,9 +3562,11 @@ static struct dentry *filename_create(int dfd, struct 
filename *name,
                goto unlock;
  
        error = -EEXIST;
@@ -80128,7 +80461,7 @@ index 1c2105e..79d9ccb 100644
        /*
         * Special case - lookup gave negative, but... we had foo/bar/
         * From the vfs_mknod() POV we just have a negative dentry -
-@@ -3465,6 +3616,20 @@ inline struct dentry *user_path_create(int dfd, const 
char __user *pathname,
+@@ -3465,6 +3620,20 @@ inline struct dentry *user_path_create(int dfd, const 
char __user *pathname,
  }
  EXPORT_SYMBOL(user_path_create);
  
@@ -80149,7 +80482,7 @@ index 1c2105e..79d9ccb 100644
  int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t 
dev)
  {
        int error = may_create(dir, dentry);
-@@ -3528,6 +3693,17 @@ retry:
+@@ -3528,6 +3697,17 @@ retry:
  
        if (!IS_POSIXACL(path.dentry->d_inode))
                mode &= ~current_umask();
@@ -80167,7 +80500,7 @@ index 1c2105e..79d9ccb 100644
        error = security_path_mknod(&path, dentry, mode, dev);
        if (error)
                goto out;
-@@ -3543,6 +3719,8 @@ retry:
+@@ -3543,6 +3723,8 @@ retry:
                        error = vfs_mknod(path.dentry->d_inode,dentry,mode,0);
                        break;
        }
@@ -80176,7 +80509,7 @@ index 1c2105e..79d9ccb 100644
  out:
        done_path_create(&path, dentry);
        if (retry_estale(error, lookup_flags)) {
-@@ -3597,9 +3775,16 @@ retry:
+@@ -3597,9 +3779,16 @@ retry:
  
        if (!IS_POSIXACL(path.dentry->d_inode))
                mode &= ~current_umask();
@@ -80193,7 +80526,7 @@ index 1c2105e..79d9ccb 100644
        done_path_create(&path, dentry);
        if (retry_estale(error, lookup_flags)) {
                lookup_flags |= LOOKUP_REVAL;
-@@ -3632,7 +3817,7 @@ void dentry_unhash(struct dentry *dentry)
+@@ -3632,7 +3821,7 @@ void dentry_unhash(struct dentry *dentry)
  {
        shrink_dcache_parent(dentry);
        spin_lock(&dentry->d_lock);
@@ -80202,7 +80535,7 @@ index 1c2105e..79d9ccb 100644
                __d_drop(dentry);
        spin_unlock(&dentry->d_lock);
  }
-@@ -3685,6 +3870,8 @@ static long do_rmdir(int dfd, const char __user 
*pathname)
+@@ -3685,6 +3874,8 @@ static long do_rmdir(int dfd, const char __user 
*pathname)
        struct path path;
        struct qstr last;
        int type;
@@ -80211,7 +80544,7 @@ index 1c2105e..79d9ccb 100644
        unsigned int lookup_flags = 0;
  retry:
        name = user_path_parent(dfd, pathname,
-@@ -3717,10 +3904,20 @@ retry:
+@@ -3717,10 +3908,20 @@ retry:
                error = -ENOENT;
                goto exit3;
        }
@@ -80232,7 +80565,7 @@ index 1c2105e..79d9ccb 100644
  exit3:
        dput(dentry);
  exit2:
-@@ -3815,6 +4012,8 @@ static long do_unlinkat(int dfd, const char __user 
*pathname)
+@@ -3815,6 +4016,8 @@ static long do_unlinkat(int dfd, const char __user 
*pathname)
        int type;
        struct inode *inode = NULL;
        struct inode *delegated_inode = NULL;
@@ -80241,7 +80574,7 @@ index 1c2105e..79d9ccb 100644
        unsigned int lookup_flags = 0;
  retry:
        name = user_path_parent(dfd, pathname,
-@@ -3841,10 +4040,21 @@ retry_deleg:
+@@ -3841,10 +4044,21 @@ retry_deleg:
                if (d_is_negative(dentry))
                        goto slashes;
                ihold(inode);
@@ -80263,7 +80596,7 @@ index 1c2105e..79d9ccb 100644
  exit2:
                dput(dentry);
        }
-@@ -3933,9 +4143,17 @@ retry:
+@@ -3933,9 +4147,17 @@ retry:
        if (IS_ERR(dentry))
                goto out_putname;
  
@@ -80281,7 +80614,7 @@ index 1c2105e..79d9ccb 100644
        done_path_create(&path, dentry);
        if (retry_estale(error, lookup_flags)) {
                lookup_flags |= LOOKUP_REVAL;
-@@ -4039,6 +4257,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user 
*, oldname,
+@@ -4039,6 +4261,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user 
*, oldname,
        struct dentry *new_dentry;
        struct path old_path, new_path;
        struct inode *delegated_inode = NULL;
@@ -80289,7 +80622,7 @@ index 1c2105e..79d9ccb 100644
        int how = 0;
        int error;
  
-@@ -4062,7 +4281,7 @@ retry:
+@@ -4062,7 +4285,7 @@ retry:
        if (error)
                return error;
  
@@ -80298,7 +80631,7 @@ index 1c2105e..79d9ccb 100644
                                        (how & LOOKUP_REVAL));
        error = PTR_ERR(new_dentry);
        if (IS_ERR(new_dentry))
-@@ -4074,11 +4293,26 @@ retry:
+@@ -4074,11 +4297,26 @@ retry:
        error = may_linkat(&old_path);
        if (unlikely(error))
                goto out_dput;
@@ -80325,7 +80658,7 @@ index 1c2105e..79d9ccb 100644
        done_path_create(&new_path, new_dentry);
        if (delegated_inode) {
                error = break_deleg_wait(&delegated_inode);
-@@ -4393,6 +4627,20 @@ retry_deleg:
+@@ -4393,6 +4631,20 @@ retry_deleg:
        if (new_dentry == trap)
                goto exit5;
  
@@ -80346,7 +80679,7 @@ index 1c2105e..79d9ccb 100644
        error = security_path_rename(&old_path, old_dentry,
                                     &new_path, new_dentry, flags);
        if (error)
-@@ -4400,6 +4648,9 @@ retry_deleg:
+@@ -4400,6 +4652,9 @@ retry_deleg:
        error = vfs_rename(old_path.dentry->d_inode, old_dentry,
                           new_path.dentry->d_inode, new_dentry,
                           &delegated_inode, flags);
@@ -80356,7 +80689,7 @@ index 1c2105e..79d9ccb 100644
  exit5:
        dput(new_dentry);
  exit4:
-@@ -4456,14 +4707,24 @@ EXPORT_SYMBOL(vfs_whiteout);
+@@ -4456,14 +4711,24 @@ EXPORT_SYMBOL(vfs_whiteout);
  
  int readlink_copy(char __user *buffer, int buflen, const char *link)
  {
@@ -121671,6 +122004,137 @@ index 338b404..839dcb0 100644
        .pf             = PF_INET,
        .get_optmin     = SO_IP_SET,
        .get_optmax     = SO_IP_SET + 1,
+diff --git a/net/netfilter/ipset/ip_set_hash_netnet.c 
b/net/netfilter/ipset/ip_set_hash_netnet.c
+index 3c862c0..a93dfeb 100644
+--- a/net/netfilter/ipset/ip_set_hash_netnet.c
++++ b/net/netfilter/ipset/ip_set_hash_netnet.c
+@@ -131,6 +131,13 @@ hash_netnet4_data_next(struct hash_netnet4_elem *next,
+ #define HOST_MASK     32
+ #include "ip_set_hash_gen.h"
+ 
++static void
++hash_netnet4_init(struct hash_netnet4_elem *e)
++{
++      e->cidr[0] = HOST_MASK;
++      e->cidr[1] = HOST_MASK;
++}
++
+ static int
+ hash_netnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
+                 const struct xt_action_param *par,
+@@ -160,7 +167,7 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+ {
+       const struct hash_netnet *h = set->data;
+       ipset_adtfn adtfn = set->variant->adt[adt];
+-      struct hash_netnet4_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, };
++      struct hash_netnet4_elem e = { };
+       struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+       u32 ip = 0, ip_to = 0, last;
+       u32 ip2 = 0, ip2_from = 0, ip2_to = 0, last2;
+@@ -169,6 +176,7 @@ hash_netnet4_uadt(struct ip_set *set, struct nlattr *tb[],
+       if (tb[IPSET_ATTR_LINENO])
+               *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
+ 
++      hash_netnet4_init(&e);
+       if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
+               return -IPSET_ERR_PROTOCOL;
+@@ -357,6 +365,13 @@ hash_netnet6_data_next(struct hash_netnet4_elem *next,
+ #define IP_SET_EMIT_CREATE
+ #include "ip_set_hash_gen.h"
+ 
++static void
++hash_netnet6_init(struct hash_netnet6_elem *e)
++{
++      e->cidr[0] = HOST_MASK;
++      e->cidr[1] = HOST_MASK;
++}
++
+ static int
+ hash_netnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
+                 const struct xt_action_param *par,
+@@ -385,13 +400,14 @@ hash_netnet6_uadt(struct ip_set *set, struct nlattr 
*tb[],
+                 enum ipset_adt adt, u32 *lineno, u32 flags, bool retried)
+ {
+       ipset_adtfn adtfn = set->variant->adt[adt];
+-      struct hash_netnet6_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, };
++      struct hash_netnet6_elem e = { };
+       struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+       int ret;
+ 
+       if (tb[IPSET_ATTR_LINENO])
+               *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
+ 
++      hash_netnet6_init(&e);
+       if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_CADT_FLAGS)))
+               return -IPSET_ERR_PROTOCOL;
+diff --git a/net/netfilter/ipset/ip_set_hash_netportnet.c 
b/net/netfilter/ipset/ip_set_hash_netportnet.c
+index 0c68734..9a14c23 100644
+--- a/net/netfilter/ipset/ip_set_hash_netportnet.c
++++ b/net/netfilter/ipset/ip_set_hash_netportnet.c
+@@ -142,6 +142,13 @@ hash_netportnet4_data_next(struct hash_netportnet4_elem 
*next,
+ #define HOST_MASK     32
+ #include "ip_set_hash_gen.h"
+ 
++static void
++hash_netportnet4_init(struct hash_netportnet4_elem *e)
++{
++      e->cidr[0] = HOST_MASK;
++      e->cidr[1] = HOST_MASK;
++}
++
+ static int
+ hash_netportnet4_kadt(struct ip_set *set, const struct sk_buff *skb,
+                     const struct xt_action_param *par,
+@@ -175,7 +182,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr 
*tb[],
+ {
+       const struct hash_netportnet *h = set->data;
+       ipset_adtfn adtfn = set->variant->adt[adt];
+-      struct hash_netportnet4_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, };
++      struct hash_netportnet4_elem e = { };
+       struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+       u32 ip = 0, ip_to = 0, ip_last, p = 0, port, port_to;
+       u32 ip2_from = 0, ip2_to = 0, ip2_last, ip2;
+@@ -185,6 +192,7 @@ hash_netportnet4_uadt(struct ip_set *set, struct nlattr 
*tb[],
+       if (tb[IPSET_ATTR_LINENO])
+               *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
+ 
++      hash_netportnet4_init(&e);
+       if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
+                    !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
+@@ -412,6 +420,13 @@ hash_netportnet6_data_next(struct hash_netportnet4_elem 
*next,
+ #define IP_SET_EMIT_CREATE
+ #include "ip_set_hash_gen.h"
+ 
++static void
++hash_netportnet6_init(struct hash_netportnet6_elem *e)
++{
++      e->cidr[0] = HOST_MASK;
++      e->cidr[1] = HOST_MASK;
++}
++
+ static int
+ hash_netportnet6_kadt(struct ip_set *set, const struct sk_buff *skb,
+                     const struct xt_action_param *par,
+@@ -445,7 +460,7 @@ hash_netportnet6_uadt(struct ip_set *set, struct nlattr 
*tb[],
+ {
+       const struct hash_netportnet *h = set->data;
+       ipset_adtfn adtfn = set->variant->adt[adt];
+-      struct hash_netportnet6_elem e = { .cidr = { HOST_MASK, HOST_MASK, }, };
++      struct hash_netportnet6_elem e = { };
+       struct ip_set_ext ext = IP_SET_INIT_UEXT(set);
+       u32 port, port_to;
+       bool with_ports = false;
+@@ -454,6 +469,7 @@ hash_netportnet6_uadt(struct ip_set *set, struct nlattr 
*tb[],
+       if (tb[IPSET_ATTR_LINENO])
+               *lineno = nla_get_u32(tb[IPSET_ATTR_LINENO]);
+ 
++      hash_netportnet6_init(&e);
+       if (unlikely(!tb[IPSET_ATTR_IP] || !tb[IPSET_ATTR_IP2] ||
+                    !ip_set_attr_netorder(tb, IPSET_ATTR_PORT) ||
+                    !ip_set_optattr_netorder(tb, IPSET_ATTR_PORT_TO) ||
 diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
 index b0f7b62..0541842 100644
 --- a/net/netfilter/ipvs/ip_vs_conn.c

Reply via email to