rpms/kernel/devel kernel.spec, 1.1222, 1.1223 linux-2.6-execshield.patch, 1.101, 1.102
Kyle McMartin
kyle at fedoraproject.org
Mon Jan 19 06:23:58 UTC 2009
Author: kyle
Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv3677
Modified Files:
kernel.spec linux-2.6-execshield.patch
Log Message:
* Mon Jan 19 2009 Kyle McMartin <kyle at redhat.com>
- execshield fixes: should no longer generate spurious handled GPFs,
fixes randomization of executables. also some clean ups.
Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.1222
retrieving revision 1.1223
diff -u -r1.1222 -r1.1223
--- kernel.spec 18 Jan 2009 01:49:11 -0000 1.1222
+++ kernel.spec 19 Jan 2009 06:23:28 -0000 1.1223
@@ -1735,6 +1735,10 @@
%kernel_variant_files -k vmlinux %{with_kdump} kdump
%changelog
+* Mon Jan 19 2009 Kyle McMartin <kyle at redhat.com>
+- execshield fixes: should no longer generate spurious handled GPFs,
+ fixes randomization of executables. also some clean ups.
+
* Sat Jan 17 2009 Dave Jones <davej at redhat.com>
- 2.6.29-rc2-git1
linux-2.6-execshield.patch:
Index: linux-2.6-execshield.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-execshield.patch,v
retrieving revision 1.101
retrieving revision 1.102
diff -u -r1.101 -r1.102
--- linux-2.6-execshield.patch 10 Jan 2009 07:46:11 -0000 1.101
+++ linux-2.6-execshield.patch 19 Jan 2009 06:23:28 -0000 1.102
@@ -1,5 +1,5 @@
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
-index dc27705..6aa5630 100644
+index dc27705..34ed3a2 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -6,6 +6,7 @@
@@ -20,7 +20,7 @@
#define write_ldt_entry(dt, entry, desc) \
native_write_ldt_entry(dt, entry, desc)
-@@ -379,6 +383,24 @@ static inline void set_system_intr_gate_ist(int n, void *addr, unsigned ist)
+@@ -379,6 +383,27 @@ static inline void set_system_intr_gate_ist(int n, void *addr, unsigned ist)
_set_gate(n, GATE_INTERRUPT, addr, 0x3, ist, __KERNEL_CS);
}
@@ -37,6 +37,9 @@
+ get_cpu_gdt_table(cpu)[GDT_ENTRY_DEFAULT_USER_CS] = (mm)->context.user_cs;
+}
+
++#define arch_add_exec_range arch_add_exec_range
++#define arch_remove_exec_range arch_remove_exec_range
++#define arch_flush_exec_range arch_flush_exec_range
+extern void arch_add_exec_range(struct mm_struct *mm, unsigned long limit);
+extern void arch_remove_exec_range(struct mm_struct *mm, unsigned long limit);
+extern void arch_flush_exec_range(struct mm_struct *mm);
@@ -111,10 +114,10 @@
extern struct pt_regs *idle_regs(struct pt_regs *);
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
-index 3f95a40..2c2893a 100644
+index 83492b1..a84c787 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
-@@ -688,6 +688,21 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
+@@ -708,6 +708,21 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
* we do "generic changes."
*/
@@ -151,21 +154,31 @@
.load_idt = native_load_idt,
.store_gdt = native_store_gdt,
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
-index 3ba155d..09ae04c 100644
+index a546f55..f180caf 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
-@@ -356,6 +356,10 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
+@@ -346,6 +346,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+ void
+ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
+ {
++ int cpu;
++
+ __asm__("movl %0, %%gs" : : "r"(0));
+ regs->fs = 0;
+ set_fs(USER_DS);
+@@ -355,6 +357,11 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
regs->cs = __USER_CS;
regs->ip = new_ip;
regs->sp = new_sp;
-+ preempt_disable();
-+ load_user_cs_desc(smp_processor_id(), current->mm);
-+ preempt_enable();
++
++ cpu = get_cpu();
++ load_user_cs_desc(cpu, current->mm);
++ put_cpu();
+
/*
* Free the old FP and other extended state
*/
-@@ -523,7 +527,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
+@@ -522,7 +529,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
/* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
__unlazy_fpu(prev_p);
@@ -175,7 +188,7 @@
/* we're going to use this soon, after a few expensive things */
if (next_p->fpu_counter > 5)
-@@ -696,3 +701,39 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
+@@ -695,3 +703,41 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
unsigned long range_end = mm->brk + 0x02000000;
return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
}
@@ -185,9 +198,11 @@
+ mm->context.exec_limit = limit;
+ set_user_cs(&mm->context.user_cs, limit);
+ if (mm == current->mm) {
-+ preempt_disable();
-+ load_user_cs_desc(smp_processor_id(), mm);
-+ preempt_enable();
++ int cpu;
++
++ cpu = get_cpu();
++ load_user_cs_desc(cpu, mm);
++ put_cpu();
+ }
+}
+
@@ -237,14 +252,25 @@
if (!cpu_isset(cpu, flush_cpumask))
goto out;
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
-index c9a666c..b702c77 100644
+index 98c2d05..db483ea 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
-@@ -157,6 +157,63 @@ static int lazy_iobitmap_copy(void)
+@@ -154,6 +154,76 @@ static int lazy_iobitmap_copy(void)
return 0;
}
+
++static inline int
++__compare_user_cs_desc(const struct desc_struct *desc1,
++ const struct desc_struct *desc2)
++{
++ return ((desc1->limit0 != desc2->limit0) ||
++ (desc1->limit != desc2->limit) ||
++ (desc1->base0 != desc2->base0) ||
++ (desc1->base1 != desc2->base1) ||
++ (desc1->base2 != desc2->base2));
++}
++
+/*
+ * lazy-check for CS validity on exec-shield binaries:
+ *
@@ -281,8 +307,7 @@
+ desc1 = ¤t->mm->context.user_cs;
+ desc2 = get_cpu_gdt_table(cpu) + GDT_ENTRY_DEFAULT_USER_CS;
+
-+ if ((desc1->a & 0xff0000ff) != (desc2->a & 0xff0000ff) ||
-+ desc1->b != desc2->b) {
++ if (__compare_user_cs_desc(desc1, desc2)) {
+ /*
+ * The CS was not in sync - reload it and retry the
+ * instruction. If the instruction still faults then
@@ -290,10 +315,13 @@
+ */
+ if (print_fatal_signals >= 2) {
+ printk(KERN_ERR "#GPF fixup (%ld[seg:%lx]) at %08lx, CPU#%d.\n",
-+ error_code, error_code/8, regs->ip, smp_processor_id());
++ error_code, error_code/8, regs->ip,
++ smp_processor_id());
+ printk(KERN_ERR "exec_limit: %08lx, user_cs: %08x/%08x, CPU_cs: %08x/%08x.\n",
-+ current->mm->context.exec_limit, desc1->a, desc1->b, desc2->a, desc2->b);
++ current->mm->context.exec_limit,
++ desc1->a, desc1->b, desc2->a, desc2->b);
+ }
++
+ load_user_cs_desc(cpu, current->mm);
+
+ return 1;
@@ -304,7 +332,7 @@
#endif
static void __kprobes
-@@ -320,6 +377,29 @@ do_general_protection(struct pt_regs *regs, long error_code)
+@@ -317,6 +387,29 @@ do_general_protection(struct pt_regs *regs, long error_code)
if (!user_mode(regs))
goto gp_in_kernel;
@@ -334,7 +362,7 @@
tsk->thread.error_code = error_code;
tsk->thread.trap_no = 13;
-@@ -926,19 +1006,37 @@ do_device_not_available(struct pt_regs *regs, long error)
+@@ -923,19 +1016,37 @@ do_device_not_available(struct pt_regs *regs, long error)
}
#ifdef CONFIG_X86_32
@@ -584,10 +612,10 @@
min_flt = task->min_flt;
maj_flt = task->maj_flt;
diff --git a/include/linux/mm.h b/include/linux/mm.h
-index b91a73f..a0f6d93 100644
+index e8ddc98..bf87f4a 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
-@@ -1123,7 +1123,13 @@ extern int install_special_mapping(struct mm_struct *mm,
+@@ -1122,7 +1122,13 @@ extern int install_special_mapping(struct mm_struct *mm,
unsigned long addr, unsigned long len,
unsigned long flags, struct page **pages);
@@ -659,7 +687,7 @@
arch_get_unmapped_area_topdown(struct file *filp, unsigned long addr,
unsigned long len, unsigned long pgoff,
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
-index 89d7443..6ea2333 100644
+index 368d163..2e4ab66 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -85,6 +85,26 @@ extern int sysctl_nr_open_min, sysctl_nr_open_max;
@@ -689,7 +717,7 @@
#ifdef CONFIG_RCU_TORTURE_TEST
extern int rcutorture_runnable;
#endif /* #ifdef CONFIG_RCU_TORTURE_TEST */
-@@ -377,6 +397,14 @@ static struct ctl_table kern_table[] = {
+@@ -378,6 +398,14 @@ static struct ctl_table kern_table[] = {
.proc_handler = &proc_dointvec,
},
{
@@ -705,7 +733,7 @@
.procname = "core_uses_pid",
.data = &core_uses_pid,
diff --git a/mm/mmap.c b/mm/mmap.c
-index 7496231..4cfb9fe 100644
+index 8d95902..c84ff1f 100644
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -27,6 +27,7 @@
@@ -793,7 +821,7 @@
if (file && file->f_op && file->f_op->get_unmapped_area)
get_area = file->f_op->get_unmapped_area;
addr = get_area(file, addr, len, pgoff, flags);
-@@ -1459,8 +1483,74 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
+@@ -1459,8 +1483,76 @@ get_unmapped_area(struct file *file, unsigned long addr, unsigned long len,
return arch_rebalance_pgtables(addr, len);
}
@@ -801,7 +829,8 @@
+
+#define SHLIB_BASE 0x00110000
+
-+unsigned long arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
++unsigned long
++arch_get_unmapped_exec_area(struct file *filp, unsigned long addr0,
+ unsigned long len0, unsigned long pgoff, unsigned long flags)
+{
+ unsigned long addr = addr0, len = len0;
@@ -815,9 +844,10 @@
+ if (flags & MAP_FIXED)
+ return addr;
+
-+ if (!addr) {
++ if (!addr)
+ addr = randomize_range(SHLIB_BASE, 0x01000000, len);
-+ } else {
++
++ if (addr) {
+ addr = PAGE_ALIGN(addr);
+ vma = find_vma(mm, addr);
+ if (TASK_SIZE - len >= addr &&
@@ -869,7 +899,7 @@
/* Look up the first VMA which satisfies addr < vm_end, NULL if none. */
struct vm_area_struct *find_vma(struct mm_struct *mm, unsigned long addr)
-@@ -1535,6 +1625,14 @@ out:
+@@ -1535,6 +1627,14 @@ out:
return prev ? prev->vm_next : vma;
}
@@ -884,7 +914,7 @@
/*
* Verify that the stack growth is acceptable and
* update accounting. This is shared with both the
-@@ -1551,7 +1649,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
+@@ -1551,7 +1651,7 @@ static int acct_stack_growth(struct vm_area_struct *vma, unsigned long size, uns
return -ENOMEM;
/* Stack limit test */
@@ -893,7 +923,7 @@
return -ENOMEM;
/* mlock limit tests */
-@@ -1861,10 +1959,14 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
+@@ -1861,10 +1961,14 @@ int split_vma(struct mm_struct * mm, struct vm_area_struct * vma,
if (new->vm_ops && new->vm_ops->open)
new->vm_ops->open(new);
@@ -910,7 +940,7 @@
vma_adjust(vma, vma->vm_start, addr, vma->vm_pgoff, new);
return 0;
-@@ -2111,6 +2213,7 @@ void exit_mmap(struct mm_struct *mm)
+@@ -2111,6 +2215,7 @@ void exit_mmap(struct mm_struct *mm)
vm_unacct_memory(nr_accounted);
free_pgtables(tlb, vma, FIRST_USER_ADDRESS, 0);
tlb_finish_mmu(tlb, 0, end);
@@ -919,26 +949,25 @@
/*
* Walk the list again, actually closing and freeing it,
diff --git a/mm/mprotect.c b/mm/mprotect.c
-index d0f6e7c..d51a400 100644
+index abe2694..eb16148 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
-@@ -25,8 +25,15 @@
+@@ -25,9 +25,14 @@
#include <linux/migrate.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/cacheflush.h>
#include <asm/tlbflush.h>
-+#ifdef CONFIG_X86
-+#include <asm/desc.h>
-+#endif
+
+#ifndef arch_remove_exec_range
+#define arch_remove_exec_range(mm, limit) do { ; } while (0)
+#endif
-
++
#ifndef pgprot_modify
static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
-@@ -138,7 +145,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
+ {
+@@ -138,7 +143,7 @@ mprotect_fixup(struct vm_area_struct *vma, struct vm_area_struct **pprev,
struct mm_struct *mm = vma->vm_mm;
unsigned long oldflags = vma->vm_flags;
long nrpages = (end - start) >> PAGE_SHIFT;
@@ -947,7 +976,7 @@
pgoff_t pgoff;
int error;
int dirty_accountable = 0;
-@@ -202,6 +209,9 @@ success:
+@@ -202,6 +207,9 @@ success:
dirty_accountable = 1;
}
@@ -958,7 +987,7 @@
if (is_vm_hugetlb_page(vma))
hugetlb_change_protection(vma, start, end, vma->vm_page_prot);
diff --git a/mm/mremap.c b/mm/mremap.c
-index 646de95..b77db03 100644
+index a39b7b9..6bebfde 100644
--- a/mm/mremap.c
+++ b/mm/mremap.c
@@ -400,8 +400,8 @@ unsigned long do_mremap(unsigned long addr,
More information about the scm-commits
mailing list