diff options
-rw-r--r-- | 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201303012253.patch (renamed from 2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201302271816.patch) | 196 | ||||
-rw-r--r-- | 3.2.39/0000_README | 2 | ||||
-rw-r--r-- | 3.2.39/4420_grsecurity-2.9.1-3.2.39-201303012254.patch (renamed from 3.2.39/4420_grsecurity-2.9.1-3.2.39-201302271819.patch) | 301 | ||||
-rw-r--r-- | 3.8.1/0000_README (renamed from 3.8.0/0000_README) | 2 | ||||
-rw-r--r-- | 3.8.1/4420_grsecurity-2.9.1-3.8.1-201303012255.patch (renamed from 3.8.0/4420_grsecurity-2.9.1-3.8.0-201302271810.patch) | 672 | ||||
-rw-r--r-- | 3.8.1/4425_grsec_remove_EI_PAX.patch (renamed from 3.8.0/4425_grsec_remove_EI_PAX.patch) | 0 | ||||
-rw-r--r-- | 3.8.1/4430_grsec-remove-localversion-grsec.patch (renamed from 3.8.0/4430_grsec-remove-localversion-grsec.patch) | 0 | ||||
-rw-r--r-- | 3.8.1/4435_grsec-mute-warnings.patch (renamed from 3.8.0/4435_grsec-mute-warnings.patch) | 0 | ||||
-rw-r--r-- | 3.8.1/4440_grsec-remove-protected-paths.patch (renamed from 3.8.0/4440_grsec-remove-protected-paths.patch) | 0 | ||||
-rw-r--r-- | 3.8.1/4450_grsec-kconfig-default-gids.patch (renamed from 3.8.0/4450_grsec-kconfig-default-gids.patch) | 0 | ||||
-rw-r--r-- | 3.8.1/4465_selinux-avc_audit-log-curr_ip.patch (renamed from 3.8.0/4465_selinux-avc_audit-log-curr_ip.patch) | 0 | ||||
-rw-r--r-- | 3.8.1/4470_disable-compat_vdso.patch (renamed from 3.8.0/4470_disable-compat_vdso.patch) | 0 |
12 files changed, 701 insertions, 472 deletions
diff --git a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201302271816.patch b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201303012253.patch index ee04841..ee59351 100644 --- a/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201302271816.patch +++ b/2.6.32/4420_grsecurity-2.9.1-2.6.32.60-201303012253.patch @@ -19276,6 +19276,91 @@ index 9dbb527..9fe4f21 100644 if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE)) return -EFAULT; +diff --git a/arch/x86/kernel/head.c b/arch/x86/kernel/head.c +index 3e66bd3..6d6adbe 100644 +--- a/arch/x86/kernel/head.c ++++ b/arch/x86/kernel/head.c +@@ -4,8 +4,6 @@ + #include <asm/setup.h> + #include <asm/bios_ebda.h> + +-#define BIOS_LOWMEM_KILOBYTES 0x413 +- + /* + * The BIOS places the EBDA/XBDA at the top of conventional + * memory, and usually decreases the reported amount of +@@ -15,17 +13,30 @@ + * chipset: reserve a page before VGA to prevent PCI prefetch + * into it (errata #56). Usually the page is reserved anyways, + * unless you have no PS/2 mouse plugged in. ++ * ++ * This functions is deliberately very conservative. Losing ++ * memory in the bottom megabyte is rarely a problem, as long ++ * as we have enough memory to install the trampoline. Using ++ * memory that is in use by the BIOS or by some DMA device ++ * the BIOS didn't shut down *is* a big problem. + */ ++ ++#define BIOS_LOWMEM_KILOBYTES 0x413 ++#define LOWMEM_CAP 0x9f000U /* Absolute maximum */ ++#define INSANE_CUTOFF 0x20000U /* Less than this = insane */ ++ + void __init reserve_ebda_region(void) + { + unsigned int lowmem, ebda_addr; + +- /* To determine the position of the EBDA and the */ +- /* end of conventional memory, we need to look at */ +- /* the BIOS data area. In a paravirtual environment */ +- /* that area is absent. We'll just have to assume */ +- /* that the paravirt case can handle memory setup */ +- /* correctly, without our help. */ ++ /* ++ * To determine the position of the EBDA and the ++ * end of conventional memory, we need to look at ++ * the BIOS data area. In a paravirtual environment ++ * that area is absent. We'll just have to assume ++ * that the paravirt case can handle memory setup ++ * correctly, without our help. ++ */ + if (paravirt_enabled()) + return; + +@@ -36,19 +47,23 @@ void __init reserve_ebda_region(void) + /* start of EBDA area */ + ebda_addr = get_bios_ebda(); + +- /* Fixup: bios puts an EBDA in the top 64K segment */ +- /* of conventional memory, but does not adjust lowmem. */ +- if ((lowmem - ebda_addr) <= 0x10000) +- lowmem = ebda_addr; ++ /* ++ * Note: some old Dells seem to need 4k EBDA without ++ * reporting so, so just consider the memory above 0x9f000 ++ * to be off limits (bugzilla 2990). ++ */ + +- /* Fixup: bios does not report an EBDA at all. */ +- /* Some old Dells seem to need 4k anyhow (bugzilla 2990) */ +- if ((ebda_addr == 0) && (lowmem >= 0x9f000)) +- lowmem = 0x9f000; ++ /* If the EBDA address is below 128K, assume it is bogus */ ++ if (ebda_addr < INSANE_CUTOFF) ++ ebda_addr = LOWMEM_CAP; + +- /* Paranoia: should never happen, but... */ +- if ((lowmem == 0) || (lowmem >= 0x100000)) +- lowmem = 0x9f000; ++ /* If lowmem is less than 128K, assume it is bogus */ ++ if (lowmem < INSANE_CUTOFF) ++ lowmem = LOWMEM_CAP; ++ ++ /* Use the lower of the lowmem and EBDA markers as the cutoff */ ++ lowmem = min(lowmem, ebda_addr); ++ lowmem = min(lowmem, LOWMEM_CAP); /* Absolute cap */ + + /* reserve all memory between lowmem and the 1MB mark */ + reserve_early_overlap_ok(lowmem, 0x100000, "BIOS reserved"); diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index 4f8e250..df24706 100644 --- a/arch/x86/kernel/head32.c @@ -100702,10 +100787,18 @@ index 0000000..3891139 + +#endif /* _LINUX_SYSLOG_H */ diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h -index 99adcdc..09207eb 100644 +index 99adcdc..377249a 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h -@@ -35,7 +35,7 @@ struct sysrq_key_op { +@@ -15,6 +15,7 @@ + #define _LINUX_SYSRQ_H + + #include <linux/errno.h> ++#include <linux/compiler.h> + + struct pt_regs; + struct tty_struct; +@@ -35,7 +36,7 @@ struct sysrq_key_op { char *help_msg; char *action_msg; int enable_mask; @@ -110252,7 +110345,7 @@ index 2d846cf..8d5cdd8 100644 capable(CAP_IPC_LOCK)) ret = do_mlockall(flags); diff --git a/mm/mmap.c b/mm/mmap.c -index 4b80cbf..1415bd8 100644 +index 4b80cbf..89f7b42 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -29,6 +29,7 @@ @@ -111136,7 +111229,7 @@ index 4b80cbf..1415bd8 100644 size = vma->vm_end - address; grow = (vma->vm_start - address) >> PAGE_SHIFT; -@@ -1689,10 +1982,22 @@ static int expand_downwards(struct vm_area_struct *vma, +@@ -1689,21 +1982,60 @@ static int expand_downwards(struct vm_area_struct *vma, if (!error) { vma->vm_start = address; vma->vm_pgoff -= grow; @@ -111159,7 +111252,60 @@ index 4b80cbf..1415bd8 100644 return error; } -@@ -1768,6 +2073,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) + int expand_stack_downwards(struct vm_area_struct *vma, unsigned long address) + { ++ struct vm_area_struct *prev; ++ ++ address &= PAGE_MASK; ++ prev = vma->vm_prev; ++ if (prev && prev->vm_end == address) { ++ if (!(prev->vm_flags & VM_GROWSDOWN)) ++ return -ENOMEM; ++ } + return expand_downwards(vma, address); + } + ++/* ++ * Note how expand_stack() refuses to expand the stack all the way to ++ * abut the next virtual mapping, *unless* that mapping itself is also ++ * a stack mapping. We want to leave room for a guard page, after all ++ * (the guard page itself is not added here, that is done by the ++ * actual page faulting logic) ++ * ++ * This matches the behavior of the guard page logic (see mm/memory.c: ++ * check_stack_guard_page()), which only allows the guard page to be ++ * removed under these circumstances. ++ */ + #ifdef CONFIG_STACK_GROWSUP + int expand_stack(struct vm_area_struct *vma, unsigned long address) + { ++ struct vm_area_struct *next; ++ ++ address &= PAGE_MASK; ++ next = vma->vm_next; ++ if (next && next->vm_start == address + PAGE_SIZE) { ++ if (!(next->vm_flags & VM_GROWSUP)) ++ return -ENOMEM; ++ } + return expand_upwards(vma, address); + } + +@@ -1727,6 +2059,14 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr) + #else + int expand_stack(struct vm_area_struct *vma, unsigned long address) + { ++ struct vm_area_struct *prev; ++ ++ address &= PAGE_MASK; ++ prev = vma->vm_prev; ++ if (prev && prev->vm_end == address) { ++ if (!(prev->vm_flags & VM_GROWSDOWN)) ++ return -ENOMEM; ++ } + return expand_downwards(vma, address); + } + +@@ -1768,6 +2108,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) do { long nrpages = vma_pages(vma); @@ -111173,7 +111319,7 @@ index 4b80cbf..1415bd8 100644 mm->total_vm -= nrpages; vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages); vma = remove_vma(vma); -@@ -1813,6 +2125,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -1813,6 +2160,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, insertion_point = (prev ? &prev->vm_next : &mm->mmap); vma->vm_prev = NULL; do { @@ -111190,7 +111336,7 @@ index 4b80cbf..1415bd8 100644 rb_erase(&vma->vm_rb, &mm->mm_rb); mm->map_count--; tail_vma = vma; -@@ -1840,10 +2162,25 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -1840,10 +2197,25 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, struct mempolicy *pol; struct vm_area_struct *new; @@ -111216,7 +111362,7 @@ index 4b80cbf..1415bd8 100644 if (mm->map_count >= sysctl_max_map_count) return -ENOMEM; -@@ -1851,6 +2188,16 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -1851,6 +2223,16 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, if (!new) return -ENOMEM; @@ -111233,7 +111379,7 @@ index 4b80cbf..1415bd8 100644 /* most fields are the same, copy all, and then fixup */ *new = *vma; -@@ -1861,8 +2208,29 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -1861,8 +2243,29 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT); } @@ -111263,7 +111409,7 @@ index 4b80cbf..1415bd8 100644 kmem_cache_free(vm_area_cachep, new); return PTR_ERR(pol); } -@@ -1883,6 +2251,28 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -1883,6 +2286,28 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, else vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new); @@ -111292,7 +111438,7 @@ index 4b80cbf..1415bd8 100644 return 0; } -@@ -1891,11 +2281,30 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -1891,11 +2316,30 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma, * work. This now handles partial unmappings. * Jeremy Fitzhardinge <jeremy@goop.org> */ @@ -111323,7 +111469,7 @@ index 4b80cbf..1415bd8 100644 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start) return -EINVAL; -@@ -1959,6 +2368,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) +@@ -1959,6 +2403,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) /* Fix up all other VM information */ remove_vma_list(mm, vma); @@ -111332,7 +111478,7 @@ index 4b80cbf..1415bd8 100644 return 0; } -@@ -1971,22 +2382,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) +@@ -1971,22 +2417,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) profile_munmap(addr); @@ -111361,7 +111507,7 @@ index 4b80cbf..1415bd8 100644 /* * this is really a simplified "do_mmap". it only handles * anonymous maps. eventually we may be able to do some -@@ -2000,6 +2407,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2000,6 +2442,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len) struct rb_node ** rb_link, * rb_parent; pgoff_t pgoff = addr >> PAGE_SHIFT; int error; @@ -111369,7 +111515,7 @@ index 4b80cbf..1415bd8 100644 len = PAGE_ALIGN(len); if (!len) -@@ -2011,16 +2419,30 @@ unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2011,16 +2454,30 @@ unsigned long do_brk(unsigned long addr, unsigned long len) flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; @@ -111401,7 +111547,7 @@ index 4b80cbf..1415bd8 100644 locked += mm->locked_vm; lock_limit = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur; lock_limit >>= PAGE_SHIFT; -@@ -2037,22 +2459,22 @@ unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2037,22 +2494,22 @@ unsigned long do_brk(unsigned long addr, unsigned long len) /* * Clear old maps. this also does some error checking for us */ @@ -111428,7 +111574,7 @@ index 4b80cbf..1415bd8 100644 return -ENOMEM; /* Can we just expand an old private anonymous mapping? */ -@@ -2066,7 +2488,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2066,7 +2523,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len) */ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); if (!vma) { @@ -111437,7 +111583,7 @@ index 4b80cbf..1415bd8 100644 return -ENOMEM; } -@@ -2078,11 +2500,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2078,11 +2535,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len) vma->vm_page_prot = vm_get_page_prot(flags); vma_link(mm, vma, prev, rb_link, rb_parent); out: @@ -111452,7 +111598,7 @@ index 4b80cbf..1415bd8 100644 return addr; } -@@ -2129,8 +2552,10 @@ void exit_mmap(struct mm_struct *mm) +@@ -2129,8 +2587,10 @@ void exit_mmap(struct mm_struct *mm) * Walk the list again, actually closing and freeing it, * with preemption enabled, without holding any MM locks. */ @@ -111464,7 +111610,7 @@ index 4b80cbf..1415bd8 100644 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT); } -@@ -2144,6 +2569,10 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) +@@ -2144,6 +2604,10 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) struct vm_area_struct * __vma, * prev; struct rb_node ** rb_link, * rb_parent; @@ -111475,7 +111621,7 @@ index 4b80cbf..1415bd8 100644 /* * The vm_pgoff of a purely anonymous vma should be irrelevant * until its first write fault, when page's anon_vma and index -@@ -2166,7 +2595,22 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) +@@ -2166,7 +2630,22 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) if ((vma->vm_flags & VM_ACCOUNT) && security_vm_enough_memory_mm(mm, vma_pages(vma))) return -ENOMEM; @@ -111498,7 +111644,7 @@ index 4b80cbf..1415bd8 100644 return 0; } -@@ -2184,6 +2628,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2184,6 +2663,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, struct rb_node **rb_link, *rb_parent; struct mempolicy *pol; @@ -111507,7 +111653,7 @@ index 4b80cbf..1415bd8 100644 /* * If anonymous vma has not yet been faulted, update new pgoff * to match new location, to increase its chance of merging. -@@ -2227,6 +2673,35 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2227,6 +2708,35 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, return new_vma; } @@ -111543,7 +111689,7 @@ index 4b80cbf..1415bd8 100644 /* * Return true if the calling process may expand its vm space by the passed * number of pages -@@ -2238,6 +2713,12 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages) +@@ -2238,6 +2748,12 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages) lim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT; @@ -111556,7 +111702,7 @@ index 4b80cbf..1415bd8 100644 if (cur + npages > lim) return 0; return 1; -@@ -2307,6 +2788,22 @@ int install_special_mapping(struct mm_struct *mm, +@@ -2307,6 +2823,22 @@ int install_special_mapping(struct mm_struct *mm, vma->vm_start = addr; vma->vm_end = addr + len; diff --git a/3.2.39/0000_README b/3.2.39/0000_README index b8fcdf1..2831c66 100644 --- a/3.2.39/0000_README +++ b/3.2.39/0000_README @@ -74,7 +74,7 @@ Patch: 1039_linux-3.2.39.patch From: http://www.kernel.org Desc: Linux 3.2.39 -Patch: 4420_grsecurity-2.9.1-3.2.39-201302271819.patch +Patch: 4420_grsecurity-2.9.1-3.2.39-201303012254.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.2.39/4420_grsecurity-2.9.1-3.2.39-201302271819.patch b/3.2.39/4420_grsecurity-2.9.1-3.2.39-201303012254.patch index b220f78..12bbb30 100644 --- a/3.2.39/4420_grsecurity-2.9.1-3.2.39-201302271819.patch +++ b/3.2.39/4420_grsecurity-2.9.1-3.2.39-201303012254.patch @@ -17637,6 +17637,91 @@ index c9a281f..3658fbe 100644 if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE)) return -EFAULT; +diff --git a/arch/x86/kernel/head.c b/arch/x86/kernel/head.c +index af0699b..f6c4674 100644 +--- a/arch/x86/kernel/head.c ++++ b/arch/x86/kernel/head.c +@@ -5,8 +5,6 @@ + #include <asm/setup.h> + #include <asm/bios_ebda.h> + +-#define BIOS_LOWMEM_KILOBYTES 0x413 +- + /* + * The BIOS places the EBDA/XBDA at the top of conventional + * memory, and usually decreases the reported amount of +@@ -16,17 +14,30 @@ + * chipset: reserve a page before VGA to prevent PCI prefetch + * into it (errata #56). Usually the page is reserved anyways, + * unless you have no PS/2 mouse plugged in. ++ * ++ * This functions is deliberately very conservative. Losing ++ * memory in the bottom megabyte is rarely a problem, as long ++ * as we have enough memory to install the trampoline. Using ++ * memory that is in use by the BIOS or by some DMA device ++ * the BIOS didn't shut down *is* a big problem. + */ ++ ++#define BIOS_LOWMEM_KILOBYTES 0x413 ++#define LOWMEM_CAP 0x9f000U /* Absolute maximum */ ++#define INSANE_CUTOFF 0x20000U /* Less than this = insane */ ++ + void __init reserve_ebda_region(void) + { + unsigned int lowmem, ebda_addr; + +- /* To determine the position of the EBDA and the */ +- /* end of conventional memory, we need to look at */ +- /* the BIOS data area. In a paravirtual environment */ +- /* that area is absent. We'll just have to assume */ +- /* that the paravirt case can handle memory setup */ +- /* correctly, without our help. */ ++ /* ++ * To determine the position of the EBDA and the ++ * end of conventional memory, we need to look at ++ * the BIOS data area. In a paravirtual environment ++ * that area is absent. We'll just have to assume ++ * that the paravirt case can handle memory setup ++ * correctly, without our help. ++ */ + if (paravirt_enabled()) + return; + +@@ -37,19 +48,23 @@ void __init reserve_ebda_region(void) + /* start of EBDA area */ + ebda_addr = get_bios_ebda(); + +- /* Fixup: bios puts an EBDA in the top 64K segment */ +- /* of conventional memory, but does not adjust lowmem. */ +- if ((lowmem - ebda_addr) <= 0x10000) +- lowmem = ebda_addr; ++ /* ++ * Note: some old Dells seem to need 4k EBDA without ++ * reporting so, so just consider the memory above 0x9f000 ++ * to be off limits (bugzilla 2990). ++ */ + +- /* Fixup: bios does not report an EBDA at all. */ +- /* Some old Dells seem to need 4k anyhow (bugzilla 2990) */ +- if ((ebda_addr == 0) && (lowmem >= 0x9f000)) +- lowmem = 0x9f000; ++ /* If the EBDA address is below 128K, assume it is bogus */ ++ if (ebda_addr < INSANE_CUTOFF) ++ ebda_addr = LOWMEM_CAP; + +- /* Paranoia: should never happen, but... */ +- if ((lowmem == 0) || (lowmem >= 0x100000)) +- lowmem = 0x9f000; ++ /* If lowmem is less than 128K, assume it is bogus */ ++ if (lowmem < INSANE_CUTOFF) ++ lowmem = LOWMEM_CAP; ++ ++ /* Use the lower of the lowmem and EBDA markers as the cutoff */ ++ lowmem = min(lowmem, ebda_addr); ++ lowmem = min(lowmem, LOWMEM_CAP); /* Absolute cap */ + + /* reserve all memory between lowmem and the 1MB mark */ + memblock_x86_reserve_range(lowmem, 0x100000, "* BIOS reserved"); diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index 3bb0850..55a56f4 100644 --- a/arch/x86/kernel/head32.c @@ -36501,6 +36586,27 @@ index a0895bf..b451f5b 100644 .owner = THIS_MODULE, .open = timblogiw_open, .release = timblogiw_close, +diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c +index 668f5c6..65df5f2 100644 +--- a/drivers/memstick/host/r592.c ++++ b/drivers/memstick/host/r592.c +@@ -454,7 +454,7 @@ static int r592_transfer_fifo_pio(struct r592_device *dev) + /* Executes one TPC (data is read/written from small or large fifo) */ + static void r592_execute_tpc(struct r592_device *dev) + { +- bool is_write = dev->req->tpc >= MS_TPC_SET_RW_REG_ADRS; ++ bool is_write; + int len, error; + u32 status, reg; + +@@ -463,6 +463,7 @@ static void r592_execute_tpc(struct r592_device *dev) + return; + } + ++ is_write = dev->req->tpc >= MS_TPC_SET_RW_REG_ADRS; + len = dev->req->long_data ? + dev->req->sg.length : dev->req->data_len; + diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index e9c6a60..daf6a33 100644 --- a/drivers/message/fusion/mptbase.c @@ -50020,7 +50126,7 @@ index 8392cb8..80d6193 100644 memcpy(c->data, &cookie, 4); c->len=4; diff --git a/fs/locks.c b/fs/locks.c -index fcc50ab..c3dacf2 100644 +index fcc50ab..c3dacf26 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -2075,16 +2075,16 @@ void locks_remove_flock(struct file *filp) @@ -50045,7 +50151,7 @@ index fcc50ab..c3dacf2 100644 lock_flocks(); diff --git a/fs/namei.c b/fs/namei.c -index 9680cef..d098ba0 100644 +index 9680cef..d943724 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -279,16 +279,32 @@ int generic_permission(struct inode *inode, int mask) @@ -50138,21 +50244,19 @@ index 9680cef..d098ba0 100644 put_link(nd, &link, cookie); } } -@@ -1624,6 +1644,21 @@ static int path_lookupat(int dfd, const char *name, +@@ -1624,6 +1644,19 @@ static int path_lookupat(int dfd, const char *name, if (!err) err = complete_walk(nd); -+ if (!(nd->flags & LOOKUP_PARENT)) { ++ if (!err && !(nd->flags & LOOKUP_PARENT)) { +#ifdef CONFIG_GRKERNSEC + if (flags & LOOKUP_RCU) { -+ if (!err) -+ path_put(&nd->path); ++ path_put(&nd->path); + err = -ECHILD; + } else +#endif + if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) { -+ if (!err) -+ path_put(&nd->path); ++ path_put(&nd->path); + err = -ENOENT; + } + } @@ -50160,7 +50264,7 @@ index 9680cef..d098ba0 100644 if (!err && nd->flags & LOOKUP_DIRECTORY) { if (!nd->inode->i_op->lookup) { path_put(&nd->path); -@@ -1651,6 +1686,15 @@ static int do_path_lookup(int dfd, const char *name, +@@ -1651,6 +1684,15 @@ static int do_path_lookup(int dfd, const char *name, retval = path_lookupat(dfd, name, flags | LOOKUP_REVAL, nd); if (likely(!retval)) { @@ -50176,7 +50280,7 @@ index 9680cef..d098ba0 100644 if (unlikely(!audit_dummy_context())) { if (nd->path.dentry && nd->inode) audit_inode(name, nd->path.dentry); -@@ -1784,7 +1828,13 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) +@@ -1784,7 +1826,13 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len) if (!len) return ERR_PTR(-EACCES); @@ -50190,7 +50294,7 @@ index 9680cef..d098ba0 100644 while (len--) { c = *(const unsigned char *)name++; if (c == '/' || c == '\0') -@@ -2048,6 +2098,13 @@ static int may_open(struct path *path, int acc_mode, int flag) +@@ -2048,6 +2096,13 @@ static int may_open(struct path *path, int acc_mode, int flag) if (flag & O_NOATIME && !inode_owner_or_capable(inode)) return -EPERM; @@ -50204,7 +50308,7 @@ index 9680cef..d098ba0 100644 return 0; } -@@ -2083,7 +2140,7 @@ static inline int open_to_namei_flags(int flag) +@@ -2083,7 +2138,7 @@ static inline int open_to_namei_flags(int flag) /* * Handle the last step of open() */ @@ -50213,7 +50317,7 @@ index 9680cef..d098ba0 100644 const struct open_flags *op, const char *pathname) { struct dentry *dir = nd->path.dentry; -@@ -2109,16 +2166,44 @@ static struct file *do_last(struct nameidata *nd, struct path *path, +@@ -2109,16 +2164,44 @@ static struct file *do_last(struct nameidata *nd, struct path *path, error = complete_walk(nd); if (error) return ERR_PTR(error); @@ -50258,7 +50362,7 @@ index 9680cef..d098ba0 100644 audit_inode(pathname, dir); goto ok; } -@@ -2134,18 +2219,37 @@ static struct file *do_last(struct nameidata *nd, struct path *path, +@@ -2134,18 +2217,37 @@ static struct file *do_last(struct nameidata *nd, struct path *path, !symlink_ok); if (error < 0) return ERR_PTR(error); @@ -50297,7 +50401,7 @@ index 9680cef..d098ba0 100644 audit_inode(pathname, nd->path.dentry); goto ok; } -@@ -2180,6 +2284,17 @@ static struct file *do_last(struct nameidata *nd, struct path *path, +@@ -2180,6 +2282,17 @@ static struct file *do_last(struct nameidata *nd, struct path *path, /* Negative dentry, just create the file */ if (!dentry->d_inode) { int mode = op->mode; @@ -50315,7 +50419,7 @@ index 9680cef..d098ba0 100644 if (!IS_POSIXACL(dir->d_inode)) mode &= ~current_umask(); /* -@@ -2203,6 +2318,8 @@ static struct file *do_last(struct nameidata *nd, struct path *path, +@@ -2203,6 +2316,8 @@ static struct file *do_last(struct nameidata *nd, struct path *path, error = vfs_create(dir->d_inode, dentry, mode, nd); if (error) goto exit_mutex_unlock; @@ -50324,7 +50428,7 @@ index 9680cef..d098ba0 100644 mutex_unlock(&dir->d_inode->i_mutex); dput(nd->path.dentry); nd->path.dentry = dentry; -@@ -2212,6 +2329,19 @@ static struct file *do_last(struct nameidata *nd, struct path *path, +@@ -2212,6 +2327,19 @@ static struct file *do_last(struct nameidata *nd, struct path *path, /* * It already exists. */ @@ -50344,7 +50448,7 @@ index 9680cef..d098ba0 100644 mutex_unlock(&dir->d_inode->i_mutex); audit_inode(pathname, path->dentry); -@@ -2230,11 +2360,17 @@ static struct file *do_last(struct nameidata *nd, struct path *path, +@@ -2230,11 +2358,17 @@ static struct file *do_last(struct nameidata *nd, struct path *path, if (!path->dentry->d_inode) goto exit_dput; @@ -50363,7 +50467,7 @@ index 9680cef..d098ba0 100644 /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */ error = complete_walk(nd); if (error) -@@ -2242,6 +2378,12 @@ static struct file *do_last(struct nameidata *nd, struct path *path, +@@ -2242,6 +2376,12 @@ static struct file *do_last(struct nameidata *nd, struct path *path, error = -EISDIR; if (S_ISDIR(nd->inode->i_mode)) goto exit; @@ -50376,7 +50480,7 @@ index 9680cef..d098ba0 100644 ok: if (!S_ISREG(nd->inode->i_mode)) will_truncate = 0; -@@ -2314,7 +2456,7 @@ static struct file *path_openat(int dfd, const char *pathname, +@@ -2314,7 +2454,7 @@ static struct file *path_openat(int dfd, const char *pathname, if (unlikely(error)) goto out_filp; @@ -50385,7 +50489,7 @@ index 9680cef..d098ba0 100644 while (unlikely(!filp)) { /* trailing symlink */ struct path link = path; void *cookie; -@@ -2329,8 +2471,9 @@ static struct file *path_openat(int dfd, const char *pathname, +@@ -2329,8 +2469,9 @@ static struct file *path_openat(int dfd, const char *pathname, error = follow_link(&link, nd, &cookie); if (unlikely(error)) filp = ERR_PTR(error); @@ -50397,7 +50501,7 @@ index 9680cef..d098ba0 100644 put_link(nd, &link, cookie); } out: -@@ -2424,6 +2567,11 @@ struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path +@@ -2424,6 +2565,11 @@ struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path *path = nd.path; return dentry; eexist: @@ -50409,7 +50513,7 @@ index 9680cef..d098ba0 100644 dput(dentry); dentry = ERR_PTR(-EEXIST); fail: -@@ -2446,6 +2594,20 @@ struct dentry *user_path_create(int dfd, const char __user *pathname, struct pat +@@ -2446,6 +2592,20 @@ struct dentry *user_path_create(int dfd, const char __user *pathname, struct pat } EXPORT_SYMBOL(user_path_create); @@ -50430,7 +50534,7 @@ index 9680cef..d098ba0 100644 int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) { int error = may_create(dir, dentry); -@@ -2513,6 +2675,17 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode, +@@ -2513,6 +2673,17 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode, error = mnt_want_write(path.mnt); if (error) goto out_dput; @@ -50448,7 +50552,7 @@ index 9680cef..d098ba0 100644 error = security_path_mknod(&path, dentry, mode, dev); if (error) goto out_drop_write; -@@ -2530,6 +2703,9 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode, +@@ -2530,6 +2701,9 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, int, mode, } out_drop_write: mnt_drop_write(path.mnt); @@ -50458,7 +50562,7 @@ index 9680cef..d098ba0 100644 out_dput: dput(dentry); mutex_unlock(&path.dentry->d_inode->i_mutex); -@@ -2579,12 +2755,21 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode) +@@ -2579,12 +2753,21 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, int, mode) error = mnt_want_write(path.mnt); if (error) goto out_dput; @@ -50480,7 +50584,7 @@ index 9680cef..d098ba0 100644 out_dput: dput(dentry); mutex_unlock(&path.dentry->d_inode->i_mutex); -@@ -2664,6 +2849,8 @@ static long do_rmdir(int dfd, const char __user *pathname) +@@ -2664,6 +2847,8 @@ static long do_rmdir(int dfd, const char __user *pathname) char * name; struct dentry *dentry; struct nameidata nd; @@ -50489,7 +50593,7 @@ index 9680cef..d098ba0 100644 error = user_path_parent(dfd, pathname, &nd, &name); if (error) -@@ -2692,6 +2879,15 @@ static long do_rmdir(int dfd, const char __user *pathname) +@@ -2692,6 +2877,15 @@ static long do_rmdir(int dfd, const char __user *pathname) error = -ENOENT; goto exit3; } @@ -50505,7 +50609,7 @@ index 9680cef..d098ba0 100644 error = mnt_want_write(nd.path.mnt); if (error) goto exit3; -@@ -2699,6 +2895,8 @@ static long do_rmdir(int dfd, const char __user *pathname) +@@ -2699,6 +2893,8 @@ static long do_rmdir(int dfd, const char __user *pathname) if (error) goto exit4; error = vfs_rmdir(nd.path.dentry->d_inode, dentry); @@ -50514,7 +50618,7 @@ index 9680cef..d098ba0 100644 exit4: mnt_drop_write(nd.path.mnt); exit3: -@@ -2761,6 +2959,8 @@ static long do_unlinkat(int dfd, const char __user *pathname) +@@ -2761,6 +2957,8 @@ static long do_unlinkat(int dfd, const char __user *pathname) struct dentry *dentry; struct nameidata nd; struct inode *inode = NULL; @@ -50523,7 +50627,7 @@ index 9680cef..d098ba0 100644 error = user_path_parent(dfd, pathname, &nd, &name); if (error) -@@ -2783,6 +2983,16 @@ static long do_unlinkat(int dfd, const char __user *pathname) +@@ -2783,6 +2981,16 @@ static long do_unlinkat(int dfd, const char __user *pathname) if (!inode) goto slashes; ihold(inode); @@ -50540,7 +50644,7 @@ index 9680cef..d098ba0 100644 error = mnt_want_write(nd.path.mnt); if (error) goto exit2; -@@ -2790,6 +3000,8 @@ static long do_unlinkat(int dfd, const char __user *pathname) +@@ -2790,6 +2998,8 @@ static long do_unlinkat(int dfd, const char __user *pathname) if (error) goto exit3; error = vfs_unlink(nd.path.dentry->d_inode, dentry); @@ -50549,7 +50653,7 @@ index 9680cef..d098ba0 100644 exit3: mnt_drop_write(nd.path.mnt); exit2: -@@ -2865,10 +3077,18 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname, +@@ -2865,10 +3075,18 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname, error = mnt_want_write(path.mnt); if (error) goto out_dput; @@ -50568,7 +50672,7 @@ index 9680cef..d098ba0 100644 out_drop_write: mnt_drop_write(path.mnt); out_dput: -@@ -2940,6 +3160,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, +@@ -2940,6 +3158,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, { struct dentry *new_dentry; struct path old_path, new_path; @@ -50576,7 +50680,7 @@ index 9680cef..d098ba0 100644 int how = 0; int error; -@@ -2963,7 +3184,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, +@@ -2963,7 +3182,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, if (error) return error; @@ -50585,7 +50689,7 @@ index 9680cef..d098ba0 100644 error = PTR_ERR(new_dentry); if (IS_ERR(new_dentry)) goto out; -@@ -2974,13 +3195,30 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, +@@ -2974,13 +3193,30 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, error = mnt_want_write(new_path.mnt); if (error) goto out_dput; @@ -50616,7 +50720,7 @@ index 9680cef..d098ba0 100644 dput(new_dentry); mutex_unlock(&new_path.dentry->d_inode->i_mutex); path_put(&new_path); -@@ -3208,6 +3446,12 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, +@@ -3208,6 +3444,12 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, if (new_dentry == trap) goto exit5; @@ -50629,7 +50733,7 @@ index 9680cef..d098ba0 100644 error = mnt_want_write(oldnd.path.mnt); if (error) goto exit5; -@@ -3217,6 +3461,9 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, +@@ -3217,6 +3459,9 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname, goto exit6; error = vfs_rename(old_dir->d_inode, old_dentry, new_dir->d_inode, new_dentry); @@ -50639,7 +50743,7 @@ index 9680cef..d098ba0 100644 exit6: mnt_drop_write(oldnd.path.mnt); exit5: -@@ -3242,6 +3489,8 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna +@@ -3242,6 +3487,8 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const char *link) { @@ -50648,7 +50752,7 @@ index 9680cef..d098ba0 100644 int len; len = PTR_ERR(link); -@@ -3251,7 +3500,14 @@ int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const c +@@ -3251,7 +3498,14 @@ int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const c len = strlen(link); if (len > (unsigned) buflen) len = buflen; @@ -68145,10 +68249,18 @@ index 703cfa33..0b8ca72ac 100644 void __user *, size_t *, loff_t *); extern int proc_dointvec_minmax(struct ctl_table *, int, diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h -index 7faf933..eb6f5e3 100644 +index 7faf933..c1ad32c 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h -@@ -36,7 +36,7 @@ struct sysrq_key_op { +@@ -15,6 +15,7 @@ + #define _LINUX_SYSRQ_H + + #include <linux/errno.h> ++#include <linux/compiler.h> + #include <linux/types.h> + + /* Enable/disable SYSRQ support by default (0==no, 1==yes). */ +@@ -36,7 +37,7 @@ struct sysrq_key_op { char *help_msg; char *action_msg; int enable_mask; @@ -74209,7 +74321,7 @@ index ea7ec7f..23d4094 100644 EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); EXPORT_SYMBOL(register_sysctl_table); diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c -index a650694..aaeeb20 100644 +index a650694..d0c4f42 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c @@ -989,7 +989,7 @@ static ssize_t bin_intvec(struct file *file, @@ -74266,7 +74378,19 @@ index a650694..aaeeb20 100644 set_fs(old_fs); if (result < 0) goto out; -@@ -1233,7 +1233,7 @@ static ssize_t bin_dn_node_address(struct file *file, +@@ -1194,9 +1194,10 @@ static ssize_t bin_dn_node_address(struct file *file, + + /* Convert the decnet address to binary */ + result = -EIO; +- nodep = strchr(buf, '.') + 1; ++ nodep = strchr(buf, '.'); + if (!nodep) + goto out; ++ ++nodep; + + area = simple_strtoul(buf, NULL, 10); + node = simple_strtoul(nodep, NULL, 10); +@@ -1233,7 +1234,7 @@ static ssize_t bin_dn_node_address(struct file *file, le16_to_cpu(dnaddr) & 0x3ff); set_fs(KERNEL_DS); @@ -76968,7 +77092,7 @@ index 4f4f53b..de8e432 100644 capable(CAP_IPC_LOCK)) ret = do_mlockall(flags); diff --git a/mm/mmap.c b/mm/mmap.c -index eae90af..09d8f77 100644 +index eae90af..0704837 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -30,6 +30,7 @@ @@ -77851,7 +77975,7 @@ index eae90af..09d8f77 100644 size = vma->vm_end - address; grow = (vma->vm_start - address) >> PAGE_SHIFT; -@@ -1786,11 +2080,22 @@ int expand_downwards(struct vm_area_struct *vma, +@@ -1786,18 +2080,48 @@ int expand_downwards(struct vm_area_struct *vma, if (!error) { vma->vm_start = address; vma->vm_pgoff -= grow; @@ -77874,7 +77998,48 @@ index eae90af..09d8f77 100644 khugepaged_enter_vma_merge(vma); return error; } -@@ -1860,6 +2165,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) + ++/* ++ * Note how expand_stack() refuses to expand the stack all the way to ++ * abut the next virtual mapping, *unless* that mapping itself is also ++ * a stack mapping. We want to leave room for a guard page, after all ++ * (the guard page itself is not added here, that is done by the ++ * actual page faulting logic) ++ * ++ * This matches the behavior of the guard page logic (see mm/memory.c: ++ * check_stack_guard_page()), which only allows the guard page to be ++ * removed under these circumstances. ++ */ + #ifdef CONFIG_STACK_GROWSUP + int expand_stack(struct vm_area_struct *vma, unsigned long address) + { ++ struct vm_area_struct *next; ++ ++ address &= PAGE_MASK; ++ next = vma->vm_next; ++ if (next && next->vm_start == address + PAGE_SIZE) { ++ if (!(next->vm_flags & VM_GROWSUP)) ++ return -ENOMEM; ++ } + return expand_upwards(vma, address); + } + +@@ -1820,6 +2144,14 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr) + #else + int expand_stack(struct vm_area_struct *vma, unsigned long address) + { ++ struct vm_area_struct *prev; ++ ++ address &= PAGE_MASK; ++ prev = vma->vm_prev; ++ if (prev && prev->vm_end == address) { ++ if (!(prev->vm_flags & VM_GROWSDOWN)) ++ return -ENOMEM; ++ } + return expand_downwards(vma, address); + } + +@@ -1860,6 +2192,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) do { long nrpages = vma_pages(vma); @@ -77888,7 +78053,7 @@ index eae90af..09d8f77 100644 mm->total_vm -= nrpages; vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages); vma = remove_vma(vma); -@@ -1905,6 +2217,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -1905,6 +2244,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, insertion_point = (prev ? &prev->vm_next : &mm->mmap); vma->vm_prev = NULL; do { @@ -77905,7 +78070,7 @@ index eae90af..09d8f77 100644 rb_erase(&vma->vm_rb, &mm->mm_rb); mm->map_count--; tail_vma = vma; -@@ -1933,14 +2255,33 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -1933,14 +2282,33 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct *new; int err = -ENOMEM; @@ -77939,7 +78104,7 @@ index eae90af..09d8f77 100644 /* most fields are the same, copy all, and then fixup */ *new = *vma; -@@ -1953,6 +2294,22 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -1953,6 +2321,22 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT); } @@ -77962,7 +78127,7 @@ index eae90af..09d8f77 100644 pol = mpol_dup(vma_policy(vma)); if (IS_ERR(pol)) { err = PTR_ERR(pol); -@@ -1978,6 +2335,42 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -1978,6 +2362,42 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, else err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new); @@ -78005,7 +78170,7 @@ index eae90af..09d8f77 100644 /* Success. */ if (!err) return 0; -@@ -1990,10 +2383,18 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -1990,10 +2410,18 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, removed_exe_file_vma(mm); fput(new->vm_file); } @@ -78025,7 +78190,7 @@ index eae90af..09d8f77 100644 kmem_cache_free(vm_area_cachep, new); out_err: return err; -@@ -2006,6 +2407,15 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2006,6 +2434,15 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, int new_below) { @@ -78041,7 +78206,7 @@ index eae90af..09d8f77 100644 if (mm->map_count >= sysctl_max_map_count) return -ENOMEM; -@@ -2017,11 +2427,30 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2017,11 +2454,30 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, * work. This now handles partial unmappings. * Jeremy Fitzhardinge <jeremy@goop.org> */ @@ -78072,7 +78237,7 @@ index eae90af..09d8f77 100644 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start) return -EINVAL; -@@ -2096,6 +2525,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) +@@ -2096,6 +2552,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) /* Fix up all other VM information */ remove_vma_list(mm, vma); @@ -78081,7 +78246,7 @@ index eae90af..09d8f77 100644 return 0; } -@@ -2108,22 +2539,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) +@@ -2108,22 +2566,18 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) profile_munmap(addr); @@ -78110,7 +78275,7 @@ index eae90af..09d8f77 100644 /* * this is really a simplified "do_mmap". it only handles * anonymous maps. eventually we may be able to do some -@@ -2137,6 +2564,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2137,6 +2591,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len) struct rb_node ** rb_link, * rb_parent; pgoff_t pgoff = addr >> PAGE_SHIFT; int error; @@ -78118,7 +78283,7 @@ index eae90af..09d8f77 100644 len = PAGE_ALIGN(len); if (!len) -@@ -2148,16 +2576,30 @@ unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2148,16 +2603,30 @@ unsigned long do_brk(unsigned long addr, unsigned long len) flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; @@ -78150,7 +78315,7 @@ index eae90af..09d8f77 100644 locked += mm->locked_vm; lock_limit = rlimit(RLIMIT_MEMLOCK); lock_limit >>= PAGE_SHIFT; -@@ -2174,22 +2616,22 @@ unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2174,22 +2643,22 @@ unsigned long do_brk(unsigned long addr, unsigned long len) /* * Clear old maps. this also does some error checking for us */ @@ -78177,7 +78342,7 @@ index eae90af..09d8f77 100644 return -ENOMEM; /* Can we just expand an old private anonymous mapping? */ -@@ -2203,7 +2645,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2203,7 +2672,7 @@ unsigned long do_brk(unsigned long addr, unsigned long len) */ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); if (!vma) { @@ -78186,7 +78351,7 @@ index eae90af..09d8f77 100644 return -ENOMEM; } -@@ -2217,11 +2659,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2217,11 +2686,12 @@ unsigned long do_brk(unsigned long addr, unsigned long len) vma_link(mm, vma, prev, rb_link, rb_parent); out: perf_event_mmap(vma); @@ -78201,7 +78366,7 @@ index eae90af..09d8f77 100644 return addr; } -@@ -2268,8 +2711,10 @@ void exit_mmap(struct mm_struct *mm) +@@ -2268,8 +2738,10 @@ void exit_mmap(struct mm_struct *mm) * Walk the list again, actually closing and freeing it, * with preemption enabled, without holding any MM locks. */ @@ -78213,7 +78378,7 @@ index eae90af..09d8f77 100644 BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT); } -@@ -2283,6 +2728,13 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) +@@ -2283,6 +2755,13 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) struct vm_area_struct * __vma, * prev; struct rb_node ** rb_link, * rb_parent; @@ -78227,7 +78392,7 @@ index eae90af..09d8f77 100644 /* * The vm_pgoff of a purely anonymous vma should be irrelevant * until its first write fault, when page's anon_vma and index -@@ -2305,7 +2757,22 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) +@@ -2305,7 +2784,22 @@ int insert_vm_struct(struct mm_struct * mm, struct vm_area_struct * vma) if ((vma->vm_flags & VM_ACCOUNT) && security_vm_enough_memory_mm(mm, vma_pages(vma))) return -ENOMEM; @@ -78250,7 +78415,7 @@ index eae90af..09d8f77 100644 return 0; } -@@ -2323,6 +2790,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2323,6 +2817,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, struct rb_node **rb_link, *rb_parent; struct mempolicy *pol; @@ -78259,7 +78424,7 @@ index eae90af..09d8f77 100644 /* * If anonymous vma has not yet been faulted, update new pgoff * to match new location, to increase its chance of merging. -@@ -2373,6 +2842,39 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2373,6 +2869,39 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, return NULL; } @@ -78299,7 +78464,7 @@ index eae90af..09d8f77 100644 /* * Return true if the calling process may expand its vm space by the passed * number of pages -@@ -2384,6 +2886,12 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages) +@@ -2384,6 +2913,12 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages) lim = rlimit(RLIMIT_AS) >> PAGE_SHIFT; @@ -78312,7 +78477,7 @@ index eae90af..09d8f77 100644 if (cur + npages > lim) return 0; return 1; -@@ -2454,6 +2962,22 @@ int install_special_mapping(struct mm_struct *mm, +@@ -2454,6 +2989,22 @@ int install_special_mapping(struct mm_struct *mm, vma->vm_start = addr; vma->vm_end = addr + len; diff --git a/3.8.0/0000_README b/3.8.1/0000_README index a9cab40..517c0e6 100644 --- a/3.8.0/0000_README +++ b/3.8.1/0000_README @@ -2,7 +2,7 @@ README ----------------------------------------------------------------------------- Individual Patch Descriptions: ----------------------------------------------------------------------------- -Patch: 4420_grsecurity-2.9.1-3.8.0-201302271810.patch +Patch: 4420_grsecurity-2.9.1-3.8.1-201303012255.patch From: http://www.grsecurity.net Desc: hardened-sources base patch from upstream grsecurity diff --git a/3.8.0/4420_grsecurity-2.9.1-3.8.0-201302271810.patch b/3.8.1/4420_grsecurity-2.9.1-3.8.1-201303012255.patch index 24c501f..b69296b 100644 --- a/3.8.0/4420_grsecurity-2.9.1-3.8.0-201302271810.patch +++ b/3.8.1/4420_grsecurity-2.9.1-3.8.1-201303012255.patch @@ -252,7 +252,7 @@ index 6c72381..2fe9ae4 100644 pcd. [PARIDE] diff --git a/Makefile b/Makefile -index d69266c..e4f6593 100644 +index 746c856..c014cfa 100644 --- a/Makefile +++ b/Makefile @@ -241,8 +241,9 @@ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ @@ -5494,10 +5494,10 @@ index fc987a1..6e068ef 100644 #endif diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h -index ee99f23..802b0a1 100644 +index 7df49fa..38b62bf 100644 --- a/arch/parisc/include/asm/pgtable.h +++ b/arch/parisc/include/asm/pgtable.h -@@ -212,6 +212,17 @@ struct vm_area_struct; +@@ -218,6 +218,17 @@ extern void purge_tlb_entries(struct mm_struct *, unsigned long); #define PAGE_EXECREAD __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_EXEC |_PAGE_ACCESSED) #define PAGE_COPY PAGE_EXECREAD #define PAGE_RWX __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_READ | _PAGE_WRITE | _PAGE_EXEC |_PAGE_ACCESSED) @@ -9071,7 +9071,7 @@ index e98bfda..ea8d221 100644 if (!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c -index 097aee7..5ca6697 100644 +index 5062ff3..e0b75f3 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c @@ -21,6 +21,9 @@ @@ -9827,7 +9827,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 225543b..f12405b 100644 +index 0694d09..b58b3aa 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -238,7 +238,7 @@ config X86_HT @@ -9874,7 +9874,7 @@ index 225543b..f12405b 100644 default 0x40000000 if VMSPLIT_1G default 0xC0000000 depends on X86_32 -@@ -1546,6 +1547,7 @@ config SECCOMP +@@ -1542,6 +1543,7 @@ config SECCOMP config CC_STACKPROTECTOR bool "Enable -fstack-protector buffer overflow detection" @@ -9882,7 +9882,7 @@ index 225543b..f12405b 100644 ---help--- This option turns on the -fstack-protector GCC feature. This feature puts, at the beginning of functions, a canary value on -@@ -1603,6 +1605,7 @@ config KEXEC_JUMP +@@ -1599,6 +1601,7 @@ config KEXEC_JUMP config PHYSICAL_START hex "Physical address where the kernel is loaded" if (EXPERT || CRASH_DUMP) default "0x1000000" @@ -9890,7 +9890,7 @@ index 225543b..f12405b 100644 ---help--- This gives the physical address where the kernel is loaded. -@@ -1666,6 +1669,7 @@ config X86_NEED_RELOCS +@@ -1662,6 +1665,7 @@ config X86_NEED_RELOCS config PHYSICAL_ALIGN hex "Alignment value to which kernel should be aligned" if X86_32 default "0x1000000" @@ -9898,7 +9898,7 @@ index 225543b..f12405b 100644 range 0x2000 0x1000000 ---help--- This value puts the alignment restrictions on physical address -@@ -1741,9 +1745,10 @@ config DEBUG_HOTPLUG_CPU0 +@@ -1737,9 +1741,10 @@ config DEBUG_HOTPLUG_CPU0 If unsure, say N. config COMPAT_VDSO @@ -19375,6 +19375,91 @@ index 1d41402..af9a46a 100644 if (probe_kernel_read(code, (void *)ip, MCOUNT_INSN_SIZE)) return -EFAULT; +diff --git a/arch/x86/kernel/head.c b/arch/x86/kernel/head.c +index 48d9d4e..992f442 100644 +--- a/arch/x86/kernel/head.c ++++ b/arch/x86/kernel/head.c +@@ -5,8 +5,6 @@ + #include <asm/setup.h> + #include <asm/bios_ebda.h> + +-#define BIOS_LOWMEM_KILOBYTES 0x413 +- + /* + * The BIOS places the EBDA/XBDA at the top of conventional + * memory, and usually decreases the reported amount of +@@ -16,17 +14,30 @@ + * chipset: reserve a page before VGA to prevent PCI prefetch + * into it (errata #56). Usually the page is reserved anyways, + * unless you have no PS/2 mouse plugged in. ++ * ++ * This functions is deliberately very conservative. Losing ++ * memory in the bottom megabyte is rarely a problem, as long ++ * as we have enough memory to install the trampoline. Using ++ * memory that is in use by the BIOS or by some DMA device ++ * the BIOS didn't shut down *is* a big problem. + */ ++ ++#define BIOS_LOWMEM_KILOBYTES 0x413 ++#define LOWMEM_CAP 0x9f000U /* Absolute maximum */ ++#define INSANE_CUTOFF 0x20000U /* Less than this = insane */ ++ + void __init reserve_ebda_region(void) + { + unsigned int lowmem, ebda_addr; + +- /* To determine the position of the EBDA and the */ +- /* end of conventional memory, we need to look at */ +- /* the BIOS data area. In a paravirtual environment */ +- /* that area is absent. We'll just have to assume */ +- /* that the paravirt case can handle memory setup */ +- /* correctly, without our help. */ ++ /* ++ * To determine the position of the EBDA and the ++ * end of conventional memory, we need to look at ++ * the BIOS data area. In a paravirtual environment ++ * that area is absent. We'll just have to assume ++ * that the paravirt case can handle memory setup ++ * correctly, without our help. ++ */ + if (paravirt_enabled()) + return; + +@@ -37,19 +48,23 @@ void __init reserve_ebda_region(void) + /* start of EBDA area */ + ebda_addr = get_bios_ebda(); + +- /* Fixup: bios puts an EBDA in the top 64K segment */ +- /* of conventional memory, but does not adjust lowmem. */ +- if ((lowmem - ebda_addr) <= 0x10000) +- lowmem = ebda_addr; ++ /* ++ * Note: some old Dells seem to need 4k EBDA without ++ * reporting so, so just consider the memory above 0x9f000 ++ * to be off limits (bugzilla 2990). ++ */ + +- /* Fixup: bios does not report an EBDA at all. */ +- /* Some old Dells seem to need 4k anyhow (bugzilla 2990) */ +- if ((ebda_addr == 0) && (lowmem >= 0x9f000)) +- lowmem = 0x9f000; ++ /* If the EBDA address is below 128K, assume it is bogus */ ++ if (ebda_addr < INSANE_CUTOFF) ++ ebda_addr = LOWMEM_CAP; + +- /* Paranoia: should never happen, but... */ +- if ((lowmem == 0) || (lowmem >= 0x100000)) +- lowmem = 0x9f000; ++ /* If lowmem is less than 128K, assume it is bogus */ ++ if (lowmem < INSANE_CUTOFF) ++ lowmem = LOWMEM_CAP; ++ ++ /* Use the lower of the lowmem and EBDA markers as the cutoff */ ++ lowmem = min(lowmem, ebda_addr); ++ lowmem = min(lowmem, LOWMEM_CAP); /* Absolute cap */ + + /* reserve all memory between lowmem and the 1MB mark */ + memblock_reserve(lowmem, 0x100000 - lowmem); diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index c18f59d..9c0c9f6 100644 --- a/arch/x86/kernel/head32.c @@ -33144,7 +33229,7 @@ index 9d7732b..0b1a793 100644 .priority = 1, }; diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c -index 3315e4b..fc38316 100644 +index b70709b..1d8d02a 100644 --- a/drivers/dma/sh/shdma.c +++ b/drivers/dma/sh/shdma.c @@ -476,7 +476,7 @@ static int sh_dmae_nmi_handler(struct notifier_block *self, @@ -33683,7 +33768,7 @@ index 6e0acad..93c8289 100644 int front_offset; } drm_i810_private_t; diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c -index 9d4a2c2..32a119f 100644 +index 8a7c48b..72effc2 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -496,7 +496,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) @@ -33709,7 +33794,7 @@ index 99daa89..84ebd44 100644 return can_switch; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h -index 12ab3bd..b3bed3b 100644 +index 7339a4b..445aaba 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -656,7 +656,7 @@ typedef struct drm_i915_private { @@ -33868,10 +33953,10 @@ index fe84338..a863190 100644 iir = I915_READ(IIR); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c -index da1ad9c..10d368b 100644 +index 80aa1fc..1ede041 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c -@@ -2244,7 +2244,7 @@ intel_finish_fb(struct drm_framebuffer *old_fb) +@@ -2255,7 +2255,7 @@ intel_finish_fb(struct drm_framebuffer *old_fb) wait_event(dev_priv->pending_flip_queue, atomic_read(&dev_priv->mm.wedged) || @@ -33880,7 +33965,7 @@ index da1ad9c..10d368b 100644 /* Big Hammer, we also need to ensure that any pending * MI_WAIT_FOR_EVENT inside a user batch buffer on the -@@ -7109,8 +7109,7 @@ static void do_intel_finish_page_flip(struct drm_device *dev, +@@ -7122,8 +7122,7 @@ static void do_intel_finish_page_flip(struct drm_device *dev, obj = work->old_fb_obj; @@ -33890,7 +33975,7 @@ index da1ad9c..10d368b 100644 wake_up(&dev_priv->pending_flip_queue); queue_work(dev_priv->wq, &work->work); -@@ -7477,7 +7476,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, +@@ -7490,7 +7489,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, /* Block clients from rendering to the new back buffer until * the flip occurs and the object is no longer visible. */ @@ -33899,7 +33984,7 @@ index da1ad9c..10d368b 100644 atomic_inc(&intel_crtc->unpin_work_count); ret = dev_priv->display.queue_flip(dev, crtc, fb, obj); -@@ -7494,7 +7493,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, +@@ -7507,7 +7506,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, cleanup_pending: atomic_dec(&intel_crtc->unpin_work_count); @@ -36566,6 +36651,27 @@ index 9382895..ac8093c 100644 /* debug */ static int dvb_usb_dw2102_debug; +diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c +index 29b2172..a7c5b31 100644 +--- a/drivers/memstick/host/r592.c ++++ b/drivers/memstick/host/r592.c +@@ -454,7 +454,7 @@ static int r592_transfer_fifo_pio(struct r592_device *dev) + /* Executes one TPC (data is read/written from small or large fifo) */ + static void r592_execute_tpc(struct r592_device *dev) + { +- bool is_write = dev->req->tpc >= MS_TPC_SET_RW_REG_ADRS; ++ bool is_write; + int len, error; + u32 status, reg; + +@@ -463,6 +463,7 @@ static void r592_execute_tpc(struct r592_device *dev) + return; + } + ++ is_write = dev->req->tpc >= MS_TPC_SET_RW_REG_ADRS; + len = dev->req->long_data ? + dev->req->sg.length : dev->req->data_len; + diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index fb69baa..cf7ad22 100644 --- a/drivers/message/fusion/mptbase.c @@ -37609,7 +37715,7 @@ index daec9b0..6428fcb 100644 } EXPORT_SYMBOL(free_mdio_bitbang); diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c -index 0b2706a..ba1430d 100644 +index 508570e..f706dc7 100644 --- a/drivers/net/ppp/ppp_generic.c +++ b/drivers/net/ppp/ppp_generic.c @@ -999,7 +999,6 @@ ppp_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) @@ -40670,7 +40776,7 @@ index f9d2850..b006f04 100644 tty_port_tty_set(&ch->port, tty); mutex_lock(&ch->port.mutex); diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c -index dcc0430..040bef9 100644 +index bfd6771..e0d93c4 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1636,7 +1636,7 @@ static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr) @@ -40682,7 +40788,7 @@ index dcc0430..040bef9 100644 kfree(dlci); return NULL; } -@@ -2924,7 +2924,7 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) +@@ -2936,7 +2936,7 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp) struct gsm_dlci *dlci = tty->driver_data; struct tty_port *port = &dlci->port; @@ -41521,19 +41627,6 @@ index 681765b..d3ccdf2 100644 if (!perm) { ret = -EPERM; goto reterr; -diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c -index 8fd8968..3614c9c 100644 ---- a/drivers/tty/vt/vt.c -+++ b/drivers/tty/vt/vt.c -@@ -539,7 +539,7 @@ static void insert_char(struct vc_data *vc, unsigned int nr) - { - unsigned short *p = (unsigned short *) vc->vc_pos; - -- scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x) * 2); -+ scr_memmovew(p + nr, p, (vc->vc_cols - vc->vc_x - nr) * 2); - scr_memsetw(p, vc->vc_video_erase_char, nr * 2); - vc->vc_need_wrap = 0; - if (DO_UPDATE(vc)) diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 5110f36..8dc0a74 100644 --- a/drivers/uio/uio.c @@ -42024,7 +42117,7 @@ index 5c3960d..15cf8fc 100644 goto out1; } diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c -index 3ff0105..7589d98 100644 +index dc61c12..e29796e 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -428,7 +428,7 @@ static void fb_do_show_logo(struct fb_info *info, struct fb_image *image, @@ -46262,7 +46355,7 @@ index b96fc6c..431d628 100644 __bio_for_each_segment(bvec, bio, i, 0) { char *addr = page_address(bvec->bv_page); diff --git a/fs/block_dev.c b/fs/block_dev.c -index 172f849..6efbf24 100644 +index 78333a3..23dcb4d 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -651,7 +651,7 @@ static bool bd_may_claim(struct block_device *bdev, struct block_device *whole, @@ -50192,7 +50285,7 @@ index 916da8c..1588998 100644 next->d_inode->i_ino, dt_type(next->d_inode)) < 0) diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c -index 54f9e6c..9ed908c 100644 +index 52e5120..808936e 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -36,11 +36,11 @@ static const struct rpc_call_ops nlmclnt_cancel_ops; @@ -50235,7 +50328,7 @@ index a94e331..060bce3 100644 lock_flocks(); diff --git a/fs/namei.c b/fs/namei.c -index 43a97ee..117e7e4 100644 +index 43a97ee..4e585fd 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -319,16 +319,32 @@ int generic_permission(struct inode *inode, int mask) @@ -50338,21 +50431,19 @@ index 43a97ee..117e7e4 100644 put_link(nd, &link, cookie); } } -@@ -1986,6 +2004,21 @@ static int path_lookupat(int dfd, const char *name, +@@ -1986,6 +2004,19 @@ static int path_lookupat(int dfd, const char *name, if (!err) err = complete_walk(nd); -+ if (!(nd->flags & LOOKUP_PARENT)) { ++ if (!err && !(nd->flags & LOOKUP_PARENT)) { +#ifdef CONFIG_GRKERNSEC + if (flags & LOOKUP_RCU) { -+ if (!err) -+ path_put(&nd->path); ++ path_put(&nd->path); + err = -ECHILD; + } else +#endif + if (!gr_acl_handle_hidden_file(nd->path.dentry, nd->path.mnt)) { -+ if (!err) -+ path_put(&nd->path); ++ path_put(&nd->path); + err = -ENOENT; + } + } @@ -50360,7 +50451,7 @@ index 43a97ee..117e7e4 100644 if (!err && nd->flags & LOOKUP_DIRECTORY) { if (!nd->inode->i_op->lookup) { path_put(&nd->path); -@@ -2013,8 +2046,17 @@ static int filename_lookup(int dfd, struct filename *name, +@@ -2013,8 +2044,17 @@ static int filename_lookup(int dfd, struct filename *name, retval = path_lookupat(dfd, name->name, flags | LOOKUP_REVAL, nd); @@ -50379,7 +50470,7 @@ index 43a97ee..117e7e4 100644 return retval; } -@@ -2392,6 +2434,13 @@ static int may_open(struct path *path, int acc_mode, int flag) +@@ -2392,6 +2432,13 @@ static int may_open(struct path *path, int acc_mode, int flag) if (flag & O_NOATIME && !inode_owner_or_capable(inode)) return -EPERM; @@ -50393,7 +50484,7 @@ index 43a97ee..117e7e4 100644 return 0; } -@@ -2613,7 +2662,7 @@ looked_up: +@@ -2613,7 +2660,7 @@ looked_up: * cleared otherwise prior to returning. */ static int lookup_open(struct nameidata *nd, struct path *path, @@ -50402,7 +50493,7 @@ index 43a97ee..117e7e4 100644 const struct open_flags *op, bool got_write, int *opened) { -@@ -2648,6 +2697,17 @@ static int lookup_open(struct nameidata *nd, struct path *path, +@@ -2648,6 +2695,17 @@ 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; @@ -50420,7 +50511,7 @@ index 43a97ee..117e7e4 100644 if (!IS_POSIXACL(dir->d_inode)) mode &= ~current_umask(); /* -@@ -2669,6 +2729,8 @@ static int lookup_open(struct nameidata *nd, struct path *path, +@@ -2669,6 +2727,8 @@ static int lookup_open(struct nameidata *nd, struct path *path, nd->flags & LOOKUP_EXCL); if (error) goto out_dput; @@ -50429,7 +50520,7 @@ index 43a97ee..117e7e4 100644 } out_no_open: path->dentry = dentry; -@@ -2683,7 +2745,7 @@ out_dput: +@@ -2683,7 +2743,7 @@ out_dput: /* * Handle the last step of open() */ @@ -50438,7 +50529,7 @@ index 43a97ee..117e7e4 100644 struct file *file, const struct open_flags *op, int *opened, struct filename *name) { -@@ -2712,16 +2774,44 @@ static int do_last(struct nameidata *nd, struct path *path, +@@ -2712,16 +2772,44 @@ static int do_last(struct nameidata *nd, struct path *path, error = complete_walk(nd); if (error) return error; @@ -50483,7 +50574,7 @@ index 43a97ee..117e7e4 100644 audit_inode(name, dir, 0); goto finish_open; } -@@ -2770,7 +2860,7 @@ retry_lookup: +@@ -2770,7 +2858,7 @@ retry_lookup: */ } mutex_lock(&dir->d_inode->i_mutex); @@ -50492,7 +50583,7 @@ index 43a97ee..117e7e4 100644 mutex_unlock(&dir->d_inode->i_mutex); if (error <= 0) { -@@ -2794,11 +2884,28 @@ retry_lookup: +@@ -2794,11 +2882,28 @@ retry_lookup: goto finish_open_created; } @@ -50522,7 +50613,7 @@ index 43a97ee..117e7e4 100644 /* * If atomic_open() acquired write access it is dropped now due to -@@ -2839,6 +2946,11 @@ finish_lookup: +@@ -2839,6 +2944,11 @@ finish_lookup: } } BUG_ON(inode != path->dentry->d_inode); @@ -50534,7 +50625,7 @@ index 43a97ee..117e7e4 100644 return 1; } -@@ -2848,7 +2960,6 @@ finish_lookup: +@@ -2848,7 +2958,6 @@ finish_lookup: save_parent.dentry = nd->path.dentry; save_parent.mnt = mntget(path->mnt); nd->path.dentry = path->dentry; @@ -50542,7 +50633,7 @@ index 43a97ee..117e7e4 100644 } nd->inode = inode; /* Why this, you ask? _Now_ we might have grown LOOKUP_JUMPED... */ -@@ -2857,6 +2968,22 @@ finish_lookup: +@@ -2857,6 +2966,22 @@ finish_lookup: path_put(&save_parent); return error; } @@ -50565,7 +50656,7 @@ index 43a97ee..117e7e4 100644 error = -EISDIR; if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) goto out; -@@ -2955,7 +3082,7 @@ static struct file *path_openat(int dfd, struct filename *pathname, +@@ -2955,7 +3080,7 @@ static struct file *path_openat(int dfd, struct filename *pathname, if (unlikely(error)) goto out; @@ -50574,7 +50665,7 @@ index 43a97ee..117e7e4 100644 while (unlikely(error > 0)) { /* trailing symlink */ struct path link = path; void *cookie; -@@ -2973,7 +3100,7 @@ static struct file *path_openat(int dfd, struct filename *pathname, +@@ -2973,7 +3098,7 @@ static struct file *path_openat(int dfd, struct filename *pathname, error = follow_link(&link, nd, &cookie); if (unlikely(error)) break; @@ -50583,7 +50674,7 @@ index 43a97ee..117e7e4 100644 put_link(nd, &link, cookie); } out: -@@ -3073,8 +3200,12 @@ struct dentry *kern_path_create(int dfd, const char *pathname, +@@ -3073,8 +3198,12 @@ struct dentry *kern_path_create(int dfd, const char *pathname, goto unlock; error = -EEXIST; @@ -50597,7 +50688,7 @@ index 43a97ee..117e7e4 100644 /* * Special case - lookup gave negative, but... we had foo/bar/ * From the vfs_mknod() POV we just have a negative dentry - -@@ -3126,6 +3257,20 @@ struct dentry *user_path_create(int dfd, const char __user *pathname, +@@ -3126,6 +3255,20 @@ struct dentry *user_path_create(int dfd, const char __user *pathname, } EXPORT_SYMBOL(user_path_create); @@ -50618,7 +50709,7 @@ index 43a97ee..117e7e4 100644 int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev) { int error = may_create(dir, dentry); -@@ -3188,6 +3333,17 @@ retry: +@@ -3188,6 +3331,17 @@ retry: if (!IS_POSIXACL(path.dentry->d_inode)) mode &= ~current_umask(); @@ -50636,7 +50727,7 @@ index 43a97ee..117e7e4 100644 error = security_path_mknod(&path, dentry, mode, dev); if (error) goto out; -@@ -3204,6 +3360,8 @@ retry: +@@ -3204,6 +3358,8 @@ retry: break; } out: @@ -50645,7 +50736,7 @@ index 43a97ee..117e7e4 100644 done_path_create(&path, dentry); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; -@@ -3256,9 +3414,16 @@ retry: +@@ -3256,9 +3412,16 @@ retry: if (!IS_POSIXACL(path.dentry->d_inode)) mode &= ~current_umask(); @@ -50662,7 +50753,7 @@ index 43a97ee..117e7e4 100644 done_path_create(&path, dentry); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; -@@ -3339,6 +3504,8 @@ static long do_rmdir(int dfd, const char __user *pathname) +@@ -3339,6 +3502,8 @@ static long do_rmdir(int dfd, const char __user *pathname) struct filename *name; struct dentry *dentry; struct nameidata nd; @@ -50671,7 +50762,7 @@ index 43a97ee..117e7e4 100644 unsigned int lookup_flags = 0; retry: name = user_path_parent(dfd, pathname, &nd, lookup_flags); -@@ -3371,10 +3538,21 @@ retry: +@@ -3371,10 +3536,21 @@ retry: error = -ENOENT; goto exit3; } @@ -50693,7 +50784,7 @@ index 43a97ee..117e7e4 100644 exit3: dput(dentry); exit2: -@@ -3440,6 +3618,8 @@ static long do_unlinkat(int dfd, const char __user *pathname) +@@ -3440,6 +3616,8 @@ static long do_unlinkat(int dfd, const char __user *pathname) struct dentry *dentry; struct nameidata nd; struct inode *inode = NULL; @@ -50702,7 +50793,7 @@ index 43a97ee..117e7e4 100644 unsigned int lookup_flags = 0; retry: name = user_path_parent(dfd, pathname, &nd, lookup_flags); -@@ -3466,10 +3646,22 @@ retry: +@@ -3466,10 +3644,22 @@ retry: if (!inode) goto slashes; ihold(inode); @@ -50725,7 +50816,7 @@ index 43a97ee..117e7e4 100644 exit2: dput(dentry); } -@@ -3547,9 +3739,17 @@ retry: +@@ -3547,9 +3737,17 @@ retry: if (IS_ERR(dentry)) goto out_putname; @@ -50743,7 +50834,7 @@ index 43a97ee..117e7e4 100644 done_path_create(&path, dentry); if (retry_estale(error, lookup_flags)) { lookup_flags |= LOOKUP_REVAL; -@@ -3623,6 +3823,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, +@@ -3623,6 +3821,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname, { struct dentry *new_dentry; struct path old_path, new_path; @@ -50751,7 +50842,7 @@ index 43a97ee..117e7e4 100644 int how = 0; int error; -@@ -3646,7 +3847,7 @@ retry: +@@ -3646,7 +3845,7 @@ retry: if (error) return error; @@ -50760,7 +50851,7 @@ index 43a97ee..117e7e4 100644 (how & LOOKUP_REVAL)); error = PTR_ERR(new_dentry); if (IS_ERR(new_dentry)) -@@ -3658,11 +3859,28 @@ retry: +@@ -3658,11 +3857,28 @@ retry: error = may_linkat(&old_path); if (unlikely(error)) goto out_dput; @@ -50789,7 +50880,7 @@ index 43a97ee..117e7e4 100644 done_path_create(&new_path, new_dentry); if (retry_estale(error, how)) { how |= LOOKUP_REVAL; -@@ -3908,12 +4126,21 @@ retry: +@@ -3908,12 +4124,21 @@ retry: if (new_dentry == trap) goto exit5; @@ -50811,7 +50902,7 @@ index 43a97ee..117e7e4 100644 exit5: dput(new_dentry); exit4: -@@ -3945,6 +4172,8 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna +@@ -3945,6 +4170,8 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const char *link) { @@ -50820,7 +50911,7 @@ index 43a97ee..117e7e4 100644 int len; len = PTR_ERR(link); -@@ -3954,7 +4183,14 @@ int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const c +@@ -3954,7 +4181,14 @@ int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const c len = strlen(link); if (len > (unsigned) buflen) len = buflen; @@ -50837,7 +50928,7 @@ index 43a97ee..117e7e4 100644 out: return len; diff --git a/fs/namespace.c b/fs/namespace.c -index 55605c5..f2908c8 100644 +index a51054f..f9b53e5 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1215,6 +1215,9 @@ static int do_umount(struct mount *mnt, int flags) @@ -50850,7 +50941,7 @@ index 55605c5..f2908c8 100644 return retval; } -@@ -1234,9 +1237,20 @@ static int do_umount(struct mount *mnt, int flags) +@@ -1234,6 +1237,9 @@ static int do_umount(struct mount *mnt, int flags) br_write_unlock(&vfsmount_lock); up_write(&namespace_sem); release_mounts(&umount_list); @@ -50860,85 +50951,7 @@ index 55605c5..f2908c8 100644 return retval; } -+/* -+ * Is the caller allowed to modify his namespace? -+ */ -+static inline bool may_mount(void) -+{ -+ return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN); -+} -+ - /* - * Now umount can handle mount points as well as block devices. - * This is important for filesystems which use unnamed block devices. -@@ -1255,6 +1269,9 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags) - if (flags & ~(MNT_FORCE | MNT_DETACH | MNT_EXPIRE | UMOUNT_NOFOLLOW)) - return -EINVAL; - -+ if (!may_mount()) -+ return -EPERM; -+ - if (!(flags & UMOUNT_NOFOLLOW)) - lookup_flags |= LOOKUP_FOLLOW; - -@@ -1268,10 +1285,6 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags) - if (!check_mnt(mnt)) - goto dput_and_out; - -- retval = -EPERM; -- if (!ns_capable(mnt->mnt_ns->user_ns, CAP_SYS_ADMIN)) -- goto dput_and_out; -- - retval = do_umount(mnt, flags); - dput_and_out: - /* we mustn't call path_put() as that would clear mnt_expiry_mark */ -@@ -1295,7 +1308,7 @@ SYSCALL_DEFINE1(oldumount, char __user *, name) - - static int mount_is_safe(struct path *path) - { -- if (ns_capable(real_mount(path->mnt)->mnt_ns->user_ns, CAP_SYS_ADMIN)) -+ if (may_mount()) - return 0; - return -EPERM; - #ifdef notyet -@@ -1633,7 +1646,7 @@ static int do_change_type(struct path *path, int flag) - int type; - int err = 0; - -- if (!ns_capable(mnt->mnt_ns->user_ns, CAP_SYS_ADMIN)) -+ if (!may_mount()) - return -EPERM; - - if (path->dentry != path->mnt->mnt_root) -@@ -1797,7 +1810,7 @@ static int do_move_mount(struct path *path, const char *old_name) - struct mount *p; - struct mount *old; - int err = 0; -- if (!ns_capable(real_mount(path->mnt)->mnt_ns->user_ns, CAP_SYS_ADMIN)) -+ if (!may_mount()) - return -EPERM; - if (!old_name || !*old_name) - return -EINVAL; -@@ -1933,16 +1946,14 @@ static int do_new_mount(struct path *path, const char *fstype, int flags, - int mnt_flags, const char *name, void *data) - { - struct file_system_type *type; -- struct user_namespace *user_ns; -+ struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns; - struct vfsmount *mnt; - int err; - - if (!fstype) - return -EINVAL; - -- /* we need capabilities... */ -- user_ns = real_mount(path->mnt)->mnt_ns->user_ns; -- if (!ns_capable(user_ns, CAP_SYS_ADMIN)) -+ if (!may_mount()) - return -EPERM; - - type = get_fs_type(fstype); -@@ -2282,6 +2293,16 @@ long do_mount(const char *dev_name, const char *dir_name, +@@ -2287,6 +2293,16 @@ long do_mount(const char *dev_name, const char *dir_name, MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT | MS_STRICTATIME); @@ -50955,7 +50968,7 @@ index 55605c5..f2908c8 100644 if (flags & MS_REMOUNT) retval = do_remount(&path, flags & ~MS_REMOUNT, mnt_flags, data_page); -@@ -2296,6 +2317,9 @@ long do_mount(const char *dev_name, const char *dir_name, +@@ -2301,6 +2317,9 @@ long do_mount(const char *dev_name, const char *dir_name, dev_name, data_page); dput_out: path_put(&path); @@ -50965,16 +50978,7 @@ index 55605c5..f2908c8 100644 return retval; } -@@ -2567,7 +2591,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, - struct mount *new_mnt, *root_mnt; - int error; - -- if (!ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN)) -+ if (!may_mount()) - return -EPERM; - - error = user_path_dir(new_root, &new); -@@ -2582,6 +2606,11 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, +@@ -2587,6 +2606,11 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, if (error) goto out2; @@ -50986,7 +50990,7 @@ index 55605c5..f2908c8 100644 get_fs_root(current->fs, &root); error = lock_mount(&old); if (error) -@@ -2785,7 +2814,7 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns) +@@ -2790,7 +2814,7 @@ static int mntns_install(struct nsproxy *nsproxy, void *ns) !nsown_capable(CAP_SYS_ADMIN)) return -EPERM; @@ -67510,10 +67514,18 @@ index 14a8ff2..21fe4c7 100644 void __user *, size_t *, loff_t *); extern int proc_dointvec_minmax(struct ctl_table *, int, diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h -index 7faf933..eb6f5e3 100644 +index 7faf933..c1ad32c 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h -@@ -36,7 +36,7 @@ struct sysrq_key_op { +@@ -15,6 +15,7 @@ + #define _LINUX_SYSRQ_H + + #include <linux/errno.h> ++#include <linux/compiler.h> + #include <linux/types.h> + + /* Enable/disable SYSRQ support by default (0==no, 1==yes). */ +@@ -36,7 +37,7 @@ struct sysrq_key_op { char *help_msg; char *action_msg; int enable_mask; @@ -68218,7 +68230,7 @@ index fdeb85a..0c554d5 100644 /* Structure to track chunk fragments that have been acked, but peer diff --git a/include/net/sock.h b/include/net/sock.h -index 182ca99..b7dc290 100644 +index 25afaa0..8bb0070 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -322,7 +322,7 @@ struct sock { @@ -70501,7 +70513,7 @@ index c535f33..1d768f9 100644 else new_fs = fs; diff --git a/kernel/futex.c b/kernel/futex.c -index 19eb089..b8c65ea 100644 +index 8879430..31696f1 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -54,6 +54,7 @@ @@ -70524,7 +70536,7 @@ index 19eb089..b8c65ea 100644 /* * The futex address must be "naturally" aligned. */ -@@ -2733,6 +2739,7 @@ static int __init futex_init(void) +@@ -2731,6 +2737,7 @@ static int __init futex_init(void) { u32 curval; int i; @@ -70532,7 +70544,7 @@ index 19eb089..b8c65ea 100644 /* * This will fail and we want it. Some arch implementations do -@@ -2744,8 +2751,11 @@ static int __init futex_init(void) +@@ -2742,8 +2749,11 @@ static int __init futex_init(void) * implementation, the non-functional ones will return * -ENOSYS. */ @@ -70570,7 +70582,7 @@ index 9b22d03..6295b62 100644 prev->next = info->next; else diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c -index 6db7a5e..0d600bd 100644 +index cdd5607..c3fc919 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -1407,7 +1407,7 @@ void hrtimer_peek_ahead_timers(void) @@ -72054,10 +72066,10 @@ index f2c6a68..4922d97 100644 { struct pid *pid; diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c -index a278cad..bff5bd3 100644 +index 942ca27..111e609 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c -@@ -1557,14 +1557,14 @@ struct k_clock clock_posix_cpu = { +@@ -1576,14 +1576,14 @@ struct k_clock clock_posix_cpu = { static __init int init_posix_cpu_timers(void) { @@ -73884,7 +73896,7 @@ index c88878d..99d321b 100644 EXPORT_SYMBOL(proc_doulongvec_minmax); EXPORT_SYMBOL(proc_doulongvec_ms_jiffies_minmax); diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c -index 5a63844..25dfc5c 100644 +index 5a63844..a199f50 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c @@ -989,7 +989,7 @@ static ssize_t bin_intvec(struct file *file, @@ -73941,7 +73953,19 @@ index 5a63844..25dfc5c 100644 set_fs(old_fs); if (result < 0) goto out; -@@ -1233,7 +1233,7 @@ static ssize_t bin_dn_node_address(struct file *file, +@@ -1194,9 +1194,10 @@ static ssize_t bin_dn_node_address(struct file *file, + + /* Convert the decnet address to binary */ + result = -EIO; +- nodep = strchr(buf, '.') + 1; ++ nodep = strchr(buf, '.'); + if (!nodep) + goto out; ++ ++nodep; + + area = simple_strtoul(buf, NULL, 10); + node = simple_strtoul(nodep, NULL, 10); +@@ -1233,7 +1234,7 @@ static ssize_t bin_dn_node_address(struct file *file, le16_to_cpu(dnaddr) & 0x3ff); set_fs(KERNEL_DS); @@ -74931,6 +74955,26 @@ index 5e396ac..58d5de1 100644 err_printk(dev, NULL, "DMA-API: device driver maps memory from" "stack [addr=%p]\n", addr); } +diff --git a/lib/idr.c b/lib/idr.c +index 6482390..ca5aa00 100644 +--- a/lib/idr.c ++++ b/lib/idr.c +@@ -625,7 +625,14 @@ void *idr_get_next(struct idr *idp, int *nextidp) + return p; + } + +- id += 1 << n; ++ /* ++ * Proceed to the next layer at the current level. Unlike ++ * idr_for_each(), @id isn't guaranteed to be aligned to ++ * layer boundary at this point and adding 1 << n may ++ * incorrectly skip IDs. Make sure we jump to the ++ * beginning of the next layer using round_up(). ++ */ ++ id = round_up(id + 1, 1 << n); + while (n < fls(id)) { + n += IDR_BITS; + p = *--paa; diff --git a/lib/inflate.c b/lib/inflate.c index 013a761..c28f3fc 100644 --- a/lib/inflate.c @@ -76511,7 +76555,7 @@ index c9bd528..da8d069 100644 capable(CAP_IPC_LOCK)) ret = do_mlockall(flags); diff --git a/mm/mmap.c b/mm/mmap.c -index d1e4124..32a6988 100644 +index d1e4124..7d36e4f 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -32,6 +32,7 @@ @@ -77257,7 +77301,51 @@ index d1e4124..32a6988 100644 spin_unlock(&vma->vm_mm->page_table_lock); perf_event_mmap(vma); -@@ -2236,6 +2544,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) +@@ -2169,9 +2477,28 @@ int expand_downwards(struct vm_area_struct *vma, + return error; + } + ++/* ++ * Note how expand_stack() refuses to expand the stack all the way to ++ * abut the next virtual mapping, *unless* that mapping itself is also ++ * a stack mapping. We want to leave room for a guard page, after all ++ * (the guard page itself is not added here, that is done by the ++ * actual page faulting logic) ++ * ++ * This matches the behavior of the guard page logic (see mm/memory.c: ++ * check_stack_guard_page()), which only allows the guard page to be ++ * removed under these circumstances. ++ */ + #ifdef CONFIG_STACK_GROWSUP + int expand_stack(struct vm_area_struct *vma, unsigned long address) + { ++ struct vm_area_struct *next; ++ ++ address &= PAGE_MASK; ++ next = vma->vm_next; ++ if (next && next->vm_start == address + PAGE_SIZE) { ++ if (!(next->vm_flags & VM_GROWSUP)) ++ return -ENOMEM; ++ } + return expand_upwards(vma, address); + } + +@@ -2194,6 +2521,14 @@ find_extend_vma(struct mm_struct *mm, unsigned long addr) + #else + int expand_stack(struct vm_area_struct *vma, unsigned long address) + { ++ struct vm_area_struct *prev; ++ ++ address &= PAGE_MASK; ++ prev = vma->vm_prev; ++ if (prev && prev->vm_end == address) { ++ if (!(prev->vm_flags & VM_GROWSDOWN)) ++ return -ENOMEM; ++ } + return expand_downwards(vma, address); + } + +@@ -2236,6 +2571,13 @@ static void remove_vma_list(struct mm_struct *mm, struct vm_area_struct *vma) do { long nrpages = vma_pages(vma); @@ -77271,7 +77359,7 @@ index d1e4124..32a6988 100644 if (vma->vm_flags & VM_ACCOUNT) nr_accounted += nrpages; vm_stat_account(mm, vma->vm_flags, vma->vm_file, -nrpages); -@@ -2281,6 +2596,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2281,6 +2623,16 @@ detach_vmas_to_be_unmapped(struct mm_struct *mm, struct vm_area_struct *vma, insertion_point = (prev ? &prev->vm_next : &mm->mmap); vma->vm_prev = NULL; do { @@ -77288,7 +77376,7 @@ index d1e4124..32a6988 100644 vma_rb_erase(vma, &mm->mm_rb); mm->map_count--; tail_vma = vma; -@@ -2312,14 +2637,33 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2312,14 +2664,33 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, struct vm_area_struct *new; int err = -ENOMEM; @@ -77322,7 +77410,7 @@ index d1e4124..32a6988 100644 /* most fields are the same, copy all, and then fixup */ *new = *vma; -@@ -2332,6 +2676,22 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2332,6 +2703,22 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, new->vm_pgoff += ((addr - vma->vm_start) >> PAGE_SHIFT); } @@ -77345,7 +77433,7 @@ index d1e4124..32a6988 100644 pol = mpol_dup(vma_policy(vma)); if (IS_ERR(pol)) { err = PTR_ERR(pol); -@@ -2354,6 +2714,36 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2354,6 +2741,36 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, else err = vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new); @@ -77382,7 +77470,7 @@ index d1e4124..32a6988 100644 /* Success. */ if (!err) return 0; -@@ -2363,10 +2753,18 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2363,10 +2780,18 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, new->vm_ops->close(new); if (new->vm_file) fput(new->vm_file); @@ -77402,7 +77490,7 @@ index d1e4124..32a6988 100644 kmem_cache_free(vm_area_cachep, new); out_err: return err; -@@ -2379,6 +2777,15 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, +@@ -2379,6 +2804,15 @@ static int __split_vma(struct mm_struct * mm, struct vm_area_struct * vma, int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, int new_below) { @@ -77418,7 +77506,7 @@ index d1e4124..32a6988 100644 if (mm->map_count >= sysctl_max_map_count) return -ENOMEM; -@@ -2390,11 +2797,30 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, +@@ -2390,11 +2824,30 @@ int split_vma(struct mm_struct *mm, struct vm_area_struct *vma, * work. This now handles partial unmappings. * Jeremy Fitzhardinge <jeremy@goop.org> */ @@ -77449,7 +77537,7 @@ index d1e4124..32a6988 100644 if ((start & ~PAGE_MASK) || start > TASK_SIZE || len > TASK_SIZE-start) return -EINVAL; -@@ -2469,6 +2895,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) +@@ -2469,6 +2922,8 @@ int do_munmap(struct mm_struct *mm, unsigned long start, size_t len) /* Fix up all other VM information */ remove_vma_list(mm, vma); @@ -77458,7 +77546,7 @@ index d1e4124..32a6988 100644 return 0; } -@@ -2477,6 +2905,13 @@ int vm_munmap(unsigned long start, size_t len) +@@ -2477,6 +2932,13 @@ int vm_munmap(unsigned long start, size_t len) int ret; struct mm_struct *mm = current->mm; @@ -77472,7 +77560,7 @@ index d1e4124..32a6988 100644 down_write(&mm->mmap_sem); ret = do_munmap(mm, start, len); up_write(&mm->mmap_sem); -@@ -2490,16 +2925,6 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) +@@ -2490,16 +2952,6 @@ SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len) return vm_munmap(addr, len); } @@ -77489,7 +77577,7 @@ index d1e4124..32a6988 100644 /* * this is really a simplified "do_mmap". it only handles * anonymous maps. eventually we may be able to do some -@@ -2513,6 +2938,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2513,6 +2965,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) struct rb_node ** rb_link, * rb_parent; pgoff_t pgoff = addr >> PAGE_SHIFT; int error; @@ -77497,7 +77585,7 @@ index d1e4124..32a6988 100644 len = PAGE_ALIGN(len); if (!len) -@@ -2520,16 +2946,30 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2520,16 +2973,30 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) flags = VM_DATA_DEFAULT_FLAGS | VM_ACCOUNT | mm->def_flags; @@ -77529,7 +77617,7 @@ index d1e4124..32a6988 100644 locked += mm->locked_vm; lock_limit = rlimit(RLIMIT_MEMLOCK); lock_limit >>= PAGE_SHIFT; -@@ -2546,21 +2986,20 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2546,21 +3013,20 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) /* * Clear old maps. this also does some error checking for us */ @@ -77554,7 +77642,7 @@ index d1e4124..32a6988 100644 return -ENOMEM; /* Can we just expand an old private anonymous mapping? */ -@@ -2574,7 +3013,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2574,7 +3040,7 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) */ vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); if (!vma) { @@ -77563,7 +77651,7 @@ index d1e4124..32a6988 100644 return -ENOMEM; } -@@ -2588,11 +3027,12 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) +@@ -2588,11 +3054,12 @@ static unsigned long do_brk(unsigned long addr, unsigned long len) vma_link(mm, vma, prev, rb_link, rb_parent); out: perf_event_mmap(vma); @@ -77578,7 +77666,7 @@ index d1e4124..32a6988 100644 return addr; } -@@ -2650,6 +3090,7 @@ void exit_mmap(struct mm_struct *mm) +@@ -2650,6 +3117,7 @@ void exit_mmap(struct mm_struct *mm) while (vma) { if (vma->vm_flags & VM_ACCOUNT) nr_accounted += vma_pages(vma); @@ -77586,7 +77674,7 @@ index d1e4124..32a6988 100644 vma = remove_vma(vma); } vm_unacct_memory(nr_accounted); -@@ -2666,6 +3107,13 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma) +@@ -2666,6 +3134,13 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma) struct vm_area_struct *prev; struct rb_node **rb_link, *rb_parent; @@ -77600,7 +77688,7 @@ index d1e4124..32a6988 100644 /* * The vm_pgoff of a purely anonymous vma should be irrelevant * until its first write fault, when page's anon_vma and index -@@ -2689,7 +3137,21 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma) +@@ -2689,7 +3164,21 @@ int insert_vm_struct(struct mm_struct *mm, struct vm_area_struct *vma) security_vm_enough_memory_mm(mm, vma_pages(vma))) return -ENOMEM; @@ -77622,7 +77710,7 @@ index d1e4124..32a6988 100644 return 0; } -@@ -2709,6 +3171,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2709,6 +3198,8 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, struct mempolicy *pol; bool faulted_in_anon_vma = true; @@ -77631,7 +77719,7 @@ index d1e4124..32a6988 100644 /* * If anonymous vma has not yet been faulted, update new pgoff * to match new location, to increase its chance of merging. -@@ -2775,6 +3239,39 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, +@@ -2775,6 +3266,39 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, return NULL; } @@ -77671,7 +77759,7 @@ index d1e4124..32a6988 100644 /* * Return true if the calling process may expand its vm space by the passed * number of pages -@@ -2786,6 +3283,12 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages) +@@ -2786,6 +3310,12 @@ int may_expand_vm(struct mm_struct *mm, unsigned long npages) lim = rlimit(RLIMIT_AS) >> PAGE_SHIFT; @@ -77684,7 +77772,7 @@ index d1e4124..32a6988 100644 if (cur + npages > lim) return 0; return 1; -@@ -2856,6 +3359,22 @@ int install_special_mapping(struct mm_struct *mm, +@@ -2856,6 +3386,22 @@ int install_special_mapping(struct mm_struct *mm, vma->vm_start = addr; vma->vm_end = addr + len; @@ -77707,136 +77795,6 @@ index d1e4124..32a6988 100644 vma->vm_flags = vm_flags | mm->def_flags | VM_DONTEXPAND; vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); -diff --git a/mm/mmu_notifier.c b/mm/mmu_notifier.c -index 8a5ac8c..f5c3d96 100644 ---- a/mm/mmu_notifier.c -+++ b/mm/mmu_notifier.c -@@ -37,49 +37,51 @@ static struct srcu_struct srcu; - void __mmu_notifier_release(struct mm_struct *mm) - { - struct mmu_notifier *mn; -- struct hlist_node *n; - int id; - - /* -- * SRCU here will block mmu_notifier_unregister until -- * ->release returns. -+ * srcu_read_lock() here will block synchronize_srcu() in -+ * mmu_notifier_unregister() until all registered -+ * ->release() callouts this function makes have -+ * returned. - */ - id = srcu_read_lock(&srcu); -- hlist_for_each_entry_rcu(mn, n, &mm->mmu_notifier_mm->list, hlist) -- /* -- * if ->release runs before mmu_notifier_unregister it -- * must be handled as it's the only way for the driver -- * to flush all existing sptes and stop the driver -- * from establishing any more sptes before all the -- * pages in the mm are freed. -- */ -- if (mn->ops->release) -- mn->ops->release(mn, mm); -- srcu_read_unlock(&srcu, id); -- - spin_lock(&mm->mmu_notifier_mm->lock); - while (unlikely(!hlist_empty(&mm->mmu_notifier_mm->list))) { - mn = hlist_entry(mm->mmu_notifier_mm->list.first, - struct mmu_notifier, - hlist); -+ - /* -- * We arrived before mmu_notifier_unregister so -- * mmu_notifier_unregister will do nothing other than -- * to wait ->release to finish and -- * mmu_notifier_unregister to return. -+ * Unlink. This will prevent mmu_notifier_unregister() -+ * from also making the ->release() callout. - */ - hlist_del_init_rcu(&mn->hlist); -+ spin_unlock(&mm->mmu_notifier_mm->lock); -+ -+ /* -+ * Clear sptes. (see 'release' description in mmu_notifier.h) -+ */ -+ if (mn->ops->release) -+ mn->ops->release(mn, mm); -+ -+ spin_lock(&mm->mmu_notifier_mm->lock); - } - spin_unlock(&mm->mmu_notifier_mm->lock); - - /* -- * synchronize_srcu here prevents mmu_notifier_release to -- * return to exit_mmap (which would proceed freeing all pages -- * in the mm) until the ->release method returns, if it was -- * invoked by mmu_notifier_unregister. -- * -- * The mmu_notifier_mm can't go away from under us because one -- * mm_count is hold by exit_mmap. -+ * All callouts to ->release() which we have done are complete. -+ * Allow synchronize_srcu() in mmu_notifier_unregister() to complete -+ */ -+ srcu_read_unlock(&srcu, id); -+ -+ /* -+ * mmu_notifier_unregister() may have unlinked a notifier and may -+ * still be calling out to it. Additionally, other notifiers -+ * may have been active via vmtruncate() et. al. Block here -+ * to ensure that all notifier callouts for this mm have been -+ * completed and the sptes are really cleaned up before returning -+ * to exit_mmap(). - */ - synchronize_srcu(&srcu); - } -@@ -294,31 +296,31 @@ void mmu_notifier_unregister(struct mmu_notifier *mn, struct mm_struct *mm) - { - BUG_ON(atomic_read(&mm->mm_count) <= 0); - -+ spin_lock(&mm->mmu_notifier_mm->lock); - if (!hlist_unhashed(&mn->hlist)) { -- /* -- * SRCU here will force exit_mmap to wait ->release to finish -- * before freeing the pages. -- */ - int id; - -+ /* -+ * Ensure we synchronize up with __mmu_notifier_release(). -+ */ - id = srcu_read_lock(&srcu); -- /* -- * exit_mmap will block in mmu_notifier_release to -- * guarantee ->release is called before freeing the -- * pages. -- */ -- if (mn->ops->release) -- mn->ops->release(mn, mm); -- srcu_read_unlock(&srcu, id); - -- spin_lock(&mm->mmu_notifier_mm->lock); - hlist_del_rcu(&mn->hlist); - spin_unlock(&mm->mmu_notifier_mm->lock); -- } -+ -+ if (mn->ops->release) -+ mn->ops->release(mn, mm); -+ -+ /* -+ * Allow __mmu_notifier_release() to complete. -+ */ -+ srcu_read_unlock(&srcu, id); -+ } else -+ spin_unlock(&mm->mmu_notifier_mm->lock); - - /* -- * Wait any running method to finish, of course including -- * ->release if it was run by mmu_notifier_relase instead of us. -+ * Wait for any running method to finish, including ->release() if it -+ * was run by __mmu_notifier_release() instead of us. - */ - synchronize_srcu(&srcu); - diff --git a/mm/mprotect.c b/mm/mprotect.c index 94722a4..9837984 100644 --- a/mm/mprotect.c @@ -78441,7 +78399,7 @@ index 2c78f8c..9e9c624 100644 struct anon_vma_chain *avc; struct anon_vma *anon_vma; diff --git a/mm/shmem.c b/mm/shmem.c -index 5dd56f6..994b702 100644 +index efd0b3a..994b702 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -31,7 +31,7 @@ @@ -78490,31 +78448,7 @@ index 5dd56f6..994b702 100644 return simple_xattr_set(&info->xattrs, name, value, size, flags); } -@@ -2487,6 +2501,7 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) - unsigned long inodes; - int error = -EINVAL; - -+ config.mpol = NULL; - if (shmem_parse_options(data, &config, true)) - return error; - -@@ -2511,8 +2526,13 @@ static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) - sbinfo->max_inodes = config.max_inodes; - sbinfo->free_inodes = config.max_inodes - inodes; - -- mpol_put(sbinfo->mpol); -- sbinfo->mpol = config.mpol; /* transfers initial ref */ -+ /* -+ * Preserve previous mempolicy unless mpol remount option was specified. -+ */ -+ if (config.mpol) { -+ mpol_put(sbinfo->mpol); -+ sbinfo->mpol = config.mpol; /* transfers initial ref */ -+ } - out: - spin_unlock(&sbinfo->stat_lock); - return error; -@@ -2556,8 +2576,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) +@@ -2562,8 +2576,7 @@ int shmem_fill_super(struct super_block *sb, void *data, int silent) int err = -ENOMEM; /* Round up to L1_CACHE_BYTES to resist false sharing */ @@ -80788,7 +80722,7 @@ index bc131d4..029e378 100644 EXPORT_SYMBOL(sock_init_data); diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c -index 602cd63..0a699b1 100644 +index 750f44f..0a699b1 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c @@ -15,20 +15,27 @@ static DEFINE_MUTEX(sock_diag_table_mutex); @@ -80841,14 +80775,11 @@ index 602cd63..0a699b1 100644 static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) { int err; -@@ -121,12 +113,20 @@ static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) - if (nlmsg_len(nlh) < sizeof(*req)) +@@ -124,12 +116,17 @@ static int __sock_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) + if (req->sdiag_family >= AF_MAX) return -EINVAL; - hndl = sock_diag_lock_handler(req->sdiag_family); -+ if (req->sdiag_family >= AF_MAX) -+ return -EINVAL; -+ + if (sock_diag_handlers[req->sdiag_family] == NULL) + request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, + NETLINK_SOCK_DIAG, req->sdiag_family); @@ -81176,7 +81107,7 @@ index 17c5e06..1b91206 100644 case IPT_SO_GET_ENTRIES: diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c -index 6f9c072..38ea6c6 100644 +index dc454cc..5bb917f 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c @@ -844,7 +844,7 @@ static void ping_format_sock(struct sock *sp, struct seq_file *f, @@ -85360,19 +85291,6 @@ index 6ece7f2..ecdb55c 100644 goto error; buflen -= tmp; -diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c -index 20e4bf5..58dfe08 100644 ---- a/security/keys/process_keys.c -+++ b/security/keys/process_keys.c -@@ -367,6 +367,8 @@ key_ref_t search_my_process_keyrings(struct key_type *type, - - switch (PTR_ERR(key_ref)) { - case -EAGAIN: /* no key */ -+ if (ret) -+ break; - case -ENOKEY: /* negative key */ - ret = key_ref; - break; diff --git a/security/min_addr.c b/security/min_addr.c index f728728..6457a0c 100644 --- a/security/min_addr.c diff --git a/3.8.0/4425_grsec_remove_EI_PAX.patch b/3.8.1/4425_grsec_remove_EI_PAX.patch index 97e6951..97e6951 100644 --- a/3.8.0/4425_grsec_remove_EI_PAX.patch +++ b/3.8.1/4425_grsec_remove_EI_PAX.patch diff --git a/3.8.0/4430_grsec-remove-localversion-grsec.patch b/3.8.1/4430_grsec-remove-localversion-grsec.patch index 31cf878..31cf878 100644 --- a/3.8.0/4430_grsec-remove-localversion-grsec.patch +++ b/3.8.1/4430_grsec-remove-localversion-grsec.patch diff --git a/3.8.0/4435_grsec-mute-warnings.patch b/3.8.1/4435_grsec-mute-warnings.patch index e1a7a3c..e1a7a3c 100644 --- a/3.8.0/4435_grsec-mute-warnings.patch +++ b/3.8.1/4435_grsec-mute-warnings.patch diff --git a/3.8.0/4440_grsec-remove-protected-paths.patch b/3.8.1/4440_grsec-remove-protected-paths.patch index 637934a..637934a 100644 --- a/3.8.0/4440_grsec-remove-protected-paths.patch +++ b/3.8.1/4440_grsec-remove-protected-paths.patch diff --git a/3.8.0/4450_grsec-kconfig-default-gids.patch b/3.8.1/4450_grsec-kconfig-default-gids.patch index 3dfdc8f..3dfdc8f 100644 --- a/3.8.0/4450_grsec-kconfig-default-gids.patch +++ b/3.8.1/4450_grsec-kconfig-default-gids.patch diff --git a/3.8.0/4465_selinux-avc_audit-log-curr_ip.patch b/3.8.1/4465_selinux-avc_audit-log-curr_ip.patch index 5b614b1..5b614b1 100644 --- a/3.8.0/4465_selinux-avc_audit-log-curr_ip.patch +++ b/3.8.1/4465_selinux-avc_audit-log-curr_ip.patch diff --git a/3.8.0/4470_disable-compat_vdso.patch b/3.8.1/4470_disable-compat_vdso.patch index 1037ba9..1037ba9 100644 --- a/3.8.0/4470_disable-compat_vdso.patch +++ b/3.8.1/4470_disable-compat_vdso.patch |