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 = &current->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