[RFC] prevention of syscalls from writable segments, breaking bug

Dan Aloni (karrde@callisto.yi.org)
Wed, 3 Jan 2001 23:13:31 +0200 (IST)


It is known that most remote exploits use the fact that stacks are
executable (in i386, at least).

On Linux, they use INT 80 system calls to execute functions in the kernel
as root, when the stack is smashed as a result of a buffer overflow bug in
various server software.

This preliminary, small patch prevents execution of system calls which
were executed from a writable segment. It was tested and seems to work,
without breaking anything. It also reports of such calls by using printk.

--- linux/arch/i386/kernel/entry.S Tue Dec 12 20:04:08 2000
+++ linux/arch/i386/kernel/entry.S Wed Jan 3 22:46:24 2001
@@ -78,8 +78,16 @@
exec_domain = 16
need_resched = 20
tsk_ptrace = 24
+tsk_mm = 44
processor = 52

+/*
+ * these are offsets into vm_area_struct
+ */
+
+vmas_flags = 20
+
+
ENOSYS = 38


@@ -196,6 +204,26 @@
pushl %eax # save orig_eax
SAVE_ALL
GET_CURRENT(%ebx)
+
+ /* only execute code from non-writable segments */
+ pushl %ebx
+ pushl %eax
+ movl tsk_mm(%ebx),%eax # get current->mm
+ movl (EIP+8)(%esp),%ebx # get caller EIP
+ pushl %ebx
+ pushl %eax
+ call find_vma
+ addl $8,%esp
+ testl %eax,%eax
+ je no_vm_area
+ movl vmas_flags(%eax), %ebx
+ andl $0x02, %ebx
+ cmpl $0x02, %ebx
+ je sys_from_wrong_mem
+no_vm_area:
+ popl %eax
+ popl %ebx
+
cmpl $(NR_syscalls),%eax
jae badsys
testb $0x02,tsk_ptrace(%ebx) # PT_TRACESYS
@@ -252,6 +280,15 @@
tracesys_exit:
call SYMBOL_NAME(syscall_trace)
jmp ret_from_sys_call
+
+sys_from_wrong_mem:
+ GET_CURRENT(%ebx)
+ push %ebx
+ call print_bad_syscall
+ addl $4,%esp
+
+ popl %eax
+ popl %ebx
badsys:
movl $-ENOSYS,EAX(%esp)
jmp ret_from_sys_call
--- linux/arch/i386/kernel/process.c Wed Jan 3 22:57:42 2001
+++ linux/arch/i386/kernel/process.c Wed Jan 3 22:57:55 2001
@@ -765,3 +765,8 @@
}
#undef last_sched
#undef first_sched
+
+void print_bad_syscall(struct task_struct *task)
+{
+ printk("process %s (%d) tried to syscall from an executable segment!\n", task->comm, task->pid);
+}

-- 
Dan Aloni 
dax@karrde.org

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/