示例#1
0
static void modify_cs(struct mm_struct *mm, unsigned long limit)
{
	mm->context.exec_limit = limit;
	set_user_cs(&mm->context.user_cs, limit);
	if (mm == current->mm) {
		int cpu;

		cpu = get_cpu();
		load_user_cs_desc(cpu, mm);
		put_cpu();
	}
}
示例#2
0
/*
 * lazy-check for CS validity on exec-shield binaries:
 *
 * the original non-exec stack patch was written by
 * Solar Designer <solar at openwall.com>. Thanks!
 */
static int
check_lazy_exec_limit(int cpu, struct pt_regs *regs, long error_code)
{
	struct desc_struct *desc1, *desc2;
	struct vm_area_struct *vma;
	unsigned long limit;

	if (current->mm == NULL)
		return 0;

	limit = -1UL;
	if (current->mm->context.exec_limit != -1UL) {
		limit = PAGE_SIZE;
		spin_lock(&current->mm->page_table_lock);
		for (vma = current->mm->mmap; vma; vma = vma->vm_next)
			if ((vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
				limit = vma->vm_end;
		vma = get_gate_vma(current->mm);
		if (vma && (vma->vm_flags & VM_EXEC) && (vma->vm_end > limit))
			limit = vma->vm_end;
		spin_unlock(&current->mm->page_table_lock);
		if (limit >= TASK_SIZE)
			limit = -1UL;
		current->mm->context.exec_limit = limit;
	}
	set_user_cs(&current->mm->context.user_cs, limit);

	desc1 = &current->mm->context.user_cs;
	desc2 = get_cpu_gdt_table(cpu) + GDT_ENTRY_DEFAULT_USER_CS;

	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
		 * we won't hit this branch next time around.
		 */
		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());
			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);
		}

		load_user_cs_desc(cpu, current->mm);

		return 1;
	}

	return 0;
}
示例#3
0
void arch_flush_exec_range(struct mm_struct *mm)
{
	mm->context.exec_limit = 0;
	set_user_cs(&mm->context.user_cs, 0);
}